From 2550b996ab84fc2aa198771d8067c0871d681f85 Mon Sep 17 00:00:00 2001 From: Bruce Irschick Date: Fri, 17 Jun 2022 16:34:03 -0700 Subject: [PATCH] [AD-767] apply .clang-format to all our code (#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. * [AD-521] remove unnecessary comment * [AD-589] fix merge issues * I missed this part of code when I was resolving the merge conflicts. Now they are corrected * [AD-589] update getMetaData JNI wrapper code to pass &errInfo * implement unit test for getMetaData * [AD-589] implement JNI wrapper for DocumentDbDatabaseSchemaMetadataGetSchemaName * implement Java class for * define constant for DocumentDbDatabaseSchemaMetadataGetSchemaName * add empty test function for TestDocumentDbDatabaseSchemaMetadataGetSchemaName * [AD-589] implement unit test for DbDatabaseSchemaMetadataGetSchemaName * [AD-521] refactor - change case of ssh to SSH for consistency * [AD-589] address code review comments * rename DocumentDbConnectionGetMetaData to DocumentDbConnectionGetDatabaseMetaData * [AD-589] change case from MetaData to Metadata to match Java method name * [AD-589] refactor: change from metaData to metadata changes occurred in: * DocumentDbConnectionGetDatabaseMetadata * DocumentDbDatabaseSchemaMetadataGetSchemaName * TestDocumentDbConnectionGetDatabaseMetadata * TestDocumentDbDatabaseSchemaMetadataGetSchemaName * Birschick bq/sync up (#21) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-735] large dataset crash issue (#23) * first test * fix performance test crash * fix performance test crash * fix whitespace issue * rework based on comments * SQLPrimaryKey using JNI * odbc test failure fix * Revert "odbc test failure fix" This reverts commit c75194688a0969edae20f59cbe6c55cf5eb4a4da. * Revert "SQLPrimaryKey using JNI" This reverts commit 02380e9e434a55a9b034da138f7d0d32d1654708. * [AD-550] Adapt Foreign Keys (#24) * [AD-550] JNI implementation for getImportedKeys * [AD-550] update Pull Request Template * added reviewees Roy Zhang and Micthell Elholm * [AD-550] add todo note to unit test * [AD-550] define GetImportedKeys in database_metadata.h/.cpp * add ODBC wrapper code to the JNI call for GetImportedKeys * [AD-550] initialize string vars to be empty string in column_metadata_query * [AD-550] modify ForeignKeysQuery to accept 3 arguments only * modified ForeignKeysQuery to only accept catalog, schema, and table, as other fields are not needed. * [AD-550] update column metadata for foreign keys * [AD-550] fix typo in primary_key_meta.h * [AD-550] define vars for foreign key meta * [AD-550] add getter functions for vars in foreign_key_meta.h * [AD-550] support vars in foreign key meta to be optional * [AD-550] add headers for boost optional * [AD-550] add headers and constructors for foreign key meta * added ForeignKeyMeta constructor, and copy constructor *added ForeignKeyMeta destructor * define ForeignKeyMetaVector * basically, complete foreign_key_meta.h * [AD-550] implement resultset.getSmallInt * implement resultset.getSmallInt taking column indices or column names as parameters * make ColumnMeta::dataType be updated with resultSet.Get()->GetSmallInt to simplify code and readbility * [AD-550] Add foreign_key_meta.cpp * implemented functions: ReadForeignKeysColumnMetaVector ForeignKeyMeta::Read * [AD-550] update CMakeLists to include foreign_key_meta.cpp * [AD-550] implement MakeRequestGetForeignKeysMeta * MakeRequestGetForeignKeysMeta calls GetImportedKeys to get Jni ResultSet object for foreign keys, and then reads the resultSet object to fill in the meta object. * [AD-550] update ForeignKeysQuery::DataAvailable and ForeignKeysQuery::Close * update meta object accordingly whenForeignKeysQuery::Close() is called. * return boolean for whether data is available based on meta object * [AD-550] implement ForeignKeysQuery::Execute and FetchNextRow * the code for ForeignKeysQuery::Execute and ForeignKeysQuery::FetchNextRow is based on ColumnMetadataQuery::Execute and ColumnMetadataQuery::FetchNextRow * [AD-550] fix Mac and Linux build * remove extra qualification on GetSmallInt function * [AD-550] implement ForeignKeysQuery::GetColumn * had formatting changes as well * [AD-550] JNI implementation for getImportedKeys * [AD-550] update Pull Request Template * added reviewees Roy Zhang and Micthell Elholm * [AD-550] add todo note to unit test * [AD-550] define GetImportedKeys in database_metadata.h/.cpp * add ODBC wrapper code to the JNI call for GetImportedKeys * [AD-550] initialize string vars to be empty string in column_metadata_query * [AD-550] modify ForeignKeysQuery to accept 3 arguments only * modified ForeignKeysQuery to only accept catalog, schema, and table, as other fields are not needed. * [AD-550] update column metadata for foreign keys * [AD-550] fix typo in primary_key_meta.h * [AD-550] define vars for foreign key meta * [AD-550] add getter functions for vars in foreign_key_meta.h * [AD-550] support vars in foreign key meta to be optional * [AD-550] add headers for boost optional * [AD-550] add headers and constructors for foreign key meta * added ForeignKeyMeta constructor, and copy constructor *added ForeignKeyMeta destructor * define ForeignKeyMetaVector * basically, complete foreign_key_meta.h * [AD-550] implement resultset.getSmallInt * implement resultset.getSmallInt taking column indices or column names as parameters * make ColumnMeta::dataType be updated with resultSet.Get()->GetSmallInt to simplify code and readbility * [AD-550] Add foreign_key_meta.cpp * implemented functions: ReadForeignKeysColumnMetaVector ForeignKeyMeta::Read * [AD-550] update CMakeLists to include foreign_key_meta.cpp * [AD-550] implement MakeRequestGetForeignKeysMeta * MakeRequestGetForeignKeysMeta calls GetImportedKeys to get Jni ResultSet object for foreign keys, and then reads the resultSet object to fill in the meta object. * [AD-550] update ForeignKeysQuery::DataAvailable and ForeignKeysQuery::Close * update meta object accordingly whenForeignKeysQuery::Close() is called. * return boolean for whether data is available based on meta object * [AD-550] implement ForeignKeysQuery::Execute and FetchNextRow * the code for ForeignKeysQuery::Execute and ForeignKeysQuery::FetchNextRow is based on ColumnMetadataQuery::Execute and ColumnMetadataQuery::FetchNextRow * [AD-550] fix Mac and Linux build * remove extra qualification on GetSmallInt function * [AD-550] implement ForeignKeysQuery::GetColumn * had formatting changes as well * [AD-550] update docs for foreign_keys_query.h * [AD-550] refine SQLForeignKey call * [AD-550] add draft foreign key test for JNI test * [AD-550] add test tables for jni test * [AD-550] update test TestDocumentDbDatabaseMetaDataGetImportedKeys * update test to query virtual table jni_test_001_sub_doc * [AD-550] add SQLForeignKeys sql api test * [AD-550] add logs for ReadForeignKeysColumnMetaVector * PK* variables will contain the list of foreign keys in the specified table * [AD-550] reformat jni_test * [AD-550] implement TestDatabaseMetaDataGetImportedKeys for java_test * [AD-550] add test document meta_queries_test_002_with_array * this document will be used to test SQLForeignKeys in meta_queries_test * [AD-550] refactor TestSQLForeignKeys test * reason: I see that `SQLCHAR empty[] = "";` is used in meta_queries_test, and I think that might be a better way of writing the parameters * [AD-550] add test for SQLForeignKeys in meta_queries_test tests added: * TestGetDataWithForeignKeysReturnsOneFromLocalServer * TestGetDataWithForeignKeysReturnsNone * they use test table meta_queries_test_002_with_array * [AD-550] clean up * add doc for SQLForeignKeys * remove comments * [AD-550] remove commented out code * [AD-550] remove unneeded commented out code * [AD-550] make ODBC pass nullptr for JString catalog and schema for SQLForeignKeys * in getImportedKeys, null boost::optional strings will be passed as nullptr to JDBC * make jni test and java test pass null boost::optional strings to JNI calls for getImportedKeys * ODBC now passes boost::optional strings foreignCatalog and foreignSchema to ExecuteGetForeignKeysQuery function. * [AD-550] add if check for sqlStrLen * if sqlString is empty, return boost::none * [AD-550] debug `choco install cppcheck -y` not working on GitHub Actions * [AD-550] add tests for testing empty string parameters * added Java test TestDatabaseMetaDataGetImportedKeysReturnsNone * added Jni test TestDocumentDbDatabaseMetaDataGetImportedKeysReturnsNone * [AD-550] disable cppcheck * created [AD-752](https://bitquill.atlassian.net/browse/AD-752) to investigate it further. * [AD-550] change the place for code doc for function SQLForeignKeys * [AD-550] update if statement check of SqlStringToOptString * to resolve code review comment * [AD-550] resolve code review comment * The sqlStrLen is an int32_t, so "!sqlStrLen" can be removed * [AD-550] make boost optional strings constant where needed * previously, I changed `const std::string` to `boost::optional< std::string >` in some areas, and this is now fixed by replacing the latter with `boost::optional< const std::string >` * [AD-550] SqlStringToOptString fix * also fixed SqlStringToConstOptString * reason: SQL_NTS is a flag that indicates that the string passed is a null-terminated string. * [AD-550] make tests pass null to SQLForeignKeys * [AD-550] add test case for TestGetDataWithForeignKeysReturnsNone * even with the correct table name, as long as empty strings are passed as catalog/schema, SQL_NO_DATA should be returned * [AD-550] update SqlStringToOptString * [AD-550] update TestSQLForeignKeys to pass NULL as parameters properly * [AD-550] move `const` out of `boost::optional< const std::string >` * reason: `const boost::optional< std::string >` works better than `boost::optional< const std::string >`. * this commit is to resolve code review comments * [AD-550] add meta_queries test that passes catalog as empty string * [AD-550] Set `fetched` to false in ForeignKeysQuery::Close() * [AD-550] add explicit conversion to boost::optional variable initialization * [AD-550] resolve code review comment * remove duplicate code * [AD-550] remove function * removed unneeded function: SqlStringToConstOptString * [AD-649] Add missing documentation (#29) ### Summary [AD-649] Add missing documentation ### Description Update ODBC driver documentation - [x] Documentation about connections string ( Parameters description) - [x] Documentation about DSN configuration window ( with screenshots) - [x] Documentation how the ODBC driver works ( ODBC and JDBC integration) - [x] Documentation what is supported ( link with JDBC driver) ### Related Issue https://bitquill.atlassian.net/browse/AD-649 * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan * [AD-735] large dataset crash issue (#74) ### Summary ODBC driver will not run on large document tests ### Description The performance test crashes for large document tests. 1. The root cause is the wrong memory is passed to SQLBindCol(). The parameter TargetValuePtr is passed &cols[i][0].data_dat[i]. The i could exceed 255 for large table while its max valid value should be 254. The correct value should be 0. 2. The SQLExtendedFetch is deprecated. Replace it with SQLFetch. ### Related Issue https://bitquill.atlassian.net/browse/AD-735 * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. * [AD-521] remove unnecessary comment * [AD-589] fix merge issues * I missed this part of code when I was resolving the merge conflicts. Now they are corrected * [AD-589] update getMetaData JNI wrapper code to pass &errInfo * implement unit test for getMetaData * [AD-589] implement JNI wrapper for DocumentDbDatabaseSchemaMetadataGetSchemaName * implement Java class for * define constant for DocumentDbDatabaseSchemaMetadataGetSchemaName * add empty test function for TestDocumentDbDatabaseSchemaMetadataGetSchemaName * [AD-589] implement unit test for DbDatabaseSchemaMetadataGetSchemaName * [AD-521] refactor - change case of ssh to SSH for consistency * [AD-589] address code review comments * rename DocumentDbConnectionGetMetaData to DocumentDbConnectionGetDatabaseMetaData * [AD-589] change case from MetaData to Metadata to match Java method name * [AD-589] refactor: change from metaData to metadata changes occurred in: * DocumentDbConnectionGetDatabaseMetadata * DocumentDbDatabaseSchemaMetadataGetSchemaName * TestDocumentDbConnectionGetDatabaseMetadata * TestDocumentDbDatabaseSchemaMetadataGetSchemaName * Birschick bq/sync up (#21) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-735] large dataset crash issue (#23) * first test * fix performance test crash * fix performance test crash * fix whitespace issue * rework based on comments Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> * [AD-649] Add missing documentation (#73) * Initial user/developer documentation Co-authored-by: andiem-bq <67925459+andiem-bq@users.noreply.github.com> Co-authored-by: Bruce Irschick Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> * Fix README.md (#30) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan * [AD-735] large dataset crash issue (#74) ### Summary ODBC driver will not run on large document tests ### Description The performance test crashes for large document tests. 1. The root cause is the wrong memory is passed to SQLBindCol(). The parameter TargetValuePtr is passed &cols[i][0].data_dat[i]. The i could exceed 255 for large table while its max valid value should be 254. The correct value should be 0. 2. The SQLExtendedFetch is deprecated. Replace it with SQLFetch. ### Related Issue https://bitquill.atlassian.net/browse/AD-735 * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. * [AD-521] remove unnecessary comment * [AD-589] fix merge issues * I missed this part of code when I was resolving the merge conflicts. Now they are corrected * [AD-589] update getMetaData JNI wrapper code to pass &errInfo * implement unit test for getMetaData * [AD-589] implement JNI wrapper for DocumentDbDatabaseSchemaMetadataGetSchemaName * implement Java class for * define constant for DocumentDbDatabaseSchemaMetadataGetSchemaName * add empty test function for TestDocumentDbDatabaseSchemaMetadataGetSchemaName * [AD-589] implement unit test for DbDatabaseSchemaMetadataGetSchemaName * [AD-521] refactor - change case of ssh to SSH for consistency * [AD-589] address code review comments * rename DocumentDbConnectionGetMetaData to DocumentDbConnectionGetDatabaseMetaData * [AD-589] change case from MetaData to Metadata to match Java method name * [AD-589] refactor: change from metaData to metadata changes occurred in: * DocumentDbConnectionGetDatabaseMetadata * DocumentDbDatabaseSchemaMetadataGetSchemaName * TestDocumentDbConnectionGetDatabaseMetadata * TestDocumentDbDatabaseSchemaMetadataGetSchemaName * Birschick bq/sync up (#21) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-735] large dataset crash issue (#23) * first test * fix performance test crash * fix performance test crash * fix whitespace issue * rework based on comments Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> * [AD-649] Add missing documentation (#73) * Initial user/developer documentation Co-authored-by: andiem-bq <67925459+andiem-bq@users.noreply.github.com> Co-authored-by: Bruce Irschick Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> * [AD 551] Adapt Primary Keys (#26) * SQLPrimaryKey using JNI * odbc test failure fix * add tests * fix test failure * using boost::optional to replace std::string * disable cppcheck * test refine * fix linux build failure * rework based on comments * fix a typo * [AD-751] make getColumns/getTables pass nullptr for catalog and schema params to JDBC (#27) ### Summary make changes so getColumns/getTables tests pass nullptr to JDBC ### Description Make getColumns pass nullptr to JDBC when ODBC receives nullptr as parameter. ### Related Issue https://bitquill.atlassian.net/browse/AD-751 * [AD-751] adapt getColumns to pass nullptr to jni * [AD-550] fix meta_queries_test to properly pass null ptr instead of empty strings * NULL and empty strings have different meanings in SQLColumns ODBC implementation. Passing catalog as null means disregard the catalog parameter, where as empty string would mean finding data without a catalog. Passing schema as null means disregard the catalog parameter, where as empty string would mean finding data without a schema. [Reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolumns-function?view=sql-server-ver15) * [AD-751] move `const` out of `boost::optional< const std::string >` * reason: `const boost::optional< std::string >` works better than `boost::optional< const std::string >`. * [AD-751] add SQLColumns meta queries tests * add test that passes non-existent catalog along with correct tables / columns. The ResultSet should still be empty. * added test that passes empty string as catalog. The result should be the same as when catalog is passed as null. * [AD-751] temporarily disable cppcheck in Windows Workflow * [AD-751] adapt getTables to pass nullptr to jni when NULL is received * added extra test case for TestGetDataWithTablesReturnsNone ( test that no result is returned with empty string schema) * add function SqlStringToOptString * refactors * code documentation changes * some tests would fail without changes in AD-751 PR * [AD-751] add test case for TestGetDataWithColumnsReturnsNone * tests passing empty string schemaName to SQLColumns returns no data * this test would fail without the new JDBC changes * [AD-751] replace NULL with nullptr in tests * and some comment refactoring * [AD-751] resolve code review comments * remove unneeded variable typesArr * [AD-751] resolve code review comments * remove SqlStringToConstOptString function * remove const keyword for optional strings in column_metadata_query.h because they are not needed * [AD-751] update documentation * [AD-751] fix build issue * remove references of removed function `SqlStringToConstOptString` * Updating JDBC version * [AD-751] update tests * update tests according to JDBC changes. In SQLTables and SQLColumns, empty string parameters for table or column are not allowed, so replacing them with "%" or actual table / column names instead. * [AD-751] make windows github workflow download JDBC 1.2.4 Co-authored-by: affonsov * AD-757 remove unused functions (#31) * remove not needed functions * remove more uneeded functions * [AD-563] Remove unnecessary libraries (#33) * add missing headers and fix compiling errors * changes to solve all build failure * fix linux build failure * fix linux and mac build failure * fix linux and mac build failure * remove unneeded code * remove unneeded functions * add missing files * remove unneeded code based on comments * add missing namespace for odbc * add _ODBC to header macro * [AD-771] fix issue of JDBC not returning tables (#37) ### Summary Make JDBC return tables/columns to ODBC ### Description * Tableau passes catalog, schema, table name, and table type as null pointers to SQLTables. PowerBI passes catalog, schema, and table name as null pointers to SQLTables. PowerBI passes column name as null pointers to SQLColumns. Therefore, if null is passed in ODBC as table pattern, "%" needs to be passed as table pattern to JDBC. Same thing with null being passed to ODBC as column name pattern. ### Related Issue https://bitquill.atlassian.net/browse/AD-771 * [AD-771] fix merge issues * [AD-771] resolve code review comments * move comments for SQLTables and SQLColumns from odbc.h to odbc.cpp. * refactor code to use `get_value_or` when retrieving values for table and column name * [AD-621] adapt SQLColAttribute (#32) ### Summary adapt the function SQLColAttribute to be ODBC 3.0 compatible. ### Description adapt the function SQLColAttribute - [x] adapt isAutoIncrement, to be used in SQLColAttribute - [x] adapt `SQL_DESC_AUTO_UNIQUE_VALUE` - [x] make sure `SQL_DESC_CASE_SENSITIVE` is implemented correctly (currently it only handles `JDBC_TYPE_VARCHAR`) and check possible JDBC types returned from JDBC - [x] adapt `SQL_DESC_LITERAL_PREFIX` and `SQL_DESC_LITERAL_SUFFIX` - [x] adapt `SQL_DESC_UNNAMED` - [x] fix adaptation of `SQL_DESC_NUM_PREC_RADIX` - [x] adapt `SQL_DESC_PRECISION` - [x] adapt `SQL_DESC_SCALE` - [x] fix implementation of `SQL_DESC_LENGTH`, `SQL_DESC_OCTET_LENGTH`, and `SQL_COLUMN_LENGTH` - [x] fix implementation of `SQL_DESC_FIXED_PREC_SCALE` Write tests for - [x] get `SQL_DESC_AUTO_UNIQUE_VALUE` by calling SQLColAttribute - [x] get `SQL_DESC_CASE_SENSITIVE` by calling SQLColAttribute - [x] get `SQL_DESC_LITERAL_PREFIX` - [x] prefix: for JDBC_BINARY types (JDBC_TYPE_VARBINARY, and JDBC_TYPE_LONGVARBINARY), make sure "0x" is returned - [x] "'" is supposed to be returned for JDBC *CHAR types for both prefix and suffix. - [x] get `SQL_DESC_LITERAL_SUFFIX` by calling SQLColAttribute - [x] get `SQL_DESC_UNNAMED` by calling SQLColAttribute - [x] get `SQL_DESC_PRECISION` by calling SQLColAttribute - [x] get `SQL_DESC_SCALE` by calling SQLColAttribute - [x] SQL_DESC_BASE_COLUMN_NAME - [x] SQL_DESC_BASE_TABLE_NAME - [x] SQL_DESC_CATALOG_NAME - [x] SQL_DESC_CONCISE_TYPE - [x] SQL_DESC_DISPLAY_SIZE - [x] SQL_DESC_FIXED_PREC_SCALE - [x] SQL_DESC_LABEL - [x] SQL_DESC_LENGTH - [x] SQL_DESC_LITERAL_SUFFIX - [x] SQL_DESC_LOCAL_TYPE_NAME - [x] SQL_DESC_NAME - [x] SQL_DESC_NULLABLE - [x] SQL_DESC_OCTET_LENGTH - [x] SQL_DESC_SCHEMA_NAME - [x] SQL_DESC_SEARCHABLE - [x] SQL_DESC_TABLE_NAME - [x] SQL_DESC_TYPE - [x] SQL_DESC_TYPE_NAME - [x] SQL_DESC_UNSIGNED - [x] SQL_DESC_UPDATABLE Fields that are already (correctly) implemented before this PR: - SQL_DESC_BASE_COLUMN_NAME - SQL_DESC_BASE_TABLE_NAME - SQL_DESC_CATALOG_NAME - SQL_DESC_CONCISE_TYPE - SQL_DESC_DISPLAY_SIZE - SQL_DESC_LABEL - SQL_DESC_LITERAL_SUFFIX - SQL_DESC_LOCAL_TYPE_NAME - SQL_DESC_NAME - SQL_DESC_NULLABLE - SQL_DESC_SCHEMA_NAME - SQL_DESC_SEARCHABLE - SQL_DESC_TABLE_NAME - SQL_DESC_TYPE - SQL_DESC_TYPE_NAME - SQL_DESC_UNSIGNED - SQL_DESC_UPDATABLE For SQL_DESC_SEARCHABLE, SQL_PRED_BASIC is always returned because our DocumentDB JDBC does not support the LIKE operator. For SQL_DESC_UPDATABLE, SQL_ATTR_READWRITE_UNKNOWN is automatically returned. ### Related Issue https://bitquill.atlassian.net/browse/AD-621 * [AD-621] add todo for adapting SQL_DESC_COUNT * reason why a TODO (AD-760) is created: Currently our DocDB JDBC only has result sets that are forward only and does not support: { resultSet.last(); count = resultSet.getRow(); } Therefore the task is more complicated than it seems and we may or may not support this feature. * [AD-621] adapt SQL_DESC_CASE_SENSITIVE * [AD-621] adapt SQL_DESC_LITERAL_PREFIX and SQL_DESC_LITERAL_SUFFIX * prefix: for JDBC_BINARY types (JDBC_TYPE_VARBINARY, and JDBC_TYPE_LONGVARBINARY), "0x" is returned * "'" is returned for JDBC *CHAR types for both prefix and suffix. * [AD-621] adapt SQL_DESC_UNNAMED * make value returned from SQL_DESC_UNNAMED match the [reference](https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlcolattribute-function?view=sql-server-ver16). - SQL_DESC_UNNAMED is set to SQL_NAMED if there is a column name or column alias. If there is no column name or a column alias, SQL_DESC_UNNAMED is set to SQL_UNNAMED. * [AD-621] adapt SQL_DESC_NUM_PREC_RADIX * for all non-numeric data types, the `SQL_DESC_NUM_PREC_RADIX` field should be set to 0, not -1. * update test for `num_prec_radix`, as it should not be null. * [AD-621] implement getting decimal digits * decimal digits have a different meaning from precision or scale, so it has its own variable * [AD-621] adapt SQL_DESC_PRECISION * and some reformatting * [AD-621] test for SQL_DESC_CASE_SENSITIVE * [AD-621] add test for SQL_DESC_AUTO_UNIQUE_VALUE * [AD-621] test for SQL_DESC_LITERAL_PREFIX * [AD-621] adapt SQL_COLUMN_SCALE * for scale, return decimal digits for all exact numeric types * [AD-621] add test TestColAttributeDescLiteralSuffix * [AD-621] remove SQL_DESC_COUNT field in ColumnMeta::GetAttribute * the SQL_DESC_COUNT field is already handled in odbc.cpp * [AD-621] add test TestColAttributeDescUnnamed * [AD-621] add test TestColAttributeDescPrecision * [AD-621] add test TestColAttributeDescScale * add implementation for BinaryTypeDecimalDigits. All exact numeric types other than SQL_DECIMAL and SQL_NUMERIC should return 0. * [AD-621] temporarily disable TestColAttributeDescPrecision * [AD-621] add tests * add tests: - TestColAttributeDescBaseColumnName - TestColAttributeDescBaseTableName - TestColAttributeDescCatalogName * [AD-621] add test TestColAttributeDescConciseType * [AD-621] add test TestColAttributeDescCount * [AD-621] update comment * [AD-621] attempt to fix TestColAttributeDescBaseColumnName and TestColAttributeDescBaseTableName * [AD-621] fix TestColAttributeDescCatalogName * [AD-621] make value -1 by default in ColumnMeta::GetAttribute(uint16_t fieldId, SqlLen& value) * [AD-621] fix TestColAttributeDescConciseType * `"columnName": null` in json table does not mean that the column is of NULL type. Therefore I'm replacing the reference of fieldNull to fieldString * [AD-621] add test TestColAttributeDescDisplaySize * [AD-621] test TestColAttributeDescPrecision * removed SQL_TYPE_NULL check because JDBC is not automatically recognizing fields containing null values as JDBC_TYPE_NULL * added test for checking precision values of SQL_VARCHAR * [AD-621] fix TestColAttributeDescDisplaySize * correct the expected value of display size for SQL_TYPE_TIMESTAMP * [AD-621] add test TestColAttributeDescFixedPrecScale * only SQL_FALSE is returned for the field SQL_DESC_FIXED_PREC_SCALE for all possible columns * [AD-621] add test TestColAttributeDescBaseLabel * SQL_DESC_LABEL returns the same value for column name * [AD-621] undo accidental commit merge * [AD-621] add test TestColAttributeDescLength * [AD-621] Refactoring comments * removed commented out code * added comments * [AD-621] update TestColAttributeDescLiteralSuffix * reason: fieldObjectId is recognized as VARCHAR type, therefore it would get the "'" literal instead. So replace fieldObjectId with fieldBoolean, which is non-char and non-binary * [AD-621] add test TestColAttributeDescLocalTypeName * tests local type names for: SQL_DOUBLE, SQL_VARCHAR, SQL_BINARY, SQL_TYPE_TIMESTAMP, SQL_INTEGER * update `req` to `req1` in `TestColAttributeDescPrecision` for a better naming convention * [AD-621] dereference optional int for scale value * this is an attempt to fix the TestColAttributeDescFixedPrecScale test * [AD-621] fix implementation of SQL_DESC_LENGTH, SQL_DESC_OCTET_LENGTH, and SQL_COLUMN_LENGTH * column length should not be the precision value and only the type_traits::BinaryTypeTransferLength function should be used for that value instead * [AD-621] fix test TestColAttributeDescLength * [AD-621] refactor replace `req` with `req1` * update `req` to `req1` in tests for a better naming convention * [AD-621] add test TestColAttributeDescName * [AD-621] add test TestColAttributeDescNullable * fieldObjectId should not be nullable because it contains an primary key id * fields that are not primary keys should be nullable. This is according to settings on JDBC driver * [AD-621] fix TestColAttributeDescLocalTypeName * reason: binary fields would be recognized as type SQL_VARBINARY instead of SQL_BINARY. * [AD-621] fix implementation of SQL_DESC_FIXED_PREC_SCALE * SQL_TRUE if the column has a fixed precision and nonzero scale that are data source-specific. * SQL_FALSE if the column does not have a fixed precision and nonzero scale that are data source specific. * refactor changes * [AD-621] add test TestColAttributeDescNumPrecRadix * tests 3 columns (field float, int, any non-numeric column), each should return 2,10, 0 for precision radix value respectively * [AD-621] fix implementation of SQL_DESC_OCTET_LENGTH * SQL_DESC_LENGTH is the character length of a datatype, and SQL_DESC_OCTET_LENGTH is SQL_DESC_LENGTH in bytes. Therefore, they should have different values if the number of bytes per char is not 1. * [AD-621] add test TestColAttributeDescOctetLength * [AD-621] fix test TestColAttributeDescNullable * meta_queries_test_001__id is the correct primary keys field * [AD-621] fix test TestColAttributeDescNumPrecRadix * added float field in test database * [AD-621] fix implementation of SQL_DESC_SCALE * [AD-621] fix implementation of precision value * JDBC precision/scale value does not apply to ODBC, thus we do not retrieve the precision/scale value from JDBC. * fixed implementation for retrieving column attribute field SQL_DESC_PRECISION. * [AD-621] add test TestColAttributeDescSchemaName * schema name is the database name * [AD-621] add tests added tests: * TestColAttributeDescSearchable * TestColAttributeDescTableName * TestColAttributeDescType * TestColAttributeDescUnsigned * TestColAttributeDescUpdatable * [AD-621] fix test TestColAttributeDescType * and added todo for re-enabling the tests * [AD-621] refactor changes * added debug messages for InternalGetColumnAttribute * [AD-621] add todo link to Jira ticket * [AD-621] add file column_meta_test.cpp * column_meta_test contains unit tests for ColumnMeta::GetAttribute * [AD-621] add checks for GetAttribute with string value * added BOOST checks for calling ColumnMeta::GetAttribute with all of SQL_DESC_* fields that apply * removed unnecessary include * [AD-621] add more checks for retrieving int values * added more boost checks for unit test * [AD-621] resolve code review comments * add function `isCharType` to replace duplicate code * fixed typo * [AD-621] code refactor * added function SqlCharToString to replace duplicate code. The function converts SQLCHAR[] array to a std::string * [AD-621] refactor code * created function callSQLColAttribute to check the return value from the attribute field with the expected string. * removed comment * [AD-621] code refactor * created function callSQLColAttribute to check the return value from the attribute field with the expected int. * added documentation for callSQLColAttribute functions * [AD-621] add more checks for TestGetAttribute * [AD-621] add unit test TestGetAttributeLiteralPrefix * [AD-621] add test TestGetAttributeLiteralSuffix * [AD-621] add unit test TestGetAttributeLocalTypeName * [AD-621] fix implementation * fix implementation of SQL_DESC_UNNAMED * fix implementation of SQL_COLUMN_PRECISION and SQL_COLUMN_SCALE. Added check to ensure decimalDigits is not -1. * [AD-621] add unit tests * added unit tests: TestGetAttributeCaseSensitive, TestGetAttributeConciseTypeAndType, TestGetAttributeDisplaySize, TestGetAttributeLength, TestGetAttributeOctetLength, TestGetAttributeNullable, TestGetAttributeNumPrecRadix, TestGetAttributePrecision, TestGetAttributeScale, TestGetAttributeUnnamed, TestGetAttributeUnsigned * [AD-621] Add test that checks multiple columns * add test TestColAttributeDataTypesAndColumnNames * [AD-621] code refactor * added function connectToLocalServer to reduce the amount of duplicate code * [AD-621] code refactor * removed duplicate code * removed extra line * [AD-621] sync with odbc repo (#39) * [AD-621] fix unit test TestGetAttributeOctetLength * changed the expected value for JDBC_TYPE_DATE, JDBC_TYPE_TIME, JDBC_TYPE_TIMESTAMP * refactored to re-use variable size_of_char * [AD-753] check JVM attach result before use it (#38) * add check for attach to JVM failure * add missing change * check Attach() result before use it * fix wrong code * remove unneeded comments * use nullptr instead of NULL * remove duplicated lines * [AD-772] add bug fix to iterate past vector end (#40) ### Summary * added if checks to check if cursor is already at the vector end ### Description The error of `expression: can't increment vector iterator past end` is actually caused by Tableau setting rowArraySize to a number that is larger than the number of available rows in the database. Our ODBC driver continues to retrieve rows when SqlResult::AI_NO_DATA is returned, which usually causes the `Error: expression: can't increment vector iterator past end` error, because SqlResult::AI_NO_DATA is returned by PrimaryKeysQuery::FetchNextRow only when cursor has reached the end of the vector. * make array row size only set to 1 ### Related Issue https://bitquill.atlassian.net/browse/AD-772 * [AD-772] add bug fix to iterate past vector end * added if checks to check if cursor is already at the vector end * [AD-772] remove comments * removed extra comments * [AD-772] update value of row array size * I had discovered that setting row array size to 3 is enough to make the tests crash with vector error without my fix, therefore I'm setting row array size to a smaller number to reduce the amount of time for tests * [AD-772] update value of row array size for test TestSQLTypeInfoHighRowArraySize * [AD-772] resolve code review comment * remove duplicate code * [AD-772] refactor code according to Roy's suggestion * `fetched` is not needed in the FetchNextRow function. * [AD-772] remove instances of `fetched` * remove the fetched flag as it is not used in anywhere * Revert "[AD-772] refactor code according to Roy's suggestion" This reverts commit 0de3cf9b291b6659caab006727acfb8e7cf85b76. * Revert "[AD-772] remove instances of `fetched`" This reverts commit 68a72d5b06fa269323a5237860369cc0ddf8726c. * [AD-772] set default value of fetched in foreign key query and primary key query * [AD-772] change code logic to remove extra if check * change code logic to remove extra if check * only increment cursor if it is not at the end of the meta * [AD-772] make ODBC not support rowArraySize to be set to a value other than 1 * rowArraySize can no longer be set to values other than 1 * removed tests that sets rowArraySize to values other than 1. `SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, ...)` can no longer be called. * [AD-772] add documentation for odbc-limitations * the documentation indicates that SQL_ATTR_ROW_ARRAY_SIZE has default value 1 and change is not supported. * the rest of documentation (odbc-limitations.md) can be completed in AD-682 * [AD-772] resolve code review comments * change documentation * remove empty line Co-Authored-By: Bruce Irschick * [AD-772] add test TestSQLSetStmtAttrRowArraySize * the test TestSQLSetStmtAttrRowArraySize checks that statement array size cannot be set to values other than 1 * [AD-772] resolve code review comments * remove empty space * [AD-772] fix mac build error * [AD-772] fix mac build error Co-authored-by: Bruce Irschick * [AD-801] add log (#42) ### Summary Add log message to statement.cpp. ### Description rowArraySize should not hold values other than 1, therefore putting a log to indicate it better ### Related Issue https://bitquill.atlassian.net/browse/AD-801 * [AD-801] add logs * rowArraySize should not hold values other than 1, therefore putting a log to indicate it better * [AD-801] reformat * [AD-801] address code review comments * [AD-573] unicode port ( ODBC W API Interfaces) (#36) ### Summary [AD-573] unicode port ( ODBC W API Interfaces) ### Description - [x] Add the -DUNICODE=1 definition. - [x] Convert SQLWCHAR to/from UTF-8 encoded strings internally - [x] Ensure tests use a combination of SQLWCHAR and SQLCHAR, where appropriate - [x] Add test to perform query with wide characters and return wide and non-wide results. - [x] Report `W` (wide) types for columns with JDBC_CHAR/JDBC_VARCHAR/JDBC_LONGVARCHAR. ### Related Issue https://bitquill.atlassian.net/browse/AD-573 * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan * [AD-735] large dataset crash issue (#74) ### Summary ODBC driver will not run on large document tests ### Description The performance test crashes for large document tests. 1. The root cause is the wrong memory is passed to SQLBindCol(). The parameter TargetValuePtr is passed &cols[i][0].data_dat[i]. The i could exceed 255 for large table while its max valid value should be 254. The correct value should be 0. 2. The SQLExtendedFetch is deprecated. Replace it with SQLFetch. ### Related Issue https://bitquill.atlassian.net/browse/AD-735 * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. * [AD-521] remove unnecessary comment * [AD-589] fix merge issues * I missed this part of code when I was resolving the merge conflicts. Now they are corrected * [AD-589] update getMetaData JNI wrapper code to pass &errInfo * implement unit test for getMetaData * [AD-589] implement JNI wrapper for DocumentDbDatabaseSchemaMetadataGetSchemaName * implement Java class for * define constant for DocumentDbDatabaseSchemaMetadataGetSchemaName * add empty test function for TestDocumentDbDatabaseSchemaMetadataGetSchemaName * [AD-589] implement unit test for DbDatabaseSchemaMetadataGetSchemaName * [AD-521] refactor - change case of ssh to SSH for consistency * [AD-589] address code review comments * rename DocumentDbConnectionGetMetaData to DocumentDbConnectionGetDatabaseMetaData * [AD-589] change case from MetaData to Metadata to match Java method name * [AD-589] refactor: change from metaData to metadata changes occurred in: * DocumentDbConnectionGetDatabaseMetadata * DocumentDbDatabaseSchemaMetadataGetSchemaName * TestDocumentDbConnectionGetDatabaseMetadata * TestDocumentDbDatabaseSchemaMetadataGetSchemaName * Birschick bq/sync up (#21) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-735] large dataset crash issue (#23) * first test * fix performance test crash * fix performance test crash * fix whitespace issue * rework based on comments Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> * [AD-649] Add missing documentation (#73) * Initial user/developer documentation Co-authored-by: andiem-bq <67925459+andiem-bq@users.noreply.github.com> Co-authored-by: Bruce Irschick Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-550] Adapt Foreign Keys (#75) Summary Adapt Foreign Keys (i.e., the SQLForeignKeys function) Description JNI wrapper code for getImportedKeys adapt SQLForeignKeys function unit test for jni_test unit test for java_test Related Issue https://bitquill.atlassian.net/browse/AD-550 * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. * [AD-521] remove unnecessary comment * [AD-589] fix merge issues * I missed this part of code when I was resolving the merge conflicts. Now they are corrected * [AD-589] update getMetaData JNI wrapper code to pass &errInfo * implement unit test for getMetaData * [AD-589] implement JNI wrapper for DocumentDbDatabaseSchemaMetadataGetSchemaName * implement Java class for * define constant for DocumentDbDatabaseSchemaMetadataGetSchemaName * add empty test function for TestDocumentDbDatabaseSchemaMetadataGetSchemaName * [AD-589] implement unit test for DbDatabaseSchemaMetadataGetSchemaName * [AD-521] refactor - change case of ssh to SSH for consistency * [AD-589] address code review comments * rename DocumentDbConnectionGetMetaData to DocumentDbConnectionGetDatabaseMetaData * [AD-589] change case from MetaData to Metadata to match Java method name * [AD-589] refactor: change from metaData to metadata changes occurred in: * DocumentDbConnectionGetDatabaseMetadata * DocumentDbDatabaseSchemaMetadataGetSchemaName * TestDocumentDbConnectionGetDatabaseMetadata * TestDocumentDbDatabaseSchemaMetadataGetSchemaName * Birschick bq/sync up (#21) * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> * [AD-735] large dataset crash issue (#23) * first test * fix performance test crash * fix performance test crash * fix whitespace issue * rework based on comments * SQLPrimaryKey using JNI * odbc test failure fix * Revert "odbc test failure fix" This reverts commit c75194688a0969edae20f59cbe6c55cf5eb4a4da. * Revert "SQLPrimaryKey using JNI" This reverts commit 02380e9e434a55a9b034da138f7d0d32d1654708. * [AD-550] Adapt Foreign Keys (#24) * [AD-550] JNI implementation for getImportedKeys * [AD-550] update Pull Request Template * added reviewees Roy Zhang and Micthell Elholm * [AD-550] add todo note to unit test * [AD-550] define GetImportedKeys in database_metadata.h/.cpp * add ODBC wrapper code to the JNI call for GetImportedKeys * [AD-550] initialize string vars to be empty string in column_metadata_query * [AD-550] modify ForeignKeysQuery to accept 3 arguments only * modified ForeignKeysQuery to only accept catalog, schema, and table, as other fields are not needed. * [AD-550] update column metadata for foreign keys * [AD-550] fix typo in primary_key_meta.h * [AD-550] define vars for foreign key meta * [AD-550] add getter functions for vars in foreign_key_meta.h * [AD-550] support vars in foreign key meta to be optional * [AD-550] add headers for boost optional * [AD-550] add headers and constructors for foreign key meta * added ForeignKeyMeta constructor, and copy constructor *added ForeignKeyMeta destructor * define ForeignKeyMetaVector * basically, complete foreign_key_meta.h * [AD-550] implement resultset.getSmallInt * implement resultset.getSmallInt taking column indices or column names as parameters * make ColumnMeta::dataType be updated with resultSet.Get()->GetSmallInt to simplify code and readbility * [AD-550] Add foreign_key_meta.cpp * implemented functions: ReadForeignKeysColumnMetaVector ForeignKeyMeta::Read * [AD-550] update CMakeLists to include foreign_key_meta.cpp * [AD-550] implement MakeRequestGetForeignKeysMeta * MakeRequestGetForeignKeysMeta calls GetImportedKeys to get Jni ResultSet object for foreign keys, and then reads the resultSet object to fill in the meta object. * [AD-550] update ForeignKeysQuery::DataAvailable and ForeignKeysQuery::Close * update meta object accordingly whenForeignKeysQuery::Close() is called. * return boolean for whether data is available based on meta object * [AD-550] implement ForeignKeysQuery::Execute and FetchNextRow * the code for ForeignKeysQuery::Execute and ForeignKeysQuery::FetchNextRow is based on ColumnMetadataQuery::Execute and ColumnMetadataQuery::FetchNextRow * [AD-550] fix Mac and Linux build * remove extra qualification on GetSmallInt function * [AD-550] implement ForeignKeysQuery::GetColumn * had formatting changes as well * [AD-550] JNI implementation for getImportedKeys * [AD-550] update Pull Request Template * added reviewees Roy Zhang and Micthell Elholm * [AD-550] add todo note to unit test * [AD-550] define GetImportedKeys in database_metadata.h/.cpp * add ODBC wrapper code to the JNI call for GetImportedKeys * [AD-550] initialize string vars to be empty string in column_metadata_query * [AD-550] modify ForeignKeysQuery to accept 3 arguments only * modified ForeignKeysQuery to only accept catalog, schema, and table, as other fields are not needed. * [AD-550] update column metadata for foreign keys * [AD-550] fix typo in primary_key_meta.h * [AD-550] define vars for foreign key meta * [AD-550] add getter functions for vars in foreign_key_meta.h * [AD-550] support vars in foreign key meta to be optional * [AD-550] add headers for boost optional * [AD-550] add headers and constructors for foreign key meta * added ForeignKeyMeta constructor, and copy constructor *added ForeignKeyMeta destructor * define ForeignKeyMetaVector * basically, complete foreign_key_meta.h * [AD-550] implement resultset.getSmallInt * implement resultset.getSmallInt taking column indices or column names as parameters * make ColumnMeta::dataType be updated with resultSet.Get()->GetSmallInt to simplify code and readbility * [AD-550] Add foreign_key_meta.cpp * implemented functions: ReadForeignKeysColumnMetaVector ForeignKeyMeta::Read * [AD-550] update CMakeLists to include foreign_key_meta.cpp * [AD-550] implement MakeRequestGetForeignKeysMeta * MakeRequestGetForeignKeysMeta calls GetImportedKeys to get Jni ResultSet object for foreign keys, and then reads the resultSet object to fill in the meta object. * [AD-550] update ForeignKeysQuery::DataAvailable and ForeignKeysQuery::Close * update meta object accordingly whenForeignKeysQuery::Close() is called. * return boolean for whether data is available based on meta object * [AD-550] implement ForeignKeysQuery::Execute and FetchNextRow * the code for ForeignKeysQuery::Execute and ForeignKeysQuery::FetchNextRow is based on ColumnMetadataQuery::Execute and ColumnMetadataQuery::FetchNextRow * [AD-550] fix Mac and Linux build * remove extra qualification on GetSmallInt function * [AD-550] implement ForeignKeysQuery::GetColumn * had formatting changes as well * [AD-550] update docs for foreign_keys_query.h * [AD-550] refine SQLForeignKey call * [AD-550] add draft foreign key test for JNI test * [AD-550] add test tables for jni test * [AD-550] update test TestDocumentDbDatabaseMetaDataGetImportedKeys * update test to query virtual table jni_test_001_sub_doc * [AD-550] add SQLForeignKeys sql api test * [AD-550] add logs for ReadForeignKeysColumnMetaVector * PK* variables will contain the list of foreign keys in the specified table * [AD-550] reformat jni_test * [AD-550] implement TestDatabaseMetaDataGetImportedKeys for java_test * [AD-550] add test document meta_queries_test_002_with_array * this document will be used to test SQLForeignKeys in meta_queries_test * [AD-550] refactor TestSQLForeignKeys test * reason: I see that `SQLCHAR empty[] = "";` is used in meta_queries_test, and I think that might be a better way of writing the parameters * [AD-550] add test for SQLForeignKeys in meta_queries_test tests added: * TestGetDataWithForeignKeysReturnsOneFromLocalServer * TestGetDataWithForeignKeysReturnsNone * they use test table meta_queries_test_002_with_array * [AD-550] clean up * add doc for SQLForeignKeys * remove comments * [AD-550] remove commented out code * [AD-550] remove unneeded commented out code * [AD-550] make ODBC pass nullptr for JString catalog and schema for SQLForeignKeys * in getImportedKeys, null boost::optional strings will be passed as nullptr to JDBC * make jni test and java test pass null boost::optional strings to JNI calls for getImportedKeys * ODBC now passes boost::optional strings foreignCatalog and foreignSchema to ExecuteGetForeignKeysQuery function. * [AD-550] add if check for sqlStrLen * if sqlString is empty, return boost::none * [AD-550] debug `choco install cppcheck -y` not working on GitHub Actions * [AD-550] add tests for testing empty string parameters * added Java test TestDatabaseMetaDataGetImportedKeysReturnsNone * added Jni test TestDocumentDbDatabaseMetaDataGetImportedKeysReturnsNone * [AD-550] disable cppcheck * created [AD-752](https://bitquill.atlassian.net/browse/AD-752) to investigate it further. * [AD-550] change the place for code doc for function SQLForeignKeys * [AD-550] update if statement check of SqlStringToOptString * to resolve code review comment * [AD-550] resolve code review comment * The sqlStrLen is an int32_t, so "!sqlStrLen" can be removed * [AD-550] make boost optional strings constant where needed * previously, I changed `const std::string` to `boost::optional< std::string >` in some areas, and this is now fixed by replacing the latter with `boost::optional< const std::string >` * [AD-550] SqlStringToOptString fix * also fixed SqlStringToConstOptString * reason: SQL_NTS is a flag that indicates that the string passed is a null-terminated string. * [AD-550] make tests pass null to SQLForeignKeys * [AD-550] add test case for TestGetDataWithForeignKeysReturnsNone * even with the correct table name, as long as empty strings are passed as catalog/schema, SQL_NO_DATA should be returned * [AD-550] update SqlStringToOptString * [AD-550] update TestSQLForeignKeys to pass NULL as parameters properly * [AD-550] move `const` out of `boost::optional< const std::string >` * reason: `const boost::optional< std::string >` works better than `boost::optional< const std::string >`. * this commit is to resolve code review comments * [AD-550] add meta_queries test that passes catalog as empty string * [AD-550] Set `fetched` to false in ForeignKeysQuery::Close() * [AD-550] add explicit conversion to boost::optional variable initialization * [AD-550] resolve code review comment * remove duplicate code * [AD-550] remove function * removed unneeded function: SqlStringToConstOptString * [AD-649] Add missing documentation (#29) ### Summary [AD-649] Add missing documentation ### Description Update ODBC driver documentation - [x] Documentation about connections string ( Parameters description) - [x] Documentation about DSN configuration window ( with screenshots) - [x] Documentation how the ODBC driver works ( ODBC and JDBC integration) - [x] Documentation what is supported ( link with JDBC driver) ### Related Issue https://bitquill.atlassian.net/browse/AD-649 * Updating JDBC version (#72) * [AD-370] upload odbc driver build on push to develop (#71) * [AD-730] upload odbc driver build at push to develop * [AD-730] update github actions to upload with v3 * [AD-730] Test artifact upload action * temporarily comment out if statement guard to test upload-artifact github action * [AD-730] upload performance test executable * [AD-730] update readme * [AD-730] upload Release folder as artifact * our odbc needs more than just the ignite.odbc.dll to run properly * [AD-730] update to upload artifacts for release build * previously, I uploaded the Debug builds, but the Release build is the one that requires less dependencies. * [AD-730] add back if statment * add the if statement back in win-build.yml to ensure that the odbc driver performance artifact is only published when pushed to develop * [AD-730] fix typo of performance test plan * [AD-735] large dataset crash issue (#74) ### Summary ODBC driver will not run on large document tests ### Description The performance test crashes for large document tests. 1. The root cause is the wrong memory is passed to SQLBindCol(). The parameter TargetValuePtr is passed &cols[i][0].data_dat[i]. The i could exceed 255 for large table while its max valid value should be 254. The correct value should be 0. 2. The SQLExtendedFetch is deprecated. Replace it with SQLFetch. ### Related Issue https://bitquill.atlassian.net/browse/AD-735 * [AD-509] Update mac developer environment setup * Adjust formatting * Add note about llvm * Add note about iodbc * Update README.md change the install options for OpenSSL, since vcpkg is a preferred option * Update README.md remove the WiX Toolset v4 requirement * Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. * [AD-517] Remove old properties + add new properties * remove SSL settings and add TLS checkbox on the Configuration Window * add comments for my own work added some comments for my own convenience. Will remove later * fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox * add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window * Update configuration.cpp add comment to illustrate plan on what to do for the configuration window * Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values * change defaultFetchSize to fetchSize in configuration.h * change Default DSN name to DocumentDB DSN * add App Name, Fetch Size, Read Preference, and login timeout to configuration window * [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. * [AD-522] save read preference settings * [AD-522] remove commented out code * [AD-522] Implement replicaSet and retryReads on Configuration Window * [AD-517] Re-enable unit tests - WIP - still need to cleanup * [AD-522] add space to code lines for format consistency in configuration_window.h * Add more unit tests * Remove extra file * [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) * Remove redundant declaration * [AD-522] add variable definitions for SSH tunnel settings for config UI * [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. * [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value * Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit 8a04166b05161326e68c30d98ca17cdbec0df1dc. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit f89a7e9516c20924fbc6c3e6d3763f26309c5723. * [AD-517] * Change the C++ version to use to compile. * [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver * [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. * Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 05eae8ade2c68607bd8a16bee8f60b5681ad74c6. * [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked * Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit 301e04524c1bfcc89db76476171714c69ca1f582. * Improvements from review * Updated comments * [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. * Removed includes no longer being used in configuration.h * Some formatting improvements * [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 * [AD-522] change from GetSshEnable to IsSshEnable for consistency * [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box * [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. * [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 * [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 * Improvements from code review + address some warnings * Change connection _test to use hostname key instead of address * Change connection_test to use databse key instead of schema key * [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value * Attempt to fix windows 32 build * [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments * [AD-522] fix config window margins now the config window is symmetric * Fix formatting * [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit 74dd190fac5ef642d0d83015766fe33dfefb3489. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler * [AD-522] make "rs0" the default value of replicaSet * [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 * [AD-522] rename SSH Known Hosts File label for clarity * [AD-522] refactor logs for retrieving TSL settings Make the sentences align * [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group * [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. * [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters * [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group * [AD-522] remove protocol version from config window * [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed * [AD-522] remove commented out #include headers * [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 * [AD-522] refactor - remove commented out header code * [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity * [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX * [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 * [AD-522] remove std::auto_ptr authSettingsGroupBox; * [AD-522] remove address field auto pointer initialization * [AD-522] remove address field from config window constructor * [AD-522] refactor - remove unneeded commented out code in HasText * [AD-522] refactor - remove white spaces and update comment * [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h * [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly * [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference * [AD-522] refactor - remove unnecessary comments * [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 * Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 696db387de8f509d846ad6351d5cdfcc9937a514, reversing changes made to 8d81a183bea353fef47a62e542bf3fd6f53c13ab. * [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 * [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 * Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit 788cad79f72a7f99ff66c5032bb1532eb71b0da5. * [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 * [AD-512] Resolve issue with missing include file. * [AD-522] make BoolParseResult recognizable * [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 * [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 * [AD-521] add comments and notes for starting AD-521 * [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. * [AD-522] reduce space between ssh private key passphrase and the checkbox below * [AD-521] define constants for Java GetSshLocalPort method call * [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes * [AD-521] refactor code * make open brace bracket start on new line for JVMException * remove excess space * [AD-427] Tracer Code - Limited Capability to load metadata - work-in-progress. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-427] Fix Windows build. * [AD-522] remove space and add new line at the end of enum types * [AD-522] add new lines at the end of Enum type files * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] add changes for Java.cpp from Bruce's AD-427 branch * those changes are not included in the previous merge, and are now added * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-427] Fix Mac build. * [AD-521] JNI wrapper calls to iSshTunnelActive and getSshLocalPort * some draft comments are left to be cleaned up * [AD-521] debug getSshLocalPort * change function type signature from optional to int * refactor - remove comments * [AD-521] change return value in getSshLocalPort from boolean to a 0 * try to fix access memory issue in TestDriverManagerGetConnection * [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers * [AD-427] Added ResultSet.next and ResultSet.GetString() * [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 * [AD-521] implement tests for JNI wrapper code * test for TestDocumentDbConnectionGetSshTunnelPortSshTunnelNotActive is not yet active, need to be enabled when we can get external SSH tunnel working. * bug fix: re-implemented DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActive. connection.Get()->GetRef() is passed as first parameter because jobject is required for CallIntMethod and CallBooleanMethod. * better JNI wrapper code is needed in the future so warnings/errors pop up when we pass jobject instead of jclass to the methods. * [AD-521] refactor - remove comments and commented out code * [AD-589] implement JNI method call for GetDatabaseMetadata * define the method constant for DocumentDbConnection.getDatabaseMetadata() * create JNI wrapper function for DocumentDbConnection.getMetaData * [AD-589] implement unit test for DocumentDbConnection.getMetaData * [AD-521] add calls to AutoCloseConnection in unit tests * pass & errInfo instead of * errInfo in DocumentDbConnectionGetSshLocalPort and DocumentDbConnectionIsSshTunnelActi… * code format change (#45) * [AD-767] Correct merge error * [AD-767] Correct merge error * [AD-767] Correct merge error Co-authored-by: Andie Montoya Co-authored-by: Alina (Xi) Li <96995091+alinaliBQ@users.noreply.github.com> Co-authored-by: Alina (Xi) Li Co-authored-by: affonsoBQ <67347924+affonsoBQ@users.noreply.github.com> Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> Co-authored-by: RoyZhang2022 Co-authored-by: affonsov Co-authored-by: andiem-bq <67925459+andiem-bq@users.noreply.github.com> --- .clang-format | 3 +- .../src/cluster_compute_example.cpp | 232 +- .../compute-example/src/compute_example.cpp | 199 +- .../src/continuous_query_example.cpp | 312 +- .../include/ignite/examples/address.h | 90 +- .../include/ignite/examples/organization.h | 100 +- src/examples/include/ignite/examples/person.h | 241 +- .../odbc-example/src/odbc_example.cpp | 760 ++-- .../put-get-example/src/put_get_example.cpp | 126 +- .../query-example/src/query_example.cpp | 502 +-- .../src/thin_client_put_get_example.cpp | 121 +- src/odbc-test/include/odbc_test_suite.h | 5 +- src/odbc-test/include/test_server.h | 2 +- src/odbc-test/include/test_type.h | 5 +- src/odbc-test/src/api_robustness_test.cpp | 47 +- .../src/application_data_buffer_test.cpp | 3 +- src/odbc-test/src/column_meta_test.cpp | 4 +- src/odbc-test/src/configuration_test.cpp | 10 +- src/odbc-test/src/connection_test.cpp | 2 +- src/odbc-test/src/java_test.cpp | 83 +- src/odbc-test/src/jni_test.cpp | 49 +- src/odbc-test/src/log_test.cpp | 3 +- src/odbc-test/src/meta_queries_test.cpp | 164 +- src/odbc-test/src/odbc_test_suite.cpp | 8 +- src/odbc-test/src/queries_test.cpp | 211 +- src/odbc-test/src/utility_test.cpp | 4 +- .../ignite/odbc/app/application_data_buffer.h | 11 +- src/odbc/include/ignite/odbc/binary/binary.h | 2 +- .../ignite/odbc/binary/binary_containers.h | 2 +- .../ignite/odbc/binary/binary_object.h | 246 +- .../ignite/odbc/binary/binary_raw_writer.h | 2 +- .../ignite/odbc/binary/binary_reader.h | 2 +- .../include/ignite/odbc/binary/binary_type.h | 2 +- .../ignite/odbc/binary/binary_writer.h | 2 +- src/odbc/include/ignite/odbc/cache/cache.h | 3617 ++++++++--------- .../ignite/odbc/cache/cache_affinity.h | 428 +- .../include/ignite/odbc/cache/cache_entry.h | 251 +- .../ignite/odbc/cache/cache_peek_mode.h | 109 +- .../odbc/cache/event/cache_entry_event.h | 215 +- .../cache/event/cache_entry_event_filter.h | 154 +- .../cache/event/cache_entry_event_listener.h | 81 +- .../ignite/odbc/cache/mutable_cache_entry.h | 282 +- .../cache/query/continuous/continuous_query.h | 475 ++- .../continuous/continuous_query_handle.h | 204 +- .../ignite/odbc/cache/query/query_cursor.h | 455 +-- .../odbc/cache/query/query_fields_cursor.h | 304 +- .../odbc/cache/query/query_fields_row.h | 376 +- .../ignite/odbc/cache/query/query_scan.h | 243 +- .../ignite/odbc/cache/query/query_sql.h | 536 ++- .../odbc/cache/query/query_sql_fields.h | 759 ++-- .../ignite/odbc/cache/query/query_text.h | 261 +- .../ignite/odbc/cluster/cluster_group.h | 466 +-- .../ignite/odbc/cluster/cluster_node.h | 275 +- .../ignite/odbc/cluster/ignite_cluster.h | 261 +- src/odbc/include/ignite/odbc/column.h | 7 +- .../include/ignite/odbc/common/cancelable.h | 74 +- .../include/ignite/odbc/common/expected.h | 2 +- src/odbc/include/ignite/odbc/common/lazy.h | 268 +- src/odbc/include/ignite/odbc/common/promise.h | 366 +- .../ignite/odbc/common/reference_impl.h | 483 +-- .../include/ignite/odbc/common/shared_state.h | 683 ++-- .../include/ignite/odbc/compute/compute.h | 689 ++-- .../ignite/odbc/compute/compute_func.h | 135 +- .../include/ignite/odbc/config/config_tools.h | 2 +- .../ignite/odbc/config/configuration.h | 5 +- .../ignite/odbc/config/connection_info.h | 2 +- .../ignite/odbc/config/settable_value.h | 2 +- src/odbc/include/ignite/odbc/connection.h | 5 +- .../ignite/odbc/diagnostic/diagnosable.h | 2 +- .../odbc/diagnostic/diagnostic_record.h | 2 +- .../diagnostic/diagnostic_record_storage.h | 2 +- .../include/ignite/odbc/documentdb_column.h | 10 +- .../include/ignite/odbc/documentdb_cursor.h | 4 +- src/odbc/include/ignite/odbc/documentdb_row.h | 6 +- src/odbc/include/ignite/odbc/end_point.h | 2 +- src/odbc/include/ignite/odbc/environment.h | 2 +- src/odbc/include/ignite/odbc/future.h | 498 ++- src/odbc/include/ignite/odbc/ignite.h | 493 ++- src/odbc/include/ignite/odbc/ignite_binding.h | 269 +- .../ignite/odbc/ignite_binding_context.h | 116 +- .../ignite/odbc/ignite_configuration.h | 86 +- src/odbc/include/ignite/odbc/ignite_error.h | 36 +- .../include/ignite/odbc/ignite_predicate.h | 2 +- .../ignite/odbc/ignite_product_version.h | 95 +- .../include/ignite/odbc/impl/binary/binary.h | 2 +- .../odbc/impl/binary/binary_object_impl.h | 3 +- .../odbc/impl/binary/binary_reader_impl.h | 19 +- .../odbc/impl/binary/binary_type_impl.h | 44 +- .../impl/binary/binary_type_updater_impl.h | 85 +- .../ignite/odbc/impl/binary/binary_utils.h | 52 +- .../odbc/impl/binary/binary_writer_impl.h | 42 +- src/odbc/include/ignite/odbc/impl/bindings.h | 183 +- .../odbc/impl/cache/cache_affinity_impl.h | 776 ++-- .../impl/cache/cache_entry_processor_holder.h | 494 ++- .../ignite/odbc/impl/cache/cache_impl.h | 839 ++-- .../event/cache_entry_event_filter_base.h | 85 +- .../event/cache_entry_event_filter_holder.h | 306 +- .../continuous/continuous_query_handle_impl.h | 131 +- .../query/continuous/continuous_query_impl.h | 717 ++-- .../odbc/impl/cache/query/query_argument.h | 325 +- .../odbc/impl/cache/query/query_batch.h | 239 +- .../impl/cache/query/query_fields_row_impl.h | 332 +- .../ignite/odbc/impl/cache/query/query_impl.h | 241 +- .../odbc/impl/cluster/cluster_group_impl.h | 825 ++-- .../odbc/impl/cluster/cluster_node_impl.h | 418 +- .../odbc/impl/cluster/ignite_cluster_impl.h | 266 +- .../odbc/impl/compute/cancelable_impl.h | 82 +- .../ignite/odbc/impl/compute/compute_impl.h | 1117 ++--- .../odbc/impl/compute/compute_job_holder.h | 343 +- .../odbc/impl/compute/compute_job_result.h | 550 ++- .../odbc/impl/compute/compute_task_holder.h | 307 +- .../impl/compute/java_compute_task_holder.h | 440 +- .../multiple_job_compute_task_holder.h | 658 ++- .../compute/single_job_compute_task_holder.h | 491 ++- .../ignite/odbc/impl/handle_registry.h | 335 +- src/odbc/include/ignite/odbc/impl/helpers.h | 63 +- .../ignite/odbc/impl/ignite_binding_impl.h | 221 +- .../ignite/odbc/impl/ignite_environment.h | 765 ++-- .../include/ignite/odbc/impl/ignite_impl.h | 461 ++- .../impl/interop/interop_external_memory.h | 58 +- .../ignite/odbc/impl/interop/interop_target.h | 497 +-- .../include/ignite/odbc/impl/module_manager.h | 230 +- .../include/ignite/odbc/impl/operations.h | 1237 +++--- .../ignite/odbc/jni/database_metadata.h | 37 +- .../ignite/odbc/jni/documentdb_connection.h | 14 +- .../odbc/jni/documentdb_database_metadata.h | 5 +- .../jni/documentdb_query_mapping_service.h | 26 +- src/odbc/include/ignite/odbc/jni/java.h | 70 +- .../ignite/odbc/jni/jdbc_column_metadata.h | 8 +- src/odbc/include/ignite/odbc/log_level.h | 8 +- src/odbc/include/ignite/odbc/message.h | 48 +- .../include/ignite/odbc/meta/column_meta.h | 5 +- .../include/ignite/odbc/meta/table_meta.h | 22 +- src/odbc/include/ignite/odbc/nested_tx_mode.h | 2 +- src/odbc/include/ignite/odbc/odbc_error.h | 2 +- src/odbc/include/ignite/odbc/parser.h | 2 +- .../ignite/odbc/query/column_metadata_query.h | 3 +- .../include/ignite/odbc/query/data_query.h | 4 +- .../ignite/odbc/query/foreign_keys_query.h | 4 +- .../ignite/odbc/query/primary_keys_query.h | 5 +- .../ignite/odbc/query/special_columns_query.h | 2 +- .../ignite/odbc/query/table_metadata_query.h | 21 +- .../ignite/odbc/query/type_info_query.h | 2 +- src/odbc/include/ignite/odbc/reference.h | 1044 +++-- src/odbc/include/ignite/odbc/result_page.h | 2 +- src/odbc/include/ignite/odbc/row.h | 2 +- .../include/ignite/odbc/sql/sql_command.h | 2 +- src/odbc/include/ignite/odbc/sql/sql_lexer.h | 2 +- src/odbc/include/ignite/odbc/sql/sql_parser.h | 2 +- .../odbc/sql/sql_set_streaming_command.h | 2 +- src/odbc/include/ignite/odbc/sql/sql_token.h | 2 +- src/odbc/include/ignite/odbc/sql/sql_utils.h | 2 +- src/odbc/include/ignite/odbc/ssl_mode.h | 2 +- src/odbc/include/ignite/odbc/statement.h | 43 +- src/odbc/include/ignite/odbc/type_traits.h | 46 +- src/odbc/include/ignite/odbc/utility.h | 35 +- .../ignite/odbc/common/dynamic_load_os.h | 210 +- .../os/linux/src/common/dynamic_load_os.cpp | 127 +- .../ignite/odbc/common/dynamic_load_os.h | 210 +- .../ignite/odbc/system/ui/custom_window.h | 16 +- .../include/ignite/odbc/system/ui/window.h | 5 +- .../os/win/src/common/dynamic_load_os.cpp | 160 +- .../os/win/src/system/ui/custom_window.cpp | 14 +- .../system/ui/dsn_configuration_window.cpp | 56 +- src/odbc/os/win/src/system/ui/window.cpp | 3 +- src/odbc/os/win/src/system_dsn.cpp | 3 +- src/odbc/src/app/application_data_buffer.cpp | 7 +- src/odbc/src/binary/binary_raw_reader.cpp | 2 +- src/odbc/src/binary/binary_reader.cpp | 1 - src/odbc/src/binary/binary_writer.cpp | 1 - src/odbc/src/cluster/cluster_group.cpp | 246 +- src/odbc/src/cluster/cluster_node.cpp | 120 +- src/odbc/src/cluster/ignite_cluster.cpp | 139 +- src/odbc/src/config/connection_info.cpp | 2 +- src/odbc/src/connection.cpp | 33 +- src/odbc/src/date.cpp | 1 - src/odbc/src/documentdb_column.cpp | 35 +- src/odbc/src/documentdb_cursor.cpp | 4 +- src/odbc/src/documentdb_row.cpp | 7 +- src/odbc/src/driver_instance.cpp | 62 +- src/odbc/src/dsn_config.cpp | 18 +- src/odbc/src/entry_points.cpp | 19 +- src/odbc/src/ignite.cpp | 95 +- .../src/impl/binary/binary_field_meta.cpp | 3 +- .../src/impl/binary/binary_object_header.cpp | 2 +- .../src/impl/binary/binary_reader_impl.cpp | 53 +- src/odbc/src/impl/binary/binary_type_impl.cpp | 1 - .../impl/binary/binary_type_updater_impl.cpp | 280 +- .../src/impl/binary/binary_writer_impl.cpp | 40 +- .../src/impl/cache/cache_affinity_impl.cpp | 288 +- src/odbc/src/impl/cache/cache_impl.cpp | 814 ++-- .../continuous_query_handle_impl.cpp | 133 +- src/odbc/src/impl/cache/query/query_batch.cpp | 62 +- src/odbc/src/impl/cache/query/query_impl.cpp | 553 ++- .../src/impl/cluster/cluster_group_impl.cpp | 1248 +++--- .../src/impl/cluster/cluster_node_impl.cpp | 297 +- .../src/impl/cluster/ignite_cluster_impl.cpp | 152 +- src/odbc/src/impl/compute/cancelable_impl.cpp | 65 +- src/odbc/src/impl/compute/compute_impl.cpp | 48 +- src/odbc/src/impl/handle_registry.cpp | 374 +- src/odbc/src/impl/ignite_binding_impl.cpp | 131 +- src/odbc/src/impl/ignite_environment.cpp | 1870 +++++---- src/odbc/src/impl/ignite_impl.cpp | 395 +- .../impl/interop/interop_external_memory.cpp | 41 +- src/odbc/src/impl/interop/interop_target.cpp | 589 ++- src/odbc/src/jni/database_metadata.cpp | 6 +- src/odbc/src/jni/documentdb_connection.cpp | 6 +- .../jni/documentdb_connection_properties.cpp | 4 +- .../src/jni/documentdb_database_metadata.cpp | 4 +- .../src/jni/documentdb_mql_query_context.cpp | 12 +- .../jni/documentdb_query_mapping_service.cpp | 3 +- src/odbc/src/jni/java.cpp | 49 +- src/odbc/src/jni/jdbc_column_metadata.cpp | 3 +- src/odbc/src/jni/os/win/utils.cpp | 2 +- src/odbc/src/log.cpp | 15 +- src/odbc/src/log_level.cpp | 3 +- src/odbc/src/meta/column_meta.cpp | 3 +- src/odbc/src/meta/foreign_key_meta.cpp | 5 +- src/odbc/src/meta/primary_key_meta.cpp | 1 - src/odbc/src/odbc.cpp | 9 +- src/odbc/src/query/column_metadata_query.cpp | 14 +- src/odbc/src/query/foreign_keys_query.cpp | 12 +- src/odbc/src/query/primary_keys_query.cpp | 22 +- src/odbc/src/query/table_metadata_query.cpp | 11 +- src/odbc/src/statement.cpp | 55 +- src/odbc/src/time.cpp | 2 +- src/odbc/src/timestamp.cpp | 2 +- src/odbc/src/type_traits.cpp | 28 +- src/odbc/src/utility.cpp | 46 +- .../include/performance_odbc_helper.h | 6 +- .../include/performance_test_runner.h | 346 +- src/tests/performance/lib/csv_cell.h | 930 ++--- src/tests/performance/lib/csv_error.h | 72 +- src/tests/performance/lib/csv_parser.h | 810 ++-- src/tests/performance/src/performance.cpp | 107 +- .../src/performance_odbc_helper.cpp | 33 +- .../src/performance_test_runner.cpp | 1658 ++++---- 237 files changed, 22646 insertions(+), 24078 deletions(-) diff --git a/.clang-format b/.clang-format index 836a6507e..51c0053f5 100644 --- a/.clang-format +++ b/.clang-format @@ -5,6 +5,7 @@ AllowShortIfStatementsOnASingleLine: 'false' AllowShortLoopsOnASingleLine: 'false' BreakBeforeBinaryOperators: NonAssignment IndentWidth: '2' +SortIncludes: false SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: 'false' SpacesInAngles: 'true' @@ -13,4 +14,4 @@ SpacesInSquareBrackets: 'false' TabWidth: '2' UseTab: 'false' -# See https://zed0.co.uk/clang-format-configurator/ for generating this file. \ No newline at end of file +# See https://zed0.co.uk/clang-format-configurator/ for generating this file. diff --git a/src/examples/cluster-compute-example/src/cluster_compute_example.cpp b/src/examples/cluster-compute-example/src/cluster_compute_example.cpp index 53f3b100e..75fc1d582 100644 --- a/src/examples/cluster-compute-example/src/cluster_compute_example.cpp +++ b/src/examples/cluster-compute-example/src/cluster_compute_example.cpp @@ -30,128 +30,122 @@ using namespace cluster; /* * Function class. */ -class PrintMsg : public ComputeFunc -{ - friend struct ignite::binary::BinaryType; -public: - /* - * Default constructor. - */ - PrintMsg() : - msg("default") - { - // No-op. - } - - /* - * Constructor. - * - * @param text Text. - */ - PrintMsg(std::string msg) : - msg(msg) - { - // No-op. - } - - /** - * Callback. - * Just print the message. - * - */ - virtual void Call() - { - std::cout << "# MESSAGE => " << msg << std::endl; - } - -private: - /** Message text. */ - std::string msg; +class PrintMsg : public ComputeFunc< void > { + friend struct ignite::binary::BinaryType< PrintMsg >; + + public: + /* + * Default constructor. + */ + PrintMsg() : msg("default") { + // No-op. + } + + /* + * Constructor. + * + * @param text Text. + */ + PrintMsg(std::string msg) : msg(msg) { + // No-op. + } + + /** + * Callback. + * Just print the message. + * + */ + virtual void Call() { + std::cout << "# MESSAGE => " << msg << std::endl; + } + + private: + /** Message text. */ + std::string msg; }; -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType: BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "Func"; - } - - static void Write(BinaryWriter& writer, const PrintMsg& obj) - { - writer.RawWriter().WriteString(obj.msg); - } - - static void Read(BinaryReader& reader, PrintMsg& dst) - { - dst.msg = reader.RawReader().ReadString(); - } - }; - } -} +namespace ignite { +namespace binary { +template <> +struct BinaryType< PrintMsg > : BinaryTypeDefaultAll< PrintMsg > { + static void GetTypeName(std::string& dst) { + dst = "Func"; + } + + static void Write(BinaryWriter& writer, const PrintMsg& obj) { + writer.RawWriter().WriteString(obj.msg); + } + + static void Read(BinaryReader& reader, PrintMsg& dst) { + dst.msg = reader.RawReader().ReadString(); + } +}; +} // namespace binary +} // namespace ignite + +int main() { + IgniteConfiguration cfgs[4]; + + cfgs[0].springCfgPath = + "platforms/cpp/examples/cluster-compute-example/config/" + "cluster-compute-example1.xml"; + cfgs[1].springCfgPath = + "platforms/cpp/examples/cluster-compute-example/config/" + "cluster-compute-example2.xml"; + cfgs[2].springCfgPath = + "platforms/cpp/examples/cluster-compute-example/config/" + "cluster-compute-example2.xml"; + cfgs[3].springCfgPath = + "platforms/cpp/examples/cluster-compute-example/config/" + "cluster-compute-example-client.xml"; + + try { + // Start server nodes. + Ignite node1 = Ignition::Start(cfgs[0], "DemoAttributeValue0"); + Ignite node2 = Ignition::Start(cfgs[1], "DemoAttributeValue1I0"); + Ignite node3 = Ignition::Start(cfgs[2], "DemoAttributeValue1I1"); + + // Start client node. + Ignite client = Ignition::Start(cfgs[3], "Client"); + + std::cout << std::endl; + std::cout << ">>> Cluster compute example started." << std::endl; + std::cout << std::endl; + + // Get binding instances and register our classes as a compute functions. + node1.GetBinding().RegisterComputeFunc< PrintMsg >(); + node2.GetBinding().RegisterComputeFunc< PrintMsg >(); + node3.GetBinding().RegisterComputeFunc< PrintMsg >(); + client.GetBinding().RegisterComputeFunc< PrintMsg >(); + + // Create cluster groups split up by demo attribute value. + ClusterGroup localGroup = client.GetCluster().AsClusterGroup(); + ClusterGroup group1 = localGroup.ForAttribute("DemoAttribute", "Value0"); + ClusterGroup group2 = localGroup.ForAttribute("DemoAttribute", "Value1"); + + // Broadcast compute jobs. + client.GetCompute(group1).Broadcast(PrintMsg("DemoAttribute=Value0")); + client.GetCompute(group2).Broadcast(PrintMsg("DemoAttribute=Value1")); + + // Waiting the compute jobs to complete. + std::cout << std::endl; + std::cout << ">>> Example finished. Press 'Enter to stop cluster nodes ..." + << std::endl; + std::cout << std::endl; + std::cin.get(); -int main() -{ - IgniteConfiguration cfgs[4]; - - cfgs[0].springCfgPath = "platforms/cpp/examples/cluster-compute-example/config/cluster-compute-example1.xml"; - cfgs[1].springCfgPath = "platforms/cpp/examples/cluster-compute-example/config/cluster-compute-example2.xml"; - cfgs[2].springCfgPath = "platforms/cpp/examples/cluster-compute-example/config/cluster-compute-example2.xml"; - cfgs[3].springCfgPath = "platforms/cpp/examples/cluster-compute-example/config/cluster-compute-example-client.xml"; - - try - { - // Start server nodes. - Ignite node1 = Ignition::Start(cfgs[0], "DemoAttributeValue0"); - Ignite node2 = Ignition::Start(cfgs[1], "DemoAttributeValue1I0"); - Ignite node3 = Ignition::Start(cfgs[2], "DemoAttributeValue1I1"); - - // Start client node. - Ignite client = Ignition::Start(cfgs[3], "Client"); - - std::cout << std::endl; - std::cout << ">>> Cluster compute example started." << std::endl; - std::cout << std::endl; - - // Get binding instances and register our classes as a compute functions. - node1.GetBinding().RegisterComputeFunc(); - node2.GetBinding().RegisterComputeFunc(); - node3.GetBinding().RegisterComputeFunc(); - client.GetBinding().RegisterComputeFunc(); - - // Create cluster groups split up by demo attribute value. - ClusterGroup localGroup = client.GetCluster().AsClusterGroup(); - ClusterGroup group1 = localGroup.ForAttribute("DemoAttribute", "Value0"); - ClusterGroup group2 = localGroup.ForAttribute("DemoAttribute", "Value1"); - - // Broadcast compute jobs. - client.GetCompute(group1).Broadcast(PrintMsg("DemoAttribute=Value0")); - client.GetCompute(group2).Broadcast(PrintMsg("DemoAttribute=Value1")); - - // Waiting the compute jobs to complete. - std::cout << std::endl; - std::cout << ">>> Example finished. Press 'Enter to stop cluster nodes ..." << std::endl; - std::cout << std::endl; - std::cin.get(); - - // Stop client node first. - Ignition::Stop(client.GetName(), true); - - // Stop server nodes. - Ignition::StopAll(false); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; - - return err.GetCode(); - } + // Stop client node first. + Ignition::Stop(client.GetName(), true); - std::cin.get(); + // Stop server nodes. + Ignition::StopAll(false); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; + + return err.GetCode(); + } + + std::cin.get(); - return 0; + return 0; } diff --git a/src/examples/compute-example/src/compute_example.cpp b/src/examples/compute-example/src/compute_example.cpp index 7ca6e0295..5d595162a 100644 --- a/src/examples/compute-example/src/compute_example.cpp +++ b/src/examples/compute-example/src/compute_example.cpp @@ -27,128 +27,115 @@ using namespace ignite; /* * Function class. */ -class CountWords : public compute::ComputeFunc -{ - friend struct ignite::binary::BinaryType; -public: - /* - * Default constructor. - */ - CountWords() : - text() - { - // No-op. - } - - /* - * Constructor. - * - * @param text Text. - */ - CountWords(const std::string& text) : - text(text) - { - // No-op. - } - - /** - * Callback. - * Counts number of words in provided text. - * - * @return Number of words in provided text. - */ - virtual int32_t Call() - { - std::stringstream buf(text); - std::string word; - - int32_t wordsCount = 0; - while (buf >> word) - ++wordsCount; - - return wordsCount; - } - -private: - /** Text in which to count words. */ - std::string text; +class CountWords : public compute::ComputeFunc< int32_t > { + friend struct ignite::binary::BinaryType< CountWords >; + + public: + /* + * Default constructor. + */ + CountWords() : text() { + // No-op. + } + + /* + * Constructor. + * + * @param text Text. + */ + CountWords(const std::string& text) : text(text) { + // No-op. + } + + /** + * Callback. + * Counts number of words in provided text. + * + * @return Number of words in provided text. + */ + virtual int32_t Call() { + std::stringstream buf(text); + std::string word; + + int32_t wordsCount = 0; + while (buf >> word) + ++wordsCount; + + return wordsCount; + } + + private: + /** Text in which to count words. */ + std::string text; }; -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType: BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "CountWords"; - } - - static void Write(BinaryWriter& writer, const CountWords& obj) - { - writer.RawWriter().WriteString(obj.text); - } - - static void Read(BinaryReader& reader, CountWords& dst) - { - dst.text = reader.RawReader().ReadString(); - } - }; - } -} +namespace ignite { +namespace binary { +template <> +struct BinaryType< CountWords > : BinaryTypeDefaultAll< CountWords > { + static void GetTypeName(std::string& dst) { + dst = "CountWords"; + } + + static void Write(BinaryWriter& writer, const CountWords& obj) { + writer.RawWriter().WriteString(obj.text); + } + + static void Read(BinaryReader& reader, CountWords& dst) { + dst.text = reader.RawReader().ReadString(); + } +}; +} // namespace binary +} // namespace ignite -int main() -{ - IgniteConfiguration cfg; +int main() { + IgniteConfiguration cfg; - cfg.springCfgPath = "platforms/cpp/examples/compute-example/config/compute-example.xml"; + cfg.springCfgPath = + "platforms/cpp/examples/compute-example/config/compute-example.xml"; - try - { - // Start a node. - Ignite ignite = Ignition::Start(cfg); + try { + // Start a node. + Ignite ignite = Ignition::Start(cfg); - std::cout << std::endl; - std::cout << ">>> Compute example started." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Compute example started." << std::endl; + std::cout << std::endl; - // Get binding instance. - IgniteBinding binding = ignite.GetBinding(); + // Get binding instance. + IgniteBinding binding = ignite.GetBinding(); - // Registering our class as a compute function. - binding.RegisterComputeFunc(); + // Registering our class as a compute function. + binding.RegisterComputeFunc< CountWords >(); - // Get compute instance. - compute::Compute compute = ignite.GetCompute(); + // Get compute instance. + compute::Compute compute = ignite.GetCompute(); - std::string testText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; + std::string testText = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; - // Declaring counter. - CountWords counter(testText); + // Declaring counter. + CountWords counter(testText); - // Making call. - int32_t wordsCount = compute.Call(counter); + // Making call. + int32_t wordsCount = compute.Call< int32_t >(counter); - // Printing result. - std::cout << ">>> Text contains " << wordsCount << " words" << std::endl; + // Printing result. + std::cout << ">>> Text contains " << wordsCount << " words" << std::endl; - // Stop node. - Ignition::StopAll(false); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; + // Stop node. + Ignition::StopAll(false); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + return err.GetCode(); + } - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); + std::cin.get(); - return 0; + return 0; } diff --git a/src/examples/continuous-query-example/src/continuous_query_example.cpp b/src/examples/continuous-query-example/src/continuous_query_example.cpp index 0763105c3..f3921a089 100644 --- a/src/examples/continuous-query-example/src/continuous_query_example.cpp +++ b/src/examples/continuous-query-example/src/continuous_query_example.cpp @@ -35,203 +35,185 @@ const char* CACHE_NAME = "cpp_cache_continuous_query"; /** * Listener class. */ -template -class Listener : public event::CacheEntryEventListener -{ -public: - /** - * Default constructor. - */ - Listener() - { - // No-op. - } - - /** - * Event callback. - * - * @param evts Events. - * @param num Events number. - */ - virtual void OnEvent(const CacheEntryEvent* evts, uint32_t num) - { - for (uint32_t i = 0; i < num; ++i) - { - std::cout << "Queried entry [key=" << (evts[i].HasValue() ? evts[i].GetKey() : K()) - << ", val=" << (evts[i].HasValue() ? evts[i].GetValue() : V()) << ']' - << std::endl; - } +template < typename K, typename V > +class Listener : public event::CacheEntryEventListener< K, V > { + public: + /** + * Default constructor. + */ + Listener() { + // No-op. + } + + /** + * Event callback. + * + * @param evts Events. + * @param num Events number. + */ + virtual void OnEvent(const CacheEntryEvent< K, V >* evts, uint32_t num) { + for (uint32_t i = 0; i < num; ++i) { + std::cout << "Queried entry [key=" + << (evts[i].HasValue() ? evts[i].GetKey() : K()) + << ", val=" << (evts[i].HasValue() ? evts[i].GetValue() : V()) + << ']' << std::endl; } + } }; /** * Range Filter. Only lets through keys from the specified range. */ -template -struct RangeFilter : event::CacheEntryEventFilter -{ - /** - * Default constructor. - */ - RangeFilter() : - rangeBegin(0), - rangeEnd(0) - { - // No-op. - } - - /** - * Constructor. - * - * @param from Range beginning. Inclusive. - * @param to Range end. Not inclusive. - */ - RangeFilter(const K& from, const K& to) : - rangeBegin(from), - rangeEnd(to) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~RangeFilter() - { - // No-op. - } - - /** - * Event callback. - * - * @param event Event. - * @return True if the event passes filter. - */ - virtual bool Process(const CacheEntryEvent& event) - { - return event.GetKey() >= rangeBegin && event.GetKey() < rangeEnd; - } - - /** Beginning of the range. */ - K rangeBegin; - - /** End of the range. */ - K rangeEnd; +template < typename K, typename V > +struct RangeFilter : event::CacheEntryEventFilter< int32_t, std::string > { + /** + * Default constructor. + */ + RangeFilter() : rangeBegin(0), rangeEnd(0) { + // No-op. + } + + /** + * Constructor. + * + * @param from Range beginning. Inclusive. + * @param to Range end. Not inclusive. + */ + RangeFilter(const K& from, const K& to) : rangeBegin(from), rangeEnd(to) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~RangeFilter() { + // No-op. + } + + /** + * Event callback. + * + * @param event Event. + * @return True if the event passes filter. + */ + virtual bool Process(const CacheEntryEvent< K, V >& event) { + return event.GetKey() >= rangeBegin && event.GetKey() < rangeEnd; + } + + /** Beginning of the range. */ + K rangeBegin; + + /** End of the range. */ + K rangeEnd; }; -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType< RangeFilter > : - BinaryTypeDefaultAll< RangeFilter > - { - static void GetTypeName(std::string& dst) - { - dst = "RangeFilter"; - - } - - static void Write(BinaryWriter& writer, const RangeFilter& obj) - { - writer.WriteInt32("rangeBegin", obj.rangeBegin); - writer.WriteInt32("rangeEnd", obj.rangeEnd); - } - - static void Read(BinaryReader& reader, RangeFilter& dst) - { - dst.rangeBegin = reader.ReadInt32("rangeBegin"); - dst.rangeEnd = reader.ReadInt32("rangeEnd"); - } - }; - } -} - - -int main() -{ - IgniteConfiguration cfg; +namespace ignite { +namespace binary { +template <> +struct BinaryType< RangeFilter< int32_t, std::string > > + : BinaryTypeDefaultAll< RangeFilter< int32_t, std::string > > { + static void GetTypeName(std::string& dst) { + dst = "RangeFilter"; + } + + static void Write(BinaryWriter& writer, + const RangeFilter< int32_t, std::string >& obj) { + writer.WriteInt32("rangeBegin", obj.rangeBegin); + writer.WriteInt32("rangeEnd", obj.rangeEnd); + } + + static void Read(BinaryReader& reader, + RangeFilter< int32_t, std::string >& dst) { + dst.rangeBegin = reader.ReadInt32("rangeBegin"); + dst.rangeEnd = reader.ReadInt32("rangeEnd"); + } +}; +} // namespace binary +} // namespace ignite - cfg.springCfgPath = "platforms/cpp/examples/continuous-query-example/config/continuous-query-example.xml"; +int main() { + IgniteConfiguration cfg; - try - { - // Start a node. - Ignite ignite = Ignition::Start(cfg); + cfg.springCfgPath = + "platforms/cpp/examples/continuous-query-example/config/" + "continuous-query-example.xml"; - std::cout << std::endl; - std::cout << ">>> Cache continuous query example started." << std::endl; - std::cout << std::endl; + try { + // Start a node. + Ignite ignite = Ignition::Start(cfg); - // Get binding. - IgniteBinding binding = ignite.GetBinding(); + std::cout << std::endl; + std::cout << ">>> Cache continuous query example started." << std::endl; + std::cout << std::endl; - // Registering remote filter. - binding.RegisterCacheEntryEventFilter< RangeFilter >(); + // Get binding. + IgniteBinding binding = ignite.GetBinding(); - // Get cache instance. - Cache cache = ignite.GetOrCreateCache(CACHE_NAME); + // Registering remote filter. + binding + .RegisterCacheEntryEventFilter< RangeFilter< int32_t, std::string > >(); - cache.Clear(); + // Get cache instance. + Cache< int32_t, std::string > cache = + ignite.GetOrCreateCache< int32_t, std::string >(CACHE_NAME); - const int32_t keyCnt = 20; + cache.Clear(); - for (int32_t i = 0; i < keyCnt; ++i) - { - std::stringstream builder; + const int32_t keyCnt = 20; - builder << i; + for (int32_t i = 0; i < keyCnt; ++i) { + std::stringstream builder; - cache.Put(i, builder.str()); - } + builder << i; - // Declaring listener. - Listener listener; + cache.Put(i, builder.str()); + } - // Declaring filter. - RangeFilter filter(keyCnt, keyCnt + 5); + // Declaring listener. + Listener< int32_t, std::string > listener; - // Declaring continuous query. - continuous::ContinuousQuery qry(MakeReference(listener), MakeReference(filter)); + // Declaring filter. + RangeFilter< int32_t, std::string > filter(keyCnt, keyCnt + 5); - { - // Continuous query scope. Query is closed when scope is left. - continuous::ContinuousQueryHandle handle = cache.QueryContinuous(qry); + // Declaring continuous query. + continuous::ContinuousQuery< int32_t, std::string > qry( + MakeReference(listener), MakeReference(filter)); - // Add a few more keys and watch more query notifications. - for (int32_t i = keyCnt; i < keyCnt + 10; ++i) - { - std::stringstream builder; + { + // Continuous query scope. Query is closed when scope is left. + continuous::ContinuousQueryHandle< int32_t, std::string > handle = + cache.QueryContinuous(qry); - builder << i; + // Add a few more keys and watch more query notifications. + for (int32_t i = keyCnt; i < keyCnt + 10; ++i) { + std::stringstream builder; - cache.Put(i, builder.str()); - } + builder << i; - // Let user wait while callback is notified about remaining puts. - std::cout << std::endl; - std::cout << ">>> Press 'Enter' to continue..." << std::endl; - std::cout << std::endl; + cache.Put(i, builder.str()); + } - std::cin.get(); - } + // Let user wait while callback is notified about remaining puts. + std::cout << std::endl; + std::cout << ">>> Press 'Enter' to continue..." << std::endl; + std::cout << std::endl; - // Stop node. - Ignition::StopAll(false); + std::cin.get(); } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + // Stop node. + Ignition::StopAll(false); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + return err.GetCode(); + } + + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); + std::cin.get(); - return 0; + return 0; } diff --git a/src/examples/include/ignite/examples/address.h b/src/examples/include/ignite/examples/address.h index 6f28f89d3..73eb367e4 100644 --- a/src/examples/include/ignite/examples/address.h +++ b/src/examples/include/ignite/examples/address.h @@ -20,63 +20,51 @@ #include "ignite/binary/binary.h" -namespace ignite -{ - namespace examples - { - struct Address - { - Address() : street(), zip(0) - { - // No-op. - } +namespace ignite { +namespace examples { +struct Address { + Address() : street(), zip(0) { + // No-op. + } - Address(const std::string& street, int zip) : - street(street), zip(zip) - { - // No-op. - } + Address(const std::string& street, int zip) : street(street), zip(zip) { + // No-op. + } - std::string ToString() - { - std::ostringstream oss; + std::string ToString() { + std::ostringstream oss; - oss << "Address [street=" << street << ", zip=" << zip << "]"; + oss << "Address [street=" << street << ", zip=" << zip << "]"; - return oss.str(); - } + return oss.str(); + } - std::string street; - int zip; - }; - } -} + std::string street; + int zip; +}; +} // namespace examples +} // namespace ignite -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType : BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "Address"; - } +namespace ignite { +namespace binary { +template <> +struct BinaryType< examples::Address > + : BinaryTypeDefaultAll< examples::Address > { + static void GetTypeName(std::string& dst) { + dst = "Address"; + } - static void Write(BinaryWriter& writer, const examples::Address& obj) - { - writer.WriteString("street", obj.street); - writer.WriteInt32("zip", obj.zip); - } + static void Write(BinaryWriter& writer, const examples::Address& obj) { + writer.WriteString("street", obj.street); + writer.WriteInt32("zip", obj.zip); + } - static void Read(BinaryReader& reader, examples::Address& dst) - { - dst.street = reader.ReadString("street"); - dst.zip = reader.ReadInt32("zip"); - } - }; - } -} + static void Read(BinaryReader& reader, examples::Address& dst) { + dst.street = reader.ReadString("street"); + dst.zip = reader.ReadInt32("zip"); + } +}; +} // namespace binary +} // namespace ignite -#endif \ No newline at end of file +#endif diff --git a/src/examples/include/ignite/examples/organization.h b/src/examples/include/ignite/examples/organization.h index 61df3f669..4573efdbd 100644 --- a/src/examples/include/ignite/examples/organization.h +++ b/src/examples/include/ignite/examples/organization.h @@ -22,70 +22,56 @@ #include "ignite/examples/address.h" -namespace ignite -{ - namespace examples - { - struct Organization - { - Organization() : - name(), addr() - { - // No-op. - } +namespace ignite { +namespace examples { +struct Organization { + Organization() : name(), addr() { + // No-op. + } - Organization(const std::string& name) : - name(name), addr() - { - // No-op. - } + Organization(const std::string& name) : name(name), addr() { + // No-op. + } - Organization(const std::string& name, Address addr) : - name(name), addr(addr) - { - // No-op. - } + Organization(const std::string& name, Address addr) : name(name), addr(addr) { + // No-op. + } - std::string ToString() - { - std::ostringstream oss; + std::string ToString() { + std::ostringstream oss; - oss << "Organization [name=" << name << ", Address=" << addr.ToString() << "]"; + oss << "Organization [name=" << name << ", Address=" << addr.ToString() + << "]"; - return oss.str(); - } + return oss.str(); + } - std::string name; - Address addr; - }; - } -} + std::string name; + Address addr; +}; +} // namespace examples +} // namespace ignite -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType : BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "Organization"; - } +namespace ignite { +namespace binary { +template <> +struct BinaryType< examples::Organization > + : BinaryTypeDefaultAll< examples::Organization > { + static void GetTypeName(std::string& dst) { + dst = "Organization"; + } - static void Write(BinaryWriter& writer, const examples::Organization& obj) - { - writer.WriteString("name", obj.name); - writer.WriteObject("addr", obj.addr); - } + static void Write(BinaryWriter& writer, const examples::Organization& obj) { + writer.WriteString("name", obj.name); + writer.WriteObject< examples::Address >("addr", obj.addr); + } - static void Read(BinaryReader& reader, examples::Organization& dst) - { - dst.name = reader.ReadString("name"); - dst.addr = reader.ReadObject("addr"); - } - }; - } -} + static void Read(BinaryReader& reader, examples::Organization& dst) { + dst.name = reader.ReadString("name"); + dst.addr = reader.ReadObject< examples::Address >("addr"); + } +}; +} // namespace binary +} // namespace ignite -#endif \ No newline at end of file +#endif diff --git a/src/examples/include/ignite/examples/person.h b/src/examples/include/ignite/examples/person.h index 69f2083ad..ad91deace 100644 --- a/src/examples/include/ignite/examples/person.h +++ b/src/examples/include/ignite/examples/person.h @@ -24,136 +24,115 @@ #include "ignite/ignite.h" #include "ignite/ignition.h" -namespace ignite -{ - namespace examples - { - struct Person - { - Person() : orgId(0), salary(.0) - { - // No-op. - } - - Person(int64_t orgId, const std::string& firstName, - const std::string& lastName, const std::string& resume, double salary) : - orgId(orgId), - firstName(firstName), - lastName(lastName), - resume(resume), - salary(salary) - { - // No-op. - } - - std::string ToString() const - { - std::ostringstream oss; - - oss << "Person [orgId=" << orgId - << ", lastName=" << lastName - << ", firstName=" << firstName - << ", salary=" << salary - << ", resume=" << resume << ']'; - - return oss.str(); - } - - int64_t orgId; - std::string firstName; - std::string lastName; - std::string resume; - double salary; - }; - - // Person key with affinity Organization info. If we want to to collocate Persons with the same value of orgId - // we need to put struct as a cache key that contains fields: 1) id of the record (person id or serial id number) - // 2) collocation column info (orgId). This is required because of constraint : affinity key must be part of the - // key. - struct PersonKey { - PersonKey(int64_t id, int64_t orgId) : id(id), orgIdAff(orgId) - { - // No-op. - } - - PersonKey() : id(0), orgIdAff(0) - { - // No-op. - } - - std::string ToString() const - { - std::ostringstream oss; - - oss << "PersonKey [id=" << id - << ", orgIdAff=" << orgIdAff - << "]"; - return oss.str(); - } - - int64_t id; - int64_t orgIdAff; - }; - } -} - -namespace ignite -{ - namespace binary - { - template<> - struct BinaryType : BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "Person"; - } - - static void Write(BinaryWriter& writer, const examples::Person& obj) - { - writer.WriteInt64("orgId", obj.orgId); - writer.WriteString("firstName", obj.firstName); - writer.WriteString("lastName", obj.lastName); - writer.WriteString("resume", obj.resume); - writer.WriteDouble("salary", obj.salary); - } - - static void Read(BinaryReader& reader, examples::Person& dst) - { - dst.orgId = reader.ReadInt64("orgId"); - dst.firstName = reader.ReadString("firstName"); - dst.lastName = reader.ReadString("lastName"); - dst.resume = reader.ReadString("resume"); - dst.salary = reader.ReadDouble("salary"); - } - }; - - template<> - struct BinaryType : BinaryTypeDefaultAll - { - static void GetTypeName(std::string& dst) - { - dst = "PersonKey"; - } - - static void GetAffinityFieldName(std::string& dst) - { - dst = "orgIdAff"; - } - - static void Write(BinaryWriter& writer, const examples::PersonKey& obj) - { - writer.WriteInt64("id", obj.id); - writer.WriteInt64("orgIdAff", obj.orgIdAff); - } - - static void Read(BinaryReader& reader, examples::PersonKey& dst) - { - dst.id = reader.ReadInt64("id"); - dst.orgIdAff = reader.ReadInt64("orgIdAff"); - } - }; - } +namespace ignite { +namespace examples { +struct Person { + Person() : orgId(0), salary(.0) { + // No-op. + } + + Person(int64_t orgId, const std::string& firstName, + const std::string& lastName, const std::string& resume, double salary) + : orgId(orgId), + firstName(firstName), + lastName(lastName), + resume(resume), + salary(salary) { + // No-op. + } + + std::string ToString() const { + std::ostringstream oss; + + oss << "Person [orgId=" << orgId << ", lastName=" << lastName + << ", firstName=" << firstName << ", salary=" << salary + << ", resume=" << resume << ']'; + + return oss.str(); + } + + int64_t orgId; + std::string firstName; + std::string lastName; + std::string resume; + double salary; }; -#endif // _IGNITE_EXAMPLES_PERSON \ No newline at end of file +// Person key with affinity Organization info. If we want to to collocate +// Persons with the same value of orgId we need to put struct as a cache key +// that contains fields: 1) id of the record (person id or serial id number) 2) +// collocation column info (orgId). This is required because of constraint : +// affinity key must be part of the key. +struct PersonKey { + PersonKey(int64_t id, int64_t orgId) : id(id), orgIdAff(orgId) { + // No-op. + } + + PersonKey() : id(0), orgIdAff(0) { + // No-op. + } + + std::string ToString() const { + std::ostringstream oss; + + oss << "PersonKey [id=" << id << ", orgIdAff=" << orgIdAff << "]"; + return oss.str(); + } + + int64_t id; + int64_t orgIdAff; +}; +} // namespace examples +} // namespace ignite + +namespace ignite { +namespace binary { +template <> +struct BinaryType< examples::Person > + : BinaryTypeDefaultAll< examples::Person > { + static void GetTypeName(std::string& dst) { + dst = "Person"; + } + + static void Write(BinaryWriter& writer, const examples::Person& obj) { + writer.WriteInt64("orgId", obj.orgId); + writer.WriteString("firstName", obj.firstName); + writer.WriteString("lastName", obj.lastName); + writer.WriteString("resume", obj.resume); + writer.WriteDouble("salary", obj.salary); + } + + static void Read(BinaryReader& reader, examples::Person& dst) { + dst.orgId = reader.ReadInt64("orgId"); + dst.firstName = reader.ReadString("firstName"); + dst.lastName = reader.ReadString("lastName"); + dst.resume = reader.ReadString("resume"); + dst.salary = reader.ReadDouble("salary"); + } +}; + +template <> +struct BinaryType< examples::PersonKey > + : BinaryTypeDefaultAll< examples::PersonKey > { + static void GetTypeName(std::string& dst) { + dst = "PersonKey"; + } + + static void GetAffinityFieldName(std::string& dst) { + dst = "orgIdAff"; + } + + static void Write(BinaryWriter& writer, const examples::PersonKey& obj) { + writer.WriteInt64("id", obj.id); + writer.WriteInt64("orgIdAff", obj.orgIdAff); + } + + static void Read(BinaryReader& reader, examples::PersonKey& dst) { + dst.id = reader.ReadInt64("id"); + dst.orgIdAff = reader.ReadInt64("orgIdAff"); + } +}; +} // namespace binary +}; // namespace ignite + +#endif // _IGNITE_EXAMPLES_PERSON diff --git a/src/examples/odbc-example/src/odbc_example.cpp b/src/examples/odbc-example/src/odbc_example.cpp index 3c706305d..1873d394a 100644 --- a/src/examples/odbc-example/src/odbc_example.cpp +++ b/src/examples/odbc-example/src/odbc_example.cpp @@ -65,10 +65,9 @@ enum { ODBC_BUFFER_SIZE = 1024 }; /** * Represents simple string buffer. */ -struct OdbcStringBuffer -{ - SQLCHAR buffer[ODBC_BUFFER_SIZE]; - SQLLEN reallen; +struct OdbcStringBuffer { + SQLCHAR buffer[ODBC_BUFFER_SIZE]; + SQLLEN reallen; }; /** @@ -76,33 +75,32 @@ struct OdbcStringBuffer * * @param stmt Statement. */ -void PrintOdbcResultSet(SQLHSTMT stmt) -{ - SQLSMALLINT columnsCnt = 0; +void PrintOdbcResultSet(SQLHSTMT stmt) { + SQLSMALLINT columnsCnt = 0; - // Getting number of columns in result set. - SQLNumResultCols(stmt, &columnsCnt); + // Getting number of columns in result set. + SQLNumResultCols(stmt, &columnsCnt); - std::vector columns(columnsCnt); + std::vector< OdbcStringBuffer > columns(columnsCnt); - // Binding colums. - for (SQLSMALLINT i = 0; i < columnsCnt; ++i) - SQLBindCol(stmt, i + 1, SQL_CHAR, columns[i].buffer, ODBC_BUFFER_SIZE, &columns[i].reallen); + // Binding colums. + for (SQLSMALLINT i = 0; i < columnsCnt; ++i) + SQLBindCol(stmt, i + 1, SQL_CHAR, columns[i].buffer, ODBC_BUFFER_SIZE, + &columns[i].reallen); - while (true) - { - SQLRETURN ret = SQLFetch(stmt); + while (true) { + SQLRETURN ret = SQLFetch(stmt); - if (!SQL_SUCCEEDED(ret)) - break; + if (!SQL_SUCCEEDED(ret)) + break; - std::cout << ">>> "; + std::cout << ">>> "; - for (size_t i = 0; i < columns.size(); ++i) - std::cout << std::setw(16) << std::left << columns[i].buffer << " "; + for (size_t i = 0; i < columns.size(); ++i) + std::cout << std::setw(16) << std::left << columns[i].buffer << " "; - std::cout << std::endl; - } + std::cout << std::endl; + } } /** @@ -112,18 +110,18 @@ void PrintOdbcResultSet(SQLHSTMT stmt) * @param handle Handle. * @return Error message. */ -std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle) -{ - SQLCHAR sqlstate[7] = {}; - SQLINTEGER nativeCode; +std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle) { + SQLCHAR sqlstate[7] = {}; + SQLINTEGER nativeCode; - SQLCHAR message[ODBC_BUFFER_SIZE]; - SQLSMALLINT reallen = 0; + SQLCHAR message[ODBC_BUFFER_SIZE]; + SQLSMALLINT reallen = 0; - SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeCode, message, ODBC_BUFFER_SIZE, &reallen); + SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeCode, message, + ODBC_BUFFER_SIZE, &reallen); - return std::string(reinterpret_cast(sqlstate)) + ": " + - std::string(reinterpret_cast(message), reallen); + return std::string(reinterpret_cast< char* >(sqlstate)) + ": " + + std::string(reinterpret_cast< char* >(message), reallen); } /** @@ -133,38 +131,38 @@ std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle) * @param handle Handle. * @param msg Error message. */ -void ThrowOdbcError(SQLSMALLINT handleType, SQLHANDLE handle, std::string msg) -{ - std::stringstream builder; +void ThrowOdbcError(SQLSMALLINT handleType, SQLHANDLE handle, std::string msg) { + std::stringstream builder; - builder << msg << ": " << GetOdbcErrorMessage(handleType, handle); + builder << msg << ": " << GetOdbcErrorMessage(handleType, handle); - std::string errorMsg = builder.str(); + std::string errorMsg = builder.str(); - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, errorMsg.c_str()); + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, errorMsg.c_str()); } /** * Fetch cache data using ODBC interface. */ -void GetDataWithOdbc(SQLHDBC dbc, const std::string& query) -{ - SQLHSTMT stmt; +void GetDataWithOdbc(SQLHDBC dbc, const std::string& query) { + SQLHSTMT stmt; - // Allocate a statement handle - SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); + // Allocate a statement handle + SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - std::vector buf(query.begin(), query.end()); + std::vector< SQLCHAR > buf(query.begin(), query.end()); - SQLRETURN ret = SQLExecDirect(stmt, &buf[0], static_cast(buf.size())); + SQLRETURN ret = + SQLExecDirect(stmt, &buf[0], static_cast< SQLSMALLINT >(buf.size())); - if (SQL_SUCCEEDED(ret)) - PrintOdbcResultSet(stmt); - else - std::cerr << "Failed to execute query: " << GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt) << std::endl; + if (SQL_SUCCEEDED(ret)) + PrintOdbcResultSet(stmt); + else + std::cerr << "Failed to execute query: " + << GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt) << std::endl; - // Releasing statement handle. - SQLFreeHandle(SQL_HANDLE_STMT, stmt); + // Releasing statement handle. + SQLFreeHandle(SQL_HANDLE_STMT, stmt); } /** @@ -172,239 +170,251 @@ void GetDataWithOdbc(SQLHDBC dbc, const std::string& query) * * @param dbc Database connection. */ -void PopulatePerson(SQLHDBC dbc) -{ - SQLHSTMT stmt; - - // Allocate a statement handle - SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to allocate statement handle"); - - try - { - SQLCHAR query[] = - "INSERT INTO Person (id, orgIdAff, orgId, firstName, lastName, resume, salary) " - "VALUES (?, ?, ?, ?, ?, ?, ?)"; +void PopulatePerson(SQLHDBC dbc) { + SQLHSTMT stmt; - ret = SQLPrepare(stmt, query, static_cast(sizeof(query))); + // Allocate a statement handle + SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to prepare query"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to allocate statement handle"); - // Binding columns. + try { + SQLCHAR query[] = + "INSERT INTO Person (id, orgIdAff, orgId, firstName, lastName, resume, " + "salary) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"; - int64_t keyId = 0; - int64_t keyOrgIdAff = 0; + ret = SQLPrepare(stmt, query, static_cast< SQLSMALLINT >(sizeof(query))); - int64_t orgId = 0; - char firstName[1024] = { 0 }; - SQLLEN firstNameLen = SQL_NTS; - char lastName[1024] = { 0 }; - SQLLEN lastNameLen = SQL_NTS; - char resume[1024] = { 0 }; - SQLLEN resumeLen = SQL_NTS; - double salary = 0.0; + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to prepare query"); - ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &keyId, 0, 0); + // Binding columns. - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + int64_t keyId = 0; + int64_t keyOrgIdAff = 0; - ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &keyOrgIdAff, 0, 0); + int64_t orgId = 0; + char firstName[1024] = {0}; + SQLLEN firstNameLen = SQL_NTS; + char lastName[1024] = {0}; + SQLLEN lastNameLen = SQL_NTS; + char resume[1024] = {0}; + SQLLEN resumeLen = SQL_NTS; + double salary = 0.0; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, + 0, &keyId, 0, 0); - ret = SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &orgId, 0, 0); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, + 0, &keyOrgIdAff, 0, 0); - ret = SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, - sizeof(firstName), sizeof(firstName), firstName, 0, &firstNameLen); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, + 0, &orgId, 0, 0); - ret = SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, - sizeof(lastName), sizeof(lastName), lastName, 0, &lastNameLen); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + sizeof(firstName), sizeof(firstName), firstName, 0, + &firstNameLen); - ret = SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, - sizeof(resume), sizeof(resume), resume, 0, &resumeLen); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + sizeof(lastName), sizeof(lastName), lastName, 0, + &lastNameLen); - ret = SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, 0, 0, &salary, 0, 0); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + ret = + SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, + sizeof(resume), sizeof(resume), resume, 0, &resumeLen); - // Filling cache. - keyId = 1; - keyOrgIdAff = 1; + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - orgId = keyOrgIdAff; - strncpy(firstName, "John", sizeof(firstName)); - strncpy(lastName, "Doe", sizeof(lastName)); - strncpy(resume, "Master Degree.", sizeof(resume)); - salary = 2200.0; + ret = SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, + 0, 0, &salary, 0, 0); - ret = SQLExecute(stmt); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + // Filling cache. + keyId = 1; + keyOrgIdAff = 1; - ret = SQLMoreResults(stmt); + orgId = keyOrgIdAff; + strncpy(firstName, "John", sizeof(firstName)); + strncpy(lastName, "Doe", sizeof(lastName)); + strncpy(resume, "Master Degree.", sizeof(resume)); + salary = 2200.0; - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + ret = SQLExecute(stmt); - ++keyId; - keyOrgIdAff = 1; + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - orgId = keyOrgIdAff; - strncpy(firstName, "Jane", sizeof(firstName)); - strncpy(lastName, "Doe", sizeof(lastName)); - strncpy(resume, "Bachelor Degree.", sizeof(resume)); - salary = 1300.0; + ret = SQLMoreResults(stmt); - ret = SQLExecute(stmt); + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + ++keyId; + keyOrgIdAff = 1; + orgId = keyOrgIdAff; + strncpy(firstName, "Jane", sizeof(firstName)); + strncpy(lastName, "Doe", sizeof(lastName)); + strncpy(resume, "Bachelor Degree.", sizeof(resume)); + salary = 1300.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 2; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "John", sizeof(firstName)); - strncpy(lastName, "Smith", sizeof(lastName)); - strncpy(resume, "Bachelor Degree.", sizeof(resume)); - salary = 1700.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 2; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + orgId = keyOrgIdAff; + strncpy(firstName, "John", sizeof(firstName)); + strncpy(lastName, "Smith", sizeof(lastName)); + strncpy(resume, "Bachelor Degree.", sizeof(resume)); + salary = 1700.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 2; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "Jane", sizeof(firstName)); - strncpy(lastName, "Smith", sizeof(lastName)); - strncpy(resume, "Master Degree.", sizeof(resume)); - salary = 2500.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 2; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + orgId = keyOrgIdAff; + strncpy(firstName, "Jane", sizeof(firstName)); + strncpy(lastName, "Smith", sizeof(lastName)); + strncpy(resume, "Master Degree.", sizeof(resume)); + salary = 2500.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 2; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "John", sizeof(firstName)); - strncpy(lastName, "Roe", sizeof(lastName)); - strncpy(resume, "Bachelor Degree.", sizeof(resume)); - salary = 1500.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 2; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + orgId = keyOrgIdAff; + strncpy(firstName, "John", sizeof(firstName)); + strncpy(lastName, "Roe", sizeof(lastName)); + strncpy(resume, "Bachelor Degree.", sizeof(resume)); + salary = 1500.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 2; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "Jane", sizeof(firstName)); - strncpy(lastName, "Roe", sizeof(lastName)); - strncpy(resume, "Bachelor Degree.", sizeof(resume)); - salary = 1000.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 2; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + orgId = keyOrgIdAff; + strncpy(firstName, "Jane", sizeof(firstName)); + strncpy(lastName, "Roe", sizeof(lastName)); + strncpy(resume, "Bachelor Degree.", sizeof(resume)); + salary = 1000.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 1; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "Richard", sizeof(firstName)); - strncpy(lastName, "Miles", sizeof(lastName)); - strncpy(resume, "Master Degree.", sizeof(resume)); - salary = 2400.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 1; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); + orgId = keyOrgIdAff; + strncpy(firstName, "Richard", sizeof(firstName)); + strncpy(lastName, "Miles", sizeof(lastName)); + strncpy(resume, "Master Degree.", sizeof(resume)); + salary = 2400.0; - ret = SQLMoreResults(stmt); + ret = SQLExecute(stmt); - if (ret != SQL_NO_DATA) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); - ++keyId; - keyOrgIdAff = 2; + ret = SQLMoreResults(stmt); - orgId = keyOrgIdAff; - strncpy(firstName, "Mary", sizeof(firstName)); - strncpy(lastName, "Major", sizeof(lastName)); - strncpy(resume, "Bachelor Degree.", sizeof(resume)); - salary = 900.0; + if (ret != SQL_NO_DATA) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "No more data expected"); - ret = SQLExecute(stmt); + ++keyId; + keyOrgIdAff = 2; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute prepared statement"); - } - catch(...) - { - // Releasing statement handle. - SQLFreeHandle(SQL_HANDLE_STMT, stmt); + orgId = keyOrgIdAff; + strncpy(firstName, "Mary", sizeof(firstName)); + strncpy(lastName, "Major", sizeof(lastName)); + strncpy(resume, "Bachelor Degree.", sizeof(resume)); + salary = 900.0; - // Re-throwing expection. - throw; - } + ret = SQLExecute(stmt); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to execute prepared statement"); + } catch (...) { // Releasing statement handle. SQLFreeHandle(SQL_HANDLE_STMT, stmt); + + // Re-throwing expection. + throw; + } + + // Releasing statement handle. + SQLFreeHandle(SQL_HANDLE_STMT, stmt); } /** @@ -412,45 +422,48 @@ void PopulatePerson(SQLHDBC dbc) * * @param dbc Database connection. */ -void PopulateOrganization(SQLHDBC dbc) -{ - SQLHSTMT stmt; +void PopulateOrganization(SQLHDBC dbc) { + SQLHSTMT stmt; - // Allocate a statement handle - SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); + // Allocate a statement handle + SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to allocate statement handle"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to allocate statement handle"); - try - { - SQLCHAR query1[] = "INSERT INTO \"Organization\".Organization (_key, name) VALUES (1L, 'Microsoft')"; + try { + SQLCHAR query1[] = + "INSERT INTO \"Organization\".Organization (_key, name) VALUES (1L, " + "'Microsoft')"; - ret = SQLExecDirect(stmt, query1, static_cast(sizeof(query1))); + ret = + SQLExecDirect(stmt, query1, static_cast< SQLSMALLINT >(sizeof(query1))); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); - - SQLFreeStmt(stmt, SQL_CLOSE); - - SQLCHAR query2[] = "INSERT INTO \"Organization\".Organization (_key, name) VALUES (2L, 'Red Cross')"; + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); - ret = SQLExecDirect(stmt, query2, static_cast(sizeof(query2))); + SQLFreeStmt(stmt, SQL_CLOSE); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); - } - catch (...) - { - // Releasing statement handle. - SQLFreeHandle(SQL_HANDLE_STMT, stmt); + SQLCHAR query2[] = + "INSERT INTO \"Organization\".Organization (_key, name) VALUES (2L, " + "'Red Cross')"; - // Re-throwing expection. - throw; - } + ret = + SQLExecDirect(stmt, query2, static_cast< SQLSMALLINT >(sizeof(query2))); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); + } catch (...) { // Releasing statement handle. SQLFreeHandle(SQL_HANDLE_STMT, stmt); + + // Re-throwing expection. + throw; + } + + // Releasing statement handle. + SQLFreeHandle(SQL_HANDLE_STMT, stmt); } /** @@ -460,46 +473,45 @@ void PopulateOrganization(SQLHDBC dbc) * @param id Person id. * @param salary New salary. */ -void AdjustSalary(SQLHDBC dbc, int64_t id, double salary) -{ - SQLHSTMT stmt; - - // Allocate a statement handle - SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); +void AdjustSalary(SQLHDBC dbc, int64_t id, double salary) { + SQLHSTMT stmt; - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to allocate statement handle"); - - try - { - SQLCHAR query[] = "UPDATE Person SET salary=? WHERE id=?"; + // Allocate a statement handle + SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, 0, 0, &salary, 0, 0); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to allocate statement handle"); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + try { + SQLCHAR query[] = "UPDATE Person SET salary=? WHERE id=?"; - ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &id, 0, 0); + ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, + 0, 0, &salary, 0, 0); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - ret = SQLExecDirect(stmt, query, static_cast(sizeof(query))); + ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, + 0, &id, 0, 0); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); - } - catch (...) - { - // Releasing statement handle. - SQLFreeHandle(SQL_HANDLE_STMT, stmt); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - // Re-throwing expection. - throw; - } + ret = SQLExecDirect(stmt, query, static_cast< SQLSMALLINT >(sizeof(query))); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); + } catch (...) { // Releasing statement handle. SQLFreeHandle(SQL_HANDLE_STMT, stmt); + + // Re-throwing expection. + throw; + } + + // Releasing statement handle. + SQLFreeHandle(SQL_HANDLE_STMT, stmt); } /** @@ -508,41 +520,39 @@ void AdjustSalary(SQLHDBC dbc, int64_t id, double salary) * @param dbc Database connection. * @param id Person id. */ -void DeletePerson(SQLHDBC dbc, int64_t id) -{ - SQLHSTMT stmt; +void DeletePerson(SQLHDBC dbc, int64_t id) { + SQLHSTMT stmt; - // Allocate a statement handle - SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); + // Allocate a statement handle + SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to allocate statement handle"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, + "Failed to allocate statement handle"); - try - { - SQLCHAR query[] = "DELETE FROM Person WHERE id=?"; + try { + SQLCHAR query[] = "DELETE FROM Person WHERE id=?"; - ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &id, 0, 0); + ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, + 0, &id, 0, 0); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - - ret = SQLExecDirect(stmt, query, static_cast(sizeof(query))); - - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); - } - catch (...) - { - // Releasing statement handle. - SQLFreeHandle(SQL_HANDLE_STMT, stmt); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to bind parameter"); - // Re-throwing expection. - throw; - } + ret = SQLExecDirect(stmt, query, static_cast< SQLSMALLINT >(sizeof(query))); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_STMT, stmt, "Failed to execute query"); + } catch (...) { // Releasing statement handle. SQLFreeHandle(SQL_HANDLE_STMT, stmt); + + // Re-throwing expection. + throw; + } + + // Releasing statement handle. + SQLFreeHandle(SQL_HANDLE_STMT, stmt); } /** @@ -550,25 +560,29 @@ void DeletePerson(SQLHDBC dbc, int64_t id) * * @param dbc Database connection. */ -void QueryData(SQLHDBC dbc) -{ - std::cout << std::endl; - std::cout << ">>> Getting list of persons:" << std::endl; +void QueryData(SQLHDBC dbc) { + std::cout << std::endl; + std::cout << ">>> Getting list of persons:" << std::endl; - GetDataWithOdbc(dbc, "SELECT firstName, lastName, resume, salary FROM Person ORDER BY id"); + GetDataWithOdbc( + dbc, + "SELECT firstName, lastName, resume, salary FROM Person ORDER BY id"); - std::cout << std::endl; - std::cout << ">>> Getting average salary by degree:" << std::endl; + std::cout << std::endl; + std::cout << ">>> Getting average salary by degree:" << std::endl; - GetDataWithOdbc(dbc, "SELECT resume, AVG(salary) FROM Person GROUP BY resume ORDER BY resume"); + GetDataWithOdbc( + dbc, + "SELECT resume, AVG(salary) FROM Person GROUP BY resume ORDER BY resume"); - std::cout << std::endl; - std::cout << ">>> Getting people with organizations:" << std::endl; + std::cout << std::endl; + std::cout << ">>> Getting people with organizations:" << std::endl; - GetDataWithOdbc(dbc, - "SELECT firstName, lastName, Organization.name FROM Person " - "INNER JOIN \"Organization\".Organization ON Person.orgId = Organization._KEY " - "ORDER BY Person.id"); + GetDataWithOdbc(dbc, + "SELECT firstName, lastName, Organization.name FROM Person " + "INNER JOIN \"Organization\".Organization ON Person.orgId = " + "Organization._KEY " + "ORDER BY Person.id"); } /** @@ -576,92 +590,94 @@ void QueryData(SQLHDBC dbc) * * @return Exit code. */ -int main() -{ - IgniteConfiguration cfg; +int main() { + IgniteConfiguration cfg; - cfg.springCfgPath = "platforms/cpp/examples/odbc-example/config/example-odbc.xml"; + cfg.springCfgPath = + "platforms/cpp/examples/odbc-example/config/example-odbc.xml"; - try - { - // Start a node. - Ignite grid = Ignition::Start(cfg); + try { + // Start a node. + Ignite grid = Ignition::Start(cfg); - SQLHENV env; + SQLHENV env; - // Allocate an environment handle - SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); + // Allocate an environment handle + SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); - // We want ODBC 3 support - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast(SQL_OV_ODBC3), 0); + // We want ODBC 3 support + SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, + reinterpret_cast< void* >(SQL_OV_ODBC3), 0); - SQLHDBC dbc; + SQLHDBC dbc; - // Allocate a connection handle - SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc); + // Allocate a connection handle + SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc); - // Combining connect string - std::string connectStr = "DRIVER={Apache Ignite};SERVER=localhost;PORT=10800;SCHEMA=Person;"; + // Combining connect string + std::string connectStr = + "DRIVER={Apache Ignite};SERVER=localhost;PORT=10800;SCHEMA=Person;"; - SQLCHAR outstr[ODBC_BUFFER_SIZE]; - SQLSMALLINT outstrlen; + SQLCHAR outstr[ODBC_BUFFER_SIZE]; + SQLSMALLINT outstrlen; - // Connecting to ODBC server. - SQLRETURN ret = SQLDriverConnect(dbc, NULL, reinterpret_cast(&connectStr[0]), - static_cast(connectStr.size()), outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE); + // Connecting to ODBC server. + SQLRETURN ret = SQLDriverConnect( + dbc, NULL, reinterpret_cast< SQLCHAR* >(&connectStr[0]), + static_cast< SQLSMALLINT >(connectStr.size()), outstr, sizeof(outstr), + &outstrlen, SQL_DRIVER_COMPLETE); - if (!SQL_SUCCEEDED(ret)) - ThrowOdbcError(SQL_HANDLE_DBC, dbc, "Failed to connect"); + if (!SQL_SUCCEEDED(ret)) + ThrowOdbcError(SQL_HANDLE_DBC, dbc, "Failed to connect"); - std::cout << std::endl; - std::cout << ">>> Cache ODBC example started." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Cache ODBC example started." << std::endl; + std::cout << std::endl; - // Populate caches. - PopulatePerson(dbc); - PopulateOrganization(dbc); + // Populate caches. + PopulatePerson(dbc); + PopulateOrganization(dbc); - QueryData(dbc); + QueryData(dbc); - std::cout << std::endl; - std::cout << std::endl; - std::cout << ">>> Adjusted salary for Mary Major. Querying again." << std::endl; + std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Adjusted salary for Mary Major. Querying again." + << std::endl; - AdjustSalary(dbc, 8, 1200.0); + AdjustSalary(dbc, 8, 1200.0); - QueryData(dbc); + QueryData(dbc); - std::cout << std::endl; - std::cout << std::endl; - std::cout << ">>> Removing several employees. Querying again." << std::endl; + std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Removing several employees. Querying again." << std::endl; - DeletePerson(dbc, 4); - DeletePerson(dbc, 5); + DeletePerson(dbc, 4); + DeletePerson(dbc, 5); - QueryData(dbc); + QueryData(dbc); - // Disconneting from the server. - SQLDisconnect(dbc); + // Disconneting from the server. + SQLDisconnect(dbc); - // Releasing allocated handles. - SQLFreeHandle(SQL_HANDLE_DBC, dbc); - SQLFreeHandle(SQL_HANDLE_ENV, env); + // Releasing allocated handles. + SQLFreeHandle(SQL_HANDLE_DBC, dbc); + SQLFreeHandle(SQL_HANDLE_ENV, env); - // Stop node. - Ignition::StopAll(false); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; + // Stop node. + Ignition::StopAll(false); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + return err.GetCode(); + } - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); + std::cin.get(); - return 0; + return 0; } diff --git a/src/examples/put-get-example/src/put_get_example.cpp b/src/examples/put-get-example/src/put_get_example.cpp index bc75954c7..922afee9e 100644 --- a/src/examples/put-get-example/src/put_get_example.cpp +++ b/src/examples/put-get-example/src/put_get_example.cpp @@ -29,97 +29,99 @@ using namespace examples; /* * Execute individual Put and Get operations. - * + * * @param cache Cache instance. */ -void PutGet(Cache& cache) -{ - // Create new Organization to store in cache. - Organization org("Microsoft", Address("1096 Eddy Street, San Francisco, CA", 94109)); +void PutGet(Cache< int, Organization >& cache) { + // Create new Organization to store in cache. + Organization org("Microsoft", + Address("1096 Eddy Street, San Francisco, CA", 94109)); - // Put organization to cache. - cache.Put(1, org); + // Put organization to cache. + cache.Put(1, org); - // Get recently created employee as a strongly-typed fully de-serialized instance. - Organization orgFromCache = cache.Get(1); + // Get recently created employee as a strongly-typed fully de-serialized + // instance. + Organization orgFromCache = cache.Get(1); - std::cout << ">>> Retrieved organization instance from cache: " << std::endl; - std::cout << orgFromCache.ToString() << std::endl; - std::cout << std::endl; + std::cout << ">>> Retrieved organization instance from cache: " << std::endl; + std::cout << orgFromCache.ToString() << std::endl; + std::cout << std::endl; } /* * Execute bulk Put and Get operations. */ -void PutGetAll(Cache& cache) -{ - // Create new Organizations to store in cache. - Organization org1("Microsoft", Address("1096 Eddy Street, San Francisco, CA", 94109)); - Organization org2("Red Cross", Address("184 Fidler Drive, San Antonio, TX", 78205)); +void PutGetAll(Cache< int, Organization >& cache) { + // Create new Organizations to store in cache. + Organization org1("Microsoft", + Address("1096 Eddy Street, San Francisco, CA", 94109)); + Organization org2("Red Cross", + Address("184 Fidler Drive, San Antonio, TX", 78205)); - // Put created data entries to cache. - std::map vals; + // Put created data entries to cache. + std::map< int, Organization > vals; - vals[1] = org1; - vals[2] = org2; + vals[1] = org1; + vals[2] = org2; - cache.PutAll(vals); + cache.PutAll(vals); - // Get recently created organizations as a strongly-typed fully de-serialized instances. - std::set keys; + // Get recently created organizations as a strongly-typed fully de-serialized + // instances. + std::set< int > keys; - keys.insert(1); - keys.insert(2); + keys.insert(1); + keys.insert(2); - std::map valsFromCache = cache.GetAll(keys); + std::map< int, Organization > valsFromCache = cache.GetAll(keys); - std::cout << ">>> Retrieved organization instances from cache: " << std::endl; + std::cout << ">>> Retrieved organization instances from cache: " << std::endl; - for (std::map::iterator it = valsFromCache.begin(); it != valsFromCache.end(); ++it) - std::cout << it->second.ToString() << std::endl; + for (std::map< int, Organization >::iterator it = valsFromCache.begin(); + it != valsFromCache.end(); ++it) + std::cout << it->second.ToString() << std::endl; - std::cout << std::endl; + std::cout << std::endl; } -int main() -{ - IgniteConfiguration cfg; +int main() { + IgniteConfiguration cfg; - cfg.springCfgPath = "platforms/cpp/examples/put-get-example/config/example-cache.xml"; + cfg.springCfgPath = + "platforms/cpp/examples/put-get-example/config/example-cache.xml"; - try - { - // Start a node. - Ignite grid = Ignition::Start(cfg); + try { + // Start a node. + Ignite grid = Ignition::Start(cfg); - std::cout << std::endl; - std::cout << ">>> Cache put-get example started." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Cache put-get example started." << std::endl; + std::cout << std::endl; - // Get cache instance. - Cache cache = grid.GetCache("atomic"); + // Get cache instance. + Cache< int, Organization > cache = + grid.GetCache< int, Organization >("atomic"); - // Clear cache. - cache.Clear(); + // Clear cache. + cache.Clear(); - PutGet(cache); - PutGetAll(cache); + PutGet(cache); + PutGetAll(cache); - // Stop node. - Ignition::StopAll(false); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; + // Stop node. + Ignition::StopAll(false); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + return err.GetCode(); + } - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); + std::cin.get(); - return 0; -} \ No newline at end of file + return 0; +} diff --git a/src/examples/query-example/src/query_example.cpp b/src/examples/query-example/src/query_example.cpp index 2b7b2c5c1..4377939ac 100644 --- a/src/examples/query-example/src/query_example.cpp +++ b/src/examples/query-example/src/query_example.cpp @@ -49,95 +49,98 @@ const char* PERSON_TYPE = "Person"; * Note that SQL Fields Query can only be performed using fields that have been * listed in "QueryEntity" been of the config. */ -void DoSqlQueryWithDistributedJoin() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoSqlQueryWithDistributedJoin() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // SQL clause query which joins on 2 types to select people for a specific organization. - SqlFieldsQuery qry( - "select firstName, lastName from Person " - "inner join \"Organization\".Organization as org " - "where Person.orgId = org._key " - "and lower(org.name) = lower(?)"); + // SQL clause query which joins on 2 types to select people for a specific + // organization. + SqlFieldsQuery qry( + "select firstName, lastName from Person " + "inner join \"Organization\".Organization as org " + "where Person.orgId = org._key " + "and lower(org.name) = lower(?)"); - qry.AddArgument("ApacheIgnite"); + qry.AddArgument< std::string >("ApacheIgnite"); - // Enable distributed joins for query. - qry.SetDistributedJoins(true); + // Enable distributed joins for query. + qry.SetDistributedJoins(true); - QueryFieldsCursor cursor = cache.Query(qry); + QueryFieldsCursor cursor = cache.Query(qry); - // Printing first result set. - std::cout << "Following people are 'ApacheIgnite' employees (distributed join): " << std::endl; + // Printing first result set. + std::cout + << "Following people are 'ApacheIgnite' employees (distributed join): " + << std::endl; - while (cursor.HasNext()) - { - QueryFieldsRow row = cursor.GetNext(); + while (cursor.HasNext()) { + QueryFieldsRow row = cursor.GetNext(); - std::string firstName = row.GetNext(); - std::string lastName = row.GetNext(); + std::string firstName = row.GetNext< std::string >(); + std::string lastName = row.GetNext< std::string >(); - std::cout << firstName << " " << lastName << std::endl; - } + std::cout << firstName << " " << lastName << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; - qry.ClearArguments(); + qry.ClearArguments(); - qry.AddArgument("Other"); + qry.AddArgument< std::string >("Other"); - cursor = cache.Query(qry); + cursor = cache.Query(qry); - // Printing second result set. - std::cout << "Following people are 'Other' employees (distributed join): " << std::endl; + // Printing second result set. + std::cout << "Following people are 'Other' employees (distributed join): " + << std::endl; - while (cursor.HasNext()) - { - QueryFieldsRow row = cursor.GetNext(); + while (cursor.HasNext()) { + QueryFieldsRow row = cursor.GetNext(); - std::string firstName = row.GetNext(); - std::string lastName = row.GetNext(); + std::string firstName = row.GetNext< std::string >(); + std::string lastName = row.GetNext< std::string >(); - std::cout << firstName << " " << lastName << std::endl; - } + std::cout << firstName << " " << lastName << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** - * Example for SQL-based fields queries that return only person name and company it works in. + * Example for SQL-based fields queries that return only person name and company + * it works in. * * Note that SQL Fields Query can only be performed using fields that have been * listed in "QueryEntity" been of the config. */ -void DoSqlQueryWithJoin() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoSqlQueryWithJoin() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // Execute query to get names of all employees. - std::string sql( - "select concat(firstName, ' ', lastName), org.name " - "from Person inner join \"Organization\".Organization as org " - "on Person.orgId = org._key"); + // Execute query to get names of all employees. + std::string sql( + "select concat(firstName, ' ', lastName), org.name " + "from Person inner join \"Organization\".Organization as org " + "on Person.orgId = org._key"); - QueryFieldsCursor cursor = cache.Query(SqlFieldsQuery(sql)); + QueryFieldsCursor cursor = cache.Query(SqlFieldsQuery(sql)); - // Print persons' names and organizations' names. - std::cout << "Names of all employees and organizations they belong to: " << std::endl; + // Print persons' names and organizations' names. + std::cout << "Names of all employees and organizations they belong to: " + << std::endl; - // In this particular case each row will have two elements with full name - // of an employees and their organization. - while (cursor.HasNext()) - { - QueryFieldsRow row = cursor.GetNext(); + // In this particular case each row will have two elements with full name + // of an employees and their organization. + while (cursor.HasNext()) { + QueryFieldsRow row = cursor.GetNext(); - std::string person = row.GetNext(); - std::string organization = row.GetNext(); + std::string person = row.GetNext< std::string >(); + std::string organization = row.GetNext< std::string >(); - std::cout << person << " is working in " << organization << std::endl; - } + std::cout << person << " is working in " << organization << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** @@ -146,61 +149,61 @@ void DoSqlQueryWithJoin() * Note that SQL Fields Query can only be performed using fields that have been * listed in "QueryEntity" been of the config. */ -void DoSqlQueryWithFunction() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoSqlQueryWithFunction() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // Execute query to get names of all employees. - QueryFieldsCursor cursor = cache.Query(SqlFieldsQuery( - "select concat(firstName, ' ', lastName) from Person")); + // Execute query to get names of all employees. + QueryFieldsCursor cursor = cache.Query( + SqlFieldsQuery("select concat(firstName, ' ', lastName) from Person")); - // Print names. - std::cout << "Names of all employees: " << std::endl; + // Print names. + std::cout << "Names of all employees: " << std::endl; - // In this particular case each row will have one element with full name of an employees. - while (cursor.HasNext()) - { - std::string person = cursor.GetNext().GetNext(); + // In this particular case each row will have one element with full name of an + // employees. + while (cursor.HasNext()) { + std::string person = cursor.GetNext().GetNext< std::string >(); - std::cout << person << std::endl; - } + std::cout << person << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** - * Example for SQL queries to calculate average salary for a specific organization. + * Example for SQL queries to calculate average salary for a specific + * organization. * * Note that SQL Fields Query can only be performed using fields that have been * listed in "QueryEntity" been of the config. */ -void DoSqlQueryWithAggregation() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoSqlQueryWithAggregation() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // Calculate average of salary of all persons in ApacheIgnite. - // Note that we also join on Organization cache as well. - SqlFieldsQuery qry( - "select avg(salary) " - "from Person, \"Organization\".Organization as org " - "where Person.orgId = org._key " - "and lower(org.name) = lower(?)"); + // Calculate average of salary of all persons in ApacheIgnite. + // Note that we also join on Organization cache as well. + SqlFieldsQuery qry( + "select avg(salary) " + "from Person, \"Organization\".Organization as org " + "where Person.orgId = org._key " + "and lower(org.name) = lower(?)"); - qry.AddArgument("ApacheIgnite"); + qry.AddArgument< std::string >("ApacheIgnite"); - QueryFieldsCursor cursor = cache.Query(qry); + QueryFieldsCursor cursor = cache.Query(qry); - // Calculate average salary for a specific organization. - std::cout << "Average salary for 'ApacheIgnite' employees: " << std::endl; + // Calculate average salary for a specific organization. + std::cout << "Average salary for 'ApacheIgnite' employees: " << std::endl; - while (cursor.HasNext()) - { - double salary = cursor.GetNext().GetNext(); + while (cursor.HasNext()) { + double salary = cursor.GetNext().GetNext< double >(); - std::cout << salary << std::endl; - } + std::cout << salary << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** @@ -209,59 +212,61 @@ void DoSqlQueryWithAggregation() * Note that SQL Query can only be performed using fields that have been * listed in "QueryEntity" been of the config. */ -void DoSqlQuery() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoSqlQuery() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // SQL clause which selects salaries based on range. - SqlFieldsQuery qry( - "select firstName, lastName, salary " - "from Person " - "where salary > ? and salary <= ?"); + // SQL clause which selects salaries based on range. + SqlFieldsQuery qry( + "select firstName, lastName, salary " + "from Person " + "where salary > ? and salary <= ?"); - // Execute queries for salary range 0 - 1000. - std::cout << "People with salaries between 0 and 1000 (queried with SQL query): " << std::endl; + // Execute queries for salary range 0 - 1000. + std::cout + << "People with salaries between 0 and 1000 (queried with SQL query): " + << std::endl; - qry.AddArgument(0); - qry.AddArgument(1000); + qry.AddArgument(0); + qry.AddArgument(1000); - QueryFieldsCursor cursor = cache.Query(qry); + QueryFieldsCursor cursor = cache.Query(qry); - while (cursor.HasNext()) - { - QueryFieldsRow row = cursor.GetNext(); + while (cursor.HasNext()) { + QueryFieldsRow row = cursor.GetNext(); - std::string firstName = row.GetNext(); - std::string lastName = row.GetNext(); - double salary = row.GetNext(); + std::string firstName = row.GetNext< std::string >(); + std::string lastName = row.GetNext< std::string >(); + double salary = row.GetNext< double >(); - std::cout << firstName << " " << lastName << " : " << salary << std::endl; - } + std::cout << firstName << " " << lastName << " : " << salary << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; - qry.ClearArguments(); + qry.ClearArguments(); - // Execute queries for salary range 1000 - 2000. - std::cout << "People with salaries between 1000 and 2000 (queried with SQL query): " << std::endl; + // Execute queries for salary range 1000 - 2000. + std::cout + << "People with salaries between 1000 and 2000 (queried with SQL query): " + << std::endl; - qry.AddArgument(1000); - qry.AddArgument(2000); + qry.AddArgument(1000); + qry.AddArgument(2000); - cursor = cache.Query(qry); + cursor = cache.Query(qry); - while (cursor.HasNext()) - { - QueryFieldsRow row = cursor.GetNext(); + while (cursor.HasNext()) { + QueryFieldsRow row = cursor.GetNext(); - std::string firstName = row.GetNext(); - std::string lastName = row.GetNext(); - double salary = row.GetNext(); + std::string firstName = row.GetNext< std::string >(); + std::string lastName = row.GetNext< std::string >(); + double salary = row.GetNext< double >(); - std::cout << firstName << " " << lastName << " : " << salary << std::endl; - } + std::cout << firstName << " " << lastName << " : " << salary << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** @@ -270,175 +275,182 @@ void DoSqlQuery() * Note that to be able to do so you have to add FULLTEXT index for the 'resume' * field of the Person type. See config for details. */ -void DoTextQuery() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoTextQuery() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - typedef std::vector< CacheEntry > ResVector; + typedef std::vector< CacheEntry< PersonKey, Person > > ResVector; - // Query for all people with "Master" in their resumes. - ResVector masters; - cache.Query(TextQuery(PERSON_TYPE, "Master")).GetAll(masters); + // Query for all people with "Master" in their resumes. + ResVector masters; + cache.Query(TextQuery(PERSON_TYPE, "Master")).GetAll(masters); - // Query for all people with "Bachelor" in their resumes. - ResVector bachelors; - cache.Query(TextQuery(PERSON_TYPE, "Bachelor")).GetAll(bachelors); + // Query for all people with "Bachelor" in their resumes. + ResVector bachelors; + cache.Query(TextQuery(PERSON_TYPE, "Bachelor")).GetAll(bachelors); - std::cout << "Following people have 'Master' in their resumes: " << std::endl; + std::cout << "Following people have 'Master' in their resumes: " << std::endl; - // Printing first result set. - for (ResVector::const_iterator i = masters.begin(); i != masters.end(); ++i) - std::cout << i->GetKey().ToString() << " : " << i->GetValue().ToString() << std::endl; + // Printing first result set. + for (ResVector::const_iterator i = masters.begin(); i != masters.end(); ++i) + std::cout << i->GetKey().ToString() << " : " << i->GetValue().ToString() + << std::endl; - std::cout << std::endl; + std::cout << std::endl; - std::cout << "Following people have 'Bachelor' in their resumes: " << std::endl; + std::cout << "Following people have 'Bachelor' in their resumes: " + << std::endl; - // Printing second result set. - for (ResVector::const_iterator i = bachelors.begin(); i != bachelors.end(); ++i) - std::cout << i->GetKey().ToString() << " : " << i->GetValue().ToString() << std::endl; + // Printing second result set. + for (ResVector::const_iterator i = bachelors.begin(); i != bachelors.end(); + ++i) + std::cout << i->GetKey().ToString() << " : " << i->GetValue().ToString() + << std::endl; - std::cout << std::endl; + std::cout << std::endl; } /** * Example for scan query based on a predicate. */ -void DoScanQuery() -{ - Cache cache = Ignition::Get().GetCache(PERSON_CACHE); +void DoScanQuery() { + Cache< PersonKey, Person > cache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - ScanQuery scan; + ScanQuery scan; - typedef std::vector< CacheEntry > ResVector; + typedef std::vector< CacheEntry< PersonKey, Person > > ResVector; - ResVector res; - cache.Query(scan).GetAll(res); + ResVector res; + cache.Query(scan).GetAll(res); - // Execute queries for salary ranges. - std::cout << "People with salaries between 0 and 1000 (queried with SCAN query): " << std::endl; + // Execute queries for salary ranges. + std::cout + << "People with salaries between 0 and 1000 (queried with SCAN query): " + << std::endl; - for (ResVector::const_iterator i = res.begin(); i != res.end(); ++i) - { - Person person(i->GetValue()); + for (ResVector::const_iterator i = res.begin(); i != res.end(); ++i) { + Person person(i->GetValue()); - if (person.salary <= 1000) - std::cout << i->GetKey().ToString() << " : " << person.ToString() << std::endl; - } + if (person.salary <= 1000) + std::cout << i->GetKey().ToString() << " : " << person.ToString() + << std::endl; + } - std::cout << std::endl; + std::cout << std::endl; } /** * Populate cache with test data. */ -void Initialize() -{ - Cache orgCache = - Ignition::Get().GetCache(ORG_CACHE); +void Initialize() { + Cache< int64_t, Organization > orgCache = + Ignition::Get().GetCache< int64_t, Organization >(ORG_CACHE); - // Clear cache before running the example. - orgCache.Clear(); + // Clear cache before running the example. + orgCache.Clear(); - // Organizations. - Organization org1("ApacheIgnite"); - Organization org2("Other"); + // Organizations. + Organization org1("ApacheIgnite"); + Organization org2("Other"); - const int64_t org1Id = 1; - const int64_t org2Id = 2; + const int64_t org1Id = 1; + const int64_t org2Id = 2; - orgCache.Put(org1Id, org1); - orgCache.Put(org2Id, org2); + orgCache.Put(org1Id, org1); + orgCache.Put(org2Id, org2); - Cache personCache = - Ignition::Get().GetCache(PERSON_CACHE); + Cache< PersonKey, Person > personCache = + Ignition::Get().GetCache< PersonKey, Person >(PERSON_CACHE); - // Clear cache before running the example. - personCache.Clear(); + // Clear cache before running the example. + personCache.Clear(); - // People. + // People. - // Collocated by 1st organisation: - Person p1(org1Id, "John", "Doe", "John Doe has Master Degree.", 2000); - Person p2(org1Id, "Jane", "Doe", "Jane Doe has Bachelor Degree.", 1000); + // Collocated by 1st organisation: + Person p1(org1Id, "John", "Doe", "John Doe has Master Degree.", 2000); + Person p2(org1Id, "Jane", "Doe", "Jane Doe has Bachelor Degree.", 1000); - PersonKey pKey1 (1, org1Id); - PersonKey pKey2 (2, org1Id); + PersonKey pKey1(1, org1Id); + PersonKey pKey2(2, org1Id); - // Collocated by second organisation: - Person p3(org2Id, "John", "Smith", "John Smith has Bachelor Degree.", 1000); - Person p4(org2Id, "Jane", "Smith", "Jane Smith has Master Degree.", 2000); + // Collocated by second organisation: + Person p3(org2Id, "John", "Smith", "John Smith has Bachelor Degree.", 1000); + Person p4(org2Id, "Jane", "Smith", "Jane Smith has Master Degree.", 2000); - PersonKey pKey3 (3, org2Id); - PersonKey pKey4 (4, org2Id); + PersonKey pKey3(3, org2Id); + PersonKey pKey4(4, org2Id); - // Note that in this example we use custom affinity key for Person objects - // to ensure that all persons are collocated with their organizations. - personCache.Put(pKey1, p1); - personCache.Put(pKey2, p2); - personCache.Put(pKey3, p3); - personCache.Put(pKey4, p4); + // Note that in this example we use custom affinity key for Person objects + // to ensure that all persons are collocated with their organizations. + personCache.Put(pKey1, p1); + personCache.Put(pKey2, p2); + personCache.Put(pKey3, p3); + personCache.Put(pKey4, p4); } -int main() -{ - try - { - IgniteConfiguration cfg; - cfg.springCfgPath = "platforms/cpp/examples/query-example/config/query-example.xml"; +int main() { + try { + IgniteConfiguration cfg; + cfg.springCfgPath = + "platforms/cpp/examples/query-example/config/query-example.xml"; - // Start a node. - Ignite ignite = Ignition::Start(cfg); + // Start a node. + Ignite ignite = Ignition::Start(cfg); - std::cout << std::endl; - std::cout << ">>> Cache query example started." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Cache query example started." << std::endl; + std::cout << std::endl; - // Get organization cache instance. - Cache orgCache = ignite.GetCache(ORG_CACHE); + // Get organization cache instance. + Cache< int64_t, Organization > orgCache = + ignite.GetCache< int64_t, Organization >(ORG_CACHE); - // Get person cache instance. - Cache personCache = ignite.GetCache(PERSON_CACHE); + // Get person cache instance. + Cache< PersonKey, Person > personCache = + ignite.GetCache< PersonKey, Person >(PERSON_CACHE); - // Populate cache. - Initialize(); + // Populate cache. + Initialize(); - // Example for SCAN-based query based on a predicate. - DoScanQuery(); + // Example for SCAN-based query based on a predicate. + DoScanQuery(); - // Example for TEXT-based querying for a given string in peoples resumes. - DoTextQuery(); + // Example for TEXT-based querying for a given string in peoples resumes. + DoTextQuery(); - // Example for SQL-based querying employees based on salary ranges. - DoSqlQuery(); + // Example for SQL-based querying employees based on salary ranges. + DoSqlQuery(); - // Example for SQL-based querying employees for a given organization (includes SQL join). - DoSqlQueryWithJoin(); + // Example for SQL-based querying employees for a given organization + // (includes SQL join). + DoSqlQueryWithJoin(); - // Example for SQL-based querying employees for a given organization (includes distributed SQL join). - DoSqlQueryWithDistributedJoin(); + // Example for SQL-based querying employees for a given organization + // (includes distributed SQL join). + DoSqlQueryWithDistributedJoin(); - // Example for SQL-based fields queries that uses SQL functions. - DoSqlQueryWithFunction(); + // Example for SQL-based fields queries that uses SQL functions. + DoSqlQueryWithFunction(); - // Example for SQL-based querying to calculate average salary among all employees within a company. - DoSqlQueryWithAggregation(); + // Example for SQL-based querying to calculate average salary among all + // employees within a company. + DoSqlQueryWithAggregation(); - // Stop node. - Ignition::StopAll(false); + // Stop node. + Ignition::StopAll(false); - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; + std::cin.get(); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + return err.GetCode(); + } - return 0; + return 0; } diff --git a/src/examples/thin-client-put-get-example/src/thin_client_put_get_example.cpp b/src/examples/thin-client-put-get-example/src/thin_client_put_get_example.cpp index 252ad3d90..a87e55141 100644 --- a/src/examples/thin-client-put-get-example/src/thin_client_put_get_example.cpp +++ b/src/examples/thin-client-put-get-example/src/thin_client_put_get_example.cpp @@ -34,20 +34,21 @@ using namespace examples; * * @param cache Cache instance. */ -void PutGet(CacheClient& cache) -{ - // Create new Organization to store in cache. - Organization org("Microsoft", Address("1096 Eddy Street, San Francisco, CA", 94109)); +void PutGet(CacheClient< int32_t, Organization >& cache) { + // Create new Organization to store in cache. + Organization org("Microsoft", + Address("1096 Eddy Street, San Francisco, CA", 94109)); - // Put organization to cache. - cache.Put(1, org); + // Put organization to cache. + cache.Put(1, org); - // Get recently created employee as a strongly-typed fully de-serialized instance. - Organization orgFromCache = cache.Get(1); + // Get recently created employee as a strongly-typed fully de-serialized + // instance. + Organization orgFromCache = cache.Get(1); - std::cout << ">>> Retrieved organization instance from cache: " << std::endl; - std::cout << orgFromCache.ToString() << std::endl; - std::cout << std::endl; + std::cout << ">>> Retrieved organization instance from cache: " << std::endl; + std::cout << orgFromCache.ToString() << std::endl; + std::cout << std::endl; } /* @@ -55,73 +56,73 @@ void PutGet(CacheClient& cache) * * @param cache Cache instance. */ -void PutGetAll(CacheClient& cache) -{ - // Create new Organizations to store in cache. - Organization org1("Microsoft", Address("1096 Eddy Street, San Francisco, CA", 94109)); - Organization org2("Red Cross", Address("184 Fidler Drive, San Antonio, TX", 78205)); +void PutGetAll(CacheClient< int32_t, Organization >& cache) { + // Create new Organizations to store in cache. + Organization org1("Microsoft", + Address("1096 Eddy Street, San Francisco, CA", 94109)); + Organization org2("Red Cross", + Address("184 Fidler Drive, San Antonio, TX", 78205)); - // Put created data entries to cache. - std::map vals; + // Put created data entries to cache. + std::map< int, Organization > vals; - vals[1] = org1; - vals[2] = org2; + vals[1] = org1; + vals[2] = org2; - cache.PutAll(vals); + cache.PutAll(vals); - // Get recently created organizations as a strongly-typed fully de-serialized instances. - std::set keys; + // Get recently created organizations as a strongly-typed fully de-serialized + // instances. + std::set< int > keys; - keys.insert(1); - keys.insert(2); + keys.insert(1); + keys.insert(2); - std::map valsFromCache; - cache.GetAll(keys, valsFromCache); + std::map< int, Organization > valsFromCache; + cache.GetAll(keys, valsFromCache); - std::cout << ">>> Retrieved organization instances from cache: " << std::endl; + std::cout << ">>> Retrieved organization instances from cache: " << std::endl; - for (std::map::iterator it = valsFromCache.begin(); it != valsFromCache.end(); ++it) - std::cout << it->second.ToString() << std::endl; + for (std::map< int, Organization >::iterator it = valsFromCache.begin(); + it != valsFromCache.end(); ++it) + std::cout << it->second.ToString() << std::endl; - std::cout << std::endl; + std::cout << std::endl; } -int main() -{ - IgniteClientConfiguration cfg; +int main() { + IgniteClientConfiguration cfg; - cfg.SetEndPoints("127.0.0.1"); + cfg.SetEndPoints("127.0.0.1"); - try - { - // Start a client. - IgniteClient client = IgniteClient::Start(cfg); + try { + // Start a client. + IgniteClient client = IgniteClient::Start(cfg); - std::cout << std::endl; - std::cout << ">>> Cache put-get example started." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Cache put-get example started." << std::endl; + std::cout << std::endl; - // Get cache instance. - CacheClient cache = client.GetOrCreateCache("PutGetExample"); + // Get cache instance. + CacheClient< int32_t, Organization > cache = + client.GetOrCreateCache< int32_t, Organization >("PutGetExample"); - // Clear cache. - cache.Clear(); + // Clear cache. + cache.Clear(); - PutGet(cache); - PutGetAll(cache); - } - catch (IgniteError& err) - { - std::cout << "An error occurred: " << err.GetText() << std::endl; + PutGet(cache); + PutGetAll(cache); + } catch (IgniteError& err) { + std::cout << "An error occurred: " << err.GetText() << std::endl; - return err.GetCode(); - } + return err.GetCode(); + } - std::cout << std::endl; - std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; - std::cout << std::endl; + std::cout << std::endl; + std::cout << ">>> Example finished, press 'Enter' to exit ..." << std::endl; + std::cout << std::endl; - std::cin.get(); + std::cin.get(); - return 0; -} \ No newline at end of file + return 0; +} diff --git a/src/odbc-test/include/odbc_test_suite.h b/src/odbc-test/include/odbc_test_suite.h index 3de458baf..7e37efced 100644 --- a/src/odbc-test/include/odbc_test_suite.h +++ b/src/odbc-test/include/odbc_test_suite.h @@ -37,8 +37,8 @@ #define BOOST_TEST_INFO(...) #endif -using ignite::odbc::common::GetEnv; using boost::unit_test::test_unit_id; +using ignite::odbc::common::GetEnv; namespace ignite { namespace odbc { @@ -367,8 +367,7 @@ struct OdbcTestSuite { * Creates the standard DSN connection string for use with local instance. */ void CreateDsnConnectionStringForLocalServer( - std::string& connectionString, - const std::string& databaseName = "", + std::string& connectionString, const std::string& databaseName = "", const std::string& userName = "", const std::string& miscOptions = "") const; diff --git a/src/odbc-test/include/test_server.h b/src/odbc-test/include/test_server.h index 1b6194929..b521fd55c 100644 --- a/src/odbc-test/include/test_server.h +++ b/src/odbc-test/include/test_server.h @@ -195,4 +195,4 @@ class TestServer { } // namespace ignite -#endif //_IGNITE_ODBC_TEST_TEST_SERVER \ No newline at end of file +#endif //_IGNITE_ODBC_TEST_TEST_SERVER diff --git a/src/odbc-test/include/test_type.h b/src/odbc-test/include/test_type.h index 6232f2ba7..7a7ef61d6 100644 --- a/src/odbc-test/include/test_type.h +++ b/src/odbc-test/include/test_type.h @@ -45,9 +45,8 @@ struct TestType { TestType(int8_t i8Field, int16_t i16Field, int32_t i32Field, int64_t i64Field, const std::string& strField, float floatField, double doubleField, - bool boolField, const Guid& guidField, - const Date& dateField, const Time& timeField, - const Timestamp& timestampField) + bool boolField, const Guid& guidField, const Date& dateField, + const Time& timeField, const Timestamp& timestampField) : allNulls(false), i8Field(i8Field), i16Field(i16Field), diff --git a/src/odbc-test/src/api_robustness_test.cpp b/src/odbc-test/src/api_robustness_test.cpp index b1fe88da1..20b577fba 100644 --- a/src/odbc-test/src/api_robustness_test.cpp +++ b/src/odbc-test/src/api_robustness_test.cpp @@ -211,8 +211,8 @@ BOOST_AUTO_TEST_CASE(TestSQLDriverConnect, *disabled()) { SQLDisconnect(dbc); // Null out string buffer length. - SQLDriverConnect(dbc, NULL, connectStr.data(), SQL_NTS, outStr, 0, - &outStrLen, SQL_DRIVER_COMPLETE); + SQLDriverConnect(dbc, NULL, connectStr.data(), SQL_NTS, outStr, 0, &outStrLen, + SQL_DRIVER_COMPLETE); SQLDisconnect(dbc); @@ -599,8 +599,8 @@ BOOST_AUTO_TEST_CASE(TestSQLNativeSql, *disabled()) { SQLINTEGER resLen = 0; // Everything is ok. - SQLRETURN ret = SQLNativeSql(dbc, sql.data(), SQL_NTS, buffer, - sizeof(buffer), &resLen); + SQLRETURN ret = + SQLNativeSql(dbc, sql.data(), SQL_NTS, buffer, sizeof(buffer), &resLen); ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); @@ -1073,52 +1073,45 @@ BOOST_AUTO_TEST_CASE(TestSQLSpecialColumns, *disabled()) { // Everything is ok. SQLRETURN ret = SQLSpecialColumns( - stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, - schemaName.data(), SQL_NTS, tableName.data(), - SQL_NTS, SQL_SCOPE_CURROW, SQL_NO_NULLS); + stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, schemaName.data(), + SQL_NTS, tableName.data(), SQL_NTS, SQL_SCOPE_CURROW, SQL_NO_NULLS); ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); SQLCloseCursor(stmt); - SQLSpecialColumns(stmt, SQL_BEST_ROWID, 0, SQL_NTS, - schemaName.data(), SQL_NTS, tableName.data(), - SQL_NTS, - SQL_SCOPE_CURROW, SQL_NO_NULLS); + SQLSpecialColumns(stmt, SQL_BEST_ROWID, 0, SQL_NTS, schemaName.data(), + SQL_NTS, tableName.data(), SQL_NTS, SQL_SCOPE_CURROW, + SQL_NO_NULLS); SQLCloseCursor(stmt); SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), 0, - schemaName.data(), SQL_NTS, tableName.data(), - SQL_NTS, + schemaName.data(), SQL_NTS, tableName.data(), SQL_NTS, SQL_SCOPE_CURROW, SQL_NO_NULLS); SQLCloseCursor(stmt); - SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), - SQL_NTS, 0, SQL_NTS, - tableName.data(), SQL_NTS, - SQL_SCOPE_CURROW, SQL_NO_NULLS); + SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, 0, + SQL_NTS, tableName.data(), SQL_NTS, SQL_SCOPE_CURROW, + SQL_NO_NULLS); SQLCloseCursor(stmt); - SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), - SQL_NTS, schemaName.data(), 0, tableName.data(), - SQL_NTS, + SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, + schemaName.data(), 0, tableName.data(), SQL_NTS, SQL_SCOPE_CURROW, SQL_NO_NULLS); SQLCloseCursor(stmt); - SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), - SQL_NTS, schemaName.data(), SQL_NTS, - 0, SQL_NTS, - SQL_SCOPE_CURROW, SQL_NO_NULLS); + SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, + schemaName.data(), SQL_NTS, 0, SQL_NTS, SQL_SCOPE_CURROW, + SQL_NO_NULLS); SQLCloseCursor(stmt); - SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), - SQL_NTS, schemaName.data(), SQL_NTS, - tableName.data(), 0, + SQLSpecialColumns(stmt, SQL_BEST_ROWID, catalogName.data(), SQL_NTS, + schemaName.data(), SQL_NTS, tableName.data(), 0, SQL_SCOPE_CURROW, SQL_NO_NULLS); SQLCloseCursor(stmt); diff --git a/src/odbc-test/src/application_data_buffer_test.cpp b/src/odbc-test/src/application_data_buffer_test.cpp index 2ef17447f..a72d061e1 100644 --- a/src/odbc-test/src/application_data_buffer_test.cpp +++ b/src/odbc-test/src/application_data_buffer_test.cpp @@ -750,7 +750,8 @@ BOOST_AUTO_TEST_CASE(TestGetIntWithOffset) { SqlLen reslen; }; - GetIntWithOffsetTestStruct buf[2] = {{12, sizeof(uint64_t)}, {42, sizeof(uint64_t)}}; + GetIntWithOffsetTestStruct buf[2] = {{12, sizeof(uint64_t)}, + {42, sizeof(uint64_t)}}; ApplicationDataBuffer appBuf(OdbcNativeType::AI_UNSIGNED_BIGINT, &buf[0].val, sizeof(buf[0].val), &buf[0].reslen); diff --git a/src/odbc-test/src/column_meta_test.cpp b/src/odbc-test/src/column_meta_test.cpp index 2e7291b2c..bd5a24dad 100644 --- a/src/odbc-test/src/column_meta_test.cpp +++ b/src/odbc-test/src/column_meta_test.cpp @@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE(TestGetAttributeNullable) { std::string resVal; bool found; ColumnMeta columnMetaNullable(schema, table, column, JDBC_TYPE_NULL, - Nullability::NULLABLE); + Nullability::NULLABLE); // test SQL_DESC_NULLABLE found = columnMetaNullable.GetAttribute(SQL_DESC_NULLABLE, intVal); @@ -539,7 +539,7 @@ BOOST_AUTO_TEST_CASE(TestGetAttributeNullable) { BOOST_CHECK_EQUAL(intVal, SQL_NULLABLE); ColumnMeta columnMetaNoNulls(schema, table, column, JDBC_TYPE_VARCHAR, - Nullability::NO_NULL); + Nullability::NO_NULL); // test SQL_DESC_NULLABLE found = columnMetaNoNulls.GetAttribute(SQL_DESC_NULLABLE, intVal); diff --git a/src/odbc-test/src/configuration_test.cpp b/src/odbc-test/src/configuration_test.cpp index d7b46f1e3..271b90d57 100644 --- a/src/odbc-test/src/configuration_test.cpp +++ b/src/odbc-test/src/configuration_test.cpp @@ -277,8 +277,7 @@ void CheckConnectionConfig(const Configuration& cfg) { << "&sshPrivateKeyPassphrase=" << testSshPrivateKeyPassphrase << "&sshStrictHostKeyChecking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) - << "&sshUser=" << testSshUser - << "&tls=" << BoolToStr(testTlsFlag) + << "&sshUser=" << testSshUser << "&tls=" << BoolToStr(testTlsFlag) << "&tlsAllowInvalidHostnames=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << "&tlsCaFile=" << EncodeURIComponent(testTlsCaFile); @@ -292,8 +291,9 @@ void CheckConnectionConfig(const Configuration& cfg) { void CheckDsnConfig(const Configuration& cfg) { // since setting logger path/level will change the logger settings, // we will not change the logger path/level in configuration_test, - // which means it is possible for the logger path/level to be equivalent to - // the default values. Therefore, there will be no boost check for logger path/level. + // which means it is possible for the logger path/level to be equivalent to + // the default values. Therefore, there will be no boost check for logger + // path/level. BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName); BOOST_CHECK_EQUAL(cfg.GetDsn(), testDsn); BOOST_CHECK_EQUAL(cfg.GetDatabase(), Configuration::DefaultValue::database); @@ -757,4 +757,4 @@ BOOST_AUTO_TEST_CASE(TestDsnStringWhitespaces) { CheckDsnConfig(cfg); } -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/odbc-test/src/connection_test.cpp b/src/odbc-test/src/connection_test.cpp index 79994ad02..5c3546ab0 100644 --- a/src/odbc-test/src/connection_test.cpp +++ b/src/odbc-test/src/connection_test.cpp @@ -30,9 +30,9 @@ #include "test_utils.h" using boost::unit_test::precondition; +using ignite::odbc::if_integration; using ignite::odbc::OdbcTestSuite; using ignite_test::GetOdbcErrorMessage; -using ignite::odbc::if_integration; /** * Test setup fixture. diff --git a/src/odbc-test/src/java_test.cpp b/src/odbc-test/src/java_test.cpp index 36abdc8c8..345cdb2c0 100644 --- a/src/odbc-test/src/java_test.cpp +++ b/src/odbc-test/src/java_test.cpp @@ -68,7 +68,8 @@ struct JavaTestSuiteFixture : OdbcTestSuite { bool isInternalSshTunnel) const { std::string dsnConnectionString; if (isIntegration) { - CreateDsnConnectionStringForRemoteServer(dsnConnectionString, isInternalSshTunnel); + CreateDsnConnectionStringForRemoteServer(dsnConnectionString, + isInternalSshTunnel); } else { CreateDsnConnectionStringForLocalServer(dsnConnectionString); } @@ -80,9 +81,11 @@ struct JavaTestSuiteFixture : OdbcTestSuite { return jdbcConnectionString; } - void PrepareContext(bool isIntegration = false, bool isInternalSshTunnel = false) { + void PrepareContext(bool isIntegration = false, + bool isInternalSshTunnel = false) { if (!_prepared) { - _jdbcConnectionString = GetJdbcConnectionString(isIntegration, isInternalSshTunnel); + _jdbcConnectionString = + GetJdbcConnectionString(isIntegration, isInternalSshTunnel); std::string cp = ResolveDocumentDbHome(); BuildJvmOptions(cp, _opts); _ctx = GetJniContext(_opts); @@ -366,7 +369,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { boost::optional< std::string > catalog = boost::none; boost::optional< std::string > schemaPattern = boost::none; std::string tableNamePattern = "%"; - boost::optional < std::vector< std::string > > types( + boost::optional< std::vector< std::string > > types( {"TABLE"}); // Need to specify this to get result. SharedPointer< GlobalJObject > resultSet; if (_ctx.Get()->DatabaseMetaDataGetTables(databaseMetaData, catalog, @@ -390,9 +393,9 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { int i = 1; while (hasNext) { - boost::optional value; + boost::optional< std::string > value; // TABLE_CAT (i.e., catalog - always NULL in our case) - if (_ctx.Get()->ResultSetGetString(resultSet, 1, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 1, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -400,8 +403,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_CHECK(!value); // TABLE_CAT (i.e., catalog - always NULL in our case) - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_CAT", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_CAT", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -409,7 +411,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_CHECK(!value); // TABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, 2, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 2, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -418,8 +420,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(*value == DATABASE_NAME); // TABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -428,7 +429,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(*value == DATABASE_NAME); // TABLE_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, 3, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 3, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -437,8 +438,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(value->size() > 0); // TABLE_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_NAME", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_NAME", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -447,7 +447,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(value->size() > 0); // TABLE_TYPE - if (_ctx.Get()->ResultSetGetString(resultSet, 4, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 4, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -456,8 +456,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(*value == "TABLE"); // TABLE_TYPE - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_TYPE", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_TYPE", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -466,8 +465,8 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetTables) { BOOST_REQUIRE(*value == "TABLE"); // check getRow - boost::optional val; - if (_ctx.Get()->ResultSetGetRow(resultSet, val, errInfo) + boost::optional< int > val; + if (_ctx.Get()->ResultSetGetRow(resultSet, val, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -536,9 +535,9 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { int i = 1; while (hasNext) { - boost::optional value; + boost::optional< std::string > value; // TABLE_CAT (i.e., catalog - always NULL in our case) - if (_ctx.Get()->ResultSetGetString(resultSet, 1, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 1, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { // grab string from first column std::string errMsg = errInfo.errMsg; @@ -547,7 +546,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_CHECK(!value); // TABLE_CAT (i.e., catalog - always NULL in our case) - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_CAT", value, + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_CAT", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { // grab string from first // column by name @@ -557,7 +556,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_CHECK(!value); // TABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, 2, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 2, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -566,8 +565,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_CHECK_EQUAL(DATABASE_NAME, *value); // TABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -576,7 +574,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_CHECK_EQUAL(DATABASE_NAME, *value); // TABLE_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, 3, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 3, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -585,8 +583,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_REQUIRE(value->size() > 0); // TABLE_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_NAME", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_NAME", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -595,7 +592,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_REQUIRE(value->size() > 0); // COLUMN_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, 4, value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, 4, value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -604,8 +601,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_REQUIRE(value->size() > 0); // COLUMN_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "COLUMN_NAME", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "COLUMN_NAME", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -615,7 +611,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { // ORDINAL_POSITION boost::optional< int > val; - if (_ctx.Get()->ResultSetGetInt(resultSet, 17, val, errInfo) + if (_ctx.Get()->ResultSetGetInt(resultSet, 17, val, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -624,8 +620,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_REQUIRE(*val > 0); // ORDINAL_POSITION - if (_ctx.Get()->ResultSetGetInt(resultSet, "ORDINAL_POSITION", val, - errInfo) + if (_ctx.Get()->ResultSetGetInt(resultSet, "ORDINAL_POSITION", val, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -634,7 +629,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetColumns) { BOOST_REQUIRE(*val > 0); // check getRow - if (_ctx.Get()->ResultSetGetRow(resultSet, val, errInfo) + if (_ctx.Get()->ResultSetGetRow(resultSet, val, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -732,8 +727,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetPrimaryKeys) { BOOST_CHECK_EQUAL(DATABASE_NAME, *value); // TABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "TABLE_SCHEM", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -805,8 +799,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetPrimaryKeys) { BOOST_CHECK(!value); // PK_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "PK_NAME", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "PK_NAME", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -906,7 +899,8 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) { BOOST_CHECK_EQUAL(DATABASE_NAME, *value); // PKTABLE_SCHEM (i.e., database) - if (_ctx.Get()->ResultSetGetString(resultSet, "PKTABLE_SCHEM", value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "PKTABLE_SCHEM", value, + errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -924,7 +918,8 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) { BOOST_CHECK_EQUAL(table, *value); // PKTABLE_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "PKTABLE_NAME", value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "PKTABLE_NAME", value, + errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -944,7 +939,8 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) { BOOST_CHECK_EQUAL(fkColumn, *value); // PKCOLUMN_NAME - if (_ctx.Get()->ResultSetGetString(resultSet, "PKCOLUMN_NAME", value, errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "PKCOLUMN_NAME", value, + errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); @@ -962,8 +958,7 @@ BOOST_AUTO_TEST_CASE(TestDatabaseMetaDataGetImportedKeys) { BOOST_CHECK(!value); // FKTABLE_CAT - if (_ctx.Get()->ResultSetGetString(resultSet, "FKTABLE_CAT", value, - errInfo) + if (_ctx.Get()->ResultSetGetString(resultSet, "FKTABLE_CAT", value, errInfo) != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { std::string errMsg = errInfo.errMsg; BOOST_FAIL(errMsg); diff --git a/src/odbc-test/src/jni_test.cpp b/src/odbc-test/src/jni_test.cpp index 766bad2c1..7219b7728 100644 --- a/src/odbc-test/src/jni_test.cpp +++ b/src/odbc-test/src/jni_test.cpp @@ -147,8 +147,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -173,8 +172,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(19, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(19, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_DECIMAL, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("DECIMAL", *columnMetadataItem.GetColumnTypeName()); @@ -199,8 +197,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(15, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_DOUBLE, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("DOUBLE", *columnMetadataItem.GetColumnTypeName()); @@ -225,8 +222,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -251,8 +247,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -277,8 +272,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(1, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_BOOLEAN, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("BOOLEAN", *columnMetadataItem.GetColumnTypeName()); @@ -303,8 +297,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_TIMESTAMP, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("TIMESTAMP", *columnMetadataItem.GetColumnTypeName()); @@ -329,8 +322,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(10, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_INTEGER, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("INTEGER", *columnMetadataItem.GetColumnTypeName()); @@ -355,8 +347,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(19, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_BIGINT, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("BIGINT", *columnMetadataItem.GetColumnTypeName()); @@ -381,8 +372,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -407,8 +397,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -434,8 +423,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARCHAR, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARCHAR", *columnMetadataItem.GetColumnTypeName()); @@ -461,8 +449,7 @@ struct JniTestSuiteFixture : OdbcTestSuite { BOOST_CHECK_EQUAL(DATABASE_NAME, *columnMetadataItem.GetSchemaName()); BOOST_CHECK_EQUAL(65536, columnMetadataItem.GetPrecision()); BOOST_CHECK_EQUAL(0, columnMetadataItem.GetScale()); - BOOST_CHECK_EQUAL(TABLE_NAME, - *columnMetadataItem.GetTableName()); + BOOST_CHECK_EQUAL(TABLE_NAME, *columnMetadataItem.GetTableName()); BOOST_CHECK(!columnMetadataItem.GetCatalogName()); BOOST_CHECK_EQUAL(JDBC_TYPE_VARBINARY, columnMetadataItem.GetColumnType()); BOOST_CHECK_EQUAL("VARBINARY", *columnMetadataItem.GetColumnTypeName()); @@ -1041,7 +1028,7 @@ BOOST_AUTO_TEST_CASE(TestDocumentDbDatabaseMetaDataGetImportedKeys) { SharedPointer< DatabaseMetaData > databaseMetaData = dbConnection.GetMetaData(errInfo); BOOST_REQUIRE(databaseMetaData.IsValid()); - + const boost::optional< std::string > fkCatalog = boost::none; const boost::optional< std::string > fkSchema = boost::none; std::string fkTable = "jni_test_001_sub_doc"; @@ -1086,7 +1073,7 @@ BOOST_AUTO_TEST_CASE(TestDocumentDbDatabaseMetaDataGetImportedKeys) { resultSet.Get()->GetString("PKTABLE_NAME", value, errInfo); BOOST_CHECK(value); BOOST_CHECK_EQUAL(table, *value); - + resultSet.Get()->GetString(4, value, errInfo); BOOST_CHECK(value); BOOST_CHECK(!value->empty()); @@ -1136,7 +1123,7 @@ BOOST_AUTO_TEST_CASE(TestDocumentDbDatabaseMetaDataGetImportedKeys) { resultSet.Get()->GetSmallInt("KEY_SEQ", smallIntValue, errInfo); BOOST_CHECK(smallIntValue); BOOST_CHECK_EQUAL(1, *smallIntValue); - + resultSet.Get()->GetSmallInt(10, smallIntValue, errInfo); BOOST_CHECK(smallIntValue); @@ -1223,7 +1210,6 @@ BOOST_AUTO_TEST_CASE(TestDocumentDbDatabaseMetaDataGetPrimaryKeysReturnsNone) { BOOST_CHECK(!dbConnection.IsOpen()); } - BOOST_AUTO_TEST_CASE(TestDocumentDbDatabaseMetaDataGetImportedKeysReturnsNone) { PrepareContext(); BOOST_REQUIRE(_ctx.Get() != nullptr); @@ -1311,8 +1297,7 @@ BOOST_AUTO_TEST_CASE(TestDocumentDbGetMqlQueryContext) { std::vector< JdbcColumnMetadata > columnMetadata = queryContext.Get()->GetColumnMetadata(); ValidateJdbcColumnMetadata(columnMetadata); - BOOST_CHECK_EQUAL(TABLE_NAME, - queryContext.Get()->GetCollectionName()); + BOOST_CHECK_EQUAL(TABLE_NAME, queryContext.Get()->GetCollectionName()); BOOST_CHECK_EQUAL(13, queryContext.Get()->GetPaths().size()); BOOST_CHECK_EQUAL(1, queryContext.Get()->GetAggregateOperations().size()); BOOST_CHECK_EQUAL( diff --git a/src/odbc-test/src/log_test.cpp b/src/odbc-test/src/log_test.cpp index 2c1a75d37..44b409250 100644 --- a/src/odbc-test/src/log_test.cpp +++ b/src/odbc-test/src/log_test.cpp @@ -291,7 +291,8 @@ BOOST_AUTO_TEST_CASE(TestLogSetInvalidLogPath) { // attempt to set wrong log path logger->SetLogPath(logPath); - // check that invalid log path is not set and the original log path remains (if not null) + // check that invalid log path is not set and the original log path remains + // (if not null) BOOST_CHECK_NE(logPath, logger->GetLogPath()); if (origLogPath) BOOST_CHECK_EQUAL(origLogPath.get(), logger->GetLogPath()); diff --git a/src/odbc-test/src/meta_queries_test.cpp b/src/odbc-test/src/meta_queries_test.cpp index c01c74537..f6497861c 100644 --- a/src/odbc-test/src/meta_queries_test.cpp +++ b/src/odbc-test/src/meta_queries_test.cpp @@ -70,7 +70,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { * @param strBuf SQLCHAR pointer * @return buf std::string */ - std::string SqlCharToString(SQLCHAR* strBuf) { + std::string SqlCharToString(SQLCHAR *strBuf) { std::stringstream bufStream; bufStream << strBuf; std::string buf; @@ -194,8 +194,8 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { ret = SQLBindCol(stmt, 7, SQL_INTEGER, &column_size, sizeof(column_size), &column_size_len); BOOST_CHECK(SQL_SUCCEEDED(ret)); - ret = SQLBindCol(stmt, 8, SQL_INTEGER, &buffer_length, sizeof(buffer_length), - &buffer_length_len); + ret = SQLBindCol(stmt, 8, SQL_INTEGER, &buffer_length, + sizeof(buffer_length), &buffer_length_len); BOOST_CHECK(SQL_SUCCEEDED(ret)); ret = SQLBindCol(stmt, 9, SQL_SMALLINT, &decimal_digits, sizeof(decimal_digits), &decimal_digits_len); @@ -242,12 +242,13 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { SQLSMALLINT fieldId, const std::string &expectedVal) { SQLWCHAR strBuf[1024]; - std::vector< SQLWCHAR > wQuery = MakeSqlBuffer(reinterpret_cast< const char* >(query)); + std::vector< SQLWCHAR > wQuery = + MakeSqlBuffer(reinterpret_cast< const char * >(query)); SQLExecDirect(stmt, wQuery.data(), SQL_NTS); - SQLRETURN ret = SQLColAttribute(stmt, 1, fieldId, strBuf, - sizeof(strBuf), nullptr, nullptr); + SQLRETURN ret = SQLColAttribute(stmt, 1, fieldId, strBuf, sizeof(strBuf), + nullptr, nullptr); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -386,10 +387,10 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { SQL_NULLABLE); CheckColumnMetaWithSQLDescribeCol(stmt, 6, "CHAR2", SQL_WVARCHAR, 42, 0, SQL_NULLABLE); - CheckColumnMetaWithSQLDescribeCol(stmt, 7, "CHAR3", SQL_WVARCHAR, 2147483647, - 0, SQL_NO_NULLS); - CheckColumnMetaWithSQLDescribeCol(stmt, 8, "VCHAR", SQL_WVARCHAR, 2147483647, - 0, SQL_NULLABLE); + CheckColumnMetaWithSQLDescribeCol(stmt, 7, "CHAR3", SQL_WVARCHAR, + 2147483647, 0, SQL_NO_NULLS); + CheckColumnMetaWithSQLDescribeCol(stmt, 8, "VCHAR", SQL_WVARCHAR, + 2147483647, 0, SQL_NULLABLE); } /** @@ -404,7 +405,7 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { * @param expNullability expected nullability. */ void CheckColumnMetaWithSQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT idx, - const std::string& expName, + const std::string &expName, SQLLEN expDataType, SQLULEN expSize, SQLLEN expScale, SQLLEN expNullability) { @@ -416,7 +417,8 @@ struct MetaQueriesTestSuiteFixture : public odbc::OdbcTestSuite { SQLLEN nullability; SQLRETURN ret = SQLColAttribute(stmt, idx, SQL_DESC_NAME, &name[0], - (SQLSMALLINT)name.size() * sizeof(SQLWCHAR), &nameLen, nullptr); + (SQLSMALLINT)name.size() * sizeof(SQLWCHAR), + &nameLen, nullptr); ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_STMT, stmt); ret = SQLColAttribute(stmt, idx, SQL_DESC_TYPE, 0, 0, 0, &dataType); @@ -684,15 +686,14 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDataTypesAndColumnNames) { SQLExecDirect(stmt, req.data(), SQL_NTS); for (int i = 1; i <= numTests; i++) { - // TODO remove below if statement when bug from JDBC (AD-765) is fixed. // https://bitquill.atlassian.net/browse/AD-766 // the fieldNull pair is the 13th pair if (i == 13) continue; - SQLRETURN ret = SQLColAttribute(stmt, SQLSMALLINT(i), SQL_DESC_TYPE, nullptr, - 0, nullptr, &intVal); + SQLRETURN ret = SQLColAttribute(stmt, SQLSMALLINT(i), SQL_DESC_TYPE, + nullptr, 0, nullptr, &intVal); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -759,8 +760,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescCatalogName) { const SQLCHAR req[] = "select fieldDecimal128 from meta_queries_test_001"; // check that catalog should be empty - callSQLColAttribute(stmt, req, SQL_DESC_CATALOG_NAME, - std::string("")); + callSQLColAttribute(stmt, req, SQL_DESC_CATALOG_NAME, std::string("")); } BOOST_AUTO_TEST_CASE(TestColAttributeDescConciseType) { @@ -782,7 +782,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescConciseType) { // TODO re-enable this test when bug from JDBC (AD-765) is fixed. // https://bitquill.atlassian.net/browse/AD-766 // const SQLCHAR req4[] = "select fieldNull from meta_queries_test_001"; - // + // // callSQLColAttribute(stmt, req3, SQL_DESC_CONCISE_TYPE, SQL_TYPE_NULL); } @@ -791,7 +791,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescCount) { connectToLocalServer(databaseName); const SQLCHAR req[] = "select fieldString from meta_queries_test_001"; - + // count should be 1 callSQLColAttribute(stmt, req, SQL_DESC_COUNT, 1); } @@ -815,7 +815,6 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescDisplaySize) { // SQL_BIGINT should have display size 20 callSQLColAttribute(stmt, req3, SQL_DESC_DISPLAY_SIZE, 20); - const SQLCHAR req4[] = "select fieldDouble from meta_queries_test_001"; // SQL_DOUBLE should have display size 24 @@ -843,8 +842,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescLabel) { const SQLCHAR req[] = "select fieldBoolean from meta_queries_test_002"; - callSQLColAttribute(stmt, req, SQL_DESC_LABEL, - std::string("fieldBoolean")); + callSQLColAttribute(stmt, req, SQL_DESC_LABEL, std::string("fieldBoolean")); } BOOST_AUTO_TEST_CASE(TestColAttributeDescLength) { @@ -884,8 +882,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescLiteralPrefix) { // test that empty string is returned for non-char and non-binary type const SQLCHAR req1[] = "select fieldDouble from meta_queries_test_001"; - callSQLColAttribute(stmt, req1, SQL_DESC_LITERAL_PREFIX, - std::string("")); + callSQLColAttribute(stmt, req1, SQL_DESC_LITERAL_PREFIX, std::string("")); // test that "'" is returned for *CHAR type const SQLCHAR req2[] = "select fieldString from meta_queries_test_002"; @@ -921,7 +918,7 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescLocalTypeName) { const SQLCHAR req1[] = "select fieldDouble from meta_queries_test_001"; - // SQL_DOUBLE should have type name SqlTypeName::DOUBLE + // SQL_DOUBLE should have type name SqlTypeName::DOUBLE callSQLColAttribute(stmt, req1, SQL_DESC_LOCAL_TYPE_NAME, SqlTypeName::DOUBLE); @@ -956,15 +953,14 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescName) { const SQLCHAR req[] = "select field from meta_queries_test_002_with_array"; - callSQLColAttribute(stmt, req, SQL_DESC_NAME, - std::string("field")); + callSQLColAttribute(stmt, req, SQL_DESC_NAME, std::string("field")); } BOOST_AUTO_TEST_CASE(TestColAttributeDescNullable) { std::string databaseName("odbc-test"); connectToLocalServer(databaseName); - // test meta_queries_test_001__id (a primary key) should not be nullable + // test meta_queries_test_001__id (a primary key) should not be nullable const SQLCHAR req1[] = "select meta_queries_test_001__id from meta_queries_test_001"; @@ -1011,7 +1007,6 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescOctetLength) { // SQL_INTEGER should have octet length 4 * sizeof(char) callSQLColAttribute(stmt, req2, SQL_DESC_OCTET_LENGTH, 4 * size_of_char); - const SQLCHAR req3[] = "select fieldLong from meta_queries_test_002"; @@ -1110,7 +1105,6 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescType) { callSQLColAttribute(stmt, req1, SQL_DESC_TYPE, SQL_WVARCHAR); - const SQLCHAR req2[] = "select fieldInt from meta_queries_test_001"; callSQLColAttribute(stmt, req2, SQL_DESC_TYPE, SQL_INTEGER); @@ -1119,11 +1113,11 @@ BOOST_AUTO_TEST_CASE(TestColAttributeDescType) { callSQLColAttribute(stmt, req3, SQL_DESC_TYPE, SQL_VARBINARY); - // TODO re-enable this test when bug from JDBC (AD-765) is fixed. + // TODO re-enable this test when bug from JDBC (AD-765) is fixed. // https://bitquill.atlassian.net/browse/AD-766 - //const SQLCHAR req4[] = "select fieldNull from meta_queries_test_001"; - // - //callSQLColAttribute(stmt, req4, SQL_DESC_TYPE, SQL_TYPE_NULL); + // const SQLCHAR req4[] = "select fieldNull from meta_queries_test_001"; + // + // callSQLColAttribute(stmt, req4, SQL_DESC_TYPE, SQL_TYPE_NULL); } BOOST_AUTO_TEST_CASE(TestColAttributeDescUnnamed) { @@ -1297,7 +1291,8 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsOne) { if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - CheckSingleRowResultSetWithGetData(stmt, 3, utility::SqlStringToString(table.data())); + CheckSingleRowResultSetWithGetData(stmt, 3, + utility::SqlStringToString(table.data())); } BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsOneFromLocalServer) { @@ -1348,7 +1343,7 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) { std::vector< SQLWCHAR > table = MakeSqlBuffer("meta_queries_test_001"); std::vector< SQLWCHAR > empty = {0}; std::vector< SQLWCHAR > schemaName = MakeSqlBuffer(databaseName); - + SQLRETURN ret = SQLColumns(stmt, nullptr, 0, schemaName.data(), SQL_NTS, table.data(), SQL_NTS, nullptr, 0); @@ -1362,8 +1357,7 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) { char type_name[C_STR_LEN_DEFAULT]{}; SQLLEN type_name_len = sizeof(type_name); - ret = - SQLBindCol(stmt, 4, SQL_C_CHAR, column_name, sizeof(column_name), + ret = SQLBindCol(stmt, 4, SQL_C_CHAR, column_name, sizeof(column_name), &column_name_len); BOOST_CHECK(SQL_SUCCEEDED(ret)); ret = SQLBindCol(stmt, 5, SQL_SMALLINT, &data_type, sizeof(data_type), @@ -1374,7 +1368,7 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) { BOOST_CHECK(SQL_SUCCEEDED(ret)); if (!SQL_SUCCEEDED(ret)) - BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) @@ -1382,39 +1376,39 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) { using namespace ignite::odbc::type_traits; BOOST_CHECK_EQUAL("meta_queries_test_001__id", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldDecimal128", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_DECIMAL, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldDecimal128", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_DECIMAL, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::DECIMAL, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldDouble", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_DOUBLE, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldDouble", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_DOUBLE, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::DOUBLE, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldString", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldString", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldObjectId", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldObjectId", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME ret = SQLFetch(stmt); @@ -1422,68 +1416,68 @@ BOOST_AUTO_TEST_CASE(TestDataTypes) { BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); BOOST_CHECK_EQUAL("fieldBoolean", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_BIT, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL(SQL_BIT, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::BIT, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldDate", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_TYPE_TIMESTAMP, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldDate", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_TYPE_TIMESTAMP, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::TIMESTAMP, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldInt", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_INTEGER, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldInt", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_INTEGER, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::INTEGER, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldLong", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_BIGINT, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldLong", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_BIGINT, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::BIGINT, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldMaxKey", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldMaxKey", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldMinKey", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldMinKey", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_WVARCHAR, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARCHAR, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldNull", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_TYPE_NULL, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldNull", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_TYPE_NULL, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::SQL_NULL, type_name); // TYPE_NAME ret = SQLFetch(stmt); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL("fieldBinary", column_name); // COLUMN_NAME - BOOST_CHECK_EQUAL(SQL_VARBINARY, data_type); // DATA_TYPE + BOOST_CHECK_EQUAL("fieldBinary", column_name); // COLUMN_NAME + BOOST_CHECK_EQUAL(SQL_VARBINARY, data_type); // DATA_TYPE BOOST_CHECK_EQUAL(SqlTypeName::VARBINARY, type_name); // TYPE_NAME ret = SQLFetch(stmt); - BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA); + BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA); } BOOST_AUTO_TEST_CASE(TestGetDataWithTablesReturnsOneForQuotedTypes) { @@ -1727,9 +1721,8 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithPrimaryKeysReturnsOneFromLocalServer) { Connect(dsnConnectionString); - SQLRETURN ret = SQLPrimaryKeys(stmt, nullptr, 0, - nullptr, 0, - table.data(), SQL_NTS); + SQLRETURN ret = + SQLPrimaryKeys(stmt, nullptr, 0, nullptr, 0, table.data(), SQL_NTS); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -1789,13 +1782,12 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithForeignKeysReturnsOneFromLocalServer) { Connect(dsnConnectionString); - SQLRETURN ret = - SQLForeignKeys(stmt, NULL, 0, /* Primary catalog */ - NULL, 0, /* Primary schema */ - NULL, 0, /* Primary table */ - NULL, 0, /* Foreign catalog */ - NULL, 0, /* Foreign schema */ - table.data(), SQL_NTS); /* Foreign table */ + SQLRETURN ret = SQLForeignKeys(stmt, NULL, 0, /* Primary catalog */ + NULL, 0, /* Primary schema */ + NULL, 0, /* Primary table */ + NULL, 0, /* Foreign catalog */ + NULL, 0, /* Foreign schema */ + table.data(), SQL_NTS); /* Foreign table */ if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -1851,7 +1843,8 @@ BOOST_AUTO_TEST_CASE(TestGetDataWithForeignKeysReturnsNone) { BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA); - // when empty strings are passed as catalog/schema, SQL_NO_DATA should be returned + // when empty strings are passed as catalog/schema, SQL_NO_DATA should be + // returned ret = SQLForeignKeys(stmt, empty.data(), SQL_NTS, /* Primary catalog */ empty.data(), SQL_NTS, /* Primary schema */ empty.data(), SQL_NTS, /* Primary table */ @@ -1942,9 +1935,8 @@ BOOST_AUTO_TEST_CASE(TestSQLColumnWithSQLBindCols) { BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); bool errorExpected = false; - BOOST_CHECK_EQUAL( - true, WasNull(table_cat_len)); - BOOST_CHECK_EQUAL("", table_cat); // TABLE_CAT + BOOST_CHECK_EQUAL(true, WasNull(table_cat_len)); + BOOST_CHECK_EQUAL("", table_cat); // TABLE_CAT BOOST_CHECK_EQUAL(false, WasNull(table_schem_len)); BOOST_CHECK_EQUAL("odbc-test", table_schem); // TABLE_SCHEM BOOST_CHECK_EQUAL(false, WasNull(table_name_len)); @@ -1957,10 +1949,7 @@ BOOST_AUTO_TEST_CASE(TestSQLColumnWithSQLBindCols) { BOOST_CHECK_EQUAL("VARCHAR", type_name); // TYPE_NAME BOOST_CHECK_EQUAL(false, WasNull(column_size_len)); BOOST_CHECK_EQUAL(SQL_NO_TOTAL, column_size); // COLUMN_SIZE - BOOST_CHECK_EQUAL( - false, - WasNull( - buffer_length_len)); + BOOST_CHECK_EQUAL(false, WasNull(buffer_length_len)); BOOST_CHECK_EQUAL(SQL_NO_TOTAL, buffer_length); // BUFFER_LENGTH BOOST_CHECK_EQUAL(true, WasNull(decimal_digits_len)); BOOST_CHECK_EQUAL(0, decimal_digits); // DECIMAL_DIGITS @@ -1968,13 +1957,9 @@ BOOST_AUTO_TEST_CASE(TestSQLColumnWithSQLBindCols) { BOOST_CHECK_EQUAL(0, num_prec_radix); // NUM_PREC_RADIX BOOST_CHECK_EQUAL(false, WasNull(nullable_len)); BOOST_CHECK_EQUAL(SQL_NO_NULLS, nullable); // NULLABLE - BOOST_CHECK_EQUAL( - true, - WasNull(remarks_len)); + BOOST_CHECK_EQUAL(true, WasNull(remarks_len)); BOOST_CHECK_EQUAL("", remarks); // REMARKS - BOOST_CHECK_EQUAL( - true, - WasNull(column_def_len)); + BOOST_CHECK_EQUAL(true, WasNull(column_def_len)); BOOST_CHECK_EQUAL("", column_def); // COLUMN_DEF BOOST_CHECK_EQUAL(false, WasNull(sql_data_type_len)); BOOST_CHECK_EQUAL(SQL_WVARCHAR, sql_data_type); // SQL_DATA_TYPE @@ -1996,7 +1981,8 @@ BOOST_AUTO_TEST_CASE(TestSQLColumnWithSQLBindCols) { if (!SQL_SUCCEEDED(ret)) { BOOST_ERROR(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); } - BOOST_CHECK_EQUAL("TABLE_SCHEM", utility::SqlStringToString(attrColumnName, attrColumnNameLen)); + BOOST_CHECK_EQUAL("TABLE_SCHEM", utility::SqlStringToString( + attrColumnName, attrColumnNameLen)); // Test that the next fetch will have no data. ret = SQLFetch(stmt); diff --git a/src/odbc-test/src/odbc_test_suite.cpp b/src/odbc-test/src/odbc_test_suite.cpp index 24425b058..b3d688aa1 100644 --- a/src/odbc-test/src/odbc_test_suite.cpp +++ b/src/odbc-test/src/odbc_test_suite.cpp @@ -802,17 +802,15 @@ void OdbcTestSuite::InsertNonFullBatchSelect(int recordsNum, int splitAt) { void OdbcTestSuite::CreateDsnConnectionStringForRemoteServer( std::string& connectionString, bool sshTunnel, const std::string& username, - const std::string& miscOptions, - const std::string databasename) const { + const std::string& miscOptions, const std::string databasename) const { std::string user = common::GetEnv("DOC_DB_USER_NAME", "documentdb"); std::string password = common::GetEnv("DOC_DB_PASSWORD", ""); std::string host = sshTunnel ? common::GetEnv("DOC_DB_HOST", "") : "localhost"; std::string sshUserAtHost = common::GetEnv("DOC_DB_USER", ""); std::string sshPrivKeyFile = common::GetEnv("DOC_DB_PRIV_KEY_FILE", ""); - std::string port = sshTunnel - ? common::GetEnv("DOC_DB_REMOTE_PORT", "27017") - : common::GetEnv("DOC_DB_LOCAL_PORT", "27019"); + std::string port = sshTunnel ? common::GetEnv("DOC_DB_REMOTE_PORT", "27017") + : common::GetEnv("DOC_DB_LOCAL_PORT", "27019"); if (!username.empty()) { user = username; diff --git a/src/odbc-test/src/queries_test.cpp b/src/odbc-test/src/queries_test.cpp index 2f18fa88c..dc3471eaf 100644 --- a/src/odbc-test/src/queries_test.cpp +++ b/src/odbc-test/src/queries_test.cpp @@ -55,7 +55,7 @@ struct QueriesTestSuiteFixture : odbc::OdbcTestSuite { * Constructor. */ QueriesTestSuiteFixture() { - // No-op + // No-op } /** @@ -85,7 +85,8 @@ struct QueriesTestSuiteFixture : odbc::OdbcTestSuite { // Binding columns. for (SQLSMALLINT i = 0; i < columnsCnt; ++i) { - ret = SQLBindCol(stmt, i + 1, type, &columns[i], sizeof(columns[i]), nullptr); + ret = SQLBindCol(stmt, i + 1, type, &columns[i], sizeof(columns[i]), + nullptr); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -231,14 +232,11 @@ BOOST_AUTO_TEST_CASE(TestMoviesCast, *disabled()) { ret = SQLFetch(stmt); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); while (SQL_SUCCEEDED(ret)) { - ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_SBIGINT, &index, sizeof(index), - &index_len); + ret = SQLGetData(stmt, 2, SQL_C_SBIGINT, &index, sizeof(index), &index_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 3, SQL_C_WCHAR, value, sizeof(value), - &value_len); + ret = SQLGetData(stmt, 3, SQL_C_WCHAR, value, sizeof(value), &value_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); @@ -299,14 +297,14 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingGetData) { ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, sizeof(fieldDecimal128), - &fieldDecimal128_len); + ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, + sizeof(fieldDecimal128), &fieldDecimal128_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); ret = SQLGetData(stmt, 3, SQL_C_DOUBLE, &fieldDouble, sizeof(fieldDouble), &fieldDouble_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = - SQLGetData(stmt, 4, SQL_C_WCHAR, fieldString, sizeof(fieldString), &fieldString_len); + ret = SQLGetData(stmt, 4, SQL_C_WCHAR, fieldString, sizeof(fieldString), + &fieldString_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); ret = SQLGetData(stmt, 5, SQL_C_WCHAR, fieldObjectId, sizeof(fieldObjectId), &fieldObjectId_len); @@ -329,22 +327,29 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingGetData) { ret = SQLGetData(stmt, 11, SQL_C_WCHAR, fieldMinKey, sizeof(fieldMinKey), &fieldMinKey_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 12, SQL_C_WCHAR, fieldNull, sizeof(fieldNull), &fieldNull_len); + ret = SQLGetData(stmt, 12, SQL_C_WCHAR, fieldNull, sizeof(fieldNull), + &fieldNull_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); ret = SQLGetData(stmt, 13, SQL_C_BINARY, fieldBinary, sizeof(fieldBinary), &fieldBinary_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d91892191475139", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d91892191475139", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDecimal128_len); - BOOST_CHECK_EQUAL("340282350000000000000", utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); + BOOST_CHECK_EQUAL( + "340282350000000000000", + utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDouble_len); BOOST_CHECK_EQUAL(1.7976931348623157e308, fieldDouble); BOOST_CHECK_NE(SQL_NULL_DATA, fieldString_len); - BOOST_CHECK_EQUAL("some Text", utility::SqlStringToString(fieldString, fieldString_len, true)); + BOOST_CHECK_EQUAL("some Text", utility::SqlStringToString( + fieldString, fieldString_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldObjectId_len); - BOOST_CHECK_EQUAL("62196dcc4d9189219147513a", utility::SqlStringToString(fieldObjectId, fieldObjectId_len, true)); + BOOST_CHECK_EQUAL( + "62196dcc4d9189219147513a", + utility::SqlStringToString(fieldObjectId, fieldObjectId_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldBoolean_len); BOOST_CHECK_EQUAL(true, fieldBoolean); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDate_len); @@ -356,9 +361,11 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingGetData) { BOOST_CHECK_NE(SQL_NULL_DATA, fieldLong_len); BOOST_CHECK_EQUAL(9223372036854775807, fieldLong); BOOST_CHECK_NE(SQL_NULL_DATA, fieldMaxKey_len); - BOOST_CHECK_EQUAL("MAXKEY", utility::SqlStringToString(fieldMaxKey, fieldMaxKey_len, true)); + BOOST_CHECK_EQUAL( + "MAXKEY", utility::SqlStringToString(fieldMaxKey, fieldMaxKey_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldMinKey_len); - BOOST_CHECK_EQUAL("MINKEY", utility::SqlStringToString(fieldMinKey, fieldMinKey_len, true)); + BOOST_CHECK_EQUAL( + "MINKEY", utility::SqlStringToString(fieldMinKey, fieldMinKey_len, true)); BOOST_CHECK_EQUAL(SQL_NULL_DATA, fieldNull_len); BOOST_CHECK_NE(SQL_NULL_DATA, fieldBinary_len); BOOST_CHECK_EQUAL(3, fieldBinary_len); @@ -413,7 +420,8 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingBindCol) { ret = SQLBindCol(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLBindCol(stmt, 2, SQL_C_WCHAR, fieldDecimal128, sizeof(fieldDecimal128), &fieldDecimal128_len); + ret = SQLBindCol(stmt, 2, SQL_C_WCHAR, fieldDecimal128, + sizeof(fieldDecimal128), &fieldDecimal128_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); ret = SQLBindCol(stmt, 3, SQL_C_DOUBLE, &fieldDouble, sizeof(fieldDouble), &fieldDouble_len); @@ -430,20 +438,23 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingBindCol) { ret = SQLBindCol(stmt, 7, SQL_C_TYPE_DATE, &fieldDate, sizeof(fieldDate), &fieldDate_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLBindCol(stmt, 8, SQL_C_SLONG, &fieldInt, sizeof(fieldInt), &fieldInt_len); + ret = SQLBindCol(stmt, 8, SQL_C_SLONG, &fieldInt, sizeof(fieldInt), + &fieldInt_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); ret = SQLBindCol(stmt, 9, SQL_C_SBIGINT, &fieldLong, sizeof(fieldLong), &fieldLong_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = - SQLBindCol(stmt, 10, SQL_C_WCHAR, fieldMaxKey, sizeof(fieldMaxKey), &fieldMaxKey_len); + ret = SQLBindCol(stmt, 10, SQL_C_WCHAR, fieldMaxKey, sizeof(fieldMaxKey), + &fieldMaxKey_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = - SQLBindCol(stmt, 11, SQL_C_WCHAR, fieldMinKey, sizeof(fieldMinKey), &fieldMinKey_len); - BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLBindCol(stmt, 12, SQL_C_WCHAR, fieldNull, sizeof(fieldNull), &fieldNull_len); + ret = SQLBindCol(stmt, 11, SQL_C_WCHAR, fieldMinKey, sizeof(fieldMinKey), + &fieldMinKey_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLBindCol(stmt, 13, SQL_C_BINARY, fieldBinary, sizeof(fieldBinary), &fieldBinary_len); + ret = SQLBindCol(stmt, 12, SQL_C_WCHAR, fieldNull, sizeof(fieldNull), + &fieldNull_len); + BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); + ret = SQLBindCol(stmt, 13, SQL_C_BINARY, fieldBinary, sizeof(fieldBinary), + &fieldBinary_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); // Fetch 1st row @@ -451,15 +462,21 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingBindCol) { BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d91892191475139", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d91892191475139", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDecimal128_len); - BOOST_CHECK_EQUAL("340282350000000000000", utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); + BOOST_CHECK_EQUAL( + "340282350000000000000", + utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDouble_len); BOOST_CHECK_EQUAL(1.7976931348623157e308, fieldDouble); BOOST_CHECK_NE(SQL_NULL_DATA, fieldString_len); - BOOST_CHECK_EQUAL("some Text", utility::SqlStringToString(fieldString, fieldString_len, true)); + BOOST_CHECK_EQUAL("some Text", utility::SqlStringToString( + fieldString, fieldString_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldObjectId_len); - BOOST_CHECK_EQUAL("62196dcc4d9189219147513a", utility::SqlStringToString(fieldObjectId, fieldObjectId_len, true)); + BOOST_CHECK_EQUAL( + "62196dcc4d9189219147513a", + utility::SqlStringToString(fieldObjectId, fieldObjectId_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldBoolean_len); BOOST_CHECK_EQUAL(true, fieldBoolean); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDate_len); @@ -471,9 +488,11 @@ BOOST_AUTO_TEST_CASE(TestSingleResultUsingBindCol) { BOOST_CHECK_NE(SQL_NULL_DATA, fieldLong_len); BOOST_CHECK_EQUAL(9223372036854775807, fieldLong); BOOST_CHECK_NE(SQL_NULL_DATA, fieldMaxKey_len); - BOOST_CHECK_EQUAL("MAXKEY", utility::SqlStringToString(fieldMaxKey, fieldMaxKey_len, true)); + BOOST_CHECK_EQUAL( + "MAXKEY", utility::SqlStringToString(fieldMaxKey, fieldMaxKey_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldMinKey_len); - BOOST_CHECK_EQUAL("MINKEY", utility::SqlStringToString(fieldMinKey, fieldMinKey_len, true)); + BOOST_CHECK_EQUAL( + "MINKEY", utility::SqlStringToString(fieldMinKey, fieldMinKey_len, true)); BOOST_CHECK_EQUAL(SQL_NULL_DATA, fieldNull_len); BOOST_CHECK_NE(SQL_NULL_DATA, fieldBinary_len); BOOST_CHECK_EQUAL(3, fieldBinary_len); @@ -491,7 +510,8 @@ BOOST_AUTO_TEST_CASE(TestMultiLineResultUsingGetData) { CreateDsnConnectionStringForLocalServer(dsnConnectionString); Connect(dsnConnectionString); SQLRETURN ret; - std::vector< SQLWCHAR > request = MakeSqlBuffer("SELECT * FROM \"queries_test_002\" ORDER BY \"queries_test_002__id\""); + std::vector< SQLWCHAR > request = MakeSqlBuffer( + "SELECT * FROM \"queries_test_002\" ORDER BY \"queries_test_002__id\""); ret = SQLExecDirect(stmt, request.data(), SQL_NTS); if (!SQL_SUCCEEDED(ret)) { @@ -511,14 +531,17 @@ BOOST_AUTO_TEST_CASE(TestMultiLineResultUsingGetData) { ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, sizeof(fieldDecimal128), - &fieldDecimal128_len); + ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, + sizeof(fieldDecimal128), &fieldDecimal128_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d91892191475139", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d91892191475139", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDecimal128_len); - BOOST_CHECK_EQUAL("340282350000000000000", utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); + BOOST_CHECK_EQUAL( + "340282350000000000000", + utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); // Fetch 2nd row ret = SQLFetch(stmt); @@ -526,11 +549,12 @@ BOOST_AUTO_TEST_CASE(TestMultiLineResultUsingGetData) { ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, sizeof(fieldDecimal128), - &fieldDecimal128_len); + ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, + sizeof(fieldDecimal128), &fieldDecimal128_len); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d9189219147513a", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d9189219147513a", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_EQUAL(SQL_NULL_DATA, fieldDecimal128_len); // Fetch 3rd row @@ -539,13 +563,16 @@ BOOST_AUTO_TEST_CASE(TestMultiLineResultUsingGetData) { ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, sizeof(fieldDecimal128), - &fieldDecimal128_len); + ret = SQLGetData(stmt, 2, SQL_C_WCHAR, fieldDecimal128, + sizeof(fieldDecimal128), &fieldDecimal128_len); BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d9189219147513b", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d9189219147513b", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, fieldDecimal128_len); - BOOST_CHECK_EQUAL("340282350000000000000", utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); + BOOST_CHECK_EQUAL( + "340282350000000000000", + utility::SqlStringToString(fieldDecimal128, fieldDecimal128_len, true)); // Fetch 4th row - not exist ret = SQLFetch(stmt); @@ -596,26 +623,34 @@ BOOST_AUTO_TEST_CASE(TestArrayStructJoinUsingGetData) { ret = SQLGetData(stmt, 1, SQL_C_WCHAR, id, sizeof(id), &id_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 2, SQL_C_SLONG, &a1_value, sizeof(a1_value), &a1_value_len); + ret = SQLGetData(stmt, 2, SQL_C_SLONG, &a1_value, sizeof(a1_value), + &a1_value_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 3, SQL_C_WCHAR, a2_value, sizeof(a2_value), &a2_value_len); + ret = SQLGetData(stmt, 3, SQL_C_WCHAR, a2_value, sizeof(a2_value), + &a2_value_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 4, SQL_C_WCHAR, d1_value, sizeof(d1_value), &d1_value_len); + ret = SQLGetData(stmt, 4, SQL_C_WCHAR, d1_value, sizeof(d1_value), + &d1_value_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); - ret = SQLGetData(stmt, 5, SQL_C_WCHAR, d2_value, sizeof(d2_value), &d2_value_len); + ret = SQLGetData(stmt, 5, SQL_C_WCHAR, d2_value, sizeof(d2_value), + &d2_value_len); BOOST_CHECK_EQUAL(SQL_SUCCESS, ret); // Check the first row BOOST_CHECK_NE(SQL_NULL_DATA, id_len); - BOOST_CHECK_EQUAL("62196dcc4d91892191475139", utility::SqlStringToString(id, id_len, true)); + BOOST_CHECK_EQUAL("62196dcc4d91892191475139", + utility::SqlStringToString(id, id_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, a1_value_len); BOOST_CHECK_EQUAL(1, a1_value); BOOST_CHECK_NE(SQL_NULL_DATA, a2_value_len); - BOOST_CHECK_EQUAL("value1", utility::SqlStringToString(a2_value, a2_value_len, true)); + BOOST_CHECK_EQUAL("value1", + utility::SqlStringToString(a2_value, a2_value_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, d1_value_len); - BOOST_CHECK_EQUAL("field1 Value", utility::SqlStringToString(d1_value, d1_value_len, true)); + BOOST_CHECK_EQUAL("field1 Value", + utility::SqlStringToString(d1_value, d1_value_len, true)); BOOST_CHECK_NE(SQL_NULL_DATA, d2_value_len); - BOOST_CHECK_EQUAL("field2 Value", utility::SqlStringToString(d2_value, d2_value_len, true)); + BOOST_CHECK_EQUAL("field2 Value", + utility::SqlStringToString(d2_value, d2_value_len, true)); // Count the rows int32_t actual_rows = 0; @@ -747,8 +782,7 @@ BOOST_AUTO_TEST_CASE(TestTwoRowsString, *disabled()) { // Such format is used because Date returned as Timestamp. BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[9]), "1976-01-12 00:00:00"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), - "00:08:59"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), "00:08:59"); BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[11]), "1978-08-21 23:13:45"); @@ -806,29 +840,20 @@ BOOST_AUTO_TEST_CASE(TestOneRowString, *disabled()) { if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[0]), - "1"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[1]), - "2"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[2]), - "3"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[3]), - "4"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[4]), - "5"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[5]), - "6"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[6]), - "7"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[7]), - "1"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[0]), "1"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[1]), "2"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[2]), "3"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[3]), "4"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[4]), "5"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[5]), "6"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[6]), "7"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[7]), "1"); BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[8]), "00000000-0000-0008-0000-000000000009"); // Such format is used because Date returned as Timestamp. BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[9]), "1987-06-05 00:00:00"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), - "12:48:12"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), "12:48:12"); BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[11]), "1998-12-27 01:02:03"); @@ -1003,8 +1028,8 @@ BOOST_AUTO_TEST_CASE(TestDataAtExecution, *disabled()) { if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_VARCHAR, 100, - 100, &ind2, sizeof(ind2), &len2); + ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_VARCHAR, + 100, 100, &ind2, sizeof(ind2), &len2); if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); @@ -1054,29 +1079,20 @@ BOOST_AUTO_TEST_CASE(TestDataAtExecution, *disabled()) { if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[0]), - "1"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[1]), - "2"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[2]), - "3"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[3]), - "4"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[4]), - "5"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[5]), - "6"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[6]), - "7"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[7]), - "1"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[0]), "1"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[1]), "2"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[2]), "3"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[3]), "4"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[4]), "5"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[5]), "6"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[6]), "7"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[7]), "1"); BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[8]), "00000000-0000-0008-0000-000000000009"); // Such format is used because Date returned as Timestamp. BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[9]), "1987-06-05 00:00:00"); - BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), - "12:48:12"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[10]), "12:48:12"); BOOST_CHECK_EQUAL(utility::SqlStringToString(columns[11]), "1998-12-27 01:02:03"); @@ -1397,7 +1413,8 @@ BOOST_AUTO_TEST_CASE(TestKeyVal, *disabled()) { if (!SQL_SUCCEEDED(ret)) BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); - std::vector< SQLWCHAR > requestStar = MakeSqlBuffer("SELECT _key, _val, * FROM ComplexType"); + std::vector< SQLWCHAR > requestStar = + MakeSqlBuffer("SELECT _key, _val, * FROM ComplexType"); ret = SQLExecDirect(stmt, requestStar.data(), SQL_NTS); if (!SQL_SUCCEEDED(ret)) @@ -1490,7 +1507,8 @@ BOOST_AUTO_TEST_CASE(TestExecuteAfterCursorClose, *disabled()) { BOOST_CHECK_EQUAL(key, 1); - BOOST_CHECK_EQUAL(utility::SqlStringToString(strField, strFieldLen, true), "5"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(strField, strFieldLen, true), + "5"); ret = SQLFetch(stmt); @@ -1538,7 +1556,8 @@ BOOST_AUTO_TEST_CASE(TestCloseNonFullFetch, *disabled()) { BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); BOOST_CHECK_EQUAL(key, 1); - BOOST_CHECK_EQUAL(utility::SqlStringToString(strField, strFieldLen, true), "str1"); + BOOST_CHECK_EQUAL(utility::SqlStringToString(strField, strFieldLen, true), + "str1"); ret = SQLFreeStmt(stmt, SQL_CLOSE); diff --git a/src/odbc-test/src/utility_test.cpp b/src/odbc-test/src/utility_test.cpp index d5ab7427b..b5e791fc9 100644 --- a/src/odbc-test/src/utility_test.cpp +++ b/src/odbc-test/src/utility_test.cpp @@ -119,14 +119,14 @@ BOOST_AUTO_TEST_CASE(TestUtilityCopyStringToBufferRepetative, *disabled()) { str.push_back(cch); } - auto t1 = std::chrono::high_resolution_clock::now(); + auto t1 = std::chrono::high_resolution_clock::now(); size_t bytesWrittenOrRequired = 0; for (int i = 0; i < 500; i++) { bytesWrittenOrRequired = CopyStringToBuffer( str, buffer.data(), ((strLen + 1) * sizeof(SQLWCHAR))); BOOST_CHECK_EQUAL(str.size(), bytesWrittenOrRequired); } - auto t2 = std::chrono::high_resolution_clock::now(); + auto t2 = std::chrono::high_resolution_clock::now(); std::cout << t2.time_since_epoch().count() - t1.time_since_epoch().count() << " nanoseconds\n"; } 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 1e1376654..19bbface5 100644 --- a/src/odbc/include/ignite/odbc/app/application_data_buffer.h +++ b/src/odbc/include/ignite/odbc/app/application_data_buffer.h @@ -144,7 +144,7 @@ class ApplicationDataBuffer { * @param value Value. * @return Conversion result. */ - ConversionResult::Type PutInt16(boost::optional value); + ConversionResult::Type PutInt16(boost::optional< int16_t > value); /** * Put in buffer value of type int16_t. @@ -224,8 +224,7 @@ class ApplicationDataBuffer { * @param optional value Value. * @return Conversion result. */ - ConversionResult::Type PutString( - const boost::optional< std::string >& value); + ConversionResult::Type PutString(const boost::optional< std::string >& value); /** * Put in buffer value of type string. @@ -275,7 +274,8 @@ class ApplicationDataBuffer { * @param value Value to put. * @return Conversion result. */ - ConversionResult::Type PutDecimal(const boost::optional< common::Decimal >& value); + ConversionResult::Type PutDecimal( + const boost::optional< common::Decimal >& value); /** * Put decimal value to buffer. @@ -307,7 +307,8 @@ class ApplicationDataBuffer { * @param value Value to put. * @return Conversion result. */ - ConversionResult::Type PutTimestamp(const boost::optional< Timestamp >& value); + ConversionResult::Type PutTimestamp( + const boost::optional< Timestamp >& value); /** * Put timestamp to buffer. diff --git a/src/odbc/include/ignite/odbc/binary/binary.h b/src/odbc/include/ignite/odbc/binary/binary.h index beb1e55e5..2b2ea21ad 100644 --- a/src/odbc/include/ignite/odbc/binary/binary.h +++ b/src/odbc/include/ignite/odbc/binary/binary.h @@ -32,4 +32,4 @@ #include #include -#endif //_IGNITE_ODBC_BINARY_BINARY +#endif //_IGNITE_ODBC_BINARY_BINARY diff --git a/src/odbc/include/ignite/odbc/binary/binary_containers.h b/src/odbc/include/ignite/odbc/binary/binary_containers.h index 8989110f6..4fba46dd8 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_containers.h +++ b/src/odbc/include/ignite/odbc/binary/binary_containers.h @@ -617,4 +617,4 @@ class BinaryMapReader { } // namespace binary } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_BINARY_BINARY_CONTAINERS +#endif //_IGNITE_ODBC_BINARY_BINARY_CONTAINERS diff --git a/src/odbc/include/ignite/odbc/binary/binary_object.h b/src/odbc/include/ignite/odbc/binary/binary_object.h index 3a5f260fe..228bb0aa0 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_object.h +++ b/src/odbc/include/ignite/odbc/binary/binary_object.h @@ -27,135 +27,121 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace binary - { - class BinaryWriterImpl; - } - } - - namespace binary - { - /** - * Binary object. - * - * This is a thin wrapper over the memory area that contains serialized - * binary object. Provides method that allows deserialize object. - */ - class IGNITE_IMPORT_EXPORT BinaryObject - { - friend class ignite::odbc::impl::binary::BinaryWriterImpl; - public: - /// @cond INTERNAL - /** - * Constructor. - * - * @param impl Implementation. - */ - BinaryObject(const impl::binary::BinaryObjectImpl& impl) : - impl(impl) - { - // No-op. - } - - /** - * Direct constructor. - * Constructs binary object without any safety checks. - * - * @param mem Binary object memory. - * @param start Object starting position in memory. - * @param idRslvr ID resolver. - * @param metaMgr Metadata manager. - */ - BinaryObject(impl::interop::InteropMemory& mem, int32_t start, - impl::binary::BinaryIdResolver* idRslvr, impl::binary::BinaryTypeManager* metaMgr) : - impl(mem, start, idRslvr, metaMgr) - { - // No-op. - } - /// @endcond - - /** - * Copy constructor. - * - * @param other Another instance. - */ - BinaryObject(const BinaryObject& other) : - impl(other.impl) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Another instance. - * @return *this. - */ - BinaryObject& operator=(const BinaryObject& other) - { - impl = other.impl; - - return *this; - } - - /** - * Deserialize object. - * @throw IgniteError if the object can not be deserialized to - * specified type. - * - * @return Deserialized value. - */ - template - T Deserialize() const - { - return impl.Deserialize(); - } - - /** - * Get field. - * @throw IgniteError if the there is no specified field or if it - * is not of the specified type. - * - * @param name Field name. - * @return Field value. - */ - template - T GetField(const char* name) const - { - return impl.GetField(name); - } - - /** - * Check if the binary object has the specified field. - * - * @param name Field name. - * @return True if the binary object has the specified field and - * false otherwise. - */ - bool HasField(const char* name) const - { - return impl.HasField(name); - } - - private: - /** Implementation. */ - impl::binary::BinaryObjectImpl impl; - }; - - /* Specialization */ - template<> - inline BinaryObject BinaryObject::GetField(const char* name) const - { - return BinaryObject(impl.GetField(name)); - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace binary { +class BinaryWriterImpl; } +} // namespace impl -#endif //_IGNITE_ODBC_BINARY_BINARY_OBJECT +namespace binary { +/** + * Binary object. + * + * This is a thin wrapper over the memory area that contains serialized + * binary object. Provides method that allows deserialize object. + */ +class IGNITE_IMPORT_EXPORT BinaryObject { + friend class ignite::odbc::impl::binary::BinaryWriterImpl; + + public: + /// @cond INTERNAL + /** + * Constructor. + * + * @param impl Implementation. + */ + BinaryObject(const impl::binary::BinaryObjectImpl& impl) : impl(impl) { + // No-op. + } + + /** + * Direct constructor. + * Constructs binary object without any safety checks. + * + * @param mem Binary object memory. + * @param start Object starting position in memory. + * @param idRslvr ID resolver. + * @param metaMgr Metadata manager. + */ + BinaryObject(impl::interop::InteropMemory& mem, int32_t start, + impl::binary::BinaryIdResolver* idRslvr, + impl::binary::BinaryTypeManager* metaMgr) + : impl(mem, start, idRslvr, metaMgr) { + // No-op. + } + /// @endcond + + /** + * Copy constructor. + * + * @param other Another instance. + */ + BinaryObject(const BinaryObject& other) : impl(other.impl) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Another instance. + * @return *this. + */ + BinaryObject& operator=(const BinaryObject& other) { + impl = other.impl; + + return *this; + } + + /** + * Deserialize object. + * @throw IgniteError if the object can not be deserialized to + * specified type. + * + * @return Deserialized value. + */ + template < typename T > + T Deserialize() const { + return impl.Deserialize< T >(); + } + + /** + * Get field. + * @throw IgniteError if the there is no specified field or if it + * is not of the specified type. + * + * @param name Field name. + * @return Field value. + */ + template < typename T > + T GetField(const char* name) const { + return impl.GetField< T >(name); + } + + /** + * Check if the binary object has the specified field. + * + * @param name Field name. + * @return True if the binary object has the specified field and + * false otherwise. + */ + bool HasField(const char* name) const { + return impl.HasField(name); + } + + private: + /** Implementation. */ + impl::binary::BinaryObjectImpl impl; +}; + +/* Specialization */ +template <> +inline BinaryObject BinaryObject::GetField(const char* name) const { + return BinaryObject(impl.GetField< impl::binary::BinaryObjectImpl >(name)); +} +} // namespace binary +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_BINARY_BINARY_OBJECT diff --git a/src/odbc/include/ignite/odbc/binary/binary_raw_writer.h b/src/odbc/include/ignite/odbc/binary/binary_raw_writer.h index 3f0edbfa0..5b1d70f20 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_raw_writer.h +++ b/src/odbc/include/ignite/odbc/binary/binary_raw_writer.h @@ -433,4 +433,4 @@ class IGNITE_IMPORT_EXPORT BinaryRawWriter { } // namespace binary } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_BINARY_BINARY_RAW_WRITER +#endif //_IGNITE_ODBC_BINARY_BINARY_RAW_WRITER diff --git a/src/odbc/include/ignite/odbc/binary/binary_reader.h b/src/odbc/include/ignite/odbc/binary/binary_reader.h index 22d1401ec..7aa7157a5 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_reader.h +++ b/src/odbc/include/ignite/odbc/binary/binary_reader.h @@ -503,4 +503,4 @@ class IGNITE_IMPORT_EXPORT BinaryReader { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_BINARY_BINARY_READER +#endif //_IGNITE_ODBC_BINARY_BINARY_READER diff --git a/src/odbc/include/ignite/odbc/binary/binary_type.h b/src/odbc/include/ignite/odbc/binary/binary_type.h index c47e45dd2..7bef7e1fe 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_type.h +++ b/src/odbc/include/ignite/odbc/binary/binary_type.h @@ -120,7 +120,7 @@ dst = 0; \ } -#endif // _IGNITE_ODBC_BINARY_TYPE_MACRO +#endif // _IGNITE_ODBC_BINARY_TYPE_MACRO namespace ignite { namespace odbc { diff --git a/src/odbc/include/ignite/odbc/binary/binary_writer.h b/src/odbc/include/ignite/odbc/binary/binary_writer.h index b03dfce26..8da67ed75 100644 --- a/src/odbc/include/ignite/odbc/binary/binary_writer.h +++ b/src/odbc/include/ignite/odbc/binary/binary_writer.h @@ -480,4 +480,4 @@ class IGNITE_IMPORT_EXPORT BinaryWriter { } // namespace binary } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_BINARY_BINARY_WRITER +#endif //_IGNITE_ODBC_BINARY_BINARY_WRITER diff --git a/src/odbc/include/ignite/odbc/cache/cache.h b/src/odbc/include/ignite/odbc/cache/cache.h index e49ec01cf..6af9c7ab6 100644 --- a/src/odbc/include/ignite/odbc/cache/cache.h +++ b/src/odbc/include/ignite/odbc/cache/cache.h @@ -45,1828 +45,1799 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * Main entry point for all Data Grid APIs. - * - * Both key and value types should be default-constructable, - * copy-constructable and assignable. Also BinaryType class - * template should be specialized for both types. - * - * This class is implemented as a reference to an implementation so copying - * of this class instance will only create another reference to the same - * underlying object. Underlying object will be released automatically once all - * the instances are destructed. - * - * @tparam K Cache key type. - * @tparam V Cache value type. - */ - template - class IGNITE_IMPORT_EXPORT Cache - { - public: - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - Cache(impl::cache::CacheImpl* impl) : - impl(impl) - { - // No-op. - } - - /** - * Get name of this cache (null for default cache). - * - * This method should only be used on the valid instance. - * - * @return Name of this cache (null for default cache). - */ - const char* GetName() const - { - return impl.Get()->GetName(); - } - - /** - * Checks whether this cache contains no key-value mappings. - * Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0. - * - * This method should only be used on the valid instance. - * - * @return True if cache is empty. - */ - bool IsEmpty() - { - IgniteError err; - - bool res = IsEmpty(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Checks whether this cache contains no key-value mappings. - * Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0. - * - * This method should only be used on the valid instance. - * - * @param err Error. - * @return True if cache is empty. - */ - bool IsEmpty(IgniteError& err) - { - return Size(err) == 0; - } - - /** - * Check if cache contains mapping for this key. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @return True if cache contains mapping for this key. - */ - bool ContainsKey(const K& key) - { - IgniteError err; - - bool res = ContainsKey(key, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check if cache contains mapping for this key. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @param err Error. - * @return True if cache contains mapping for this key. - */ - bool ContainsKey(const K& key, IgniteError& err) - { - impl::In1Operation op(key); - - return impl.Get()->ContainsKey(op, err); - } - - /** - * Check if cache contains mapping for these keys. - * - * This method should only be used on the valid instance. - * - * @param keys Keys. - * @return True if cache contains mapping for all these keys. - */ - bool ContainsKeys(const std::set& keys) - { - IgniteError err; - - bool res = ContainsKeys(keys, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check if cache contains mapping for these keys. - * - * This method should only be used on the valid instance. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - * @return True if cache contains mapping for all these keys. - */ - template - bool ContainsKeys(InputIter begin, InputIter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - bool res = impl.Get()->ContainsKeys(op, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check if cache contains mapping for these keys. - * - * This method should only be used on the valid instance. - * - * @param keys Keys. - * @param err Error. - * @return True if cache contains mapping for all these keys. - */ - bool ContainsKeys(const std::set& keys, IgniteError& err) - { - impl::InSetOperation op(keys); - - return impl.Get()->ContainsKeys(op, err); - } - - /** - * Peeks at cached value using optional set of peek modes. This method will sequentially - * iterate over given peek modes, and try to peek at value using each peek mode. Once a - * non-null value is found, it will be immediately returned. - * This method does not participate in any transactions, however, it may peek at transactional - * value depending on the peek modes used. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @param peekModes Peek modes. - * @return Value. - */ - V LocalPeek(const K& key, int32_t peekModes) - { - IgniteError err; - - V res = LocalPeek(key, peekModes, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Peeks at cached value using optional set of peek modes. This method will sequentially - * iterate over given peek modes, and try to peek at value using each peek mode. Once a - * non-null value is found, it will be immediately returned. - * This method does not participate in any transactions, however, it may peek at transactional - * value depending on the peek modes used. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @param peekModes Peek modes. - * @param err Error. - * @return Value. - */ - V LocalPeek(const K& key, int32_t peekModes, IgniteError& err) - { - V val; - - impl::InCacheLocalPeekOperation inOp(key, peekModes); - impl::Out1Operation outOp(val); - - impl.Get()->LocalPeek(inOp, outOp, err); - - return val; - } - - /** - * Retrieves value mapped to the specified key from cache. - * If the value is not present in cache, then it will be looked up from swap storage. If - * it's not present in swap, or if swap is disabled, and if read-through is allowed, value - * will be loaded from persistent store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @return Value. - */ - V Get(const K& key) - { - IgniteError err; - - V res = Get(key, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Retrieves value mapped to the specified key from cache. - * If the value is not present in cache, then it will be looked up from swap storage. If - * it's not present in swap, or if swap is disabled, and if read-through is allowed, value - * will be loaded from persistent store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key. - * @param err Error. - * @return Value. - */ - V Get(const K& key, IgniteError& err) - { - V val; - impl::In1Operation inOp(key); - impl::Out1Operation outOp(val); - - impl.Get()->Get(inOp, outOp, err); - - return val; - } - - /** - * Retrieves values mapped to the specified keys from cache. - * If some value is not present in cache, then it will be looked up from swap storage. If - * it's not present in swap, or if swap is disabled, and if read-through is allowed, value - * will be loaded from persistent store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param keys Keys. - * @return Map of key-value pairs. - */ - std::map GetAll(const std::set& keys) - { - IgniteError err; - - std::map res = GetAll(keys, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Retrieves values mapped to the specified keys from cache. - * If some value is not present in cache, then it will be looked up from swap storage. If - * it's not present in swap, or if swap is disabled, and if read-through is allowed, value - * will be loaded from persistent store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param keys Keys. - * @param err Error. - * @return Map of key-value pairs. - */ - std::map GetAll(const std::set& keys, IgniteError& err) - { - std::map res; - - impl::InSetOperation inOp(keys); - impl::OutMapOperation outOp(res); - - impl.Get()->GetAll(inOp, outOp, err); - - return res; - } - - /** - * Retrieves values mapped to the specified keys from cache. - * If some value is not present in cache, then it will be looked up from swap storage. If - * it's not present in swap, or if swap is disabled, and if read-through is allowed, value - * will be loaded from persistent store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - * @param dst Output iterator. Should dereference to std::pair or CacheEntry. - */ - template - void GetAll(InIter begin, InIter end, OutIter dst) - { - IgniteError err; - - impl::InIterOperation inOp(begin, end); - impl::OutMapIterOperation outOp(dst); - - impl.Get()->GetAll(inOp, outOp, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Associates the specified value with the specified key in the cache. - * If the cache previously contained a mapping for the key, - * the old value is replaced by the specified value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - */ - void Put(const K& key, const V& val) - { - IgniteError err; - - Put(key, val, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Associates the specified value with the specified key in the cache. - * If the cache previously contained a mapping for the key, - * the old value is replaced by the specified value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @param err Error. - */ - void Put(const K& key, const V& val, IgniteError& err) - { - impl::In2Operation op(key, val); - - impl.Get()->Put(op, err); - } - - /** - * Stores given key-value pairs in cache. - * If write-through is enabled, the stored values will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param vals Key-value pairs to store in cache. - */ - void PutAll(const std::map& vals) - { - IgniteError err; - - PutAll(vals, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Stores given key-value pairs in cache. - * If write-through is enabled, the stored values will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param vals Key-value pairs to store in cache. - * @param err Error. - */ - void PutAll(const std::map& vals, IgniteError& err) - { - impl::InMapOperation op(vals); - - impl.Get()->PutAll(op, err); - } - - /** - * Stores given key-value pairs in cache. - * If write-through is enabled, the stored values will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * Keys are locked in the order of iteration. It is caller's responsibility to make sure keys always follow - * same order. If that is not observed, calling this method in parallel will lead to deadlock. - * - * @param begin Iterator pointing to the beggining of the key-value pair sequence. - * @param end Iterator pointing to the end of the key-value pair sequence. - */ - template - void PutAll(Iter begin, Iter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - impl.Get()->PutAll(op, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Associates the specified value with the specified key in this cache, - * returning an existing value if one existed. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @return The value associated with the key at the start of the - * operation or null if none was associated. - */ - V GetAndPut(const K& key, const V& val) - { - IgniteError err; - - V res = GetAndPut(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Associates the specified value with the specified key in this cache, - * returning an existing value if one existed. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @param err Error. - * @return The value associated with the key at the start of the - * operation or null if none was associated. - */ - V GetAndPut(const K& key, const V& val, IgniteError& err) - { - V oldVal; - - impl::In2Operation inOp(key, val); - impl::Out1Operation outOp(oldVal); - - impl.Get()->GetAndPut(inOp, outOp, err); - - return oldVal; - } - - /** - * Atomically replaces the value for a given key if and only if there is a value currently mapped by - * the key. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @return The previous value associated with the specified key, or null if there was no mapping for - * the key. - */ - V GetAndReplace(const K& key, const V& val) - { - IgniteError err; - - V res = GetAndReplace(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Atomically replaces the value for a given key if and only if there is a value currently mapped by - * the key. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @param err Error. - * @return The previous value associated with the specified key, or null if there was no mapping for - * the key. - */ - V GetAndReplace(const K& key, const V& val, IgniteError& err) - { - V oldVal; - - impl::In2Operation inOp(key, val); - impl::Out1Operation outOp(oldVal); - - impl.Get()->GetAndReplace(inOp, outOp, err); - - return oldVal; - } - - /** - * Atomically removes the entry for a key only if currently mapped to some value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is associated. - * @return The value if one existed or null if no mapping existed for this key. - */ - V GetAndRemove(const K& key) - { - IgniteError err; - - V res = GetAndRemove(key, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Atomically removes the entry for a key only if currently mapped to some value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is associated. - * @param err Error. - * @return The value if one existed or null if no mapping existed for this key. - */ - V GetAndRemove(const K& key, IgniteError& err) - { - V oldVal; - - impl::In1Operation inOp(key); - impl::Out1Operation outOp(oldVal); - - impl.Get()->GetAndRemove(inOp, outOp, err); - - return oldVal; - } - - /** - * Atomically associates the specified key with the given value if it is not already associated with - * a value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @return True if a value was set. - */ - bool PutIfAbsent(const K& key, const V& val) - { - IgniteError err; - - bool res = PutIfAbsent(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Atomically associates the specified key with the given value if it is not already associated with - * a value. - * - * This method should only be used on the valid instance. - * - * @param key Key with which the specified value is to be associated. - * @param val Value to be associated with the specified key. - * @param err Error. - * @return True if a value was set. - */ - bool PutIfAbsent(const K& key, const V& val, IgniteError& err) - { - impl::In2Operation op(key, val); - - return impl.Get()->PutIfAbsent(op, err); - } - - /** - * Stores given key-value pair in cache only if cache had no previous mapping for it. - * If cache previously contained value for the given key, then this value is returned. - * In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node, - * which in its turn may load the value from the swap storage, and consecutively, if it's not - * in swap, from the underlying persistent storage. - * If the returned value is not needed, method putxIfAbsent() should be used instead of this one to - * avoid the overhead associated with returning of the previous value. - * If write-through is enabled, the stored value will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param val Value to be associated with the given key. - * @return Previously contained value regardless of whether put happened or not - * (null if there was no previous value). - */ - V GetAndPutIfAbsent(const K& key, const V& val) - { - IgniteError err; - - V res = GetAndPutIfAbsent(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Stores given key-value pair in cache only if cache had no previous mapping for it. - * If cache previously contained value for the given key, then this value is returned. - * In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node, - * which in its turn may load the value from the swap storage, and consecutively, if it's not - * in swap, from the underlying persistent storage. - * If the returned value is not needed, method putxIfAbsent() should be used instead of this one to - * avoid the overhead associated with returning of the previous value. - * If write-through is enabled, the stored value will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param val Value to be associated with the given key. - * @param err Error. - * @return Previously contained value regardless of whether put happened or not - * (null if there was no previous value). - */ - V GetAndPutIfAbsent(const K& key, const V& val, IgniteError& err) - { - V oldVal; - - impl::In2Operation inOp(key, val); - impl::Out1Operation outOp(oldVal); - - impl.Get()->GetAndPutIfAbsent(inOp, outOp, err); - - return oldVal; - } - - /** - * Stores given key-value pair in cache only if there is a previous mapping for it. - * If cache previously contained value for the given key, then this value is returned. - * In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node, - * which in its turn may load the value from the swap storage, and consecutively, if it's not - * in swap, rom the underlying persistent storage. - * If write-through is enabled, the stored value will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param val Value to be associated with the given key. - * @return True if the value was replaced. - */ - bool Replace(const K& key, const V& val) - { - IgniteError err; - - bool res = Replace(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Stores given key-value pair in cache only if there is a previous mapping for it. - * If cache previously contained value for the given key, then this value is returned. - * In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node, - * which in its turn may load the value from the swap storage, and consecutively, if it's not - * in swap, rom the underlying persistent storage. - * If write-through is enabled, the stored value will be persisted to store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param val Value to be associated with the given key. - * @param err Error. - * @return True if the value was replaced. - */ - bool Replace(const K& key, const V& val, IgniteError& err) - { - impl::In2Operation op(key, val); - - return impl.Get()->Replace(op, err); - } - - /** - * Stores given key-value pair in cache only if the previous value is equal to the old value passed - * as argument. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param oldVal Old value to match. - * @param newVal Value to be associated with the given key. - * @return True if replace happened, false otherwise. - */ - bool Replace(const K& key, const V& oldVal, const V& newVal) - { - IgniteError err; - - bool res = Replace(key, oldVal, newVal, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Stores given key-value pair in cache only if the previous value is equal to the old value passed - * as argument. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key to store in cache. - * @param oldVal Old value to match. - * @param newVal Value to be associated with the given key. - * @param err Error. - * @return True if replace happened, false otherwise. - */ - bool Replace(const K& key, const V& oldVal, const V& newVal, IgniteError& err) - { - impl::In3Operation op(key, oldVal, newVal); - - return impl.Get()->ReplaceIfEqual(op, err); - } - - /** - * Attempts to evict all entries associated with keys. - * - * @note Entry will be evicted only if it's not used (not - * participating in any locks or transactions). - * - * This method should only be used on the valid instance. - * - * @param keys Keys to evict from cache. - */ - void LocalEvict(const std::set& keys) - { - IgniteError err; - - LocalEvict(keys, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Attempts to evict all entries associated with keys. - * - * @note Entry will be evicted only if it's not used (not - * participating in any locks or transactions). - * - * This method should only be used on the valid instance. - * - * @param keys Keys to evict from cache. - * @param err Error. - */ - void LocalEvict(const std::set& keys, IgniteError& err) - { - impl::InSetOperation op(keys); - - impl.Get()->LocalEvict(op, err); - } - - /** - * Attempts to evict all entries associated with keys. - * - * @note Entry will be evicted only if it's not used (not - * participating in any locks or transactions). - * - * This method should only be used on the valid instance. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - */ - template - void LocalEvict(Iter begin, Iter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - impl.Get()->LocalEvict(op, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear cache. - * - * This method should only be used on the valid instance. - */ - void Clear() - { - IgniteError err; - - Clear(err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear cache. - * - * This method should only be used on the valid instance. - * - * @param err Error. - */ - void Clear(IgniteError& err) - { - impl.Get()->Clear(err); - } - - /** - * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * This method should only be used on the valid instance. - * - * @param key Key to clear. - */ - void Clear(const K& key) - { - IgniteError err; - - Clear(key, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * This method should only be used on the valid instance. - * - * @param key Key to clear. - * @param err Error. - */ - void Clear(const K& key, IgniteError& err) - { - impl::In1Operation op(key); - - impl.Get()->Clear(op, err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * This method should only be used on the valid instance. - * - * @param keys Keys to clear. - */ - void ClearAll(const std::set& keys) - { - IgniteError err; - - ClearAll(keys, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * This method should only be used on the valid instance. - * - * @param keys Keys to clear. - * @param err Error. - */ - void ClearAll(const std::set& keys, IgniteError& err) - { - impl::InSetOperation op(keys); - - impl.Get()->ClearAll(op, err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * This method should only be used on the valid instance. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - */ - template - void ClearAll(Iter begin, Iter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - impl.Get()->ClearAll(op, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * @note This operation is local as it merely clears an entry from local cache, it does not - * remove entries from remote caches. - * - * This method should only be used on the valid instance. - * - * @param key Key to clear. - */ - void LocalClear(const K& key) - { - IgniteError err; - - LocalClear(key, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * @note This operation is local as it merely clears an entry from local cache, it does not - * remove entries from remote caches. - * - * This method should only be used on the valid instance. - * - * @param key Key to clear. - * @param err Error. - */ - void LocalClear(const K& key, IgniteError& err) - { - impl::In1Operation op(key); - - impl.Get()->LocalClear(op, err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * @note This operation is local as it merely clears entries from local cache, it does not - * remove entries from remote caches. - * - * This method should only be used on the valid instance. - * - * @param keys Keys to clear. - */ - void LocalClearAll(const std::set& keys) - { - IgniteError err; - - LocalClearAll(keys, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * @note This operation is local as it merely clears entries from local cache, it does not - * remove entries from remote caches. - * - * This method should only be used on the valid instance. - * - * @param keys Keys to clear. - * @param err Error. - */ - void LocalClearAll(const std::set& keys, IgniteError& err) - { - impl::InSetOperation op(keys); - - impl.Get()->LocalClearAll(op, err); - } - - /** - * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters. - * Entry is cleared only if it is not currently locked, and is not participating in a transaction. - * - * @note This operation is local as it merely clears entries from local cache, it does not - * remove entries from remote caches. - * - * This method should only be used on the valid instance. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - */ - template - void LocalClearAll(Iter begin, Iter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - impl.Get()->LocalClearAll(op, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Removes given key mapping from cache. If cache previously contained value for the given key, - * then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be - * loaded from the primary node, which in its turn may load the value from the disk-based swap - * storage, and consecutively, if it's not in swap, from the underlying persistent storage. - * If the returned value is not needed, method removex() should always be used instead of this - * one to avoid the overhead associated with returning of the previous value. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key whose mapping is to be removed from cache. - * @return False if there was no matching key. - */ - bool Remove(const K& key) - { - IgniteError err; - - bool res = Remove(key, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Removes given key mapping from cache. If cache previously contained value for the given key, - * then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be - * loaded from the primary node, which in its turn may load the value from the disk-based swap - * storage, and consecutively, if it's not in swap, from the underlying persistent storage. - * If the returned value is not needed, method removex() should always be used instead of this - * one to avoid the overhead associated with returning of the previous value. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key whose mapping is to be removed from cache. - * @param err Error. - * @return False if there was no matching key. - */ - bool Remove(const K& key, IgniteError& err) - { - impl::In1Operation op(key); - - return impl.Get()->Remove(op, err); - } - - /** - * Removes given key mapping from cache if one exists and value is equal to the passed in value. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key whose mapping is to be removed from cache. - * @param val Value to match against currently cached value. - * @return True if entry was removed, false otherwise. - */ - bool Remove(const K& key, const V& val) - { - IgniteError err; - - bool res = Remove(key, val, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Removes given key mapping from cache if one exists and value is equal to the passed in value. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param key Key whose mapping is to be removed from cache. - * @param val Value to match against currently cached value. - * @param err Error. - * @return True if entry was removed, false otherwise. - */ - bool Remove(const K& key, const V& val, IgniteError& err) - { - impl::In2Operation op(key, val); - - return impl.Get()->RemoveIfEqual(op, err); - } - - /** - * Removes given key mappings from cache. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param keys Keys whose mappings are to be removed from cache. - */ - void RemoveAll(const std::set& keys) - { - IgniteError err; - - RemoveAll(keys, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Removes given key mappings from cache. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param keys Keys whose mappings are to be removed from cache. - * @param err Error. - */ - void RemoveAll(const std::set& keys, IgniteError& err) - { - impl::InSetOperation op(keys); - - impl.Get()->RemoveAll(op, err); - } - - /** - * Removes given key mappings from cache. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * Keys are locked in the order of iteration. It is caller's responsibility to make sure keys always follow - * same order. If that is not observed, calling this method in parallel will lead to deadlock. - * - * @param begin Iterator pointing to the beggining of the key sequence. - * @param end Iterator pointing to the end of the key sequence. - */ - template - void RemoveAll(Iter begin, Iter end) - { - IgniteError err; - - impl::InIterOperation op(begin, end); - - impl.Get()->RemoveAll(op, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Removes all mappings from cache. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - */ - void RemoveAll() - { - IgniteError err; - - RemoveAll(err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Removes all mappings from cache. - * If write-through is enabled, the value will be removed from store. - * This method is transactional and will enlist the entry into ongoing transaction if there is one. - * - * This method should only be used on the valid instance. - * - * @param err Error. - */ - void RemoveAll(IgniteError& err) - { - return impl.Get()->RemoveAll(err); - } - - /** - * Gets the number of all entries cached on this node. - * - * This method should only be used on the valid instance. - * - * @return Cache size on this node. - */ - int32_t LocalSize() - { - return LocalSize(CachePeekMode::ALL); - } - - /** - * Gets the number of all entries cached on this node. - * - * This method should only be used on the valid instance. - * - * @param err Error. - * @return Cache size on this node. - */ - int32_t LocalSize(IgniteError& err) - { - return LocalSize(CachePeekMode::ALL, err); - } - - /** - * Gets the number of all entries cached on this node. - * - * This method should only be used on the valid instance. - * - * @param peekModes Peek modes. - * @return Cache size on this node. - */ - int32_t LocalSize(int32_t peekModes) - { - IgniteError err; - - int32_t res = LocalSize(peekModes, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Gets the number of all entries cached on this node. - * - * This method should only be used on the valid instance. - * - * @param peekModes Peek modes. - * @param err Error. - * @return Cache size on this node. - */ - int32_t LocalSize(int32_t peekModes, IgniteError& err) - { - return impl.Get()->Size(peekModes, true, err); - } - - /** - * Gets the number of all entries cached across all nodes. - * @note this operation is distributed and will query all participating nodes for their cache sizes. - * - * This method should only be used on the valid instance. - * - * @return Cache size across all nodes. - */ - int32_t Size() - { - return Size(ignite::odbc::cache::CachePeekMode::ALL); - } - - /** - * Gets the number of all entries cached across all nodes. - * @note This operation is distributed and will query all participating nodes for their cache sizes. - * - * This method should only be used on the valid instance. - * - * @param err Error. - * @return Cache size across all nodes. - */ - int32_t Size(IgniteError& err) - { - return Size(ignite::odbc::cache::CachePeekMode::ALL, err); - } - - /** - * Gets the number of all entries cached across all nodes. - * @note This operation is distributed and will query all participating nodes for their cache sizes. - * - * This method should only be used on the valid instance. - * - * @param peekModes Peek modes. - * @return Cache size across all nodes. - */ - int32_t Size(int32_t peekModes) - { - IgniteError err; - - int32_t res = Size(peekModes, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Gets the number of all entries cached across all nodes. - * @note This operation is distributed and will query all participating nodes for their cache sizes. - * - * This method should only be used on the valid instance. - * - * @param peekModes Peek modes. - * @param err Error. - * @return Cache size across all nodes. - */ - int32_t Size(int32_t peekModes, IgniteError& err) - { - return impl.Get()->Size(peekModes, false, err); - } - - /** - * Perform SQL query. - * @deprecated Will be removed in future releases. Use SqlFieldsQuery instead. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @return Query cursor. - */ - query::QueryCursor Query(const query::SqlQuery& qry) - { - IgniteError err; - - query::QueryCursor res = Query(qry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Perform SQL query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursor Query(const query::SqlQuery& qry, IgniteError& err) - { - impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySql(qry, err); - - return query::QueryCursor(cursorImpl); - } - - /** - * Perform text query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @return Query cursor. - */ - query::QueryCursor Query(const query::TextQuery& qry) - { - IgniteError err; - - query::QueryCursor res = Query(qry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Perform text query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursor Query(const query::TextQuery& qry, IgniteError& err) - { - impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryText(qry, err); - - return query::QueryCursor(cursorImpl); - } - - /** - * Perform scan query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @return Query cursor. - */ - query::QueryCursor Query(const query::ScanQuery& qry) - { - IgniteError err; - - query::QueryCursor res = Query(qry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Perform scan query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursor Query(const query::ScanQuery& qry, IgniteError& err) - { - impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QueryScan(qry, err); - - return query::QueryCursor(cursorImpl); - } - - /** - * Perform sql fields query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @return Query cursor. - */ - query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry) - { - IgniteError err; - - query::QueryFieldsCursor res = Query(qry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Perform sql fields query. - * - * This method should only be used on the valid instance. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry, IgniteError& err) - { - impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySqlFields(qry, err); - - return query::QueryFieldsCursor(cursorImpl); - } - - /** - * Invokes an CacheEntryProcessor against the MutableCacheEntry - * specified by the provided key. If an entry does not exist for the - * specified key, an attempt is made to load it (if a loader is - * configured) or a surrogate entry, consisting of the key with a - * null value is used instead. - * - * Return value, processor and argument classes should all be - * default-constructable, copy-constructable and assignable. Also, - * BinaryType class template should be specialized for every custom - * class. - * - * Processor class should be registered as a cache entry processor - * using IgniteBinding::RegisterCacheEntryProcessor() method. You - * can declare #IgniteModuleInit() function to register your cache - * processors upon module loading. There should be at most one - * instance of such function per module. - * - * See the example below for details: - * @code{.cpp} - * IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::odbc::IgniteBindingContext& context) - * { - * IgniteBinding binding = context.GetBinding(); - * - * binding.RegisterCacheEntryProcessor(); - * binding.RegisterCacheEntryProcessor(); - * // ... - * binding.RegisterCacheEntryProcessor(); - * } - * @endcode - * - * Additionally, processor class should be derived from the - * ignite::odbc::cacheEntryProcessor class. - * - * @throw IgniteError on fail. - * - * @param key The key. - * @param processor The processor. - * @param arg The argument. - * @return Result of the processing. - */ - template - R Invoke(const K& key, const P& processor, const A& arg) - { - IgniteError err; - - R res = Invoke(key, processor, arg, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Invokes an CacheEntryProcessor against the MutableCacheEntry - * specified by the provided key. If an entry does not exist for the - * specified key, an attempt is made to load it (if a loader is - * configured) or a surrogate entry, consisting of the key with a - * null value is used instead. - * - * Return value, processor and argument classes should all be - * default-constructable, copy-constructable and assignable. Also, - * BinaryType class template should be specialized for every custom - * class. - * - * Processor class should be registered as a cache entry processor - * using IgniteBinding::RegisterCacheEntryProcessor() method. You - * can declare #IgniteModuleInit() function to register your cache - * processors upon module loading. There should be at most one - * instance of such function per module. - * - * See the example below for details: - * @code{.cpp} - * IGNITE_EXPORTED_CALL void IgniteModuleInit(ignite::odbc::IgniteBindingContext& context) - * { - * IgniteBinding binding = context.GetBinding(); - * - * binding.RegisterCacheEntryProcessor(); - * binding.RegisterCacheEntryProcessor(); - * // ... - * binding.RegisterCacheEntryProcessor(); - * } - * @endcode - * - * Additionally, processor class should be derived from the - * ignite::odbc::cacheEntryProcessor class. - * - * Sets err param which should be checked for the operation result. - * - * @param key The key. - * @param processor The processor. - * @param arg The argument. - * @param err Error. - * @return Result of the processing. Default-constructed value on - * error. - */ - template - R Invoke(const K& key, const P& processor, const A& arg, IgniteError& err) - { - typedef impl::cache::CacheEntryProcessorHolder ProcessorHolder; - - R res; - ProcessorHolder procHolder(processor, arg); - - impl::InCacheInvokeOperation inOp(key, procHolder); - impl::Out1Operation outOp(res); - - impl.Get()->Invoke(inOp, outOp, err); - - return res; - } - - /** - * Invokes an instance of Java class CacheEntryProcessor against the - * entry specified by the provided key. If an entry does not exist - * for the specified key, an attempt is made to load it (if a loader - * is configured) or a surrogate entry, consisting of the key with a - * null value is used instead. - * - * If task for given name has not been deployed yet, then - * @c processorName will be used as task class name to auto-deploy - * the task. - * - * Return value and argument classes should all be - * default-constructable, copy-constructable and assignable. Also, - * BinaryType class template should be specialized for every custom - * class. - * - * For additional information on CacheEntryProcessor class and - * details of its invocation refer to Java API documentation for - * method org.apache.ignite.IgniteCache#invoke(...). - * - * @throw IgniteError on fail. - * - * @param key The key. - * @param arg The argument. - * @return Result of the processing. - */ - template - R InvokeJava(const K& key, const std::string& processorName, const A& arg) - { - IgniteError err; - - R res = InvokeJava(key, processorName, arg, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Invokes an instance of Java class CacheEntryProcessor against the - * entry specified by the provided key. If an entry does not exist - * for the specified key, an attempt is made to load it (if a loader - * is configured) or a surrogate entry, consisting of the key with a - * null value is used instead. - * - * If task for given name has not been deployed yet, then - * @c processorName will be used as task class name to auto-deploy - * the task. - * - * Return value and argument classes should all be - * default-constructable, copy-constructable and assignable. Also, - * BinaryType class template should be specialized for every custom - * class. - * - * For additional information on CacheEntryProcessor class and - * details of its invocation refer to Java API documentation for - * method org.apache.ignite.IgniteCache#invoke(...). - * - * @throw IgniteError on fail. - * - * @param key The key. - * @param arg The argument. - * @return Result of the processing. - */ - template - R InvokeJava(const K& key, const std::string& processorName, const A& arg, IgniteError& err) - { - R res; - - impl::In3Operation inOp(processorName, key, arg); - impl::Out1Operation outOp(res); - - impl.Get()->InvokeJava(inOp, outOp, err); - - return res; - } - - /** - * Start continuous query execution. - * - * @param qry Continuous query. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandle QueryContinuous( - const query::continuous::ContinuousQuery& qry) - { - IgniteError err; - - query::continuous::ContinuousQueryHandle res = QueryContinuous(qry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Start continuous query execution. - * - * @param qry Continuous query. - * @param err Error. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandle QueryContinuous( - const query::continuous::ContinuousQuery& qry, IgniteError& err) - { - using namespace impl::cache::query::continuous; - using namespace common::concurrent; - - const SharedPointer >& qryImpl = qry.impl; - - if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener()) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Event listener is not set for ContinuousQuery instance"); - - return query::continuous::ContinuousQueryHandle(); - } - - ContinuousQueryHandleImpl* cqImpl = impl.Get()->QueryContinuous(qryImpl, err); - - return query::continuous::ContinuousQueryHandle(cqImpl); - } - - /** - * Start continuous query execution with the initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query to be executed. - * @return Continuous query handle. - */ - template - query::continuous::ContinuousQueryHandle QueryContinuous( - const query::continuous::ContinuousQuery& qry, - const Q& initialQry) - { - IgniteError err; - - query::continuous::ContinuousQueryHandle res = QueryContinuous(qry, initialQry, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Start continuous query execution with the initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query to be executed. - * @param err Error. - * @return Continuous query handle. - */ - template - query::continuous::ContinuousQueryHandle QueryContinuous( - const query::continuous::ContinuousQuery& qry, - const Q& initialQry, IgniteError& err) - { - using namespace impl::cache::query::continuous; - using namespace common::concurrent; - - const SharedPointer >& qryImpl = qry.impl; - - if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener()) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Event listener is not set for ContinuousQuery instance"); - - return query::continuous::ContinuousQueryHandle(); - } - - ContinuousQueryHandleImpl* cqImpl = impl.Get()->QueryContinuous(qryImpl, initialQry, err); - - return query::continuous::ContinuousQueryHandle(cqImpl); - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - /** - * Executes LocalLoadCache on all cache nodes. - */ - void LoadCache() - { - IgniteError err; - - impl.Get()->LoadCache(err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Loads state from the underlying persistent storage. - * - * This method is not transactional and may end up loading a stale value into - * cache if another thread has updated the value immediately after it has been - * loaded. It is mostly useful when pre-loading the cache from underlying - * data store before start, or for read-only caches. - */ - void LocalLoadCache() - { - IgniteError err; - - impl.Get()->LocalLoadCache(err); - - IgniteError::ThrowIfNeeded(err); - } - - private: - /** Implementation delegate. */ - common::concurrent::SharedPointer impl; - }; - } +namespace ignite { +namespace odbc { +namespace cache { +/** + * Main entry point for all Data Grid APIs. + * + * Both key and value types should be default-constructable, + * copy-constructable and assignable. Also BinaryType class + * template should be specialized for both types. + * + * This class is implemented as a reference to an implementation so copying + * of this class instance will only create another reference to the same + * underlying object. Underlying object will be released automatically once all + * the instances are destructed. + * + * @tparam K Cache key type. + * @tparam V Cache value type. + */ +template < typename K, typename V > +class IGNITE_IMPORT_EXPORT Cache { + public: + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + Cache(impl::cache::CacheImpl* impl) : impl(impl) { + // No-op. + } + + /** + * Get name of this cache (null for default cache). + * + * This method should only be used on the valid instance. + * + * @return Name of this cache (null for default cache). + */ + const char* GetName() const { + return impl.Get()->GetName(); + } + + /** + * Checks whether this cache contains no key-value mappings. + * Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0. + * + * This method should only be used on the valid instance. + * + * @return True if cache is empty. + */ + bool IsEmpty() { + IgniteError err; + + bool res = IsEmpty(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Checks whether this cache contains no key-value mappings. + * Semantically equals to Cache.Size(CachePeekMode::PRIMARY) == 0. + * + * This method should only be used on the valid instance. + * + * @param err Error. + * @return True if cache is empty. + */ + bool IsEmpty(IgniteError& err) { + return Size(err) == 0; + } + + /** + * Check if cache contains mapping for this key. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @return True if cache contains mapping for this key. + */ + bool ContainsKey(const K& key) { + IgniteError err; + + bool res = ContainsKey(key, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check if cache contains mapping for this key. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @param err Error. + * @return True if cache contains mapping for this key. + */ + bool ContainsKey(const K& key, IgniteError& err) { + impl::In1Operation< K > op(key); + + return impl.Get()->ContainsKey(op, err); + } + + /** + * Check if cache contains mapping for these keys. + * + * This method should only be used on the valid instance. + * + * @param keys Keys. + * @return True if cache contains mapping for all these keys. + */ + bool ContainsKeys(const std::set< K >& keys) { + IgniteError err; + + bool res = ContainsKeys(keys, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check if cache contains mapping for these keys. + * + * This method should only be used on the valid instance. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + * @return True if cache contains mapping for all these keys. + */ + template < typename InputIter > + bool ContainsKeys(InputIter begin, InputIter end) { + IgniteError err; + + impl::InIterOperation< K, V, InputIter > op(begin, end); + + bool res = impl.Get()->ContainsKeys(op, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check if cache contains mapping for these keys. + * + * This method should only be used on the valid instance. + * + * @param keys Keys. + * @param err Error. + * @return True if cache contains mapping for all these keys. + */ + bool ContainsKeys(const std::set< K >& keys, IgniteError& err) { + impl::InSetOperation< K > op(keys); + + return impl.Get()->ContainsKeys(op, err); + } + + /** + * Peeks at cached value using optional set of peek modes. This method will + * sequentially iterate over given peek modes, and try to peek at value using + * each peek mode. Once a non-null value is found, it will be immediately + * returned. This method does not participate in any transactions, however, it + * may peek at transactional value depending on the peek modes used. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @param peekModes Peek modes. + * @return Value. + */ + V LocalPeek(const K& key, int32_t peekModes) { + IgniteError err; + + V res = LocalPeek(key, peekModes, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Peeks at cached value using optional set of peek modes. This method will + * sequentially iterate over given peek modes, and try to peek at value using + * each peek mode. Once a non-null value is found, it will be immediately + * returned. This method does not participate in any transactions, however, it + * may peek at transactional value depending on the peek modes used. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @param peekModes Peek modes. + * @param err Error. + * @return Value. + */ + V LocalPeek(const K& key, int32_t peekModes, IgniteError& err) { + V val; + + impl::InCacheLocalPeekOperation< K > inOp(key, peekModes); + impl::Out1Operation< V > outOp(val); + + impl.Get()->LocalPeek(inOp, outOp, err); + + return val; + } + + /** + * Retrieves value mapped to the specified key from cache. + * If the value is not present in cache, then it will be looked up from swap + * storage. If it's not present in swap, or if swap is disabled, and if + * read-through is allowed, value will be loaded from persistent store. This + * method is transactional and will enlist the entry into ongoing transaction + * if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @return Value. + */ + V Get(const K& key) { + IgniteError err; + + V res = Get(key, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Retrieves value mapped to the specified key from cache. + * If the value is not present in cache, then it will be looked up from swap + * storage. If it's not present in swap, or if swap is disabled, and if + * read-through is allowed, value will be loaded from persistent store. This + * method is transactional and will enlist the entry into ongoing transaction + * if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key. + * @param err Error. + * @return Value. + */ + V Get(const K& key, IgniteError& err) { + V val; + impl::In1Operation< K > inOp(key); + impl::Out1Operation< V > outOp(val); + + impl.Get()->Get(inOp, outOp, err); + + return val; + } + + /** + * Retrieves values mapped to the specified keys from cache. + * If some value is not present in cache, then it will be looked up from swap + * storage. If it's not present in swap, or if swap is disabled, and if + * read-through is allowed, value will be loaded from persistent store. This + * method is transactional and will enlist the entry into ongoing transaction + * if there is one. + * + * This method should only be used on the valid instance. + * + * @param keys Keys. + * @return Map of key-value pairs. + */ + std::map< K, V > GetAll(const std::set< K >& keys) { + IgniteError err; + + std::map< K, V > res = GetAll(keys, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Retrieves values mapped to the specified keys from cache. + * If some value is not present in cache, then it will be looked up from swap + * storage. If it's not present in swap, or if swap is disabled, and if + * read-through is allowed, value will be loaded from persistent store. This + * method is transactional and will enlist the entry into ongoing transaction + * if there is one. + * + * This method should only be used on the valid instance. + * + * @param keys Keys. + * @param err Error. + * @return Map of key-value pairs. + */ + std::map< K, V > GetAll(const std::set< K >& keys, IgniteError& err) { + std::map< K, V > res; + + impl::InSetOperation< K > inOp(keys); + impl::OutMapOperation< K, V > outOp(res); + + impl.Get()->GetAll(inOp, outOp, err); + + return res; + } + + /** + * Retrieves values mapped to the specified keys from cache. + * If some value is not present in cache, then it will be looked up from swap + * storage. If it's not present in swap, or if swap is disabled, and if + * read-through is allowed, value will be loaded from persistent store. This + * method is transactional and will enlist the entry into ongoing transaction + * if there is one. + * + * This method should only be used on the valid instance. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + * @param dst Output iterator. Should dereference to std::pair or CacheEntry. + */ + template < typename InIter, typename OutIter > + void GetAll(InIter begin, InIter end, OutIter dst) { + IgniteError err; + + impl::InIterOperation< K, V, InIter > inOp(begin, end); + impl::OutMapIterOperation< K, V, OutIter > outOp(dst); + + impl.Get()->GetAll(inOp, outOp, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Associates the specified value with the specified key in the cache. + * If the cache previously contained a mapping for the key, + * the old value is replaced by the specified value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + */ + void Put(const K& key, const V& val) { + IgniteError err; + + Put(key, val, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Associates the specified value with the specified key in the cache. + * If the cache previously contained a mapping for the key, + * the old value is replaced by the specified value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @param err Error. + */ + void Put(const K& key, const V& val, IgniteError& err) { + impl::In2Operation< K, V > op(key, val); + + impl.Get()->Put(op, err); + } + + /** + * Stores given key-value pairs in cache. + * If write-through is enabled, the stored values will be persisted to store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param vals Key-value pairs to store in cache. + */ + void PutAll(const std::map< K, V >& vals) { + IgniteError err; + + PutAll(vals, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Stores given key-value pairs in cache. + * If write-through is enabled, the stored values will be persisted to store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param vals Key-value pairs to store in cache. + * @param err Error. + */ + void PutAll(const std::map< K, V >& vals, IgniteError& err) { + impl::InMapOperation< K, V > op(vals); + + impl.Get()->PutAll(op, err); + } + + /** + * Stores given key-value pairs in cache. + * If write-through is enabled, the stored values will be persisted to store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * Keys are locked in the order of iteration. It is caller's responsibility to + * make sure keys always follow same order. If that is not observed, calling + * this method in parallel will lead to deadlock. + * + * @param begin Iterator pointing to the beggining of the key-value pair + * sequence. + * @param end Iterator pointing to the end of the key-value pair sequence. + */ + template < typename Iter > + void PutAll(Iter begin, Iter end) { + IgniteError err; + + impl::InIterOperation< K, V, Iter > op(begin, end); + + impl.Get()->PutAll(op, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Associates the specified value with the specified key in this cache, + * returning an existing value if one existed. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @return The value associated with the key at the start of the + * operation or null if none was associated. + */ + V GetAndPut(const K& key, const V& val) { + IgniteError err; + + V res = GetAndPut(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Associates the specified value with the specified key in this cache, + * returning an existing value if one existed. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @param err Error. + * @return The value associated with the key at the start of the + * operation or null if none was associated. + */ + V GetAndPut(const K& key, const V& val, IgniteError& err) { + V oldVal; + + impl::In2Operation< K, V > inOp(key, val); + impl::Out1Operation< V > outOp(oldVal); + + impl.Get()->GetAndPut(inOp, outOp, err); + + return oldVal; + } + + /** + * Atomically replaces the value for a given key if and only if there is a + * value currently mapped by the key. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @return The previous value associated with the specified key, or null if + * there was no mapping for the key. + */ + V GetAndReplace(const K& key, const V& val) { + IgniteError err; + + V res = GetAndReplace(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Atomically replaces the value for a given key if and only if there is a + * value currently mapped by the key. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @param err Error. + * @return The previous value associated with the specified key, or null if + * there was no mapping for the key. + */ + V GetAndReplace(const K& key, const V& val, IgniteError& err) { + V oldVal; + + impl::In2Operation< K, V > inOp(key, val); + impl::Out1Operation< V > outOp(oldVal); + + impl.Get()->GetAndReplace(inOp, outOp, err); + + return oldVal; + } + + /** + * Atomically removes the entry for a key only if currently mapped to some + * value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is associated. + * @return The value if one existed or null if no mapping existed for this + * key. + */ + V GetAndRemove(const K& key) { + IgniteError err; + + V res = GetAndRemove(key, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Atomically removes the entry for a key only if currently mapped to some + * value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is associated. + * @param err Error. + * @return The value if one existed or null if no mapping existed for this + * key. + */ + V GetAndRemove(const K& key, IgniteError& err) { + V oldVal; + + impl::In1Operation< K > inOp(key); + impl::Out1Operation< V > outOp(oldVal); + + impl.Get()->GetAndRemove(inOp, outOp, err); + + return oldVal; + } + + /** + * Atomically associates the specified key with the given value if it is not + * already associated with a value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @return True if a value was set. + */ + bool PutIfAbsent(const K& key, const V& val) { + IgniteError err; + + bool res = PutIfAbsent(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Atomically associates the specified key with the given value if it is not + * already associated with a value. + * + * This method should only be used on the valid instance. + * + * @param key Key with which the specified value is to be associated. + * @param val Value to be associated with the specified key. + * @param err Error. + * @return True if a value was set. + */ + bool PutIfAbsent(const K& key, const V& val, IgniteError& err) { + impl::In2Operation< K, V > op(key, val); + + return impl.Get()->PutIfAbsent(op, err); + } + + /** + * Stores given key-value pair in cache only if cache had no previous mapping + * for it. If cache previously contained value for the given key, then this + * value is returned. In case of PARTITIONED or REPLICATED caches, the value + * will be loaded from the primary node, which in its turn may load the value + * from the swap storage, and consecutively, if it's not in swap, from the + * underlying persistent storage. If the returned value is not needed, method + * putxIfAbsent() should be used instead of this one to avoid the overhead + * associated with returning of the previous value. If write-through is + * enabled, the stored value will be persisted to store. This method is + * transactional and will enlist the entry into ongoing transaction if there + * is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @return Previously contained value regardless of whether put happened or + * not (null if there was no previous value). + */ + V GetAndPutIfAbsent(const K& key, const V& val) { + IgniteError err; + + V res = GetAndPutIfAbsent(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Stores given key-value pair in cache only if cache had no previous mapping + * for it. If cache previously contained value for the given key, then this + * value is returned. In case of PARTITIONED or REPLICATED caches, the value + * will be loaded from the primary node, which in its turn may load the value + * from the swap storage, and consecutively, if it's not in swap, from the + * underlying persistent storage. If the returned value is not needed, method + * putxIfAbsent() should be used instead of this one to avoid the overhead + * associated with returning of the previous value. If write-through is + * enabled, the stored value will be persisted to store. This method is + * transactional and will enlist the entry into ongoing transaction if there + * is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @param err Error. + * @return Previously contained value regardless of whether put happened or + * not (null if there was no previous value). + */ + V GetAndPutIfAbsent(const K& key, const V& val, IgniteError& err) { + V oldVal; + + impl::In2Operation< K, V > inOp(key, val); + impl::Out1Operation< V > outOp(oldVal); + + impl.Get()->GetAndPutIfAbsent(inOp, outOp, err); + + return oldVal; + } + + /** + * Stores given key-value pair in cache only if there is a previous mapping + * for it. If cache previously contained value for the given key, then this + * value is returned. In case of PARTITIONED or REPLICATED caches, the value + * will be loaded from the primary node, which in its turn may load the value + * from the swap storage, and consecutively, if it's not in swap, rom the + * underlying persistent storage. If write-through is enabled, the stored + * value will be persisted to store. This method is transactional and will + * enlist the entry into ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @return True if the value was replaced. + */ + bool Replace(const K& key, const V& val) { + IgniteError err; + + bool res = Replace(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Stores given key-value pair in cache only if there is a previous mapping + * for it. If cache previously contained value for the given key, then this + * value is returned. In case of PARTITIONED or REPLICATED caches, the value + * will be loaded from the primary node, which in its turn may load the value + * from the swap storage, and consecutively, if it's not in swap, rom the + * underlying persistent storage. If write-through is enabled, the stored + * value will be persisted to store. This method is transactional and will + * enlist the entry into ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param val Value to be associated with the given key. + * @param err Error. + * @return True if the value was replaced. + */ + bool Replace(const K& key, const V& val, IgniteError& err) { + impl::In2Operation< K, V > op(key, val); + + return impl.Get()->Replace(op, err); + } + + /** + * Stores given key-value pair in cache only if the previous value is equal to + * the old value passed as argument. This method is transactional and will + * enlist the entry into ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param oldVal Old value to match. + * @param newVal Value to be associated with the given key. + * @return True if replace happened, false otherwise. + */ + bool Replace(const K& key, const V& oldVal, const V& newVal) { + IgniteError err; + + bool res = Replace(key, oldVal, newVal, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Stores given key-value pair in cache only if the previous value is equal to + * the old value passed as argument. This method is transactional and will + * enlist the entry into ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key to store in cache. + * @param oldVal Old value to match. + * @param newVal Value to be associated with the given key. + * @param err Error. + * @return True if replace happened, false otherwise. + */ + bool Replace(const K& key, const V& oldVal, const V& newVal, + IgniteError& err) { + impl::In3Operation< K, V, V > op(key, oldVal, newVal); + + return impl.Get()->ReplaceIfEqual(op, err); + } + + /** + * Attempts to evict all entries associated with keys. + * + * @note Entry will be evicted only if it's not used (not + * participating in any locks or transactions). + * + * This method should only be used on the valid instance. + * + * @param keys Keys to evict from cache. + */ + void LocalEvict(const std::set< K >& keys) { + IgniteError err; + + LocalEvict(keys, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Attempts to evict all entries associated with keys. + * + * @note Entry will be evicted only if it's not used (not + * participating in any locks or transactions). + * + * This method should only be used on the valid instance. + * + * @param keys Keys to evict from cache. + * @param err Error. + */ + void LocalEvict(const std::set< K >& keys, IgniteError& err) { + impl::InSetOperation< K > op(keys); + + impl.Get()->LocalEvict(op, err); + } + + /** + * Attempts to evict all entries associated with keys. + * + * @note Entry will be evicted only if it's not used (not + * participating in any locks or transactions). + * + * This method should only be used on the valid instance. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + */ + template < typename Iter > + void LocalEvict(Iter begin, Iter end) { + IgniteError err; + + impl::InIterOperation< K, V, Iter > op(begin, end); + + impl.Get()->LocalEvict(op, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear cache. + * + * This method should only be used on the valid instance. + */ + void Clear() { + IgniteError err; + + Clear(err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear cache. + * + * This method should only be used on the valid instance. + * + * @param err Error. + */ + void Clear(IgniteError& err) { + impl.Get()->Clear(err); + } + + /** + * Clear entry from the cache and swap storage, without notifying listeners or + * CacheWriters. Entry is cleared only if it is not currently locked, and is + * not participating in a transaction. + * + * This method should only be used on the valid instance. + * + * @param key Key to clear. + */ + void Clear(const K& key) { + IgniteError err; + + Clear(key, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear entry from the cache and swap storage, without notifying listeners or + * CacheWriters. Entry is cleared only if it is not currently locked, and is + * not participating in a transaction. + * + * This method should only be used on the valid instance. + * + * @param key Key to clear. + * @param err Error. + */ + void Clear(const K& key, IgniteError& err) { + impl::In1Operation< K > op(key); + + impl.Get()->Clear(op, err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * This method should only be used on the valid instance. + * + * @param keys Keys to clear. + */ + void ClearAll(const std::set< K >& keys) { + IgniteError err; + + ClearAll(keys, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * This method should only be used on the valid instance. + * + * @param keys Keys to clear. + * @param err Error. + */ + void ClearAll(const std::set< K >& keys, IgniteError& err) { + impl::InSetOperation< K > op(keys); + + impl.Get()->ClearAll(op, err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * This method should only be used on the valid instance. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + */ + template < typename Iter > + void ClearAll(Iter begin, Iter end) { + IgniteError err; + + impl::InIterOperation< K, V, Iter > op(begin, end); + + impl.Get()->ClearAll(op, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear entry from the cache and swap storage, without notifying listeners or + * CacheWriters. Entry is cleared only if it is not currently locked, and is + * not participating in a transaction. + * + * @note This operation is local as it merely clears an entry from local + * cache, it does not remove entries from remote caches. + * + * This method should only be used on the valid instance. + * + * @param key Key to clear. + */ + void LocalClear(const K& key) { + IgniteError err; + + LocalClear(key, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear entry from the cache and swap storage, without notifying listeners or + * CacheWriters. Entry is cleared only if it is not currently locked, and is + * not participating in a transaction. + * + * @note This operation is local as it merely clears an entry from local + * cache, it does not remove entries from remote caches. + * + * This method should only be used on the valid instance. + * + * @param key Key to clear. + * @param err Error. + */ + void LocalClear(const K& key, IgniteError& err) { + impl::In1Operation< K > op(key); + + impl.Get()->LocalClear(op, err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * @note This operation is local as it merely clears entries from local cache, + * it does not remove entries from remote caches. + * + * This method should only be used on the valid instance. + * + * @param keys Keys to clear. + */ + void LocalClearAll(const std::set< K >& keys) { + IgniteError err; + + LocalClearAll(keys, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * @note This operation is local as it merely clears entries from local cache, + * it does not remove entries from remote caches. + * + * This method should only be used on the valid instance. + * + * @param keys Keys to clear. + * @param err Error. + */ + void LocalClearAll(const std::set< K >& keys, IgniteError& err) { + impl::InSetOperation< K > op(keys); + + impl.Get()->LocalClearAll(op, err); + } + + /** + * Clear entries from the cache and swap storage, without notifying listeners + * or CacheWriters. Entry is cleared only if it is not currently locked, and + * is not participating in a transaction. + * + * @note This operation is local as it merely clears entries from local cache, + * it does not remove entries from remote caches. + * + * This method should only be used on the valid instance. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + */ + template < typename Iter > + void LocalClearAll(Iter begin, Iter end) { + IgniteError err; + + impl::InIterOperation< K, V, Iter > op(begin, end); + + impl.Get()->LocalClearAll(op, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Removes given key mapping from cache. If cache previously contained value + * for the given key, then this value is returned. In case of PARTITIONED or + * REPLICATED caches, the value will be loaded from the primary node, which in + * its turn may load the value from the disk-based swap storage, and + * consecutively, if it's not in swap, from the underlying persistent storage. + * If the returned value is not needed, method removex() should always be used + * instead of this one to avoid the overhead associated with returning of the + * previous value. If write-through is enabled, the value will be removed from + * store. This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key whose mapping is to be removed from cache. + * @return False if there was no matching key. + */ + bool Remove(const K& key) { + IgniteError err; + + bool res = Remove(key, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Removes given key mapping from cache. If cache previously contained value + * for the given key, then this value is returned. In case of PARTITIONED or + * REPLICATED caches, the value will be loaded from the primary node, which in + * its turn may load the value from the disk-based swap storage, and + * consecutively, if it's not in swap, from the underlying persistent storage. + * If the returned value is not needed, method removex() should always be used + * instead of this one to avoid the overhead associated with returning of the + * previous value. If write-through is enabled, the value will be removed from + * store. This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key whose mapping is to be removed from cache. + * @param err Error. + * @return False if there was no matching key. + */ + bool Remove(const K& key, IgniteError& err) { + impl::In1Operation< K > op(key); + + return impl.Get()->Remove(op, err); + } + + /** + * Removes given key mapping from cache if one exists and value is equal to + * the passed in value. If write-through is enabled, the value will be removed + * from store. This method is transactional and will enlist the entry into + * ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key whose mapping is to be removed from cache. + * @param val Value to match against currently cached value. + * @return True if entry was removed, false otherwise. + */ + bool Remove(const K& key, const V& val) { + IgniteError err; + + bool res = Remove(key, val, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Removes given key mapping from cache if one exists and value is equal to + * the passed in value. If write-through is enabled, the value will be removed + * from store. This method is transactional and will enlist the entry into + * ongoing transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param key Key whose mapping is to be removed from cache. + * @param val Value to match against currently cached value. + * @param err Error. + * @return True if entry was removed, false otherwise. + */ + bool Remove(const K& key, const V& val, IgniteError& err) { + impl::In2Operation< K, V > op(key, val); + + return impl.Get()->RemoveIfEqual(op, err); + } + + /** + * Removes given key mappings from cache. + * If write-through is enabled, the value will be removed from store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param keys Keys whose mappings are to be removed from cache. + */ + void RemoveAll(const std::set< K >& keys) { + IgniteError err; + + RemoveAll(keys, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Removes given key mappings from cache. + * If write-through is enabled, the value will be removed from store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param keys Keys whose mappings are to be removed from cache. + * @param err Error. + */ + void RemoveAll(const std::set< K >& keys, IgniteError& err) { + impl::InSetOperation< K > op(keys); + + impl.Get()->RemoveAll(op, err); + } + + /** + * Removes given key mappings from cache. + * If write-through is enabled, the value will be removed from store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * Keys are locked in the order of iteration. It is caller's responsibility to + * make sure keys always follow same order. If that is not observed, calling + * this method in parallel will lead to deadlock. + * + * @param begin Iterator pointing to the beggining of the key sequence. + * @param end Iterator pointing to the end of the key sequence. + */ + template < typename Iter > + void RemoveAll(Iter begin, Iter end) { + IgniteError err; + + impl::InIterOperation< K, V, Iter > op(begin, end); + + impl.Get()->RemoveAll(op, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Removes all mappings from cache. + * If write-through is enabled, the value will be removed from store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + */ + void RemoveAll() { + IgniteError err; + + RemoveAll(err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Removes all mappings from cache. + * If write-through is enabled, the value will be removed from store. + * This method is transactional and will enlist the entry into ongoing + * transaction if there is one. + * + * This method should only be used on the valid instance. + * + * @param err Error. + */ + void RemoveAll(IgniteError& err) { + return impl.Get()->RemoveAll(err); + } + + /** + * Gets the number of all entries cached on this node. + * + * This method should only be used on the valid instance. + * + * @return Cache size on this node. + */ + int32_t LocalSize() { + return LocalSize(CachePeekMode::ALL); + } + + /** + * Gets the number of all entries cached on this node. + * + * This method should only be used on the valid instance. + * + * @param err Error. + * @return Cache size on this node. + */ + int32_t LocalSize(IgniteError& err) { + return LocalSize(CachePeekMode::ALL, err); + } + + /** + * Gets the number of all entries cached on this node. + * + * This method should only be used on the valid instance. + * + * @param peekModes Peek modes. + * @return Cache size on this node. + */ + int32_t LocalSize(int32_t peekModes) { + IgniteError err; + + int32_t res = LocalSize(peekModes, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Gets the number of all entries cached on this node. + * + * This method should only be used on the valid instance. + * + * @param peekModes Peek modes. + * @param err Error. + * @return Cache size on this node. + */ + int32_t LocalSize(int32_t peekModes, IgniteError& err) { + return impl.Get()->Size(peekModes, true, err); + } + + /** + * Gets the number of all entries cached across all nodes. + * @note this operation is distributed and will query all participating nodes + * for their cache sizes. + * + * This method should only be used on the valid instance. + * + * @return Cache size across all nodes. + */ + int32_t Size() { + return Size(ignite::odbc::cache::CachePeekMode::ALL); + } + + /** + * Gets the number of all entries cached across all nodes. + * @note This operation is distributed and will query all participating nodes + * for their cache sizes. + * + * This method should only be used on the valid instance. + * + * @param err Error. + * @return Cache size across all nodes. + */ + int32_t Size(IgniteError& err) { + return Size(ignite::odbc::cache::CachePeekMode::ALL, err); + } + + /** + * Gets the number of all entries cached across all nodes. + * @note This operation is distributed and will query all participating nodes + * for their cache sizes. + * + * This method should only be used on the valid instance. + * + * @param peekModes Peek modes. + * @return Cache size across all nodes. + */ + int32_t Size(int32_t peekModes) { + IgniteError err; + + int32_t res = Size(peekModes, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Gets the number of all entries cached across all nodes. + * @note This operation is distributed and will query all participating nodes + * for their cache sizes. + * + * This method should only be used on the valid instance. + * + * @param peekModes Peek modes. + * @param err Error. + * @return Cache size across all nodes. + */ + int32_t Size(int32_t peekModes, IgniteError& err) { + return impl.Get()->Size(peekModes, false, err); + } + + /** + * Perform SQL query. + * @deprecated Will be removed in future releases. Use SqlFieldsQuery instead. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::SqlQuery& qry) { + IgniteError err; + + query::QueryCursor< K, V > res = Query(qry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Perform SQL query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::SqlQuery& qry, + IgniteError& err) { + impl::cache::query::QueryCursorImpl* cursorImpl = + impl.Get()->QuerySql(qry, err); + + return query::QueryCursor< K, V >(cursorImpl); + } + + /** + * Perform text query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::TextQuery& qry) { + IgniteError err; + + query::QueryCursor< K, V > res = Query(qry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Perform text query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::TextQuery& qry, + IgniteError& err) { + impl::cache::query::QueryCursorImpl* cursorImpl = + impl.Get()->QueryText(qry, err); + + return query::QueryCursor< K, V >(cursorImpl); + } + + /** + * Perform scan query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::ScanQuery& qry) { + IgniteError err; + + query::QueryCursor< K, V > res = Query(qry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Perform scan query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursor< K, V > Query(const query::ScanQuery& qry, + IgniteError& err) { + impl::cache::query::QueryCursorImpl* cursorImpl = + impl.Get()->QueryScan(qry, err); + + return query::QueryCursor< K, V >(cursorImpl); + } + + /** + * Perform sql fields query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @return Query cursor. + */ + query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry) { + IgniteError err; + + query::QueryFieldsCursor res = Query(qry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Perform sql fields query. + * + * This method should only be used on the valid instance. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry, + IgniteError& err) { + impl::cache::query::QueryCursorImpl* cursorImpl = + impl.Get()->QuerySqlFields(qry, err); + + return query::QueryFieldsCursor(cursorImpl); + } + + /** + * Invokes an CacheEntryProcessor against the MutableCacheEntry + * specified by the provided key. If an entry does not exist for the + * specified key, an attempt is made to load it (if a loader is + * configured) or a surrogate entry, consisting of the key with a + * null value is used instead. + * + * Return value, processor and argument classes should all be + * default-constructable, copy-constructable and assignable. Also, + * BinaryType class template should be specialized for every custom + * class. + * + * Processor class should be registered as a cache entry processor + * using IgniteBinding::RegisterCacheEntryProcessor() method. You + * can declare #IgniteModuleInit() function to register your cache + * processors upon module loading. There should be at most one + * instance of such function per module. + * + * See the example below for details: + * @code{.cpp} + * IGNITE_EXPORTED_CALL void + * IgniteModuleInit(ignite::odbc::IgniteBindingContext& context) + * { + * IgniteBinding binding = context.GetBinding(); + * + * binding.RegisterCacheEntryProcessor(); + * binding.RegisterCacheEntryProcessor(); + * // ... + * binding.RegisterCacheEntryProcessor(); + * } + * @endcode + * + * Additionally, processor class should be derived from the + * ignite::odbc::cacheEntryProcessor class. + * + * @throw IgniteError on fail. + * + * @param key The key. + * @param processor The processor. + * @param arg The argument. + * @return Result of the processing. + */ + template < typename R, typename P, typename A > + R Invoke(const K& key, const P& processor, const A& arg) { + IgniteError err; + + R res = Invoke< R >(key, processor, arg, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Invokes an CacheEntryProcessor against the MutableCacheEntry + * specified by the provided key. If an entry does not exist for the + * specified key, an attempt is made to load it (if a loader is + * configured) or a surrogate entry, consisting of the key with a + * null value is used instead. + * + * Return value, processor and argument classes should all be + * default-constructable, copy-constructable and assignable. Also, + * BinaryType class template should be specialized for every custom + * class. + * + * Processor class should be registered as a cache entry processor + * using IgniteBinding::RegisterCacheEntryProcessor() method. You + * can declare #IgniteModuleInit() function to register your cache + * processors upon module loading. There should be at most one + * instance of such function per module. + * + * See the example below for details: + * @code{.cpp} + * IGNITE_EXPORTED_CALL void + * IgniteModuleInit(ignite::odbc::IgniteBindingContext& context) + * { + * IgniteBinding binding = context.GetBinding(); + * + * binding.RegisterCacheEntryProcessor(); + * binding.RegisterCacheEntryProcessor(); + * // ... + * binding.RegisterCacheEntryProcessor(); + * } + * @endcode + * + * Additionally, processor class should be derived from the + * ignite::odbc::cacheEntryProcessor class. + * + * Sets err param which should be checked for the operation result. + * + * @param key The key. + * @param processor The processor. + * @param arg The argument. + * @param err Error. + * @return Result of the processing. Default-constructed value on + * error. + */ + template < typename R, typename P, typename A > + R Invoke(const K& key, const P& processor, const A& arg, IgniteError& err) { + typedef impl::cache::CacheEntryProcessorHolder< P, A > ProcessorHolder; + + R res; + ProcessorHolder procHolder(processor, arg); + + impl::InCacheInvokeOperation< K, ProcessorHolder > inOp(key, procHolder); + impl::Out1Operation< R > outOp(res); + + impl.Get()->Invoke(inOp, outOp, err); + + return res; + } + + /** + * Invokes an instance of Java class CacheEntryProcessor against the + * entry specified by the provided key. If an entry does not exist + * for the specified key, an attempt is made to load it (if a loader + * is configured) or a surrogate entry, consisting of the key with a + * null value is used instead. + * + * If task for given name has not been deployed yet, then + * @c processorName will be used as task class name to auto-deploy + * the task. + * + * Return value and argument classes should all be + * default-constructable, copy-constructable and assignable. Also, + * BinaryType class template should be specialized for every custom + * class. + * + * For additional information on CacheEntryProcessor class and + * details of its invocation refer to Java API documentation for + * method org.apache.ignite.IgniteCache#invoke(...). + * + * @throw IgniteError on fail. + * + * @param key The key. + * @param arg The argument. + * @return Result of the processing. + */ + template < typename R, typename A > + R InvokeJava(const K& key, const std::string& processorName, const A& arg) { + IgniteError err; + + R res = InvokeJava< R >(key, processorName, arg, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Invokes an instance of Java class CacheEntryProcessor against the + * entry specified by the provided key. If an entry does not exist + * for the specified key, an attempt is made to load it (if a loader + * is configured) or a surrogate entry, consisting of the key with a + * null value is used instead. + * + * If task for given name has not been deployed yet, then + * @c processorName will be used as task class name to auto-deploy + * the task. + * + * Return value and argument classes should all be + * default-constructable, copy-constructable and assignable. Also, + * BinaryType class template should be specialized for every custom + * class. + * + * For additional information on CacheEntryProcessor class and + * details of its invocation refer to Java API documentation for + * method org.apache.ignite.IgniteCache#invoke(...). + * + * @throw IgniteError on fail. + * + * @param key The key. + * @param arg The argument. + * @return Result of the processing. + */ + template < typename R, typename A > + R InvokeJava(const K& key, const std::string& processorName, const A& arg, + IgniteError& err) { + R res; + + impl::In3Operation< std::string, K, A > inOp(processorName, key, arg); + impl::Out1Operation< R > outOp(res); + + impl.Get()->InvokeJava(inOp, outOp, err); + + return res; + } + + /** + * Start continuous query execution. + * + * @param qry Continuous query. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandle< K, V > QueryContinuous( + const query::continuous::ContinuousQuery< K, V >& qry) { + IgniteError err; + + query::continuous::ContinuousQueryHandle< K, V > res = + QueryContinuous(qry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Start continuous query execution. + * + * @param qry Continuous query. + * @param err Error. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandle< K, V > QueryContinuous( + const query::continuous::ContinuousQuery< K, V >& qry, IgniteError& err) { + using namespace impl::cache::query::continuous; + using namespace common::concurrent; + + const SharedPointer< ContinuousQueryImpl< K, V > >& qryImpl = qry.impl; + + if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener()) { + err = + IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Event listener is not set for ContinuousQuery instance"); + + return query::continuous::ContinuousQueryHandle< K, V >(); } -} -#endif //_IGNITE_ODBC_CACHE_CACHE + ContinuousQueryHandleImpl* cqImpl = + impl.Get()->QueryContinuous(qryImpl, err); + + return query::continuous::ContinuousQueryHandle< K, V >(cqImpl); + } + + /** + * Start continuous query execution with the initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query to be executed. + * @return Continuous query handle. + */ + template < typename Q > + query::continuous::ContinuousQueryHandle< K, V > QueryContinuous( + const query::continuous::ContinuousQuery< K, V >& qry, + const Q& initialQry) { + IgniteError err; + + query::continuous::ContinuousQueryHandle< K, V > res = + QueryContinuous(qry, initialQry, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Start continuous query execution with the initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query to be executed. + * @param err Error. + * @return Continuous query handle. + */ + template < typename Q > + query::continuous::ContinuousQueryHandle< K, V > QueryContinuous( + const query::continuous::ContinuousQuery< K, V >& qry, + const Q& initialQry, IgniteError& err) { + using namespace impl::cache::query::continuous; + using namespace common::concurrent; + + const SharedPointer< ContinuousQueryImpl< K, V > >& qryImpl = qry.impl; + + if (!qryImpl.IsValid() || !qryImpl.Get()->HasListener()) { + err = + IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Event listener is not set for ContinuousQuery instance"); + + return query::continuous::ContinuousQueryHandle< K, V >(); + } + + ContinuousQueryHandleImpl* cqImpl = + impl.Get()->QueryContinuous(qryImpl, initialQry, err); + + return query::continuous::ContinuousQueryHandle< K, V >(cqImpl); + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + /** + * Executes LocalLoadCache on all cache nodes. + */ + void LoadCache() { + IgniteError err; + + impl.Get()->LoadCache(err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Loads state from the underlying persistent storage. + * + * This method is not transactional and may end up loading a stale value into + * cache if another thread has updated the value immediately after it has been + * loaded. It is mostly useful when pre-loading the cache from underlying + * data store before start, or for read-only caches. + */ + void LocalLoadCache() { + IgniteError err; + + impl.Get()->LocalLoadCache(err); + + IgniteError::ThrowIfNeeded(err); + } + + private: + /** Implementation delegate. */ + common::concurrent::SharedPointer< impl::cache::CacheImpl > impl; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_CACHE diff --git a/src/odbc/include/ignite/odbc/cache/cache_affinity.h b/src/odbc/include/ignite/odbc/cache/cache_affinity.h index 8289759a0..cd41e4f22 100644 --- a/src/odbc/include/ignite/odbc/cache/cache_affinity.h +++ b/src/odbc/include/ignite/odbc/cache/cache_affinity.h @@ -15,10 +15,10 @@ * limitations under the License. */ - /** - * @file - * Declares ignite::odbc::cache::CacheAffinity class. - */ +/** + * @file + * Declares ignite::odbc::cache::CacheAffinity class. + */ #ifndef _IGNITE_ODBC_CACHE_AFFINITY #define _IGNITE_ODBC_CACHE_AFFINITY @@ -27,218 +27,208 @@ #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * Provides affinity information to detect which node is primary and which nodes are backups - * for a partitioned or replicated cache. - * You can get an instance of this interface by calling Ignite.GetAffinity(cacheName) method. - * - * @tparam K Cache affinity key type. - */ - template - class IGNITE_IMPORT_EXPORT CacheAffinity - { - public: - /** - * Constructor. - * - * @param impl Pointer to cache affinity implementation. - */ - CacheAffinity(impl::cache::SP_CacheAffinityImpl impl) : - impl(impl) - { - // No-op. - } - - /** - * Get number of partitions in cache according to configured affinity function. - * - * @return Number of partitions. - */ - int32_t GetPartitions() - { - return impl.Get()->GetPartitions(); - } - - /** - * Get partition id for the given key. - * - * @param key Key to get partition id for. - * @return Partition id. - */ - int32_t GetPartition(const K& key) - { - return impl.Get()->GetPartition(key); - } - - /** - * Return true if given node is the primary node for given key. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if given node is primary node for given key. - */ - bool IsPrimary(cluster::ClusterNode node, const K& key) - { - return impl.Get()->IsPrimary(node, key); - } - - /** - * Return true if local node is one of the backup nodes for given key. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if local node is one of the backup nodes for given key. - */ - bool IsBackup(cluster::ClusterNode node, const K& key) - { - return impl.Get()->IsBackup(node, key); - } - - /** - * Returns true if local node is primary or one of the backup nodes. - * This method is essentially equivalent to calling - * "isPrimary(ClusterNode, Object) || isBackup(ClusterNode, Object))", - * however it is more efficient as it makes both checks at once. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if local node is primary or one of the backup nodes. - */ - bool IsPrimaryOrBackup(cluster::ClusterNode node, const K& key) - { - return impl.Get()->IsPrimaryOrBackup(node, key); - } - - /** - * Get partition ids for which the given cluster node has primary ownership. - * - * @param node Cluster node. - * @return Container of partition ids for which the given cluster node has primary ownership. - */ - std::vector GetPrimaryPartitions(cluster::ClusterNode node) - { - return impl.Get()->GetPrimaryPartitions(node); - } - - /** - * Get partition ids for which given cluster node has backup ownership. - * - * @param node Cluster node. - * @return Container of partition ids for which given cluster node has backup ownership. - */ - std::vector GetBackupPartitions(cluster::ClusterNode node) - { - return impl.Get()->GetBackupPartitions(node); - } - - /** - * Get partition ids for which given cluster node has any ownership (either primary or backup). - * - * @param node Cluster node. - * @return Container of partition ids for which given cluster node has any ownership (either primary or backup). - */ - std::vector GetAllPartitions(cluster::ClusterNode node) - { - return impl.Get()->GetAllPartitions(node); - } - - /** - * Map passed in key to a key which will be used for node affinity. - * - * @tparam TR Key to be used for node-to-affinity mapping type. - * - * @param key Key to map. - * @return Key to be used for node-to-affinity mapping (may be the same key as passed in). - */ - template - TR GetAffinityKey(const K& key) - { - return impl.Get()->template GetAffinityKey(key); - } - - /** - * This method provides ability to detect which keys are mapped to which nodes. - * Use it to determine which nodes are storing which keys prior to sending - * jobs that access these keys. - * - * @param keys Keys to map to nodes. - * @return Map of nodes to keys or empty map if there are no alive nodes for this cache. - */ - std::map > MapKeysToNodes(const std::vector& keys) - { - return impl.Get()->MapKeysToNodes(keys); - } - - /** - * This method provides ability to detect to which primary node the given key is mapped. - * Use it to determine which nodes are storing which keys prior to sending - * jobs that access these keys. - * - * @param key Key to map to node. - * @return Primary node for the key. - */ - cluster::ClusterNode MapKeyToNode(const K& key) - { - return impl.Get()->MapKeyToNode(key); - } - - /** - * Get primary and backup nodes for the key. - * Note that primary node is always first in the returned collection. - * - * @param key Key to map to nodes. - * @return Collection of cluster nodes. - */ - std::vector MapKeyToPrimaryAndBackups(const K& key) - { - return impl.Get()->MapKeyToPrimaryAndBackups(key); - } - - /** - * Get primary node for the given partition. - * - * @param part Partition id. - * @return Primary node for the given partition. - */ - cluster::ClusterNode MapPartitionToNode(int32_t part) - { - return impl.Get()->MapPartitionToNode(part); - } - - /** - * Get primary nodes for the given partitions. - * - * @param parts Partition ids. - * @return Mapping of given partitions to their primary nodes. - */ - std::map MapPartitionsToNodes(const std::vector& parts) - { - return impl.Get()->MapPartitionsToNodes(parts); - } - - /** - * Get primary and backup nodes for partition. - * Note that primary node is always first in the returned collection. - * - * @param part Partition to get affinity nodes for. - * @return Collection of primary and backup nodes for partition with primary node always first. - */ - std::vector MapPartitionToPrimaryAndBackups(int32_t part) - { - return impl.Get()->MapPartitionToPrimaryAndBackups(part); - } - - private: - impl::cache::SP_CacheAffinityImpl impl; - }; - } - } -} - -#endif //_IGNITE_ODBC_CACHE_AFFINITY +namespace ignite { +namespace odbc { +namespace cache { +/** + * Provides affinity information to detect which node is primary and which nodes + * are backups for a partitioned or replicated cache. You can get an instance of + * this interface by calling Ignite.GetAffinity(cacheName) method. + * + * @tparam K Cache affinity key type. + */ +template < typename K > +class IGNITE_IMPORT_EXPORT CacheAffinity { + public: + /** + * Constructor. + * + * @param impl Pointer to cache affinity implementation. + */ + CacheAffinity(impl::cache::SP_CacheAffinityImpl impl) : impl(impl) { + // No-op. + } + + /** + * Get number of partitions in cache according to configured affinity + * function. + * + * @return Number of partitions. + */ + int32_t GetPartitions() { + return impl.Get()->GetPartitions(); + } + + /** + * Get partition id for the given key. + * + * @param key Key to get partition id for. + * @return Partition id. + */ + int32_t GetPartition(const K& key) { + return impl.Get()->GetPartition(key); + } + + /** + * Return true if given node is the primary node for given key. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if given node is primary node for given key. + */ + bool IsPrimary(cluster::ClusterNode node, const K& key) { + return impl.Get()->IsPrimary(node, key); + } + + /** + * Return true if local node is one of the backup nodes for given key. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if local node is one of the backup nodes for given key. + */ + bool IsBackup(cluster::ClusterNode node, const K& key) { + return impl.Get()->IsBackup(node, key); + } + + /** + * Returns true if local node is primary or one of the backup nodes. + * This method is essentially equivalent to calling + * "isPrimary(ClusterNode, Object) || isBackup(ClusterNode, Object))", + * however it is more efficient as it makes both checks at once. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if local node is primary or one of the backup nodes. + */ + bool IsPrimaryOrBackup(cluster::ClusterNode node, const K& key) { + return impl.Get()->IsPrimaryOrBackup(node, key); + } + + /** + * Get partition ids for which the given cluster node has primary ownership. + * + * @param node Cluster node. + * @return Container of partition ids for which the given cluster node has + * primary ownership. + */ + std::vector< int32_t > GetPrimaryPartitions(cluster::ClusterNode node) { + return impl.Get()->GetPrimaryPartitions(node); + } + + /** + * Get partition ids for which given cluster node has backup ownership. + * + * @param node Cluster node. + * @return Container of partition ids for which given cluster node has backup + * ownership. + */ + std::vector< int32_t > GetBackupPartitions(cluster::ClusterNode node) { + return impl.Get()->GetBackupPartitions(node); + } + + /** + * Get partition ids for which given cluster node has any ownership (either + * primary or backup). + * + * @param node Cluster node. + * @return Container of partition ids for which given cluster node has any + * ownership (either primary or backup). + */ + std::vector< int32_t > GetAllPartitions(cluster::ClusterNode node) { + return impl.Get()->GetAllPartitions(node); + } + + /** + * Map passed in key to a key which will be used for node affinity. + * + * @tparam TR Key to be used for node-to-affinity mapping type. + * + * @param key Key to map. + * @return Key to be used for node-to-affinity mapping (may be the same key as + * passed in). + */ + template < typename TR > + TR GetAffinityKey(const K& key) { + return impl.Get()->template GetAffinityKey< K, TR >(key); + } + + /** + * This method provides ability to detect which keys are mapped to which + * nodes. Use it to determine which nodes are storing which keys prior to + * sending jobs that access these keys. + * + * @param keys Keys to map to nodes. + * @return Map of nodes to keys or empty map if there are no alive nodes for + * this cache. + */ + std::map< cluster::ClusterNode, std::vector< K > > MapKeysToNodes( + const std::vector< K >& keys) { + return impl.Get()->MapKeysToNodes(keys); + } + + /** + * This method provides ability to detect to which primary node the given key + * is mapped. Use it to determine which nodes are storing which keys prior to + * sending jobs that access these keys. + * + * @param key Key to map to node. + * @return Primary node for the key. + */ + cluster::ClusterNode MapKeyToNode(const K& key) { + return impl.Get()->MapKeyToNode(key); + } + + /** + * Get primary and backup nodes for the key. + * Note that primary node is always first in the returned collection. + * + * @param key Key to map to nodes. + * @return Collection of cluster nodes. + */ + std::vector< cluster::ClusterNode > MapKeyToPrimaryAndBackups(const K& key) { + return impl.Get()->MapKeyToPrimaryAndBackups(key); + } + + /** + * Get primary node for the given partition. + * + * @param part Partition id. + * @return Primary node for the given partition. + */ + cluster::ClusterNode MapPartitionToNode(int32_t part) { + return impl.Get()->MapPartitionToNode(part); + } + + /** + * Get primary nodes for the given partitions. + * + * @param parts Partition ids. + * @return Mapping of given partitions to their primary nodes. + */ + std::map< int32_t, cluster::ClusterNode > MapPartitionsToNodes( + const std::vector< int32_t >& parts) { + return impl.Get()->MapPartitionsToNodes(parts); + } + + /** + * Get primary and backup nodes for partition. + * Note that primary node is always first in the returned collection. + * + * @param part Partition to get affinity nodes for. + * @return Collection of primary and backup nodes for partition with primary + * node always first. + */ + std::vector< cluster::ClusterNode > MapPartitionToPrimaryAndBackups( + int32_t part) { + return impl.Get()->MapPartitionToPrimaryAndBackups(part); + } + + private: + impl::cache::SP_CacheAffinityImpl impl; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_AFFINITY diff --git a/src/odbc/include/ignite/odbc/cache/cache_entry.h b/src/odbc/include/ignite/odbc/cache/cache_entry.h index bf468f040..486c00d43 100644 --- a/src/odbc/include/ignite/odbc/cache/cache_entry.h +++ b/src/odbc/include/ignite/odbc/cache/cache_entry.h @@ -26,143 +26,118 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * %Cache entry class template. - * - * Both key and value types should be default-constructable, - * copy-constructable and assignable. - */ - template - class CacheEntry - { - public: - /** - * Default constructor. - * - * Creates instance with both key and value default-constructed. - */ - CacheEntry() : - key(), - val(), - hasValue(false) - { - // No-op. - } - - /** - * Constructor. - * - * @param key Key. - * @param val Value. - */ - CacheEntry(const K& key, const V& val) : - key(key), - val(val), - hasValue(true) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - CacheEntry(const CacheEntry& other) : - key(other.key), - val(other.val), - hasValue(other.hasValue) - { - // No-op. - } - - /** - * Constructor. - * - * @param p Pair. - */ - CacheEntry(const std::pair& p) : - key(p.first), - val(p.second), - hasValue(true) - { - // No-op. - } - - - /** - * Destructor. - */ - virtual ~CacheEntry() - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - */ - CacheEntry& operator=(const CacheEntry& other) - { - if (this != &other) - { - key = other.key; - val = other.val; - hasValue = other.hasValue; - } - - return *this; - } - - /** - * Get key. - * - * @return Key. - */ - const K& GetKey() const - { - return key; - } - - /** - * Get value. - * - * @return Value. - */ - const V& GetValue() const - { - return val; - } - - /** - * Check if the value exists. - * - * @return True, if the value exists. - */ - bool HasValue() const - { - return hasValue; - } - - protected: - /** Key. */ - K key; - - /** Value. */ - V val; - - /** Indicates whether value exists */ - bool hasValue; - }; - } +namespace ignite { +namespace odbc { +namespace cache { +/** + * %Cache entry class template. + * + * Both key and value types should be default-constructable, + * copy-constructable and assignable. + */ +template < typename K, typename V > +class CacheEntry { + public: + /** + * Default constructor. + * + * Creates instance with both key and value default-constructed. + */ + CacheEntry() : key(), val(), hasValue(false) { + // No-op. + } + + /** + * Constructor. + * + * @param key Key. + * @param val Value. + */ + CacheEntry(const K& key, const V& val) : key(key), val(val), hasValue(true) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + CacheEntry(const CacheEntry& other) + : key(other.key), val(other.val), hasValue(other.hasValue) { + // No-op. + } + + /** + * Constructor. + * + * @param p Pair. + */ + CacheEntry(const std::pair< K, V >& p) + : key(p.first), val(p.second), hasValue(true) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntry() { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + */ + CacheEntry& operator=(const CacheEntry& other) { + if (this != &other) { + key = other.key; + val = other.val; + hasValue = other.hasValue; } -} -#endif //_IGNITE_ODBC_CACHE_CACHE_ENTRY + return *this; + } + + /** + * Get key. + * + * @return Key. + */ + const K& GetKey() const { + return key; + } + + /** + * Get value. + * + * @return Value. + */ + const V& GetValue() const { + return val; + } + + /** + * Check if the value exists. + * + * @return True, if the value exists. + */ + bool HasValue() const { + return hasValue; + } + + protected: + /** Key. */ + K key; + + /** Value. */ + V val; + + /** Indicates whether value exists */ + bool hasValue; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_CACHE_ENTRY diff --git a/src/odbc/include/ignite/odbc/cache/cache_peek_mode.h b/src/odbc/include/ignite/odbc/cache/cache_peek_mode.h index 6946563eb..ead1b643d 100644 --- a/src/odbc/include/ignite/odbc/cache/cache_peek_mode.h +++ b/src/odbc/include/ignite/odbc/cache/cache_peek_mode.h @@ -23,60 +23,57 @@ #ifndef _IGNITE_ODBC_CACHE_CACHE_PEEK_MODE #define _IGNITE_ODBC_CACHE_CACHE_PEEK_MODE -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * Enumeration of all supported cache peek modes. - */ - struct CachePeekMode - { - enum Type - { - /** - * Peeks into all available cache storages. - */ - ALL = 0x01, - - /** - * Peek into near cache only (don't peek into partitioned cache). - * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. - */ - NEAR_CACHE = 0x02, - - /** - * Peek value from primary copy of partitioned cache only (skip near cache). - * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. - */ - PRIMARY = 0x04, - - /** - * Peek value from backup copies of partitioned cache only (skip near cache). - * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. - */ - BACKUP = 0x08, - - /** - * Peeks value from the on-heap storage only. - */ - ONHEAP = 0x10, - - /** - * Peeks value from the off-heap storage only, without loading off-heap value into cache. - */ - OFFHEAP = 0x20, - - /** - * Peeks value from the swap storage only, without loading swapped value into cache. - */ - SWAP = 0x40 - }; - }; - } - } -} +namespace ignite { +namespace odbc { +namespace cache { +/** + * Enumeration of all supported cache peek modes. + */ +struct CachePeekMode { + enum Type { + /** + * Peeks into all available cache storages. + */ + ALL = 0x01, + + /** + * Peek into near cache only (don't peek into partitioned cache). + * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + NEAR_CACHE = 0x02, + + /** + * Peek value from primary copy of partitioned cache only (skip near cache). + * In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + PRIMARY = 0x04, + + /** + * Peek value from backup copies of partitioned cache only (skip near + * cache). In case of LOCAL cache, behaves as CachePeekMode::ALL mode. + */ + BACKUP = 0x08, + + /** + * Peeks value from the on-heap storage only. + */ + ONHEAP = 0x10, + + /** + * Peeks value from the off-heap storage only, without loading off-heap + * value into cache. + */ + OFFHEAP = 0x20, + + /** + * Peeks value from the swap storage only, without loading swapped value + * into cache. + */ + SWAP = 0x40 + }; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_CACHE_CACHE_PEEK_MODE +#endif //_IGNITE_ODBC_CACHE_CACHE_PEEK_MODE diff --git a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event.h b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event.h index 5f3ace806..cbf6c4d10 100644 --- a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event.h +++ b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event.h @@ -26,120 +26,105 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * Cache entry event class template. - * - * Both key and value types should be default-constructable, - * copy-constructable and assignable. - */ - template - class CacheEntryEvent : public CacheEntry - { - public: - /** - * Default constructor. - * - * Creates instance with all fields default-constructed. - */ - CacheEntryEvent() : - CacheEntry(), - oldVal(), - hasOldValue(false) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - CacheEntryEvent(const CacheEntryEvent& other) : - CacheEntry(other), - oldVal(other.oldVal), - hasOldValue(other.hasOldValue) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEvent() - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - CacheEntryEvent& operator=(const CacheEntryEvent& other) - { - if (this != &other) - { - CacheEntry::operator=(other); - - oldVal = other.oldVal; - hasOldValue = other.hasOldValue; - } - - return *this; - } - - /** - * Get old value. - * - * @return Old value. - */ - const V& GetOldValue() const - { - return oldVal; - } - - /** - * Check if the old value exists. - * - * @return True, if the old value exists. - */ - bool HasOldValue() const - { - return hasOldValue; - } - - /** - * Reads cache event using provided raw reader. - * - * @param reader Reader to use. - */ - void Read(binary::BinaryRawReader& reader) - { - this->key = reader.ReadObject(); - - this->hasOldValue = reader.TryReadObject(this->oldVal); - this->hasValue = reader.TryReadObject(this->val); - - // Java send an event type, we need to fetch it from the buffer. - reader.ReadInt8(); - } - - private: - /** Old value. */ - V oldVal; - - /** Indicates whether old value exists */ - bool hasOldValue; - }; - } +namespace ignite { +namespace odbc { +namespace cache { +/** + * Cache entry event class template. + * + * Both key and value types should be default-constructable, + * copy-constructable and assignable. + */ +template < typename K, typename V > +class CacheEntryEvent : public CacheEntry< K, V > { + public: + /** + * Default constructor. + * + * Creates instance with all fields default-constructed. + */ + CacheEntryEvent() : CacheEntry< K, V >(), oldVal(), hasOldValue(false) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + CacheEntryEvent(const CacheEntryEvent< K, V >& other) + : CacheEntry< K, V >(other), + oldVal(other.oldVal), + hasOldValue(other.hasOldValue) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEvent() { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + CacheEntryEvent& operator=(const CacheEntryEvent< K, V >& other) { + if (this != &other) { + CacheEntry< K, V >::operator=(other); + + oldVal = other.oldVal; + hasOldValue = other.hasOldValue; } -} -#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT + return *this; + } + + /** + * Get old value. + * + * @return Old value. + */ + const V& GetOldValue() const { + return oldVal; + } + + /** + * Check if the old value exists. + * + * @return True, if the old value exists. + */ + bool HasOldValue() const { + return hasOldValue; + } + + /** + * Reads cache event using provided raw reader. + * + * @param reader Reader to use. + */ + void Read(binary::BinaryRawReader& reader) { + this->key = reader.ReadObject< K >(); + + this->hasOldValue = reader.TryReadObject(this->oldVal); + this->hasValue = reader.TryReadObject(this->val); + + // Java send an event type, we need to fetch it from the buffer. + reader.ReadInt8(); + } + + private: + /** Old value. */ + V oldVal; + + /** Indicates whether old value exists */ + bool hasOldValue; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT diff --git a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_filter.h b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_filter.h index 9987fbc14..f05bcd91a 100644 --- a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_filter.h +++ b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_filter.h @@ -26,87 +26,77 @@ #include #include -namespace ignite -{ - namespace odbc - { - class IgniteBinding; - - namespace impl - { - namespace cache - { - namespace event - { - template - class CacheEntryEventFilterHolder; - } - } - } - - namespace cache - { - namespace event - { - /** - * Cache entry event filter. - * - * All templated types should be default-constructable, - * copy-constructable and assignable. - * - * @tparam K Key type. - * @tparam V Value type. - */ - template - class CacheEntryEventFilter : private impl::cache::event::CacheEntryEventFilterBase - { - template - friend class impl::cache::event::CacheEntryEventFilterHolder; - - public: - /** - * Default constructor. - */ - CacheEntryEventFilter() - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEventFilter() - { - // No-op. - } - - /** - * Event callback. - * - * @param event Event. - * @return True if the event passes filter. - */ - virtual bool Process(const CacheEntryEvent& event) = 0; - - private: - /** - * Process serialized events. - * - * @param reader Reader for a serialized event. - * @return Filter evaluation result. - */ - virtual bool ReadAndProcessEvent(binary::BinaryRawReader& reader) - { - CacheEntryEvent event; - - event.Read(reader); - - return Process(event); - } - }; - } - } - } +namespace ignite { +namespace odbc { +class IgniteBinding; + +namespace impl { +namespace cache { +namespace event { +template < typename T > +class CacheEntryEventFilterHolder; } +} // namespace cache +} // namespace impl + +namespace cache { +namespace event { +/** + * Cache entry event filter. + * + * All templated types should be default-constructable, + * copy-constructable and assignable. + * + * @tparam K Key type. + * @tparam V Value type. + */ +template < typename K, typename V > +class CacheEntryEventFilter + : private impl::cache::event::CacheEntryEventFilterBase { + template < typename T > + friend class impl::cache::event::CacheEntryEventFilterHolder; + + public: + /** + * Default constructor. + */ + CacheEntryEventFilter() { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEventFilter() { + // No-op. + } + + /** + * Event callback. + * + * @param event Event. + * @return True if the event passes filter. + */ + virtual bool Process(const CacheEntryEvent< K, V >& event) = 0; + + private: + /** + * Process serialized events. + * + * @param reader Reader for a serialized event. + * @return Filter evaluation result. + */ + virtual bool ReadAndProcessEvent(binary::BinaryRawReader& reader) { + CacheEntryEvent< K, V > event; + + event.Read(reader); + + return Process(event); + } +}; +} // namespace event +} // namespace cache +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER +#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER diff --git a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_listener.h b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_listener.h index a99d98fb5..346525fec 100644 --- a/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_listener.h +++ b/src/odbc/include/ignite/odbc/cache/event/cache_entry_event_listener.h @@ -27,48 +27,41 @@ #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace event - { - /** - * Cache entry event listener. - */ - template - class CacheEntryEventListener - { - public: - /** - * Default constructor. - */ - CacheEntryEventListener() - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEventListener() - { - // No-op. - } - - /** - * Event callback. - * - * @param evts Events. - * @param num Events number. - */ - virtual void OnEvent(const CacheEntryEvent* evts, uint32_t num) = 0; - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace cache { +namespace event { +/** + * Cache entry event listener. + */ +template < typename K, typename V > +class CacheEntryEventListener { + public: + /** + * Default constructor. + */ + CacheEntryEventListener() { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEventListener() { + // No-op. + } + + /** + * Event callback. + * + * @param evts Events. + * @param num Events number. + */ + virtual void OnEvent(const CacheEntryEvent< K, V >* evts, uint32_t num) = 0; +}; +} // namespace event +} // namespace cache +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT_LISTENER +#endif //_IGNITE_ODBC_CACHE_EVENT_CACHE_ENTRY_EVENT_LISTENER diff --git a/src/odbc/include/ignite/odbc/cache/mutable_cache_entry.h b/src/odbc/include/ignite/odbc/cache/mutable_cache_entry.h index c02dff699..930f80736 100644 --- a/src/odbc/include/ignite/odbc/cache/mutable_cache_entry.h +++ b/src/odbc/include/ignite/odbc/cache/mutable_cache_entry.h @@ -23,160 +23,134 @@ #ifndef _IGNITE_ODBC_CACHE_MUTABLE_CACHE_ENTRY #define _IGNITE_ODBC_CACHE_MUTABLE_CACHE_ENTRY -namespace ignite -{ - namespace odbc - { - namespace cache - { - /** - * Mutable representation of CacheEntry class template. - * - * Both key and value types should be default-constructable, - * copy-constructable and assignable. - * - * Additionally, equality operator should be defined for - * the value type. - */ - template - class MutableCacheEntry - { - public: - /** - * Default constructor. - */ - MutableCacheEntry() : - key(), - val(), - exists(false) - { - // No-op. - } - - /** - * Constructor for non-existing entry. - * - * @param key Key. - */ - MutableCacheEntry(const K& key) : - key(key), - val(), - exists(false) - { - // No-op. - } - - /** - * Constructor for existing entry. - * - * @param key Key. - * @param val Value. - */ - MutableCacheEntry(const K& key, const V& val) : - key(key), - val(val), - exists(true) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - MutableCacheEntry(const MutableCacheEntry& other) : - key(other.key), - val(other.val), - exists(other.exists) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - MutableCacheEntry& operator=(const MutableCacheEntry& other) - { - if (this != &other) - { - key = other.key; - val = other.val; - exists = other.exists; - } - - return *this; - } - - /** - * Check whether cache entry exists in cache. - * - * @return True if the cache entry exists in cache and false - * otherwise. - */ - bool IsExists() const - { - return exists; - } - - /** - * Removes the entry from the Cache. - */ - void Remove() - { - exists = false; - } - - /** - * Get key. - * - * @return Key. - */ - const K& GetKey() const - { - return key; - } - - /** - * Get value. - * - * @return Value. - */ - const V& GetValue() const - { - return val; - } - - /** - * Sets or replaces the value associated with the key. - * - * After setter invocation "IsExists" will return true. - * - * @param val Value to set. - */ - void SetValue(const V& val) - { - this->val = val; - - exists = true; - } - - private: - /** Key. */ - K key; - - /** Value. */ - V val; - - /** Exists. */ - bool exists; - }; - } +namespace ignite { +namespace odbc { +namespace cache { +/** + * Mutable representation of CacheEntry class template. + * + * Both key and value types should be default-constructable, + * copy-constructable and assignable. + * + * Additionally, equality operator should be defined for + * the value type. + */ +template < typename K, typename V > +class MutableCacheEntry { + public: + /** + * Default constructor. + */ + MutableCacheEntry() : key(), val(), exists(false) { + // No-op. + } + + /** + * Constructor for non-existing entry. + * + * @param key Key. + */ + MutableCacheEntry(const K& key) : key(key), val(), exists(false) { + // No-op. + } + + /** + * Constructor for existing entry. + * + * @param key Key. + * @param val Value. + */ + MutableCacheEntry(const K& key, const V& val) + : key(key), val(val), exists(true) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + MutableCacheEntry(const MutableCacheEntry& other) + : key(other.key), val(other.val), exists(other.exists) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + MutableCacheEntry& operator=(const MutableCacheEntry& other) { + if (this != &other) { + key = other.key; + val = other.val; + exists = other.exists; } -} -#endif //_IGNITE_ODBC_CACHE_MUTABLE_CACHE_ENTRY + return *this; + } + + /** + * Check whether cache entry exists in cache. + * + * @return True if the cache entry exists in cache and false + * otherwise. + */ + bool IsExists() const { + return exists; + } + + /** + * Removes the entry from the Cache. + */ + void Remove() { + exists = false; + } + + /** + * Get key. + * + * @return Key. + */ + const K& GetKey() const { + return key; + } + + /** + * Get value. + * + * @return Value. + */ + const V& GetValue() const { + return val; + } + + /** + * Sets or replaces the value associated with the key. + * + * After setter invocation "IsExists" will return true. + * + * @param val Value to set. + */ + void SetValue(const V& val) { + this->val = val; + + exists = true; + } + + private: + /** Key. */ + K key; + + /** Value. */ + V val; + + /** Exists. */ + bool exists; +}; +} // namespace cache +} // namespace odbc +} // namespace ignite +#endif //_IGNITE_ODBC_CACHE_MUTABLE_CACHE_ENTRY diff --git a/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query.h b/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query.h index 7cb3d75bd..d1d48eb3b 100644 --- a/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query.h +++ b/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query.h @@ -28,248 +28,235 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - // Forward-declaration. - template - class IGNITE_IMPORT_EXPORT Cache; - - namespace query - { - namespace continuous - { - /** - * Continuous query. - * - * Continuous queries allow to register a remote and a listener - * for cache update events. On any update to the related cache - * an event is sent to the node that has executed the query and - * listener is notified on that node. - * - * Continuous query can either be executed on the whole topology - * or only on local node. - * - * To execute the query over the cache use method - * ignite::odbc::cache::Cache::QueryContinuous(). - */ - template - class ContinuousQuery - { - friend class Cache; - public: - - /** - * Default value for the buffer size. - */ - enum { DEFAULT_BUFFER_SIZE = 1 }; - - /** - * Default value for the time interval. - */ - enum { DEFAULT_TIME_INTERVAL = 0 }; - - /** - * Destructor. - */ - ~ContinuousQuery() - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener. Invoked on the node where - * continuous query execution has been started. - */ - ContinuousQuery(Reference > lsnr) : - impl(new impl::cache::query::continuous::ContinuousQueryImpl(lsnr, false)) - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener Invoked on the node where - * continuous query execution has been started. - * @param loc Whether query should be executed locally. - */ - ContinuousQuery(Reference > lsnr, bool loc) : - impl(new impl::cache::query::continuous::ContinuousQueryImpl(lsnr, loc)) - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener. Invoked on the node where - * continuous query execution has been started. - * @param remoteFilter Remote filter. - */ - template - ContinuousQuery(Reference > lsnr, - const Reference& remoteFilter) : - impl(new impl::cache::query::continuous::ContinuousQueryImpl(lsnr, false, remoteFilter)) - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener Invoked on the node where - * continuous query execution has been started. - * @param remoteFilter Remote filter. - * @param loc Whether query should be executed locally. - */ - template - ContinuousQuery(Reference > lsnr, - const Reference& remoteFilter, bool loc) : - impl(new impl::cache::query::continuous::ContinuousQueryImpl(lsnr, loc, remoteFilter)) - { - // No-op. - } - - /** - * Set local flag. - * - * @param val Value of the flag. If true, query will be - * executed only on local node, so only local entries - * will be returned as query result. - */ - void SetLocal(bool val) - { - impl.Get()->SetLocal(val); - } - - /** - * Get local flag. - * - * @return Value of the flag. If true, query will be - * executed only on local node, so only local entries - * will be returned as query result. - */ - bool GetLocal() const - { - return impl.Get()->GetLocal(); - } - - /** - * Set buffer size. - * - * When a cache update happens, entry is first - * put into a buffer. Entries from buffer will be sent to - * the master node only if the buffer is full or time - * provided via timeInterval is exceeded. - * - * @param val Buffer size. - */ - void SetBufferSize(int32_t val) - { - impl.Get()->SetBufferSize(val); - } - - /** - * Get buffer size. - * - * When a cache update happens, entry is first - * put into a buffer. Entries from buffer will be sent to - * the master node only if the buffer is full or time - * provided via timeInterval is exceeded. - * - * @return Buffer size. - */ - int32_t GetBufferSize() const - { - return impl.Get()->GetBufferSize(); - } - - /** - * Set time interval. - * - * When a cache update happens, entry is first put into - * a buffer. Entries from buffer are sent to the master node - * only if the buffer is full (its size can be changed via - * SetBufferSize) or time provided via this method is - * exceeded. - * - * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which - * means that time check is disabled and entries will be - * sent only when buffer is full. - * - * @param val Time interval in miliseconds. - */ - void SetTimeInterval(int64_t val) - { - impl.Get()->SetTimeInterval(val); - } - - /** - * Get time interval. - * - * When a cache update happens, entry is first put into - * a buffer. Entries from buffer are sent to the master node - * only if the buffer is full (its size can be changed via - * SetBufferSize) or time provided via SetTimeInterval - * method is exceeded. - * - * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which - * means that time check is disabled and entries will be - * sent only when buffer is full. - * - * @return Time interval. - */ - int64_t GetTimeInterval() const - { - return impl.Get()->GetTimeInterval(); - } - - /** - * Set cache entry event listener. - * - * @param lsnr Cache entry event listener. Invoked on the - * node where continuous query execution has been - * started. - */ - void SetListener(Reference > lsnr) - { - impl.Get()->SetListener(lsnr); - } - - /** - * Get cache entry event listener. - * - * @return Cache entry event listener. - */ - const event::CacheEntryEventListener& GetListener() const - { - return impl.Get()->GetListener(); - } - - /** - * Get cache entry event listener. - * - * @return Cache entry event listener. - */ - event::CacheEntryEventListener& GetListener() - { - return impl.Get()->GetListener(); - } - - private: - /** Implementation. */ - common::concurrent::SharedPointer > impl; - }; - } - } - } - } -} +namespace ignite { +namespace odbc { +namespace cache { +// Forward-declaration. +template < typename K, typename V > +class IGNITE_IMPORT_EXPORT Cache; -#endif //_IGNITE_ODBC_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY +namespace query { +namespace continuous { +/** + * Continuous query. + * + * Continuous queries allow to register a remote and a listener + * for cache update events. On any update to the related cache + * an event is sent to the node that has executed the query and + * listener is notified on that node. + * + * Continuous query can either be executed on the whole topology + * or only on local node. + * + * To execute the query over the cache use method + * ignite::odbc::cache::Cache::QueryContinuous(). + */ +template < typename K, typename V > +class ContinuousQuery { + friend class Cache< K, V >; + + public: + /** + * Default value for the buffer size. + */ + enum { DEFAULT_BUFFER_SIZE = 1 }; + + /** + * Default value for the time interval. + */ + enum { DEFAULT_TIME_INTERVAL = 0 }; + + /** + * Destructor. + */ + ~ContinuousQuery() { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener. Invoked on the node where + * continuous query execution has been started. + */ + ContinuousQuery(Reference< event::CacheEntryEventListener< K, V > > lsnr) + : impl(new impl::cache::query::continuous::ContinuousQueryImpl< K, V >( + lsnr, false)) { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener Invoked on the node where + * continuous query execution has been started. + * @param loc Whether query should be executed locally. + */ + ContinuousQuery(Reference< event::CacheEntryEventListener< K, V > > lsnr, + bool loc) + : impl(new impl::cache::query::continuous::ContinuousQueryImpl< K, V >( + lsnr, loc)) { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener. Invoked on the node where + * continuous query execution has been started. + * @param remoteFilter Remote filter. + */ + template < typename F > + ContinuousQuery(Reference< event::CacheEntryEventListener< K, V > > lsnr, + const Reference< F >& remoteFilter) + : impl(new impl::cache::query::continuous::ContinuousQueryImpl< K, V >( + lsnr, false, remoteFilter)) { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener Invoked on the node where + * continuous query execution has been started. + * @param remoteFilter Remote filter. + * @param loc Whether query should be executed locally. + */ + template < typename F > + ContinuousQuery(Reference< event::CacheEntryEventListener< K, V > > lsnr, + const Reference< F >& remoteFilter, bool loc) + : impl(new impl::cache::query::continuous::ContinuousQueryImpl< K, V >( + lsnr, loc, remoteFilter)) { + // No-op. + } + + /** + * Set local flag. + * + * @param val Value of the flag. If true, query will be + * executed only on local node, so only local entries + * will be returned as query result. + */ + void SetLocal(bool val) { + impl.Get()->SetLocal(val); + } + + /** + * Get local flag. + * + * @return Value of the flag. If true, query will be + * executed only on local node, so only local entries + * will be returned as query result. + */ + bool GetLocal() const { + return impl.Get()->GetLocal(); + } + + /** + * Set buffer size. + * + * When a cache update happens, entry is first + * put into a buffer. Entries from buffer will be sent to + * the master node only if the buffer is full or time + * provided via timeInterval is exceeded. + * + * @param val Buffer size. + */ + void SetBufferSize(int32_t val) { + impl.Get()->SetBufferSize(val); + } + + /** + * Get buffer size. + * + * When a cache update happens, entry is first + * put into a buffer. Entries from buffer will be sent to + * the master node only if the buffer is full or time + * provided via timeInterval is exceeded. + * + * @return Buffer size. + */ + int32_t GetBufferSize() const { + return impl.Get()->GetBufferSize(); + } + + /** + * Set time interval. + * + * When a cache update happens, entry is first put into + * a buffer. Entries from buffer are sent to the master node + * only if the buffer is full (its size can be changed via + * SetBufferSize) or time provided via this method is + * exceeded. + * + * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which + * means that time check is disabled and entries will be + * sent only when buffer is full. + * + * @param val Time interval in miliseconds. + */ + void SetTimeInterval(int64_t val) { + impl.Get()->SetTimeInterval(val); + } + + /** + * Get time interval. + * + * When a cache update happens, entry is first put into + * a buffer. Entries from buffer are sent to the master node + * only if the buffer is full (its size can be changed via + * SetBufferSize) or time provided via SetTimeInterval + * method is exceeded. + * + * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which + * means that time check is disabled and entries will be + * sent only when buffer is full. + * + * @return Time interval. + */ + int64_t GetTimeInterval() const { + return impl.Get()->GetTimeInterval(); + } + + /** + * Set cache entry event listener. + * + * @param lsnr Cache entry event listener. Invoked on the + * node where continuous query execution has been + * started. + */ + void SetListener(Reference< event::CacheEntryEventListener< K, V > > lsnr) { + impl.Get()->SetListener(lsnr); + } + + /** + * Get cache entry event listener. + * + * @return Cache entry event listener. + */ + const event::CacheEntryEventListener< K, V >& GetListener() const { + return impl.Get()->GetListener(); + } + + /** + * Get cache entry event listener. + * + * @return Cache entry event listener. + */ + event::CacheEntryEventListener< K, V >& GetListener() { + return impl.Get()->GetListener(); + } + + private: + /** Implementation. */ + common::concurrent::SharedPointer< + impl::cache::query::continuous::ContinuousQueryImpl< K, V > > + impl; +}; +} // namespace continuous +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY diff --git a/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query_handle.h b/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query_handle.h index 54495d492..3cf4bc86e 100644 --- a/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query_handle.h +++ b/src/odbc/include/ignite/odbc/cache/query/continuous/continuous_query_handle.h @@ -25,112 +25,102 @@ #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - namespace continuous - { - /** - * Continuous query handle. - */ - template - class ContinuousQueryHandle - { - public: - /** - * Default constructor. - */ - ContinuousQueryHandle() : - impl() - { - // No-op. - } - - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - ContinuousQueryHandle(impl::cache::query::continuous::ContinuousQueryHandleImpl* impl) : - impl(impl) - { - // No-op. - } - - /** - * Gets the cursor for initial query. - * Can be called only once, throws IgniteError on consequent - * calls. - * - * @return Initial query cursor. - */ - QueryCursor GetInitialQueryCursor() - { - IgniteError err; - - QueryCursor res = GetInitialQueryCursor(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Gets the cursor for initial query. - * Can be called only once, results in error on consequent - * calls. - * - * @param err Error. - * @return Initial query cursor. - */ - QueryCursor GetInitialQueryCursor(IgniteError& err) - { - impl::cache::query::continuous::ContinuousQueryHandleImpl* impl0 = impl.Get(); - - if (impl0) - return QueryCursor(impl0->GetInitialQueryCursor(err)); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return QueryCursor(); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - typedef impl::cache::query::continuous::ContinuousQueryHandleImpl ContinuousQueryHandleImpl; - - /** Implementation delegate. */ - common::concurrent::SharedPointer impl; - }; - } - } - } +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +namespace continuous { +/** + * Continuous query handle. + */ +template < typename K, typename V > +class ContinuousQueryHandle { + public: + /** + * Default constructor. + */ + ContinuousQueryHandle() : impl() { + // No-op. + } + + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + ContinuousQueryHandle( + impl::cache::query::continuous::ContinuousQueryHandleImpl* impl) + : impl(impl) { + // No-op. + } + + /** + * Gets the cursor for initial query. + * Can be called only once, throws IgniteError on consequent + * calls. + * + * @return Initial query cursor. + */ + QueryCursor< K, V > GetInitialQueryCursor() { + IgniteError err; + + QueryCursor< K, V > res = GetInitialQueryCursor(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Gets the cursor for initial query. + * Can be called only once, results in error on consequent + * calls. + * + * @param err Error. + * @return Initial query cursor. + */ + QueryCursor< K, V > GetInitialQueryCursor(IgniteError& err) { + impl::cache::query::continuous::ContinuousQueryHandleImpl* impl0 = + impl.Get(); + + if (impl0) + return QueryCursor< K, V >(impl0->GetInitialQueryCursor(err)); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return QueryCursor< K, V >(); } -} + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + typedef impl::cache::query::continuous::ContinuousQueryHandleImpl + ContinuousQueryHandleImpl; + + /** Implementation delegate. */ + common::concurrent::SharedPointer< ContinuousQueryHandleImpl > impl; +}; +} // namespace continuous +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_HANDLE +#endif //_IGNITE_ODBC_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_HANDLE diff --git a/src/odbc/include/ignite/odbc/cache/query/query_cursor.h b/src/odbc/include/ignite/odbc/cache/query/query_cursor.h index 1336786ae..f10ac450f 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_cursor.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_cursor.h @@ -32,240 +32,221 @@ #include "ignite/odbc/impl/cache/query/query_impl.h" #include "ignite/odbc/impl/operations.h" -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Query cursor class template. - * - * Both key and value types should be default-constructable, - * copy-constructable and assignable. Also BinaryType class - * template should be specialized for both types. - * - * This class is implemented as a reference to an implementation so copying - * of this class instance will only create another reference to the same - * underlying object. Underlying object will be released automatically once all - * the instances are destructed. - */ - template - class QueryCursor - { - public: - /** - * Default constructor. - * - * Constructed instance is not valid and thus can not be used - * as a cursor. - */ - QueryCursor() : impl(0) - { - // No-op. - } - - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - QueryCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl) - { - // No-op. - } - - /** - * Check whether next entry exists. - * - * This method should only be used on the valid instance. - * - * @return True if next entry exists. - * - * @throw IgniteError class instance in case of failure. - */ - bool HasNext() - { - IgniteError err; - - bool res = HasNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check whether next entry exists. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return True if next entry exists and operation resulted in - * success. Returns false on failure. - */ - bool HasNext(IgniteError& err) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->HasNext(err); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return false; - } - } - - /** - * Get next entry. - * - * This method should only be used on the valid instance. - * - * @return Next entry. - * - * @throw IgniteError class instance in case of failure. - */ - CacheEntry GetNext() - { - IgniteError err; - - CacheEntry res = GetNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get next entry. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return Next entry on success and default-constructed - * entry on failure. Default-constructed entry contains - * default-constructed instances of both key and value types. - */ - CacheEntry GetNext(IgniteError& err) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) { - K key; - V val; - - impl::Out2Operation outOp(key, val); - - impl0->GetNext(outOp, err); - - return CacheEntry(key, val); - } - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return CacheEntry(); - } - } - - /** - * Get all entries. - * - * This method should only be used on the valid instance. - * - * @param res Vector where query entries will be stored. - * - * @throw IgniteError class instance in case of failure. - */ - void GetAll(std::vector >& res) - { - IgniteError err; - - GetAll(res, err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Get all entries. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param res Vector where query entries will be stored. - * @param err Used to set operation result. - */ - void GetAll(std::vector >& res, IgniteError& err) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) { - impl::OutQueryGetAllOperation outOp(res); - - impl0->GetAll(outOp, err); - } - else - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - } - - /** - * Get all entries. - * - * This method should only be used on the valid instance. - * - * @param iter Output iterator. - */ - template - void GetAll(OutIter iter) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) { - impl::OutQueryGetAllOperationIter outOp(iter); - - impl0->GetAll(outOp); - } - else - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - /** Implementation delegate. */ - ignite::odbc::common::concurrent::SharedPointer impl; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_CURSOR +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Query cursor class template. + * + * Both key and value types should be default-constructable, + * copy-constructable and assignable. Also BinaryType class + * template should be specialized for both types. + * + * This class is implemented as a reference to an implementation so copying + * of this class instance will only create another reference to the same + * underlying object. Underlying object will be released automatically once all + * the instances are destructed. + */ +template < typename K, typename V > +class QueryCursor { + public: + /** + * Default constructor. + * + * Constructed instance is not valid and thus can not be used + * as a cursor. + */ + QueryCursor() : impl(0) { + // No-op. + } + + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + QueryCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl) { + // No-op. + } + + /** + * Check whether next entry exists. + * + * This method should only be used on the valid instance. + * + * @return True if next entry exists. + * + * @throw IgniteError class instance in case of failure. + */ + bool HasNext() { + IgniteError err; + + bool res = HasNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check whether next entry exists. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return True if next entry exists and operation resulted in + * success. Returns false on failure. + */ + bool HasNext(IgniteError& err) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->HasNext(err); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return false; + } + } + + /** + * Get next entry. + * + * This method should only be used on the valid instance. + * + * @return Next entry. + * + * @throw IgniteError class instance in case of failure. + */ + CacheEntry< K, V > GetNext() { + IgniteError err; + + CacheEntry< K, V > res = GetNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get next entry. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return Next entry on success and default-constructed + * entry on failure. Default-constructed entry contains + * default-constructed instances of both key and value types. + */ + CacheEntry< K, V > GetNext(IgniteError& err) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) { + K key; + V val; + + impl::Out2Operation< K, V > outOp(key, val); + + impl0->GetNext(outOp, err); + + return CacheEntry< K, V >(key, val); + } else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return CacheEntry< K, V >(); + } + } + + /** + * Get all entries. + * + * This method should only be used on the valid instance. + * + * @param res Vector where query entries will be stored. + * + * @throw IgniteError class instance in case of failure. + */ + void GetAll(std::vector< CacheEntry< K, V > >& res) { + IgniteError err; + + GetAll(res, err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Get all entries. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param res Vector where query entries will be stored. + * @param err Used to set operation result. + */ + void GetAll(std::vector< CacheEntry< K, V > >& res, IgniteError& err) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) { + impl::OutQueryGetAllOperation< K, V > outOp(res); + + impl0->GetAll(outOp, err); + } else + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + } + + /** + * Get all entries. + * + * This method should only be used on the valid instance. + * + * @param iter Output iterator. + */ + template < typename OutIter > + void GetAll(OutIter iter) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) { + impl::OutQueryGetAllOperationIter< K, V, OutIter > outOp(iter); + + impl0->GetAll(outOp); + } else { + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + } + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + /** Implementation delegate. */ + ignite::odbc::common::concurrent::SharedPointer< + impl::cache::query::QueryCursorImpl > + impl; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_CURSOR diff --git a/src/odbc/include/ignite/odbc/cache/query/query_fields_cursor.h b/src/odbc/include/ignite/odbc/cache/query/query_fields_cursor.h index e1131a7a3..a72625da6 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_fields_cursor.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_fields_cursor.h @@ -33,161 +33,149 @@ #include "ignite/odbc/impl/cache/query/query_impl.h" #include "ignite/odbc/impl/operations.h" -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Query fields cursor. - * - * This class is implemented as a reference to an implementation so copying - * of this class instance will only create another reference to the same - * underlying object. Underlying object will be released automatically once all - * the instances are destructed. - */ - class QueryFieldsCursor - { - public: - /** - * Default constructor. - * - * Constructed instance is not valid and thus can not be used - * as a cursor. - */ - QueryFieldsCursor() : impl(0) - { - // No-op. - } - - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - QueryFieldsCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl) - { - // No-op. - } - - /** - * Check whether next entry exists. - * - * This method should only be used on the valid instance. - * - * @return True if next entry exists. - * - * @throw IgniteError class instance in case of failure. - */ - bool HasNext() - { - IgniteError err; - - bool res = HasNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check whether next entry exists. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return True if next entry exists and operation resulted in - * success. Returns false on failure. - */ - bool HasNext(IgniteError& err) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->HasNext(err); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return false; - } - } - - /** - * Get next entry. - * - * This method should only be used on the valid instance. - * - * @return Next entry. - * - * @throw IgniteError class instance in case of failure. - */ - QueryFieldsRow GetNext() - { - IgniteError err; - - QueryFieldsRow res = GetNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get next entry. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return Next entry on success and invalid row instance on - * failure. - */ - QueryFieldsRow GetNext(IgniteError& err) - { - impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->GetNextRow(err); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return QueryFieldsRow(); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - /** Implementation delegate. */ - ignite::odbc::common::concurrent::SharedPointer impl; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_FIELDS_CURSOR +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Query fields cursor. + * + * This class is implemented as a reference to an implementation so copying + * of this class instance will only create another reference to the same + * underlying object. Underlying object will be released automatically once all + * the instances are destructed. + */ +class QueryFieldsCursor { + public: + /** + * Default constructor. + * + * Constructed instance is not valid and thus can not be used + * as a cursor. + */ + QueryFieldsCursor() : impl(0) { + // No-op. + } + + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + QueryFieldsCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl) { + // No-op. + } + + /** + * Check whether next entry exists. + * + * This method should only be used on the valid instance. + * + * @return True if next entry exists. + * + * @throw IgniteError class instance in case of failure. + */ + bool HasNext() { + IgniteError err; + + bool res = HasNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check whether next entry exists. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return True if next entry exists and operation resulted in + * success. Returns false on failure. + */ + bool HasNext(IgniteError& err) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->HasNext(err); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return false; + } + } + + /** + * Get next entry. + * + * This method should only be used on the valid instance. + * + * @return Next entry. + * + * @throw IgniteError class instance in case of failure. + */ + QueryFieldsRow GetNext() { + IgniteError err; + + QueryFieldsRow res = GetNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get next entry. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return Next entry on success and invalid row instance on + * failure. + */ + QueryFieldsRow GetNext(IgniteError& err) { + impl::cache::query::QueryCursorImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->GetNextRow(err); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return QueryFieldsRow(); + } + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + /** Implementation delegate. */ + ignite::odbc::common::concurrent::SharedPointer< + impl::cache::query::QueryCursorImpl > + impl; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_FIELDS_CURSOR diff --git a/src/odbc/include/ignite/odbc/cache/query/query_fields_row.h b/src/odbc/include/ignite/odbc/cache/query/query_fields_row.h index 1aaa0747f..349f4690f 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_fields_row.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_fields_row.h @@ -32,198 +32,184 @@ #include "ignite/odbc/impl/cache/query/query_fields_row_impl.h" #include "ignite/odbc/impl/operations.h" -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Query fields cursor. - * - * This class is implemented as a reference to an implementation so copying - * of this class instance will only create another reference to the same - * underlying object. Underlying object will be released automatically once all - * the instances are destructed. - */ - class QueryFieldsRow - { - public: - /** - * Default constructor. - * - * Constructed instance is not valid and thus can not be used. - */ - QueryFieldsRow() : impl(0) - { - // No-op. - } - - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - QueryFieldsRow(impl::cache::query::QueryFieldsRowImpl* impl) : impl(impl) - { - // No-op. - } - - /** - * Check whether next entry exists. - * - * This method should only be used on the valid instance. - * - * @return True if next entry exists. - * - * @throw IgniteError class instance in case of failure. - */ - bool HasNext() - { - IgniteError err; - - bool res = HasNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check whether next entry exists. - * Properly sets error param in case of failure. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return True if next entry exists and operation resulted in - * success. Returns false on failure. - */ - bool HasNext(IgniteError& err) - { - impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->HasNext(); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return false; - } - } - - /** - * Get next entry. - * - * Template argument type should be default-constructable, - * copy-constructable and assignable. Also BinaryType class - * template should be specialized for this type. - * - * This method should only be used on the valid instance. - * - * @return Next entry. - * - * @throw IgniteError class instance in case of failure. - */ - template - T GetNext() - { - IgniteError err; - - T res = GetNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get next entry. - * Properly sets error param in case of failure. - * - * Template argument type should be default-constructable, - * copy-constructable and assignable. Also BinaryType class - * template should be specialized for this type. - * - * This method should only be used on the valid instance. - * - * @param err Used to set operation result. - * @return Next entry on success and default-constructed type - * instance on failure. - */ - template - T GetNext(IgniteError& err) - { - impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->GetNext(err); - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return T(); - } - } - - /** - * Get next entry assuming it's an array of 8-byte signed - * integers. Maps to "byte[]" type in Java. - * - * This method should only be used on the valid instance. - * - * @param dst Array to store data to. - * @param len Expected length of array. - * @return Actual amount of elements read. If "len" argument is less than actual - * array size or resulting array is set to null, nothing will be written - * to resulting array and returned value will contain required array length. - * -1 will be returned in case array in stream was null. - * - * @throw IgniteError class instance in case of failure. - */ - int32_t GetNextInt8Array(int8_t* dst, int32_t len) - { - impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); - - if (impl0) - return impl0->GetNextInt8Array(dst, len); - else - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - /** Implementation delegate. */ - ignite::odbc::common::concurrent::SharedPointer impl; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_FIELDS_ROW +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Query fields cursor. + * + * This class is implemented as a reference to an implementation so copying + * of this class instance will only create another reference to the same + * underlying object. Underlying object will be released automatically once all + * the instances are destructed. + */ +class QueryFieldsRow { + public: + /** + * Default constructor. + * + * Constructed instance is not valid and thus can not be used. + */ + QueryFieldsRow() : impl(0) { + // No-op. + } + + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + QueryFieldsRow(impl::cache::query::QueryFieldsRowImpl* impl) : impl(impl) { + // No-op. + } + + /** + * Check whether next entry exists. + * + * This method should only be used on the valid instance. + * + * @return True if next entry exists. + * + * @throw IgniteError class instance in case of failure. + */ + bool HasNext() { + IgniteError err; + + bool res = HasNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check whether next entry exists. + * Properly sets error param in case of failure. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return True if next entry exists and operation resulted in + * success. Returns false on failure. + */ + bool HasNext(IgniteError& err) { + impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->HasNext(); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return false; + } + } + + /** + * Get next entry. + * + * Template argument type should be default-constructable, + * copy-constructable and assignable. Also BinaryType class + * template should be specialized for this type. + * + * This method should only be used on the valid instance. + * + * @return Next entry. + * + * @throw IgniteError class instance in case of failure. + */ + template < typename T > + T GetNext() { + IgniteError err; + + T res = GetNext< T >(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get next entry. + * Properly sets error param in case of failure. + * + * Template argument type should be default-constructable, + * copy-constructable and assignable. Also BinaryType class + * template should be specialized for this type. + * + * This method should only be used on the valid instance. + * + * @param err Used to set operation result. + * @return Next entry on success and default-constructed type + * instance on failure. + */ + template < typename T > + T GetNext(IgniteError& err) { + impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->GetNext< T >(err); + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return T(); + } + } + + /** + * Get next entry assuming it's an array of 8-byte signed + * integers. Maps to "byte[]" type in Java. + * + * This method should only be used on the valid instance. + * + * @param dst Array to store data to. + * @param len Expected length of array. + * @return Actual amount of elements read. If "len" argument is less than + * actual array size or resulting array is set to null, nothing will be + * written to resulting array and returned value will contain required array + * length. -1 will be returned in case array in stream was null. + * + * @throw IgniteError class instance in case of failure. + */ + int32_t GetNextInt8Array(int8_t* dst, int32_t len) { + impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get(); + + if (impl0) + return impl0->GetNextInt8Array(dst, len); + else { + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + } + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + /** Implementation delegate. */ + ignite::odbc::common::concurrent::SharedPointer< + impl::cache::query::QueryFieldsRowImpl > + impl; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_FIELDS_ROW diff --git a/src/odbc/include/ignite/odbc/cache/query/query_scan.h b/src/odbc/include/ignite/odbc/cache/query/query_scan.h index 7b36513ad..3a6b72f48 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_scan.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_scan.h @@ -28,132 +28,117 @@ #include "ignite/odbc/binary/binary_raw_writer.h" -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Scan query. - */ - class ScanQuery - { - public: - /** - * Default constructor. - */ - ScanQuery() : part(-1), pageSize(1024), loc(false) - { - // No-op. - } - - /** - * Constructor. - * - * @param part Partition. - */ - ScanQuery(int32_t part) : part(part), pageSize(1024), loc(false) - { - // No-op. - } - - /** - * Get partition to scan. - * - * @return Partition to scan. - */ - int32_t GetPartition() const - { - return part; - } - - /** - * Set partition to scan. - * - * @param part Partition to scan. - */ - void SetPartition(int32_t part) - { - this->part = part; - } - - /** - * Get page size. - * - * @return Page size. - */ - int32_t GetPageSize() const - { - return pageSize; - } - - /** - * Set page size. - * - * @param pageSize Page size. - */ - void SetPageSize(int32_t pageSize) - { - this->pageSize = pageSize; - } - - /** - * Get local flag. - * - * @return Local flag. - */ - bool IsLocal() const - { - return loc; - } - - /** - * Set local flag. - * - * @param loc Local flag. - */ - void SetLocal(bool loc) - { - this->loc = loc; - } - - /** - * Write query info to the stream. - * - * @param writer Writer. - */ - void Write(binary::BinaryRawWriter& writer) const - { - writer.WriteBool(loc); - writer.WriteInt32(pageSize); - - if (part < 0) - writer.WriteBool(false); - else - { - writer.WriteBool(true); - writer.WriteInt32(part); - } - - writer.WriteNull(); // Predicates are not supported yet. - } - - private: - /** Partition. */ - int32_t part; - - /** Page size. */ - int32_t pageSize; - - /** Local flag. */ - bool loc; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SCAN +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Scan query. + */ +class ScanQuery { + public: + /** + * Default constructor. + */ + ScanQuery() : part(-1), pageSize(1024), loc(false) { + // No-op. + } + + /** + * Constructor. + * + * @param part Partition. + */ + ScanQuery(int32_t part) : part(part), pageSize(1024), loc(false) { + // No-op. + } + + /** + * Get partition to scan. + * + * @return Partition to scan. + */ + int32_t GetPartition() const { + return part; + } + + /** + * Set partition to scan. + * + * @param part Partition to scan. + */ + void SetPartition(int32_t part) { + this->part = part; + } + + /** + * Get page size. + * + * @return Page size. + */ + int32_t GetPageSize() const { + return pageSize; + } + + /** + * Set page size. + * + * @param pageSize Page size. + */ + void SetPageSize(int32_t pageSize) { + this->pageSize = pageSize; + } + + /** + * Get local flag. + * + * @return Local flag. + */ + bool IsLocal() const { + return loc; + } + + /** + * Set local flag. + * + * @param loc Local flag. + */ + void SetLocal(bool loc) { + this->loc = loc; + } + + /** + * Write query info to the stream. + * + * @param writer Writer. + */ + void Write(binary::BinaryRawWriter& writer) const { + writer.WriteBool(loc); + writer.WriteInt32(pageSize); + + if (part < 0) + writer.WriteBool(false); + else { + writer.WriteBool(true); + writer.WriteInt32(part); + } + + writer.WriteNull(); // Predicates are not supported yet. + } + + private: + /** Partition. */ + int32_t part; + + /** Page size. */ + int32_t pageSize; + + /** Local flag. */ + bool loc; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SCAN diff --git a/src/odbc/include/ignite/odbc/cache/query/query_sql.h b/src/odbc/include/ignite/odbc/cache/query/query_sql.h index d7e308978..87c9a5a6c 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_sql.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_sql.h @@ -30,282 +30,260 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Sql query. - * - * @deprecated Will be removed in future releases. Use SqlFieldsQuery instead. - */ - class SqlQuery - { - public: - /** - * Constructor. - * - * @param type Type name. - * @param sql SQL string. - */ - SqlQuery(const std::string& type, const std::string& sql) : - type(type), - sql(sql), - pageSize(1024), - loc(false), - distributedJoins(false), - args() - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - SqlQuery(const SqlQuery& other) : - type(other.type), - sql(other.sql), - pageSize(other.pageSize), - loc(other.loc), - distributedJoins(other.distributedJoins), - args() - { - args.reserve(other.args.size()); - - typedef std::vector::const_iterator Iter; - - for (Iter i = other.args.begin(); i != other.args.end(); ++i) - args.push_back((*i)->Copy()); - } - - /** - * Assignment operator. - * - * @param other Other instance. - */ - SqlQuery& operator=(const SqlQuery& other) - { - if (this != &other) - { - SqlQuery tmp(other); - - Swap(tmp); - } - - return *this; - } - - /** - * Destructor. - */ - ~SqlQuery() - { - typedef std::vector::const_iterator Iter; - - for (Iter it = args.begin(); it != args.end(); ++it) - delete *it; - } - - /** - * Efficiently swaps contents with another SqlQuery instance. - * - * @param other Other instance. - */ - void Swap(SqlQuery& other) - { - if (this != &other) - { - std::swap(type, other.type); - std::swap(sql, other.sql); - std::swap(pageSize, other.pageSize); - std::swap(loc, other.loc); - std::swap(distributedJoins, other.distributedJoins); - std::swap(args, other.args); - } - } - - /** - * Get type name. - * - * @return Type name. - */ - const std::string& GetType() const - { - return type; - } - - /** - * Set type name. - * - * @param sql Type name. - */ - void SetType(const std::string& type) - { - this->type = type; - } - - /** - * Get SQL string. - * - * @return SQL string. - */ - const std::string& GetSql() const - { - return sql; - } - - /** - * Set SQL string. - * - * @param sql SQL string. - */ - void SetSql(const std::string& sql) - { - this->sql = sql; - } - - /** - * Get page size. - * - * @return Page size. - */ - int32_t GetPageSize() const - { - return pageSize; - } - - /** - * Set page size. - * - * @param pageSize Page size. - */ - void SetPageSize(int32_t pageSize) - { - this->pageSize = pageSize; - } - - /** - * Get local flag. - * - * @return Local flag. - */ - bool IsLocal() const - { - return loc; - } - - /** - * Set local flag. - * - * @param loc Local flag. - */ - void SetLocal(bool loc) - { - this->loc = loc; - } - - /** - * Check if distributed joins are enabled for this query. - * - * @return True If distributed joind enabled. - */ - bool IsDistributedJoins() const - { - return distributedJoins; - } - - /** - * Specify if distributed joins are enabled for this query. - * - * When disabled, join results will only contain colocated data (joins work locally). - * When enabled, joins work as expected, no matter how the data is distributed. - * - * @param enabled Distributed joins enabled. - */ - void SetDistributedJoins(bool enabled) - { - distributedJoins = enabled; - } - - /** - * Add argument. - * - * Template argument type should be copy-constructable and - * assignable. Also BinaryType class template should be specialized - * for this type. - * - * @param arg Argument. - */ - template - void AddArgument(const T& arg) - { - args.push_back(new impl::cache::query::QueryArgument(arg)); - } - - /** - * Remove all added arguments. - */ - void ClearArguments() - { - std::vector::iterator iter; - for (iter = args.begin(); iter != args.end(); ++iter) - delete *iter; - - args.clear(); - } - - /** - * Write query info to the stream. - * - * @param writer Writer. - */ - void Write(binary::BinaryRawWriter& writer) const - { - writer.WriteBool(loc); - writer.WriteString(sql); - writer.WriteString(type); - writer.WriteInt32(pageSize); - - writer.WriteInt32(static_cast(args.size())); - - std::vector::const_iterator it; - - for (it = args.begin(); it != args.end(); ++it) - (*it)->Write(writer); - - writer.WriteBool(distributedJoins); - writer.WriteInt32(0); // Timeout, ms - writer.WriteBool(false); // ReplicatedOnly - } - - private: - /** Type name. */ - std::string type; - - /** SQL string. */ - std::string sql; - - /** Page size. */ - int32_t pageSize; - - /** Local flag. */ - bool loc; - - /** Distributed joins flag. */ - bool distributedJoins; - - /** Arguments. */ - std::vector args; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SQL +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Sql query. + * + * @deprecated Will be removed in future releases. Use SqlFieldsQuery instead. + */ +class SqlQuery { + public: + /** + * Constructor. + * + * @param type Type name. + * @param sql SQL string. + */ + SqlQuery(const std::string& type, const std::string& sql) + : type(type), + sql(sql), + pageSize(1024), + loc(false), + distributedJoins(false), + args() { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + SqlQuery(const SqlQuery& other) + : type(other.type), + sql(other.sql), + pageSize(other.pageSize), + loc(other.loc), + distributedJoins(other.distributedJoins), + args() { + args.reserve(other.args.size()); + + typedef std::vector< + impl::cache::query::QueryArgumentBase* >::const_iterator Iter; + + for (Iter i = other.args.begin(); i != other.args.end(); ++i) + args.push_back((*i)->Copy()); + } + + /** + * Assignment operator. + * + * @param other Other instance. + */ + SqlQuery& operator=(const SqlQuery& other) { + if (this != &other) { + SqlQuery tmp(other); + + Swap(tmp); + } + + return *this; + } + + /** + * Destructor. + */ + ~SqlQuery() { + typedef std::vector< + impl::cache::query::QueryArgumentBase* >::const_iterator Iter; + + for (Iter it = args.begin(); it != args.end(); ++it) + delete *it; + } + + /** + * Efficiently swaps contents with another SqlQuery instance. + * + * @param other Other instance. + */ + void Swap(SqlQuery& other) { + if (this != &other) { + std::swap(type, other.type); + std::swap(sql, other.sql); + std::swap(pageSize, other.pageSize); + std::swap(loc, other.loc); + std::swap(distributedJoins, other.distributedJoins); + std::swap(args, other.args); + } + } + + /** + * Get type name. + * + * @return Type name. + */ + const std::string& GetType() const { + return type; + } + + /** + * Set type name. + * + * @param sql Type name. + */ + void SetType(const std::string& type) { + this->type = type; + } + + /** + * Get SQL string. + * + * @return SQL string. + */ + const std::string& GetSql() const { + return sql; + } + + /** + * Set SQL string. + * + * @param sql SQL string. + */ + void SetSql(const std::string& sql) { + this->sql = sql; + } + + /** + * Get page size. + * + * @return Page size. + */ + int32_t GetPageSize() const { + return pageSize; + } + + /** + * Set page size. + * + * @param pageSize Page size. + */ + void SetPageSize(int32_t pageSize) { + this->pageSize = pageSize; + } + + /** + * Get local flag. + * + * @return Local flag. + */ + bool IsLocal() const { + return loc; + } + + /** + * Set local flag. + * + * @param loc Local flag. + */ + void SetLocal(bool loc) { + this->loc = loc; + } + + /** + * Check if distributed joins are enabled for this query. + * + * @return True If distributed joind enabled. + */ + bool IsDistributedJoins() const { + return distributedJoins; + } + + /** + * Specify if distributed joins are enabled for this query. + * + * When disabled, join results will only contain colocated data (joins work + * locally). When enabled, joins work as expected, no matter how the data is + * distributed. + * + * @param enabled Distributed joins enabled. + */ + void SetDistributedJoins(bool enabled) { + distributedJoins = enabled; + } + + /** + * Add argument. + * + * Template argument type should be copy-constructable and + * assignable. Also BinaryType class template should be specialized + * for this type. + * + * @param arg Argument. + */ + template < typename T > + void AddArgument(const T& arg) { + args.push_back(new impl::cache::query::QueryArgument< T >(arg)); + } + + /** + * Remove all added arguments. + */ + void ClearArguments() { + std::vector< impl::cache::query::QueryArgumentBase* >::iterator iter; + for (iter = args.begin(); iter != args.end(); ++iter) + delete *iter; + + args.clear(); + } + + /** + * Write query info to the stream. + * + * @param writer Writer. + */ + void Write(binary::BinaryRawWriter& writer) const { + writer.WriteBool(loc); + writer.WriteString(sql); + writer.WriteString(type); + writer.WriteInt32(pageSize); + + writer.WriteInt32(static_cast< int32_t >(args.size())); + + std::vector< impl::cache::query::QueryArgumentBase* >::const_iterator it; + + for (it = args.begin(); it != args.end(); ++it) + (*it)->Write(writer); + + writer.WriteBool(distributedJoins); + writer.WriteInt32(0); // Timeout, ms + writer.WriteBool(false); // ReplicatedOnly + } + + private: + /** Type name. */ + std::string type; + + /** SQL string. */ + std::string sql; + + /** Page size. */ + int32_t pageSize; + + /** Local flag. */ + bool loc; + + /** Distributed joins flag. */ + bool distributedJoins; + + /** Arguments. */ + std::vector< impl::cache::query::QueryArgumentBase* > args; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SQL diff --git a/src/odbc/include/ignite/odbc/cache/query/query_sql_fields.h b/src/odbc/include/ignite/odbc/cache/query/query_sql_fields.h index afca734a4..a65354c15 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_sql_fields.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_sql_fields.h @@ -30,394 +30,371 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Sql fields query. - */ - class SqlFieldsQuery - { - public: - /** - * Constructor. - * - * @param sql SQL string. - */ - SqlFieldsQuery(const std::string& sql) : - sql(sql), - schema(), - pageSize(1024), - loc(false), - distributedJoins(false), - enforceJoinOrder(false), - lazy(false), - args() - { - // No-op. - } - - /** - * Constructor. - * - * @param sql SQL string. - * @param loc Whether query should be executed locally. - */ - SqlFieldsQuery(const std::string& sql, bool loc) : - sql(sql), - schema(), - pageSize(1024), - loc(loc), - distributedJoins(false), - enforceJoinOrder(false), - lazy(false), - args() - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - SqlFieldsQuery(const SqlFieldsQuery& other) : - sql(other.sql), - schema(other.schema), - pageSize(other.pageSize), - loc(other.loc), - distributedJoins(other.distributedJoins), - enforceJoinOrder(other.enforceJoinOrder), - lazy(other.lazy), - args() - { - args.reserve(other.args.size()); - - typedef std::vector::const_iterator Iter; - - for (Iter i = other.args.begin(); i != other.args.end(); ++i) - args.push_back((*i)->Copy()); - } - - /** - * Assignment operator. - * - * @param other Other instance. - */ - SqlFieldsQuery& operator=(const SqlFieldsQuery& other) - { - if (this != &other) - { - SqlFieldsQuery tmp(other); - - Swap(tmp); - } - - return *this; - } - - /** - * Destructor. - */ - ~SqlFieldsQuery() - { - typedef std::vector::const_iterator Iter; - - for (Iter it = args.begin(); it != args.end(); ++it) - delete *it; - } - - /** - * Efficiently swaps contents with another SqlQuery instance. - * - * @param other Other instance. - */ - void Swap(SqlFieldsQuery& other) - { - if (this != &other) - { - using std::swap; - - swap(sql, other.sql); - swap(schema, other.schema); - swap(pageSize, other.pageSize); - swap(loc, other.loc); - swap(distributedJoins, other.distributedJoins); - swap(enforceJoinOrder, other.enforceJoinOrder); - swap(lazy, other.lazy); - swap(args, other.args); - } - } - - /** - * Get SQL string. - * - * @return SQL string. - */ - const std::string& GetSql() const - { - return sql; - } - - /** - * Set SQL string. - * - * @param sql SQL string. - */ - void SetSql(const std::string& sql) - { - this->sql = sql; - } - - /** - * Get page size. - * - * @return Page size. - */ - int32_t GetPageSize() const - { - return pageSize; - } - - /** - * Set page size. - * - * @param pageSize Page size. - */ - void SetPageSize(int32_t pageSize) - { - this->pageSize = pageSize; - } - - /** - * Get local flag. - * - * @return Local flag. - */ - bool IsLocal() const - { - return loc; - } - - /** - * Set local flag. - * - * @param loc Local flag. - */ - void SetLocal(bool loc) - { - this->loc = loc; - } - - /** - * Gets lazy query execution flag. - * - * See SetLazy(bool) for more information. - * - * @return Lazy flag. - */ - bool IsLazy() const - { - return lazy; - } - - /** - * Sets lazy query execution flag. - * - * By default Ignite attempts to fetch the whole query result set to memory and send it to the client. - * For small and medium result sets this provides optimal performance and minimize duration of internal - * database locks, thus increasing concurrency. - * - * If result set is too big to fit in available memory this could lead to excessive GC pauses and even - * OutOfMemoryError. Use this flag as a hint for Ignite to fetch result set lazily, thus minimizing - * memory consumption at the cost of moderate performance hit. - * - * Defaults to @c false, meaning that the whole result set is fetched to memory eagerly. - * - * @param lazy Lazy query execution flag. - */ - void SetLazy(bool lazy) - { - this->lazy = lazy; - } - - /** - * Checks if join order of tables if enforced. - * - * @return Flag value. - */ - bool IsEnforceJoinOrder() const - { - return enforceJoinOrder; - } - - /** - * Sets flag to enforce join order of tables in the query. - * - * If set to true query optimizer will not reorder tables in join. By default is false. - * - * It is not recommended to enable this property unless you are sure that your indexes and the query - * itself are correct and tuned as much as possible but query optimizer still produces wrong join order. - * - * @param enforce Flag value. - */ - void SetEnforceJoinOrder(bool enforce) - { - enforceJoinOrder = enforce; - } - - /** - * Check if distributed joins are enabled for this query. - * - * @return True If distributed joind enabled. - */ - bool IsDistributedJoins() const - { - return distributedJoins; - } - - /** - * Specify if distributed joins are enabled for this query. - * - * When disabled, join results will only contain colocated data (joins work locally). - * When enabled, joins work as expected, no matter how the data is distributed. - * - * @param enabled Distributed joins enabled. - */ - void SetDistributedJoins(bool enabled) - { - distributedJoins = enabled; - } - - /** - * Add argument. - * - * Template argument type should be copy-constructable and assignable. Also BinaryType class template - * should be specialized for this type. - * - * @param arg Argument. - */ - template - void AddArgument(const T& arg) - { - args.push_back(new impl::cache::query::QueryArgument(arg)); - } - - /** - * Add array of bytes as an argument. - * - * @param src Array pointer. - * @param len Array length in bytes. - */ - void AddInt8ArrayArgument(const int8_t* src, int32_t len) - { - args.push_back(new impl::cache::query::QueryInt8ArrayArgument(src, len)); - } - - /** - * Remove all added arguments. - */ - void ClearArguments() - { - std::vector::iterator iter; - for (iter = args.begin(); iter != args.end(); ++iter) - delete *iter; - - args.clear(); - } - - /** - * Set schema name for the query. - * If not set, current cache name is used, which means you can omit schema name for tables within the - * current cache. - * - * @param schema Schema. Empty string to unset. - */ - void SetSchema(const std::string& schema) - { - this->schema = schema; - } - - /** - * Get schema name for the query. - * - * If not set, current cache name is used, which means you can omit schema name for tables within the - * current cache. - * - * @return Schema. Empty string if not set. - */ - const std::string& GetSchema() const - { - return schema; - } - - /** - * Write query info to the stream. - * - * @param writer Writer. - */ - void Write(binary::BinaryRawWriter& writer) const - { - writer.WriteBool(loc); - writer.WriteString(sql); - writer.WriteInt32(pageSize); - - writer.WriteInt32(static_cast(args.size())); - - std::vector::const_iterator it; - - for (it = args.begin(); it != args.end(); ++it) - (*it)->Write(writer); - - writer.WriteBool(distributedJoins); - writer.WriteBool(enforceJoinOrder); - writer.WriteBool(lazy); - writer.WriteInt32(0); // Timeout, ms - writer.WriteBool(false); // ReplicatedOnly - writer.WriteBool(false); // Colocated - - if (schema.empty()) - writer.WriteNull(); - else - writer.WriteString(schema); - - writer.WriteInt32Array(NULL, 0); // Partitions - writer.WriteInt32(1); // UpdateBatchSize - } - - private: - /** SQL string. */ - std::string sql; - - /** SQL Schema. */ - std::string schema; - - /** Page size. */ - int32_t pageSize; - - /** Local flag. */ - bool loc; - - /** Distributed joins flag. */ - bool distributedJoins; - - /** Enforce join order flag. */ - bool enforceJoinOrder; - - /** Lazy flag. */ - bool lazy; - - /** Arguments. */ - std::vector args; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SQL_FIELDS +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Sql fields query. + */ +class SqlFieldsQuery { + public: + /** + * Constructor. + * + * @param sql SQL string. + */ + SqlFieldsQuery(const std::string& sql) + : sql(sql), + schema(), + pageSize(1024), + loc(false), + distributedJoins(false), + enforceJoinOrder(false), + lazy(false), + args() { + // No-op. + } + + /** + * Constructor. + * + * @param sql SQL string. + * @param loc Whether query should be executed locally. + */ + SqlFieldsQuery(const std::string& sql, bool loc) + : sql(sql), + schema(), + pageSize(1024), + loc(loc), + distributedJoins(false), + enforceJoinOrder(false), + lazy(false), + args() { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + SqlFieldsQuery(const SqlFieldsQuery& other) + : sql(other.sql), + schema(other.schema), + pageSize(other.pageSize), + loc(other.loc), + distributedJoins(other.distributedJoins), + enforceJoinOrder(other.enforceJoinOrder), + lazy(other.lazy), + args() { + args.reserve(other.args.size()); + + typedef std::vector< + impl::cache::query::QueryArgumentBase* >::const_iterator Iter; + + for (Iter i = other.args.begin(); i != other.args.end(); ++i) + args.push_back((*i)->Copy()); + } + + /** + * Assignment operator. + * + * @param other Other instance. + */ + SqlFieldsQuery& operator=(const SqlFieldsQuery& other) { + if (this != &other) { + SqlFieldsQuery tmp(other); + + Swap(tmp); + } + + return *this; + } + + /** + * Destructor. + */ + ~SqlFieldsQuery() { + typedef std::vector< + impl::cache::query::QueryArgumentBase* >::const_iterator Iter; + + for (Iter it = args.begin(); it != args.end(); ++it) + delete *it; + } + + /** + * Efficiently swaps contents with another SqlQuery instance. + * + * @param other Other instance. + */ + void Swap(SqlFieldsQuery& other) { + if (this != &other) { + using std::swap; + + swap(sql, other.sql); + swap(schema, other.schema); + swap(pageSize, other.pageSize); + swap(loc, other.loc); + swap(distributedJoins, other.distributedJoins); + swap(enforceJoinOrder, other.enforceJoinOrder); + swap(lazy, other.lazy); + swap(args, other.args); + } + } + + /** + * Get SQL string. + * + * @return SQL string. + */ + const std::string& GetSql() const { + return sql; + } + + /** + * Set SQL string. + * + * @param sql SQL string. + */ + void SetSql(const std::string& sql) { + this->sql = sql; + } + + /** + * Get page size. + * + * @return Page size. + */ + int32_t GetPageSize() const { + return pageSize; + } + + /** + * Set page size. + * + * @param pageSize Page size. + */ + void SetPageSize(int32_t pageSize) { + this->pageSize = pageSize; + } + + /** + * Get local flag. + * + * @return Local flag. + */ + bool IsLocal() const { + return loc; + } + + /** + * Set local flag. + * + * @param loc Local flag. + */ + void SetLocal(bool loc) { + this->loc = loc; + } + + /** + * Gets lazy query execution flag. + * + * See SetLazy(bool) for more information. + * + * @return Lazy flag. + */ + bool IsLazy() const { + return lazy; + } + + /** + * Sets lazy query execution flag. + * + * By default Ignite attempts to fetch the whole query result set to memory + * and send it to the client. For small and medium result sets this provides + * optimal performance and minimize duration of internal database locks, thus + * increasing concurrency. + * + * If result set is too big to fit in available memory this could lead to + * excessive GC pauses and even OutOfMemoryError. Use this flag as a hint for + * Ignite to fetch result set lazily, thus minimizing memory consumption at + * the cost of moderate performance hit. + * + * Defaults to @c false, meaning that the whole result set is fetched to + * memory eagerly. + * + * @param lazy Lazy query execution flag. + */ + void SetLazy(bool lazy) { + this->lazy = lazy; + } + + /** + * Checks if join order of tables if enforced. + * + * @return Flag value. + */ + bool IsEnforceJoinOrder() const { + return enforceJoinOrder; + } + + /** + * Sets flag to enforce join order of tables in the query. + * + * If set to true query optimizer will not reorder tables in join. By default + * is false. + * + * It is not recommended to enable this property unless you are sure that your + * indexes and the query itself are correct and tuned as much as possible but + * query optimizer still produces wrong join order. + * + * @param enforce Flag value. + */ + void SetEnforceJoinOrder(bool enforce) { + enforceJoinOrder = enforce; + } + + /** + * Check if distributed joins are enabled for this query. + * + * @return True If distributed joind enabled. + */ + bool IsDistributedJoins() const { + return distributedJoins; + } + + /** + * Specify if distributed joins are enabled for this query. + * + * When disabled, join results will only contain colocated data (joins work + * locally). When enabled, joins work as expected, no matter how the data is + * distributed. + * + * @param enabled Distributed joins enabled. + */ + void SetDistributedJoins(bool enabled) { + distributedJoins = enabled; + } + + /** + * Add argument. + * + * Template argument type should be copy-constructable and assignable. Also + * BinaryType class template should be specialized for this type. + * + * @param arg Argument. + */ + template < typename T > + void AddArgument(const T& arg) { + args.push_back(new impl::cache::query::QueryArgument< T >(arg)); + } + + /** + * Add array of bytes as an argument. + * + * @param src Array pointer. + * @param len Array length in bytes. + */ + void AddInt8ArrayArgument(const int8_t* src, int32_t len) { + args.push_back(new impl::cache::query::QueryInt8ArrayArgument(src, len)); + } + + /** + * Remove all added arguments. + */ + void ClearArguments() { + std::vector< impl::cache::query::QueryArgumentBase* >::iterator iter; + for (iter = args.begin(); iter != args.end(); ++iter) + delete *iter; + + args.clear(); + } + + /** + * Set schema name for the query. + * If not set, current cache name is used, which means you can omit schema + * name for tables within the current cache. + * + * @param schema Schema. Empty string to unset. + */ + void SetSchema(const std::string& schema) { + this->schema = schema; + } + + /** + * Get schema name for the query. + * + * If not set, current cache name is used, which means you can omit schema + * name for tables within the current cache. + * + * @return Schema. Empty string if not set. + */ + const std::string& GetSchema() const { + return schema; + } + + /** + * Write query info to the stream. + * + * @param writer Writer. + */ + void Write(binary::BinaryRawWriter& writer) const { + writer.WriteBool(loc); + writer.WriteString(sql); + writer.WriteInt32(pageSize); + + writer.WriteInt32(static_cast< int32_t >(args.size())); + + std::vector< impl::cache::query::QueryArgumentBase* >::const_iterator it; + + for (it = args.begin(); it != args.end(); ++it) + (*it)->Write(writer); + + writer.WriteBool(distributedJoins); + writer.WriteBool(enforceJoinOrder); + writer.WriteBool(lazy); + writer.WriteInt32(0); // Timeout, ms + writer.WriteBool(false); // ReplicatedOnly + writer.WriteBool(false); // Colocated + + if (schema.empty()) + writer.WriteNull(); + else + writer.WriteString(schema); + + writer.WriteInt32Array(NULL, 0); // Partitions + writer.WriteInt32(1); // UpdateBatchSize + } + + private: + /** SQL string. */ + std::string sql; + + /** SQL Schema. */ + std::string schema; + + /** Page size. */ + int32_t pageSize; + + /** Local flag. */ + bool loc; + + /** Distributed joins flag. */ + bool distributedJoins; + + /** Enforce join order flag. */ + bool enforceJoinOrder; + + /** Lazy flag. */ + bool lazy; + + /** Arguments. */ + std::vector< impl::cache::query::QueryArgumentBase* > args; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_SQL_FIELDS diff --git a/src/odbc/include/ignite/odbc/cache/query/query_text.h b/src/odbc/include/ignite/odbc/cache/query/query_text.h index 34c4d2e5f..b3b4b9dbd 100644 --- a/src/odbc/include/ignite/odbc/cache/query/query_text.h +++ b/src/odbc/include/ignite/odbc/cache/query/query_text.h @@ -28,141 +28,126 @@ #include "ignite/odbc/binary/binary_raw_writer.h" -namespace ignite -{ - namespace odbc - { - namespace cache - { - namespace query - { - /** - * Text query. - */ - class TextQuery - { - public: - /** - * Constructor. - * - * @param type Type name. - * @param text Text string. - */ - TextQuery(const std::string& type, const std::string& text) : - type(type), text(text), pageSize(1024), loc(false) - { - // No-op. - } - - /** - * Get type name. - * - * @return Type name. - */ - const std::string& GetType() const - { - return type; - } - - /** - * Set type name. - * - * @param sql Type name. - */ - void SetType(const std::string& type) - { - this->type = type; - } - - /** - * Get text string. - * - * @return text string. - */ - const std::string& GetText() const - { - return text; - } - - /** - * Set text string. - * - * @param text Text string. - */ - void SetText(const std::string& text) - { - this->text = text; - } - - /** - * Get page size. - * - * @return Page size. - */ - int32_t GetPageSize() const - { - return pageSize; - } - - /** - * Set page size. - * - * @param pageSize Page size. - */ - void SetPageSize(int32_t pageSize) - { - this->pageSize = pageSize; - } - - /** - * Get local flag. - * - * @return Local flag. - */ - bool IsLocal() const - { - return loc; - } - - /** - * Set local flag. - * - * @param loc Local flag. - */ - void SetLocal(bool loc) - { - this->loc = loc; - } - - /** - * Write query info to the stream. - * - * @param writer Writer. - */ - void Write(binary::BinaryRawWriter& writer) const - { - writer.WriteBool(loc); - writer.WriteString(text); - writer.WriteString(type); - writer.WriteInt32(pageSize); - } - - private: - /** Type name. */ - std::string type; - - /** Text string. */ - std::string text; - - /** Page size. */ - int32_t pageSize; - - /** Local flag. */ - bool loc; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_TEXT +namespace ignite { +namespace odbc { +namespace cache { +namespace query { +/** + * Text query. + */ +class TextQuery { + public: + /** + * Constructor. + * + * @param type Type name. + * @param text Text string. + */ + TextQuery(const std::string& type, const std::string& text) + : type(type), text(text), pageSize(1024), loc(false) { + // No-op. + } + + /** + * Get type name. + * + * @return Type name. + */ + const std::string& GetType() const { + return type; + } + + /** + * Set type name. + * + * @param sql Type name. + */ + void SetType(const std::string& type) { + this->type = type; + } + + /** + * Get text string. + * + * @return text string. + */ + const std::string& GetText() const { + return text; + } + + /** + * Set text string. + * + * @param text Text string. + */ + void SetText(const std::string& text) { + this->text = text; + } + + /** + * Get page size. + * + * @return Page size. + */ + int32_t GetPageSize() const { + return pageSize; + } + + /** + * Set page size. + * + * @param pageSize Page size. + */ + void SetPageSize(int32_t pageSize) { + this->pageSize = pageSize; + } + + /** + * Get local flag. + * + * @return Local flag. + */ + bool IsLocal() const { + return loc; + } + + /** + * Set local flag. + * + * @param loc Local flag. + */ + void SetLocal(bool loc) { + this->loc = loc; + } + + /** + * Write query info to the stream. + * + * @param writer Writer. + */ + void Write(binary::BinaryRawWriter& writer) const { + writer.WriteBool(loc); + writer.WriteString(text); + writer.WriteString(type); + writer.WriteInt32(pageSize); + } + + private: + /** Type name. */ + std::string type; + + /** Text string. */ + std::string text; + + /** Page size. */ + int32_t pageSize; + + /** Local flag. */ + bool loc; +}; +} // namespace query +} // namespace cache +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CACHE_QUERY_QUERY_TEXT diff --git a/src/odbc/include/ignite/odbc/cluster/cluster_group.h b/src/odbc/include/ignite/odbc/cluster/cluster_group.h index 75bb7cdf9..d62ee5bca 100644 --- a/src/odbc/include/ignite/odbc/cluster/cluster_group.h +++ b/src/odbc/include/ignite/odbc/cluster/cluster_group.h @@ -15,10 +15,10 @@ * limitations under the License. */ - /** - * @file - * Declares ignite::odbc::cluster::ClusterGroup class. - */ +/** + * @file + * Declares ignite::odbc::cluster::ClusterGroup class. + */ #ifndef _IGNITE_ODBC_CLUSTER_CLUSTER_GROUP #define _IGNITE_ODBC_CLUSTER_CLUSTER_GROUP @@ -27,229 +27,239 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - class IgniteImpl; - } - - namespace cluster - { - /** - * Defines a cluster group which contains all or a subset of cluster nodes. - * Cluster group allows to group cluster nodes into various subgroups to perform distributed operations on them. - * The IgniteCluster interface itself also contains the ClusterGroup which makes an instance of IgniteCluster - * into a cluster group containing all cluster nodes. Use IgniteCluster::AsClusterGroup() to get the cluster group in this case. - */ - class IGNITE_IMPORT_EXPORT ClusterGroup - { - friend class impl::cluster::ClusterGroupImpl; - friend class impl::IgniteImpl; - public: - /** - * Constructor. - * - * @param pointer to cluster group implementation. - */ - ClusterGroup(impl::cluster::SP_ClusterGroupImpl impl); - - /** - * Get cluster group for nodes containing given name and value specified in user attributes. - * - * @param name Name of the attribute. - * @param val Optional attribute value to match. - * @return Cluster group for nodes containing specified attribute. - */ - ClusterGroup ForAttribute(std::string name, std::string val); - - /** - * Get cluster group for all nodes that have cache with specified name, either in client or server modes. - * - * @param cacheName Cache name. - * @return Cluster group over nodes that have the cache with the specified name running. - */ - ClusterGroup ForCacheNodes(std::string cacheName); - - /** - * Get cluster group for all client nodes that access cache with the specified name. - * - * @param cacheName Cache name. - * @return Cluster group over nodes that have the cache with the specified name running. - */ - ClusterGroup ForClientNodes(std::string cacheName); - - /** - * Get a cluster group of nodes started in client mode. - * - * @return Cluster group over nodes that started in client mode. - */ - ClusterGroup ForClients(); - - /** - * Get cluster group consisting from the daemon nodes. - * - * @return Cluster group consisting from the daemon nodes. - */ - ClusterGroup ForDaemons(); - - /** - * Get ClusterGroup for all data nodes that have the cache with the specified name running. - * - * @param cacheName Cache name. - * @return Cluster group over nodes that have the cache with the specified name running. - */ - ClusterGroup ForDataNodes(std::string cacheName); - - /** - * Get cluster group consisting from the nodes in this cluster group residing on the same host as the given node. - * - * @param node Cluster node. - * @return Cluster group residing on the same host as the given node. - */ - ClusterGroup ForHost(ClusterNode node); - - /** - * Get cluster group consisting from the nodes running on the host specified. - * - * @param hostName Host name. - * @return Cluster group over nodes that have requested host name. - */ - ClusterGroup ForHost(std::string hostName); - - /** - * Get cluster group consisting from the nodes running on the hosts specified. - * - * @param hostNames Container of host names. - * @return Cluster group over nodes that have requested host names. - */ - ClusterGroup ForHosts(std::vector hostNames); - - /** - * Get cluster group for the given node. - * - * @param node Cluster node. - * @return Cluster group for the given node. - */ - ClusterGroup ForNode(ClusterNode node); - - /** - * Get cluster group for a node with the specified ID. - * - * @param id Cluster node ID. - * @return Cluster group for a node with the specified ID. - */ - ClusterGroup ForNodeId(Guid id); - - /** - * Get cluster group over nodes with specified node IDs. - * - * @param ids Cluster node IDs. - * @return Cluster group over nodes with specified node IDs. - */ - ClusterGroup ForNodeIds(std::vector ids); - - /** - * Get cluster group over a given set of nodes. - * - * @param nodes Cluster nodes. - * @return Cluster group over a given set of nodes. - */ - ClusterGroup ForNodes(std::vector nodes); - - /** - * Get cluster group with one oldest node from the current cluster group. - * - * @return Cluster group with one oldest node from the current cluster group. - */ - ClusterGroup ForOldest(); - - /** - * Create a new cluster group which includes all nodes that pass the given predicate filter. - * - * @param pred Pointer to predicate heap object. User should NOT free the memory used by object. - * @return Newly created cluster group. - * - * @throw IgniteError if there are no nodes in the cluster group. - */ - ClusterGroup ForPredicate(IgnitePredicate* pred); - - /** - * Get cluster group with one random node from the current cluster group. - * - * @return Cluster group with one random node from the current cluster group. - */ - ClusterGroup ForRandom(); - - /** - * Get cluster group consisting from the nodes in this cluster group excluding the local node. - * - * @return Cluster group consisting from the nodes in this cluster group excluding the local node. - */ - ClusterGroup ForRemotes(); - - /** - * Creates a cluster group of nodes started in server mode. - * - * @return Cluster group of nodes started in server mode. - */ - ClusterGroup ForServers(); - - /** - * Get cluster group with one youngest node in the current cluster group. - * - * @return Cluster group with one youngest node in the current cluster group. - */ - ClusterGroup ForYoungest(); - - /** - * Creates a cluster group of cpp nodes. - * - * @return Cluster group of cpp nodes. - */ - ClusterGroup ForCpp(); - - /** - * Get first node from the list of nodes in this cluster group. - * - * @return Cluster node in this cluster group. - * - * @throw IgniteError if there are no nodes in the cluster group. - */ - ClusterNode GetNode(); - - /** - * Get node for given ID from this cluster group. - * - * @param nid Cluster node ID. - * @return Cluster node in this cluster group. - * - * @throw IgniteError if there is no node with specified ID. - */ - ClusterNode GetNode(Guid nid); - - /** - * Get the vector of nodes in this cluster group. - * - * @return All nodes in this cluster group. - */ - std::vector GetNodes(); - - /** - * Get predicate that defines a subset of nodes for this cluster group. - * - * @return Pointer to predicate. - */ - IgnitePredicate* GetPredicate(); - - private: - impl::cluster::SP_ClusterGroupImpl impl; - impl::cluster::SP_ClusterGroupImpl GetImpl(); - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +class IgniteImpl; } -#endif //_IGNITE_ODBC_CLUSTER_CLUSTER_GROUP +namespace cluster { +/** + * Defines a cluster group which contains all or a subset of cluster nodes. + * Cluster group allows to group cluster nodes into various subgroups to perform + * distributed operations on them. The IgniteCluster interface itself also + * contains the ClusterGroup which makes an instance of IgniteCluster into a + * cluster group containing all cluster nodes. Use + * IgniteCluster::AsClusterGroup() to get the cluster group in this case. + */ +class IGNITE_IMPORT_EXPORT ClusterGroup { + friend class impl::cluster::ClusterGroupImpl; + friend class impl::IgniteImpl; + + public: + /** + * Constructor. + * + * @param pointer to cluster group implementation. + */ + ClusterGroup(impl::cluster::SP_ClusterGroupImpl impl); + + /** + * Get cluster group for nodes containing given name and value specified in + * user attributes. + * + * @param name Name of the attribute. + * @param val Optional attribute value to match. + * @return Cluster group for nodes containing specified attribute. + */ + ClusterGroup ForAttribute(std::string name, std::string val); + + /** + * Get cluster group for all nodes that have cache with specified name, either + * in client or server modes. + * + * @param cacheName Cache name. + * @return Cluster group over nodes that have the cache with the specified + * name running. + */ + ClusterGroup ForCacheNodes(std::string cacheName); + + /** + * Get cluster group for all client nodes that access cache with the specified + * name. + * + * @param cacheName Cache name. + * @return Cluster group over nodes that have the cache with the specified + * name running. + */ + ClusterGroup ForClientNodes(std::string cacheName); + + /** + * Get a cluster group of nodes started in client mode. + * + * @return Cluster group over nodes that started in client mode. + */ + ClusterGroup ForClients(); + + /** + * Get cluster group consisting from the daemon nodes. + * + * @return Cluster group consisting from the daemon nodes. + */ + ClusterGroup ForDaemons(); + + /** + * Get ClusterGroup for all data nodes that have the cache with the specified + * name running. + * + * @param cacheName Cache name. + * @return Cluster group over nodes that have the cache with the specified + * name running. + */ + ClusterGroup ForDataNodes(std::string cacheName); + + /** + * Get cluster group consisting from the nodes in this cluster group residing + * on the same host as the given node. + * + * @param node Cluster node. + * @return Cluster group residing on the same host as the given node. + */ + ClusterGroup ForHost(ClusterNode node); + + /** + * Get cluster group consisting from the nodes running on the host specified. + * + * @param hostName Host name. + * @return Cluster group over nodes that have requested host name. + */ + ClusterGroup ForHost(std::string hostName); + + /** + * Get cluster group consisting from the nodes running on the hosts specified. + * + * @param hostNames Container of host names. + * @return Cluster group over nodes that have requested host names. + */ + ClusterGroup ForHosts(std::vector< std::string > hostNames); + + /** + * Get cluster group for the given node. + * + * @param node Cluster node. + * @return Cluster group for the given node. + */ + ClusterGroup ForNode(ClusterNode node); + + /** + * Get cluster group for a node with the specified ID. + * + * @param id Cluster node ID. + * @return Cluster group for a node with the specified ID. + */ + ClusterGroup ForNodeId(Guid id); + + /** + * Get cluster group over nodes with specified node IDs. + * + * @param ids Cluster node IDs. + * @return Cluster group over nodes with specified node IDs. + */ + ClusterGroup ForNodeIds(std::vector< Guid > ids); + + /** + * Get cluster group over a given set of nodes. + * + * @param nodes Cluster nodes. + * @return Cluster group over a given set of nodes. + */ + ClusterGroup ForNodes(std::vector< ClusterNode > nodes); + + /** + * Get cluster group with one oldest node from the current cluster group. + * + * @return Cluster group with one oldest node from the current cluster group. + */ + ClusterGroup ForOldest(); + + /** + * Create a new cluster group which includes all nodes that pass the given + * predicate filter. + * + * @param pred Pointer to predicate heap object. User should NOT free the + * memory used by object. + * @return Newly created cluster group. + * + * @throw IgniteError if there are no nodes in the cluster group. + */ + ClusterGroup ForPredicate(IgnitePredicate< ClusterNode >* pred); + + /** + * Get cluster group with one random node from the current cluster group. + * + * @return Cluster group with one random node from the current cluster group. + */ + ClusterGroup ForRandom(); + + /** + * Get cluster group consisting from the nodes in this cluster group excluding + * the local node. + * + * @return Cluster group consisting from the nodes in this cluster group + * excluding the local node. + */ + ClusterGroup ForRemotes(); + + /** + * Creates a cluster group of nodes started in server mode. + * + * @return Cluster group of nodes started in server mode. + */ + ClusterGroup ForServers(); + + /** + * Get cluster group with one youngest node in the current cluster group. + * + * @return Cluster group with one youngest node in the current cluster group. + */ + ClusterGroup ForYoungest(); + + /** + * Creates a cluster group of cpp nodes. + * + * @return Cluster group of cpp nodes. + */ + ClusterGroup ForCpp(); + + /** + * Get first node from the list of nodes in this cluster group. + * + * @return Cluster node in this cluster group. + * + * @throw IgniteError if there are no nodes in the cluster group. + */ + ClusterNode GetNode(); + + /** + * Get node for given ID from this cluster group. + * + * @param nid Cluster node ID. + * @return Cluster node in this cluster group. + * + * @throw IgniteError if there is no node with specified ID. + */ + ClusterNode GetNode(Guid nid); + + /** + * Get the vector of nodes in this cluster group. + * + * @return All nodes in this cluster group. + */ + std::vector< ClusterNode > GetNodes(); + + /** + * Get predicate that defines a subset of nodes for this cluster group. + * + * @return Pointer to predicate. + */ + IgnitePredicate< ClusterNode >* GetPredicate(); + + private: + impl::cluster::SP_ClusterGroupImpl impl; + impl::cluster::SP_ClusterGroupImpl GetImpl(); +}; +} // namespace cluster +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CLUSTER_CLUSTER_GROUP diff --git a/src/odbc/include/ignite/odbc/cluster/cluster_node.h b/src/odbc/include/ignite/odbc/cluster/cluster_node.h index 52bf23279..7d549ed8b 100644 --- a/src/odbc/include/ignite/odbc/cluster/cluster_node.h +++ b/src/odbc/include/ignite/odbc/cluster/cluster_node.h @@ -15,146 +15,147 @@ * limitations under the License. */ - /** - * @file - * Declares ignite::odbc::cluster::ClusterNode class. - */ +/** + * @file + * Declares ignite::odbc::cluster::ClusterNode class. + */ #ifndef _IGNITE_ODBC_CLUSTER_CLUSTER_NODE #define _IGNITE_ODBC_CLUSTER_CLUSTER_NODE #include -namespace ignite -{ - namespace odbc - { - namespace cluster - { - /** - * Interface representing a single cluster node. - * Use GetAttribute(String) or GetMetrics() to get static and dynamic information about cluster nodes. - */ - class IGNITE_IMPORT_EXPORT ClusterNode - { - public: - /** - * Constructor. - * - * @param impl Pointer to cluster node implementation. - */ - ClusterNode(common::concurrent::SharedPointer impl); - - /** - * Get collection of addresses this node is known by. - * - * @return Collection of addresses this node is known by. - */ - const std::vector& GetAddresses() const; - - /** - * Check if node attribute is set. - * - * @param name Node attribute name. - * @return True if set. - */ - bool IsAttributeSet(std::string name) const; - - /** - * Get a node attribute. - * - * @param name Node attribute name. - * @return Node attribute. - * - * @throw IgniteError in case of attribute name does not exist - * or if template type is not compatible with attribute. - */ - template - T GetAttribute(std::string name) const - { - return impl.Get()->GetAttribute(name); - } - - /** - * Get collection of all Cluster Node attributes names. - * - * @return Node attributes names collection. - */ - std::vector GetAttributes() const; - - /** - * Get Cluster Node consistent ID. - * - * @return Cluster Node consistent ID. - */ - std::string GetConsistentId() const; - - /** - * Get collection of host names this node is known by. - * - * @return Collection of host names this node is known by. - */ - const std::vector& GetHostNames() const; - - /** - * Get globally unique node ID. A new ID is generated every time a node restarts - * - * @return Node Guid. - */ - Guid GetId() const; - - /** - * Check if cluster node started in client mode. - * - * @return True if in client mode and false otherwise. - */ - bool IsClient() const; - - /** - * Check whether or not this node is a daemon. - * - * @return True if is daemon and false otherwise. - */ - bool IsDaemon() const; - - /** - * Check whether or not this node is a local node. - * - * @return True if is local and false otherwise. - */ - bool IsLocal() const; - - /** - * Node order within grid topology. - * - * @return Node order. - */ - int64_t GetOrder() const; - - /** - * Get node version. - * - * @return Prodcut version. - */ - const IgniteProductVersion& GetVersion() const; - - /** - * Define "less" operator to allow Cluster Node usage as STL container key. - * - * @param lnode Left cluster node. - * @param rnode Right cluster node. - * @return True if less. - */ - friend IGNITE_IMPORT_EXPORT bool operator<(const ClusterNode& lnode, const ClusterNode& rnode) - { - return lnode.GetId() < rnode.GetId(); - } - - private: - common::concurrent::SharedPointer impl; - }; - } - } -} - -#endif //_IGNITE_ODBC_CLUSTER_CLUSTER_NODE +namespace ignite { +namespace odbc { +namespace cluster { +/** + * Interface representing a single cluster node. + * Use GetAttribute(String) or GetMetrics() to get static and dynamic + * information about cluster nodes. + */ +class IGNITE_IMPORT_EXPORT ClusterNode { + public: + /** + * Constructor. + * + * @param impl Pointer to cluster node implementation. + */ + ClusterNode(common::concurrent::SharedPointer< + ignite::odbc::impl::cluster::ClusterNodeImpl > + impl); + + /** + * Get collection of addresses this node is known by. + * + * @return Collection of addresses this node is known by. + */ + const std::vector< std::string >& GetAddresses() const; + + /** + * Check if node attribute is set. + * + * @param name Node attribute name. + * @return True if set. + */ + bool IsAttributeSet(std::string name) const; + + /** + * Get a node attribute. + * + * @param name Node attribute name. + * @return Node attribute. + * + * @throw IgniteError in case of attribute name does not exist + * or if template type is not compatible with attribute. + */ + template < typename T > + T GetAttribute(std::string name) const { + return impl.Get()->GetAttribute< T >(name); + } + + /** + * Get collection of all Cluster Node attributes names. + * + * @return Node attributes names collection. + */ + std::vector< std::string > GetAttributes() const; + + /** + * Get Cluster Node consistent ID. + * + * @return Cluster Node consistent ID. + */ + std::string GetConsistentId() const; + + /** + * Get collection of host names this node is known by. + * + * @return Collection of host names this node is known by. + */ + const std::vector< std::string >& GetHostNames() const; + + /** + * Get globally unique node ID. A new ID is generated every time a node + * restarts + * + * @return Node Guid. + */ + Guid GetId() const; + + /** + * Check if cluster node started in client mode. + * + * @return True if in client mode and false otherwise. + */ + bool IsClient() const; + + /** + * Check whether or not this node is a daemon. + * + * @return True if is daemon and false otherwise. + */ + bool IsDaemon() const; + + /** + * Check whether or not this node is a local node. + * + * @return True if is local and false otherwise. + */ + bool IsLocal() const; + + /** + * Node order within grid topology. + * + * @return Node order. + */ + int64_t GetOrder() const; + + /** + * Get node version. + * + * @return Prodcut version. + */ + const IgniteProductVersion& GetVersion() const; + + /** + * Define "less" operator to allow Cluster Node usage as STL container key. + * + * @param lnode Left cluster node. + * @param rnode Right cluster node. + * @return True if less. + */ + friend IGNITE_IMPORT_EXPORT bool operator<(const ClusterNode& lnode, + const ClusterNode& rnode) { + return lnode.GetId() < rnode.GetId(); + } + + private: + common::concurrent::SharedPointer< + ignite::odbc::impl::cluster::ClusterNodeImpl > + impl; +}; +} // namespace cluster +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CLUSTER_CLUSTER_NODE diff --git a/src/odbc/include/ignite/odbc/cluster/ignite_cluster.h b/src/odbc/include/ignite/odbc/cluster/ignite_cluster.h index 08f11c0b5..51fce6da5 100644 --- a/src/odbc/include/ignite/odbc/cluster/ignite_cluster.h +++ b/src/odbc/include/ignite/odbc/cluster/ignite_cluster.h @@ -15,10 +15,10 @@ * limitations under the License. */ - /** - * @file - * Declares ignite::odbc::cluster::IgniteCluster class. - */ +/** + * @file + * Declares ignite::odbc::cluster::IgniteCluster class. + */ #ifndef _IGNITE_ODBC_CLUSTER_IGNITE_ODBC_CLUSTER #define _IGNITE_ODBC_CLUSTER_IGNITE_ODBC_CLUSTER @@ -27,129 +27,130 @@ #include -namespace ignite -{ - namespace odbc - { - namespace cluster - { - /** - * Represents whole cluster (all available nodes). Node-local map is useful for saving shared state - * between job executions on the grid. Additionally you can also ping, start, and restart remote nodes, map keys to - * caching nodes, and get other useful information about topology. - */ - class IGNITE_IMPORT_EXPORT IgniteCluster - { - public: - /** - * Constructor. - * - * @param impl Pointer to ignite cluster implementation. - */ - IgniteCluster(common::concurrent::SharedPointer impl); - - /** - * Check if the Ignite grid is active. - * - * @return True if grid is active and false otherwise. - */ - bool IsActive(); - - /** - * Change Ignite grid state to active or inactive. - * - * @param active If true start activation process. If false start - * deactivation process. - */ - void SetActive(bool active); - - /** - * Disable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void DisableWal(std::string cacheName); - - /** - * Enable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void EnableWal(std::string cacheName); - - /** - * Check if write - ahead logging is enabled for specified cache. - * - * @param cacheName Cache name. - * - * @return True if enabled. - */ - bool IsWalEnabled(std::string cacheName); - - /** - * Get a cluster group consisting from the local node. - * - * @return Cluster group consisting from the local node. - */ - cluster::ClusterGroup ForLocal(); - - /** - * Get local grid node. - * - * @return Local node. - */ - cluster::ClusterNode GetLocalNode(); - - /** - * Set baseline topology constructed from the cluster topology of the given version. - * The method succeeds only if the cluster topology has not changed. - * - * @param topVer Topology version. - */ - void SetBaselineTopologyVersion(int64_t topVer); - - /** - * Set transaction timeout on partition map exchange. - * - * @param timeout Timeout in milliseconds. - */ - void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); - - /** - * Ping node. - * - * @param nid Cluster node ID. - * @return True in case of success. - */ - bool PingNode(Guid nid); - - /** - * Get a topology by version. - * - * @param version Topology version. - * @return Nodes collection for the requested topology version. - */ - std::vector GetTopology(int64_t version); - - /** - * Get current topology version. - * - * @return Current topology version. - */ - int64_t GetTopologyVersion(); - - /** - * Get cluster group consisting of all cluster nodes. - * - * @return ClusterGroup instance. - */ - ClusterGroup AsClusterGroup(); - - private: - common::concurrent::SharedPointer impl; - }; - } - } -} - -#endif //_IGNITE_ODBC_CLUSTER_IGNITE_ODBC_CLUSTER +namespace ignite { +namespace odbc { +namespace cluster { +/** + * Represents whole cluster (all available nodes). Node-local map is useful for + * saving shared state between job executions on the grid. Additionally you can + * also ping, start, and restart remote nodes, map keys to caching nodes, and + * get other useful information about topology. + */ +class IGNITE_IMPORT_EXPORT IgniteCluster { + public: + /** + * Constructor. + * + * @param impl Pointer to ignite cluster implementation. + */ + IgniteCluster(common::concurrent::SharedPointer< + ignite::odbc::impl::cluster::IgniteClusterImpl > + impl); + + /** + * Check if the Ignite grid is active. + * + * @return True if grid is active and false otherwise. + */ + bool IsActive(); + + /** + * Change Ignite grid state to active or inactive. + * + * @param active If true start activation process. If false start + * deactivation process. + */ + void SetActive(bool active); + + /** + * Disable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void DisableWal(std::string cacheName); + + /** + * Enable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void EnableWal(std::string cacheName); + + /** + * Check if write - ahead logging is enabled for specified cache. + * + * @param cacheName Cache name. + * + * @return True if enabled. + */ + bool IsWalEnabled(std::string cacheName); + + /** + * Get a cluster group consisting from the local node. + * + * @return Cluster group consisting from the local node. + */ + cluster::ClusterGroup ForLocal(); + + /** + * Get local grid node. + * + * @return Local node. + */ + cluster::ClusterNode GetLocalNode(); + + /** + * Set baseline topology constructed from the cluster topology of the given + * version. The method succeeds only if the cluster topology has not changed. + * + * @param topVer Topology version. + */ + void SetBaselineTopologyVersion(int64_t topVer); + + /** + * Set transaction timeout on partition map exchange. + * + * @param timeout Timeout in milliseconds. + */ + void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); + + /** + * Ping node. + * + * @param nid Cluster node ID. + * @return True in case of success. + */ + bool PingNode(Guid nid); + + /** + * Get a topology by version. + * + * @param version Topology version. + * @return Nodes collection for the requested topology version. + */ + std::vector< ClusterNode > GetTopology(int64_t version); + + /** + * Get current topology version. + * + * @return Current topology version. + */ + int64_t GetTopologyVersion(); + + /** + * Get cluster group consisting of all cluster nodes. + * + * @return ClusterGroup instance. + */ + ClusterGroup AsClusterGroup(); + + private: + common::concurrent::SharedPointer< + ignite::odbc::impl::cluster::IgniteClusterImpl > + impl; +}; +} // namespace cluster +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_CLUSTER_IGNITE_ODBC_CLUSTER diff --git a/src/odbc/include/ignite/odbc/column.h b/src/odbc/include/ignite/odbc/column.h index 04300c0f1..509cb80b3 100644 --- a/src/odbc/include/ignite/odbc/column.h +++ b/src/odbc/include/ignite/odbc/column.h @@ -79,9 +79,8 @@ class Column { * @param dataBuf Application data buffer. * @return Operation result. */ - app::ConversionResult::Type ReadToBuffer( - BinaryReaderImpl& reader, - app::ApplicationDataBuffer& dataBuf); + app::ConversionResult::Type ReadToBuffer(BinaryReaderImpl& reader, + app::ApplicationDataBuffer& dataBuf); /** * Check if the column is in valid state. @@ -147,4 +146,4 @@ class Column { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_COLUMN \ No newline at end of file +#endif //_IGNITE_ODBC_COLUMN diff --git a/src/odbc/include/ignite/odbc/common/cancelable.h b/src/odbc/include/ignite/odbc/common/cancelable.h index b2a68605a..816e3e005 100644 --- a/src/odbc/include/ignite/odbc/common/cancelable.h +++ b/src/odbc/include/ignite/odbc/common/cancelable.h @@ -25,44 +25,38 @@ #include -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Cancelable. - */ - class IGNITE_IMPORT_EXPORT Cancelable - { - public: - /** - * Default constructor. - */ - Cancelable() - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~Cancelable() - { - // No-op. - } - - /** - * Cancels the operation. - */ - virtual void Cancel() = 0; - - private: - IGNITE_NO_COPY_ASSIGNMENT(Cancelable); - }; - } - } -} +namespace ignite { +namespace odbc { +namespace common { +/** + * Cancelable. + */ +class IGNITE_IMPORT_EXPORT Cancelable { + public: + /** + * Default constructor. + */ + Cancelable() { + // No-op. + } + + /** + * Destructor. + */ + virtual ~Cancelable() { + // No-op. + } + + /** + * Cancels the operation. + */ + virtual void Cancel() = 0; + + private: + IGNITE_NO_COPY_ASSIGNMENT(Cancelable); +}; +} // namespace common +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_COMMON_CANCELABLE +#endif //_IGNITE_ODBC_COMMON_CANCELABLE diff --git a/src/odbc/include/ignite/odbc/common/expected.h b/src/odbc/include/ignite/odbc/common/expected.h index f5727ea1d..cb203d554 100644 --- a/src/odbc/include/ignite/odbc/common/expected.h +++ b/src/odbc/include/ignite/odbc/common/expected.h @@ -266,4 +266,4 @@ class Expected { } // namespace odbc } // namespace ignite -#endif // _IGNITE_ODBC_COMMON_EXPECTED \ No newline at end of file +#endif // _IGNITE_ODBC_COMMON_EXPECTED diff --git a/src/odbc/include/ignite/odbc/common/lazy.h b/src/odbc/include/ignite/odbc/common/lazy.h index 744b5a587..60d466531 100644 --- a/src/odbc/include/ignite/odbc/common/lazy.h +++ b/src/odbc/include/ignite/odbc/common/lazy.h @@ -22,138 +22,136 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace common { - /** - * Lazy initialization template. - */ - template < typename T > - class IGNITE_IMPORT_EXPORT Lazy { - /** - * Init function type. - */ - struct InitFunctionType { - /** - * Destructor. - */ - virtual ~InitFunctionType() { - // No-op. - } - - /** - * Call init function. - * - * @return Init function. - */ - virtual T* Init() = 0; - }; - - /** - * Init function type. - */ - template < typename F > - struct InitFunctionType0 : InitFunctionType { - /** - * Constructor. - * - * @param func Function. - */ - InitFunctionType0(F func) : func(func) { - // No-op. - } - - /** - * Destructor. - */ - virtual ~InitFunctionType0() { - // No-op. - } - - /** - * Call init function. - * - * @return Init function. - */ - virtual T* Init() { - return func(); - } - - private: - /** Init function. */ - F func; - }; - - public: - typedef T InstanceType; - - /** - * Constructor. - * - * @param initFunc Initialization function. - */ - template < typename F > - Lazy(F initFunc) - : initFunc(new InitFunctionType0< F >(initFunc)), instance(), lock() { - // No-op. - } - - /** - * Default constructor for late init. - */ - Lazy() : initFunc(), instance(), lock() { - // No-op. - } - - /** - * Init function. Can be used for late init. - * - * @warning Do not re-init inited instances to avoid undefined behaviour. - * - * @param initFunc Initialization function. - */ - template < typename F > - void Init(F initFunc) { - this->initFunc = concurrent::SharedPointer< InitFunctionType >( - new InitFunctionType0< F >(initFunc)); - } - - /** - * Get instance. - * - * Inits if was not inited prior. - * - * @return Instance. - */ - concurrent::SharedPointer< InstanceType > Get() { - if (instance.Get()) - return instance; - - concurrent::CsLockGuard guard(lock); - - if (instance.Get()) - return instance; - - instance = - concurrent::SharedPointer< InstanceType >(initFunc.Get()->Init()); - - return instance; - } - - private: - /** Init function. */ - concurrent::SharedPointer< InitFunctionType > initFunc; - - /** Instance. */ - concurrent::SharedPointer< InstanceType > instance; - - /** Sync lock. */ - concurrent::CriticalSection lock; - }; - } // namespace common - } // namespace odbc -} // namespace ignite - -#endif // _IGNITE_ODBC_COMMON_LAZY +namespace ignite { +namespace odbc { +namespace common { +/** + * Lazy initialization template. + */ +template < typename T > +class IGNITE_IMPORT_EXPORT Lazy { + /** + * Init function type. + */ + struct InitFunctionType { + /** + * Destructor. + */ + virtual ~InitFunctionType() { + // No-op. + } + + /** + * Call init function. + * + * @return Init function. + */ + virtual T* Init() = 0; + }; + + /** + * Init function type. + */ + template < typename F > + struct InitFunctionType0 : InitFunctionType { + /** + * Constructor. + * + * @param func Function. + */ + InitFunctionType0(F func) : func(func) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~InitFunctionType0() { + // No-op. + } + + /** + * Call init function. + * + * @return Init function. + */ + virtual T* Init() { + return func(); + } + + private: + /** Init function. */ + F func; + }; + + public: + typedef T InstanceType; + + /** + * Constructor. + * + * @param initFunc Initialization function. + */ + template < typename F > + Lazy(F initFunc) + : initFunc(new InitFunctionType0< F >(initFunc)), instance(), lock() { + // No-op. + } + + /** + * Default constructor for late init. + */ + Lazy() : initFunc(), instance(), lock() { + // No-op. + } + + /** + * Init function. Can be used for late init. + * + * @warning Do not re-init inited instances to avoid undefined behaviour. + * + * @param initFunc Initialization function. + */ + template < typename F > + void Init(F initFunc) { + this->initFunc = concurrent::SharedPointer< InitFunctionType >( + new InitFunctionType0< F >(initFunc)); + } + + /** + * Get instance. + * + * Inits if was not inited prior. + * + * @return Instance. + */ + concurrent::SharedPointer< InstanceType > Get() { + if (instance.Get()) + return instance; + + concurrent::CsLockGuard guard(lock); + + if (instance.Get()) + return instance; + + instance = + concurrent::SharedPointer< InstanceType >(initFunc.Get()->Init()); + + return instance; + } + + private: + /** Init function. */ + concurrent::SharedPointer< InitFunctionType > initFunc; + + /** Instance. */ + concurrent::SharedPointer< InstanceType > instance; + + /** Sync lock. */ + concurrent::CriticalSection lock; +}; +} // namespace common +} // namespace odbc +} // namespace ignite + +#endif // _IGNITE_ODBC_COMMON_LAZY diff --git a/src/odbc/include/ignite/odbc/common/promise.h b/src/odbc/include/ignite/odbc/common/promise.h index d6e8da580..c3fe05406 100644 --- a/src/odbc/include/ignite/odbc/common/promise.h +++ b/src/odbc/include/ignite/odbc/common/promise.h @@ -20,7 +20,6 @@ * Declares ignite::odbc::commom::Promise class template. */ - #ifndef _IGNITE_PROMISE #define _IGNITE_PROMISE @@ -30,193 +29,178 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Promise class template. Used to set result of the asynchroniously - * started computation. - * - * @tparam T Promised value type. - */ - template - class Promise - { - public: - /** Template value type */ - typedef T ValueType; - - /** - * Constructor. - */ - Promise() : - state(new SharedState()) - { - // No-op. - } - - /** - * Destructor. - */ - ~Promise() - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - if (!state0->IsSet()) - state0->SetError(IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, - "Broken promise. Value will never be set due to internal error.")); - } - - - /** - * Get future for this promise. - * - * @return New future instance. - */ - Future GetFuture() const - { - return Future(state); - } - - /** - * Set value. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param val Value to set. - */ - void SetValue(std::shared_ptr val) - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->SetValue(val); - } - - /** - * Set error. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param err Error to set. - */ - void SetError(const IgniteError& err) - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->SetError(err); - } - - /** - * Set cancel target. - */ - void SetCancelTarget(std::shared_ptr& target) - { - state.Get()->SetCancelTarget(target); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(Promise); - - /** Shared state. */ - concurrent::SharedPointer< SharedState > state; - }; - - /** - * Specialization for void. - */ - template<> - class Promise - { - public: - /** Template value type */ - typedef void ValueType; - - /** - * Constructor. - */ - Promise() : - state(new SharedState()) - { - // No-op. - } - - /** - * Destructor. - */ - ~Promise() - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - if (!state0->IsSet()) - state0->SetError(IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, - "Broken promise. Value will never be set due to internal error.")); - } - - - /** - * Get future for this promise. - * - * @return New future instance. - */ - Future GetFuture() const - { - return Future(state); - } - - /** - * Mark as complete. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - */ - void SetValue() - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->SetValue(); - } - - /** - * Set error. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param err Error to set. - */ - void SetError(const IgniteError& err) - { - SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->SetError(err); - } - - /** - * Set cancel target. - */ - void SetCancelTarget(std::shared_ptr& target) - { - state.Get()->SetCancelTarget(target); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(Promise); - - /** Shared state. */ - concurrent::SharedPointer< SharedState > state; - }; - } - } -} - -#endif //_IGNITE_PROMISE +namespace ignite { +namespace odbc { +namespace common { +/** + * Promise class template. Used to set result of the asynchroniously + * started computation. + * + * @tparam T Promised value type. + */ +template < typename T > +class Promise { + public: + /** Template value type */ + typedef T ValueType; + + /** + * Constructor. + */ + Promise() : state(new SharedState< ValueType >()) { + // No-op. + } + + /** + * Destructor. + */ + ~Promise() { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + if (!state0->IsSet()) + state0->SetError(IgniteError( + IgniteError::IGNITE_ERR_FUTURE_STATE, + "Broken promise. Value will never be set due to internal error.")); + } + + /** + * Get future for this promise. + * + * @return New future instance. + */ + Future< ValueType > GetFuture() const { + return Future< ValueType >(state); + } + + /** + * Set value. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param val Value to set. + */ + void SetValue(std::shared_ptr< ValueType > val) { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->SetValue(val); + } + + /** + * Set error. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param err Error to set. + */ + void SetError(const IgniteError& err) { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->SetError(err); + } + + /** + * Set cancel target. + */ + void SetCancelTarget(std::shared_ptr< Cancelable >& target) { + state.Get()->SetCancelTarget(target); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(Promise); + + /** Shared state. */ + concurrent::SharedPointer< SharedState< ValueType > > state; +}; + +/** + * Specialization for void. + */ +template <> +class Promise< void > { + public: + /** Template value type */ + typedef void ValueType; + + /** + * Constructor. + */ + Promise() : state(new SharedState< ValueType >()) { + // No-op. + } + + /** + * Destructor. + */ + ~Promise() { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + if (!state0->IsSet()) + state0->SetError(IgniteError( + IgniteError::IGNITE_ERR_FUTURE_STATE, + "Broken promise. Value will never be set due to internal error.")); + } + + /** + * Get future for this promise. + * + * @return New future instance. + */ + Future< ValueType > GetFuture() const { + return Future< ValueType >(state); + } + + /** + * Mark as complete. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + */ + void SetValue() { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->SetValue(); + } + + /** + * Set error. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param err Error to set. + */ + void SetError(const IgniteError& err) { + SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->SetError(err); + } + + /** + * Set cancel target. + */ + void SetCancelTarget(std::shared_ptr< Cancelable >& target) { + state.Get()->SetCancelTarget(target); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(Promise); + + /** Shared state. */ + concurrent::SharedPointer< SharedState< ValueType > > state; +}; +} // namespace common +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_PROMISE diff --git a/src/odbc/include/ignite/odbc/common/reference_impl.h b/src/odbc/include/ignite/odbc/common/reference_impl.h index d558661d6..ca0e8f7b5 100644 --- a/src/odbc/include/ignite/odbc/common/reference_impl.h +++ b/src/odbc/include/ignite/odbc/common/reference_impl.h @@ -27,263 +27,226 @@ #include -namespace ignite -{ - namespace odbc - { - namespace common - { - // Any number is good as long as it is not null. - enum { POINTER_CAST_MAGIC_NUMBER = 80000 }; - - /** - * Interface for constant Reference implementation class template. - */ - class ConstReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ConstReferenceImplBase() - { - // No-op. - } - - /** - * Get the constant pointer. - * - * @return Constant pointer to underlying value. - */ - virtual const void* Get() const = 0; - }; - - /** - * Interface for Reference implementation class template. - */ - class ReferenceImplBase : public ConstReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ReferenceImplBase() - { - // No-op. - } - - virtual const void* Get() const = 0; - - /** - * Get the pointer. - * - * @return Pointer to underlying value. - */ - virtual void* Get() = 0; - }; - - /** - * Reference class implementation for smart pointers. - * - * Note, this class does not implement any smart pointer functionality - * itself, instead it wraps one of the existing wide-spread smart - * pointer implementations and provides unified interface for them. - */ - template - class ReferenceSmartPointer : public ReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ReferenceSmartPointer() - { - // No-op. - } - - /** - * Default constructor. - */ - ReferenceSmartPointer() : - ptr() - { - // No-op. - } - - virtual const void* Get() const - { - return reinterpret_cast(&(*ptr)); - } - - virtual void* Get() - { - return reinterpret_cast(&(*ptr)); - } - - /** - * Swap underlying smart pointer. - * - * @param other Another instance. - */ - void Swap(P& other) - { - using std::swap; - - swap(ptr, other); - } - - private: - /** Underlying pointer. */ - P ptr; - }; - - /** - * Reference implementation for the owning raw pointer. - */ - template - class ReferenceOwningRawPointer : public ReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ReferenceOwningRawPointer() - { - delete ptr; - } - - /** - * Default constructor. - */ - ReferenceOwningRawPointer() : - ptr(0) - { - // No-op. - } - - /** - * Pointer constructor. - * - * @param ptr Pointer to take ownership over. - */ - ReferenceOwningRawPointer(T* ptr) : - ptr(ptr) - { - // No-op. - } - - virtual const void* Get() const - { - return reinterpret_cast(ptr); - } - - virtual void* Get() - { - return reinterpret_cast(ptr); - } - - private: - /** Underlying pointer. */ - T* ptr; - }; - - /** - * Reference implementation for the raw pointer. - */ - template - class ReferenceNonOwningRawPointer : public ReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ReferenceNonOwningRawPointer() - { - // No-op. - } - - /** - * Default constructor. - */ - ReferenceNonOwningRawPointer() : - ptr(0) - { - // No-op. - } - - /** - * Pointer constructor. - * - * @param ptr Pointer. - */ - ReferenceNonOwningRawPointer(T* ptr) : - ptr(ptr) - { - // No-op. - } - - virtual const void* Get() const - { - return reinterpret_cast(ptr); - } - - virtual void* Get() - { - return reinterpret_cast(ptr); - } - - private: - /** Underlying pointer. */ - T* ptr; - }; - - /** - * Constant reference implementation for the raw pointer. - */ - template - class ConstReferenceNonOwningRawPointer : public ConstReferenceImplBase - { - public: - /** - * Destructor. - */ - virtual ~ConstReferenceNonOwningRawPointer() - { - // No-op. - } - - /** - * Default constructor. - */ - ConstReferenceNonOwningRawPointer() : - ptr(0) - { - // No-op. - } - - /** - * Pointer constructor. - * - * @param ptr Pointer. - */ - ConstReferenceNonOwningRawPointer(const T* ptr) : - ptr(ptr) - { - // No-op. - } - - virtual const void* Get() const - { - return reinterpret_cast(ptr); - } - - private: - /** Underlying pointer. */ - const T* ptr; - }; - - } - } -} - -#endif //_IGNITE_ODBC_COMMON_REFERENCE_IMPL +namespace ignite { +namespace odbc { +namespace common { +// Any number is good as long as it is not null. +enum { POINTER_CAST_MAGIC_NUMBER = 80000 }; + +/** + * Interface for constant Reference implementation class template. + */ +class ConstReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ConstReferenceImplBase() { + // No-op. + } + + /** + * Get the constant pointer. + * + * @return Constant pointer to underlying value. + */ + virtual const void* Get() const = 0; +}; + +/** + * Interface for Reference implementation class template. + */ +class ReferenceImplBase : public ConstReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ReferenceImplBase() { + // No-op. + } + + virtual const void* Get() const = 0; + + /** + * Get the pointer. + * + * @return Pointer to underlying value. + */ + virtual void* Get() = 0; +}; + +/** + * Reference class implementation for smart pointers. + * + * Note, this class does not implement any smart pointer functionality + * itself, instead it wraps one of the existing wide-spread smart + * pointer implementations and provides unified interface for them. + */ +template < typename P > +class ReferenceSmartPointer : public ReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ReferenceSmartPointer() { + // No-op. + } + + /** + * Default constructor. + */ + ReferenceSmartPointer() : ptr() { + // No-op. + } + + virtual const void* Get() const { + return reinterpret_cast< const void* >(&(*ptr)); + } + + virtual void* Get() { + return reinterpret_cast< void* >(&(*ptr)); + } + + /** + * Swap underlying smart pointer. + * + * @param other Another instance. + */ + void Swap(P& other) { + using std::swap; + + swap(ptr, other); + } + + private: + /** Underlying pointer. */ + P ptr; +}; + +/** + * Reference implementation for the owning raw pointer. + */ +template < typename T > +class ReferenceOwningRawPointer : public ReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ReferenceOwningRawPointer() { + delete ptr; + } + + /** + * Default constructor. + */ + ReferenceOwningRawPointer() : ptr(0) { + // No-op. + } + + /** + * Pointer constructor. + * + * @param ptr Pointer to take ownership over. + */ + ReferenceOwningRawPointer(T* ptr) : ptr(ptr) { + // No-op. + } + + virtual const void* Get() const { + return reinterpret_cast< const void* >(ptr); + } + + virtual void* Get() { + return reinterpret_cast< void* >(ptr); + } + + private: + /** Underlying pointer. */ + T* ptr; +}; + +/** + * Reference implementation for the raw pointer. + */ +template < typename T > +class ReferenceNonOwningRawPointer : public ReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ReferenceNonOwningRawPointer() { + // No-op. + } + + /** + * Default constructor. + */ + ReferenceNonOwningRawPointer() : ptr(0) { + // No-op. + } + + /** + * Pointer constructor. + * + * @param ptr Pointer. + */ + ReferenceNonOwningRawPointer(T* ptr) : ptr(ptr) { + // No-op. + } + + virtual const void* Get() const { + return reinterpret_cast< const void* >(ptr); + } + + virtual void* Get() { + return reinterpret_cast< void* >(ptr); + } + + private: + /** Underlying pointer. */ + T* ptr; +}; + +/** + * Constant reference implementation for the raw pointer. + */ +template < typename T > +class ConstReferenceNonOwningRawPointer : public ConstReferenceImplBase { + public: + /** + * Destructor. + */ + virtual ~ConstReferenceNonOwningRawPointer() { + // No-op. + } + + /** + * Default constructor. + */ + ConstReferenceNonOwningRawPointer() : ptr(0) { + // No-op. + } + + /** + * Pointer constructor. + * + * @param ptr Pointer. + */ + ConstReferenceNonOwningRawPointer(const T* ptr) : ptr(ptr) { + // No-op. + } + + virtual const void* Get() const { + return reinterpret_cast< const void* >(ptr); + } + + private: + /** Underlying pointer. */ + const T* ptr; +}; + +} // namespace common +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_COMMON_REFERENCE_IMPL diff --git a/src/odbc/include/ignite/odbc/common/shared_state.h b/src/odbc/include/ignite/odbc/common/shared_state.h index 608a60834..f14612141 100644 --- a/src/odbc/include/ignite/odbc/common/shared_state.h +++ b/src/odbc/include/ignite/odbc/common/shared_state.h @@ -30,356 +30,337 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace common - { - template - class SharedState - { - public: - /** Template value type */ - typedef T ValueType; - - /** - * Default constructor. - * Constructs non-set SharedState instance. - */ - SharedState() : - value(), - error() - { - // No-op. - } - - /** - * Destructor. - */ - ~SharedState() - { - // No-op. - } - - /** - * Checks if the value or error set for the state. - * @return True if the value or error set for the state. - */ - bool IsSet() const - { - return value.get() || error.GetCode() != IgniteError::IGNITE_SUCCESS; - } - - /** - * Set value. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param val Value to set. - */ - void SetValue(std::shared_ptr val) - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - { - if (value.get()) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future value already set"); - - if (error.GetCode() != IgniteError::IGNITE_SUCCESS) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future error already set"); - } - - value = val; - - cond.NotifyAll(); - } - - /** - * Set error. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param err Error to set. - */ - void SetError(const IgniteError& err) - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - { - if (value.get()) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future value already set"); - - if (error.GetCode() != IgniteError::IGNITE_SUCCESS) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future error already set"); - } - - error = err; - - cond.NotifyAll(); - } - - /** - * Wait for value to be set. - * Active thread will be blocked until value or error will be set. - */ - void Wait() const - { - concurrent::CsLockGuard guard(mutex); - - while (!IsSet()) - cond.Wait(mutex); - } - - /** - * Wait for value to be set for specified time. - * Active thread will be blocked until value or error will be set or timeout will end. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) const - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - return true; - - return cond.WaitFor(mutex, msTimeout); - } - - /** - * Get the set value. - * Active thread will be blocked until value or error will be set. - * - * @throw IgniteError if error has been set. - * @return Value that has been set on success. - */ - const ValueType& GetValue() const - { - Wait(); - - if (value.get()) - return *value; - - assert(error.GetCode() != IgniteError::IGNITE_SUCCESS); - - throw error; - } - - /** - * Set cancel target. - */ - void SetCancelTarget(std::shared_ptr& target) - { - concurrent::CsLockGuard guard(mutex); - - cancelTarget = target; - } - - /** - * Cancel related operation. - */ - void Cancel() - { - concurrent::CsLockGuard guard(mutex); - - if (cancelTarget.get()) - cancelTarget->Cancel(); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(SharedState); - - /** Cancel target. */ - std::shared_ptr cancelTarget; - - /** Value. */ - std::shared_ptr value; - - /** Error. */ - IgniteError error; - - /** Condition variable which serves to signal that value is set. */ - mutable concurrent::ConditionVariable cond; - - /** Lock that used to prevent double-set of the value. */ - mutable concurrent::CriticalSection mutex; - }; - - /** - * Specialization for void type. - */ - template<> - class SharedState - { - public: - /** Template value type */ - typedef void ValueType; - - /** - * Default constructor. - * Constructs non-set SharedState instance. - */ - SharedState() : - done(false), - error() - { - // No-op. - } - - /** - * Destructor. - */ - ~SharedState() - { - // No-op. - } - - /** - * Checks if the value or error set for the state. - * @return True if the value or error set for the state. - */ - bool IsSet() const - { - return done || error.GetCode() != IgniteError::IGNITE_SUCCESS; - } - - /** - * Set value. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - */ - void SetValue() - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - { - if (done) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future value already set"); - - if (error.GetCode() != IgniteError::IGNITE_SUCCESS) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future error already set"); - } - - done = true; - - cond.NotifyAll(); - } - - /** - * Set error. - * - * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or value has been set already. - * @param err Error to set. - */ - void SetError(const IgniteError& err) - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - { - if (done) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future value already set"); - - if (error.GetCode() != IgniteError::IGNITE_SUCCESS) - throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, "Future error already set"); - } - - error = err; - - cond.NotifyAll(); - } - - /** - * Wait for value to be set. - * Active thread will be blocked until value or error will be set. - */ - void Wait() const - { - concurrent::CsLockGuard guard(mutex); - - while (!IsSet()) - cond.Wait(mutex); - } - - /** - * Wait for value to be set for specified time. - * Active thread will be blocked until value or error will be set or timeout will end. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) const - { - concurrent::CsLockGuard guard(mutex); - - if (IsSet()) - return true; - - return cond.WaitFor(mutex, msTimeout); - } - - /** - * Get the set value. - * Active thread will be blocked until value or error will be set. - * - * @throw IgniteError if error has been set. - */ - void GetValue() const - { - Wait(); - - if (done) - return; - - assert(error.GetCode() != IgniteError::IGNITE_SUCCESS); - - throw error; - } - - /** - * Set cancel target. - */ - void SetCancelTarget(std::shared_ptr& target) - { - concurrent::CsLockGuard guard(mutex); - - cancelTarget = target; - } - - /** - * Cancel related operation. - */ - void Cancel() - { - concurrent::CsLockGuard guard(mutex); - - if (cancelTarget.get()) - cancelTarget->Cancel(); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(SharedState); - - /** Cancel target. */ - std::shared_ptr cancelTarget; - - /** Marker. */ - bool done; - - /** Error. */ - IgniteError error; - - /** Condition variable which serves to signal that value is set. */ - mutable concurrent::ConditionVariable cond; - - /** Lock that used to prevent double-set of the value. */ - mutable concurrent::CriticalSection mutex; - }; - } +namespace ignite { +namespace odbc { +namespace common { +template < typename T > +class SharedState { + public: + /** Template value type */ + typedef T ValueType; + + /** + * Default constructor. + * Constructs non-set SharedState instance. + */ + SharedState() : value(), error() { + // No-op. + } + + /** + * Destructor. + */ + ~SharedState() { + // No-op. + } + + /** + * Checks if the value or error set for the state. + * @return True if the value or error set for the state. + */ + bool IsSet() const { + return value.get() || error.GetCode() != IgniteError::IGNITE_SUCCESS; + } + + /** + * Set value. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param val Value to set. + */ + void SetValue(std::shared_ptr< ValueType > val) { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) { + if (value.get()) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future value already set"); + + if (error.GetCode() != IgniteError::IGNITE_SUCCESS) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future error already set"); + } + + value = val; + + cond.NotifyAll(); + } + + /** + * Set error. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param err Error to set. + */ + void SetError(const IgniteError& err) { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) { + if (value.get()) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future value already set"); + + if (error.GetCode() != IgniteError::IGNITE_SUCCESS) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future error already set"); + } + + error = err; + + cond.NotifyAll(); + } + + /** + * Wait for value to be set. + * Active thread will be blocked until value or error will be set. + */ + void Wait() const { + concurrent::CsLockGuard guard(mutex); + + while (!IsSet()) + cond.Wait(mutex); + } + + /** + * Wait for value to be set for specified time. + * Active thread will be blocked until value or error will be set or timeout + * will end. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) const { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) + return true; + + return cond.WaitFor(mutex, msTimeout); + } + + /** + * Get the set value. + * Active thread will be blocked until value or error will be set. + * + * @throw IgniteError if error has been set. + * @return Value that has been set on success. + */ + const ValueType& GetValue() const { + Wait(); + + if (value.get()) + return *value; + + assert(error.GetCode() != IgniteError::IGNITE_SUCCESS); + + throw error; + } + + /** + * Set cancel target. + */ + void SetCancelTarget(std::shared_ptr< Cancelable >& target) { + concurrent::CsLockGuard guard(mutex); + + cancelTarget = target; + } + + /** + * Cancel related operation. + */ + void Cancel() { + concurrent::CsLockGuard guard(mutex); + + if (cancelTarget.get()) + cancelTarget->Cancel(); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(SharedState); + + /** Cancel target. */ + std::shared_ptr< Cancelable > cancelTarget; + + /** Value. */ + std::shared_ptr< ValueType > value; + + /** Error. */ + IgniteError error; + + /** Condition variable which serves to signal that value is set. */ + mutable concurrent::ConditionVariable cond; + + /** Lock that used to prevent double-set of the value. */ + mutable concurrent::CriticalSection mutex; +}; + +/** + * Specialization for void type. + */ +template <> +class SharedState< void > { + public: + /** Template value type */ + typedef void ValueType; + + /** + * Default constructor. + * Constructs non-set SharedState instance. + */ + SharedState() : done(false), error() { + // No-op. + } + + /** + * Destructor. + */ + ~SharedState() { + // No-op. + } + + /** + * Checks if the value or error set for the state. + * @return True if the value or error set for the state. + */ + bool IsSet() const { + return done || error.GetCode() != IgniteError::IGNITE_SUCCESS; + } + + /** + * Set value. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + */ + void SetValue() { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) { + if (done) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future value already set"); + + if (error.GetCode() != IgniteError::IGNITE_SUCCESS) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future error already set"); + } + + done = true; + + cond.NotifyAll(); + } + + /** + * Set error. + * + * @throw IgniteError with IgniteError::IGNITE_ERR_FUTURE_STATE if error or + * value has been set already. + * @param err Error to set. + */ + void SetError(const IgniteError& err) { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) { + if (done) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future value already set"); + + if (error.GetCode() != IgniteError::IGNITE_SUCCESS) + throw IgniteError(IgniteError::IGNITE_ERR_FUTURE_STATE, + "Future error already set"); } -} -#endif //_IGNITE_SHARED_STATE + error = err; + + cond.NotifyAll(); + } + + /** + * Wait for value to be set. + * Active thread will be blocked until value or error will be set. + */ + void Wait() const { + concurrent::CsLockGuard guard(mutex); + + while (!IsSet()) + cond.Wait(mutex); + } + + /** + * Wait for value to be set for specified time. + * Active thread will be blocked until value or error will be set or timeout + * will end. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) const { + concurrent::CsLockGuard guard(mutex); + + if (IsSet()) + return true; + + return cond.WaitFor(mutex, msTimeout); + } + + /** + * Get the set value. + * Active thread will be blocked until value or error will be set. + * + * @throw IgniteError if error has been set. + */ + void GetValue() const { + Wait(); + + if (done) + return; + + assert(error.GetCode() != IgniteError::IGNITE_SUCCESS); + + throw error; + } + + /** + * Set cancel target. + */ + void SetCancelTarget(std::shared_ptr< Cancelable >& target) { + concurrent::CsLockGuard guard(mutex); + + cancelTarget = target; + } + + /** + * Cancel related operation. + */ + void Cancel() { + concurrent::CsLockGuard guard(mutex); + + if (cancelTarget.get()) + cancelTarget->Cancel(); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(SharedState); + + /** Cancel target. */ + std::shared_ptr< Cancelable > cancelTarget; + + /** Marker. */ + bool done; + + /** Error. */ + IgniteError error; + + /** Condition variable which serves to signal that value is set. */ + mutable concurrent::ConditionVariable cond; + + /** Lock that used to prevent double-set of the value. */ + mutable concurrent::CriticalSection mutex; +}; +} // namespace common +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_SHARED_STATE diff --git a/src/odbc/include/ignite/odbc/compute/compute.h b/src/odbc/include/ignite/odbc/compute/compute.h index 517c45bc0..704630cf7 100644 --- a/src/odbc/include/ignite/odbc/compute/compute.h +++ b/src/odbc/include/ignite/odbc/compute/compute.h @@ -31,353 +31,344 @@ #include -namespace ignite -{ - namespace odbc - { - namespace compute - { - /** - * Defines compute grid functionality for executing tasks and closures - * over nodes in the ClusterGroup. Instance of Compute is obtained from - * Ignite as follows: - * @code{.cpp} - * Ignite node = Ignition::Get(); - * - * // Compute over all nodes in the cluster. - * Compute c = node.GetCompute(); - * @endcode - * - * @par Load Balancing - * In all cases other than Broadcast(...), Ignite must select - * a node for a computation to be executed. The node will be selected - * based on the underlying \c LoadBalancingSpi, which by default - * sequentially picks next available node from the underlying cluster - * group. Other load balancing policies, such as \c random or - * \c adaptive, can be configured as well by selecting a different - * load balancing SPI in Ignite configuration. - * - * @par Fault Tolerance - * Ignite guarantees that as long as there is at least one grid node - * standing, every job will be executed. Jobs will automatically - * failover to another node if a remote node crashed or has rejected - * execution due to lack of resources. By default, in case of failover, - * next load balanced node will be picked for job execution. Also jobs - * will never be re-routed to the nodes they have failed on. This - * behavior can be changed by configuring any of the existing or a - * custom FailoverSpi in grid configuration. - * - * @par Computation SPIs - * Note that regardless of which method is used for executing - * computations, all relevant SPI implementations configured for this - * compute instance will be used (i.e. failover, load balancing, - * collision resolution, checkpoints, etc.). - */ - class IGNITE_IMPORT_EXPORT Compute - { - public: - /** - * Constructor. - * - * Internal method. Should not be used by user. - * - * @param impl Implementation. - */ - Compute(common::concurrent::SharedPointer impl) : - impl(impl) - { - // No-op. - } - - /** - * Executes given job on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::AffinityRun(). - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache name to use for affinity co-location. - * @param key Affinity key. - * @param func Compute function to call. - * @return Computation result. - * @throw IgniteError in case of error. - */ - template - R AffinityCall(const std::string& cacheName, const K& key, const F& func) - { - return impl.Get()->AffinityCallAsync(cacheName, key, func).GetValue(); - } - - /** - * Executes given job asynchronously on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::AffinityRun(). - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache name to use for affinity co-location. - * @param key Affinity key. - * @param func Compute function to call. - * @return Future that can be used to access computation result once - * it's ready. - * @throw IgniteError in case of error. - */ - template - Future AffinityCallAsync(const std::string& cacheName, const K& key, const F& func) - { - return impl.Get()->AffinityCallAsync(cacheName, key, func); - } - - /** - * Executes given job on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache names to use for affinity co-location. - * @param key Affinity key. - * @param action Compute action to call. - * @throw IgniteError in case of error. - */ - template - void AffinityRun(const std::string& cacheName, const K& key, const F& action) - { - return impl.Get()->AffinityRunAsync(cacheName, key, action).GetValue(); - } - - /** - * Executes given job asynchronously on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache names to use for affinity co-location. - * @param key Affinity key. - * @param action Compute action to call. - * @return Future that can be used to access computation result once - * it's ready. - * @throw IgniteError in case of error. - */ - template - Future AffinityRunAsync(const std::string& cacheName, const K& key, const F& action) - { - return impl.Get()->AffinityRunAsync(cacheName, key, action); - } - - /** - * Calls provided ComputeFunc on a node within the underlying - * cluster group. - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::Run(). - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @return Computation result. - * @throw IgniteError in case of error. - */ - template - R Call(const F& func) - { - return impl.Get()->CallAsync(func).GetValue(); - } - - /** - * Asyncronuously calls provided ComputeFunc on a node within - * the underlying cluster group. - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::Run(). - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @return Future that can be used to access computation result once - * it's ready. - * @throw IgniteError in case of error. - */ - template - Future CallAsync(const F& func) - { - return impl.Get()->CallAsync(func); - } - - /** - * Runs provided ComputeFunc on a node within the underlying cluster - * group. - * - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param action Compute function to call. - * @throw IgniteError in case of error. - */ - template - void Run(const F& action) - { - return impl.Get()->RunAsync(action).GetValue(); - } - - /** - * Asyncronuously runs provided ComputeFunc on a node within the - * underlying cluster group. - * - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param action Compute function to call. - * @return Future that can be used to wait for action to complete. - * @throw IgniteError in case of error. - */ - template - Future RunAsync(const F& action) - { - return impl.Get()->RunAsync(action); - } - - /** - * Broadcasts provided ComputeFunc to all nodes in the cluster group. - * - * @tparam R Function return type. BinaryType should be specialized - * for the type if it is not primitive. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @return Vector containing computation results. - * @throw IgniteError in case of error. - */ - template - std::vector Broadcast(const F& func) - { - return impl.Get()->BroadcastAsync(func).GetValue(); - } - - /** - * Broadcasts provided ComputeFunc to all nodes in the cluster group. - * - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @throw IgniteError in case of error. - */ - template - void Broadcast(const F& func) - { - impl.Get()->BroadcastAsync(func).GetValue(); - } - - /** - * Asyncronuously broadcasts provided ComputeFunc to all nodes in the - * cluster group. - * - * @tparam R Function return type. BinaryType should be specialized - * for the type if it is not primitive. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @return Future that can be used to access computation results once - * they are ready. - * @throw IgniteError in case of error. - */ - template - Future< std::vector > BroadcastAsync(const F& func) - { - return impl.Get()->BroadcastAsync(func); - } - - /** - * Asyncronuously broadcasts provided ComputeFunc to all nodes in the - * cluster group. - * - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param func Compute function to call. - * @return Future that can be used to wait for action to complete. - * @throw IgniteError in case of error. - */ - template - Future BroadcastAsync(const F& func) - { - return impl.Get()->BroadcastAsync(func); - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - R ExecuteJavaTask(const std::string& taskName, const A& taskArg) - { - return impl.Get()->ExecuteJavaTask(taskName, taskArg); - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - */ - template - R ExecuteJavaTask(const std::string& taskName) - { - return impl.Get()->ExecuteJavaTask(taskName); - } - - /** - * Asynchronously executes given Java task on the grid projection. If task for given name has not been - * deployed yet, then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @return Future containing a result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - Future ExecuteJavaTaskAsync(const std::string& taskName, const A& taskArg) - { - return impl.Get()->ExecuteJavaTaskAsync(taskName, taskArg); - } - - /** - * Asynchronously executes given Java task on the grid projection. If task for given name has not been - * deployed yet, then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @return Future containing a result of type @c R. - * - * @tparam R Type of task result. - */ - template - Future ExecuteJavaTaskAsync(const std::string& taskName) - { - return impl.Get()->ExecuteJavaTaskAsync(taskName); - } - - private: - /** Implementation. */ - common::concurrent::SharedPointer impl; - }; - } - } -} +namespace ignite { +namespace odbc { +namespace compute { +/** + * Defines compute grid functionality for executing tasks and closures + * over nodes in the ClusterGroup. Instance of Compute is obtained from + * Ignite as follows: + * @code{.cpp} + * Ignite node = Ignition::Get(); + * + * // Compute over all nodes in the cluster. + * Compute c = node.GetCompute(); + * @endcode + * + * @par Load Balancing + * In all cases other than Broadcast(...), Ignite must select + * a node for a computation to be executed. The node will be selected + * based on the underlying \c LoadBalancingSpi, which by default + * sequentially picks next available node from the underlying cluster + * group. Other load balancing policies, such as \c random or + * \c adaptive, can be configured as well by selecting a different + * load balancing SPI in Ignite configuration. + * + * @par Fault Tolerance + * Ignite guarantees that as long as there is at least one grid node + * standing, every job will be executed. Jobs will automatically + * failover to another node if a remote node crashed or has rejected + * execution due to lack of resources. By default, in case of failover, + * next load balanced node will be picked for job execution. Also jobs + * will never be re-routed to the nodes they have failed on. This + * behavior can be changed by configuring any of the existing or a + * custom FailoverSpi in grid configuration. + * + * @par Computation SPIs + * Note that regardless of which method is used for executing + * computations, all relevant SPI implementations configured for this + * compute instance will be used (i.e. failover, load balancing, + * collision resolution, checkpoints, etc.). + */ +class IGNITE_IMPORT_EXPORT Compute { + public: + /** + * Constructor. + * + * Internal method. Should not be used by user. + * + * @param impl Implementation. + */ + Compute(common::concurrent::SharedPointer< impl::compute::ComputeImpl > impl) + : impl(impl) { + // No-op. + } + + /** + * Executes given job on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::AffinityRun(). + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache name to use for affinity co-location. + * @param key Affinity key. + * @param func Compute function to call. + * @return Computation result. + * @throw IgniteError in case of error. + */ + template < typename R, typename K, typename F > + R AffinityCall(const std::string& cacheName, const K& key, const F& func) { + return impl.Get() + ->AffinityCallAsync< R, K, F >(cacheName, key, func) + .GetValue(); + } + + /** + * Executes given job asynchronously on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::AffinityRun(). + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache name to use for affinity co-location. + * @param key Affinity key. + * @param func Compute function to call. + * @return Future that can be used to access computation result once + * it's ready. + * @throw IgniteError in case of error. + */ + template < typename R, typename K, typename F > + Future< R > AffinityCallAsync(const std::string& cacheName, const K& key, + const F& func) { + return impl.Get()->AffinityCallAsync< R, K, F >(cacheName, key, func); + } + + /** + * Executes given job on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache names to use for affinity co-location. + * @param key Affinity key. + * @param action Compute action to call. + * @throw IgniteError in case of error. + */ + template < typename K, typename F > + void AffinityRun(const std::string& cacheName, const K& key, + const F& action) { + return impl.Get() + ->AffinityRunAsync< K, F >(cacheName, key, action) + .GetValue(); + } + + /** + * Executes given job asynchronously on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache names to use for affinity co-location. + * @param key Affinity key. + * @param action Compute action to call. + * @return Future that can be used to access computation result once + * it's ready. + * @throw IgniteError in case of error. + */ + template < typename K, typename F > + Future< void > AffinityRunAsync(const std::string& cacheName, const K& key, + const F& action) { + return impl.Get()->AffinityRunAsync< K, F >(cacheName, key, action); + } + + /** + * Calls provided ComputeFunc on a node within the underlying + * cluster group. + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::Run(). + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @return Computation result. + * @throw IgniteError in case of error. + */ + template < typename R, typename F > + R Call(const F& func) { + return impl.Get()->CallAsync< R, F >(func).GetValue(); + } + + /** + * Asyncronuously calls provided ComputeFunc on a node within + * the underlying cluster group. + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::Run(). + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @return Future that can be used to access computation result once + * it's ready. + * @throw IgniteError in case of error. + */ + template < typename R, typename F > + Future< R > CallAsync(const F& func) { + return impl.Get()->CallAsync< R, F >(func); + } + + /** + * Runs provided ComputeFunc on a node within the underlying cluster + * group. + * + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param action Compute function to call. + * @throw IgniteError in case of error. + */ + template < typename F > + void Run(const F& action) { + return impl.Get()->RunAsync< F >(action).GetValue(); + } + + /** + * Asyncronuously runs provided ComputeFunc on a node within the + * underlying cluster group. + * + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param action Compute function to call. + * @return Future that can be used to wait for action to complete. + * @throw IgniteError in case of error. + */ + template < typename F > + Future< void > RunAsync(const F& action) { + return impl.Get()->RunAsync< F >(action); + } + + /** + * Broadcasts provided ComputeFunc to all nodes in the cluster group. + * + * @tparam R Function return type. BinaryType should be specialized + * for the type if it is not primitive. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @return Vector containing computation results. + * @throw IgniteError in case of error. + */ + template < typename R, typename F > + std::vector< R > Broadcast(const F& func) { + return impl.Get()->BroadcastAsync< R, F >(func).GetValue(); + } + + /** + * Broadcasts provided ComputeFunc to all nodes in the cluster group. + * + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @throw IgniteError in case of error. + */ + template < typename F > + void Broadcast(const F& func) { + impl.Get()->BroadcastAsync< F, false >(func).GetValue(); + } + + /** + * Asyncronuously broadcasts provided ComputeFunc to all nodes in the + * cluster group. + * + * @tparam R Function return type. BinaryType should be specialized + * for the type if it is not primitive. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @return Future that can be used to access computation results once + * they are ready. + * @throw IgniteError in case of error. + */ + template < typename R, typename F > + Future< std::vector< R > > BroadcastAsync(const F& func) { + return impl.Get()->BroadcastAsync< R, F >(func); + } + + /** + * Asyncronuously broadcasts provided ComputeFunc to all nodes in the + * cluster group. + * + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param func Compute function to call. + * @return Future that can be used to wait for action to complete. + * @throw IgniteError in case of error. + */ + template < typename F > + Future< void > BroadcastAsync(const F& func) { + return impl.Get()->BroadcastAsync< F, false >(func); + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + R ExecuteJavaTask(const std::string& taskName, const A& taskArg) { + return impl.Get()->ExecuteJavaTask< R, A >(taskName, taskArg); + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + */ + template < typename R > + R ExecuteJavaTask(const std::string& taskName) { + return impl.Get()->ExecuteJavaTask< R >(taskName); + } + + /** + * Asynchronously executes given Java task on the grid projection. If task for + * given name has not been deployed yet, then 'taskName' will be used as task + * class name to auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @return Future containing a result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + Future< R > ExecuteJavaTaskAsync(const std::string& taskName, + const A& taskArg) { + return impl.Get()->ExecuteJavaTaskAsync< R, A >(taskName, taskArg); + } + + /** + * Asynchronously executes given Java task on the grid projection. If task for + * given name has not been deployed yet, then 'taskName' will be used as task + * class name to auto-deploy the task. + * + * @param taskName Java task name. + * @return Future containing a result of type @c R. + * + * @tparam R Type of task result. + */ + template < typename R > + Future< R > ExecuteJavaTaskAsync(const std::string& taskName) { + return impl.Get()->ExecuteJavaTaskAsync< R >(taskName); + } + + private: + /** Implementation. */ + common::concurrent::SharedPointer< impl::compute::ComputeImpl > impl; +}; +} // namespace compute +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_COMPUTE_COMPUTE +#endif //_IGNITE_ODBC_COMPUTE_COMPUTE diff --git a/src/odbc/include/ignite/odbc/compute/compute_func.h b/src/odbc/include/ignite/odbc/compute/compute_func.h index 4f15be257..5406266e7 100644 --- a/src/odbc/include/ignite/odbc/compute/compute_func.h +++ b/src/odbc/include/ignite/odbc/compute/compute_func.h @@ -23,83 +23,76 @@ #ifndef _IGNITE_ODBC_COMPUTE_COMPUTE_FUNC #define _IGNITE_ODBC_COMPUTE_COMPUTE_FUNC -namespace ignite -{ - class Ignite; - class IgniteBinding; +namespace ignite { +class Ignite; +class IgniteBinding; - namespace compute - { - /** - * Interface for a simple compute function that can be serialized and - * called on the remote nodes. ignite::odbc::binary::BinaryType class template - * should be specialized for any class, inheriting from this class. - * - * @tparam R Call return type. BinaryType should be specialized for the - * type if it is not primitive. - */ - template - class ComputeFunc - { - template - friend class ignite::odbc::impl::compute::ComputeJobHolderImpl; - friend class ignite::odbc::IgniteBinding; +namespace compute { +/** + * Interface for a simple compute function that can be serialized and + * called on the remote nodes. ignite::odbc::binary::BinaryType class template + * should be specialized for any class, inheriting from this class. + * + * @tparam R Call return type. BinaryType should be specialized for the + * type if it is not primitive. + */ +template < typename R > +class ComputeFunc { + template < typename TF, typename TR > + friend class ignite::odbc::impl::compute::ComputeJobHolderImpl; + friend class ignite::odbc::IgniteBinding; + + typedef R ReturnType; - typedef R ReturnType; - public: - /** - * Constructor. - */ - ComputeFunc() : - ignite(0) - { - // No-op. - } + public: + /** + * Constructor. + */ + ComputeFunc() : ignite(0) { + // No-op. + } - /** - * Destructor. - */ - virtual ~ComputeFunc() - { - // No-op. - } + /** + * Destructor. + */ + virtual ~ComputeFunc() { + // No-op. + } - /** - * Called upon execution by compute. - * - * @return Computation result. - */ - virtual R Call() = 0; + /** + * Called upon execution by compute. + * + * @return Computation result. + */ + virtual R Call() = 0; - protected: - /* - * Get ignite node pointer. - * Return pointer to the node on which this function was called. - * - * @return Ignite node pointer. - */ - Ignite& GetIgnite() - { - assert(ignite != 0); + protected: + /* + * Get ignite node pointer. + * Return pointer to the node on which this function was called. + * + * @return Ignite node pointer. + */ + Ignite& GetIgnite() { + assert(ignite != 0); - return *ignite; - } + return *ignite; + } - private: - /* - * Set ignite node pointer. - * - * @param ignite Ignite node pointer. - */ - void SetIgnite(Ignite* ignite) - { - this->ignite = ignite; - } + private: + /* + * Set ignite node pointer. + * + * @param ignite Ignite node pointer. + */ + void SetIgnite(Ignite* ignite) { + this->ignite = ignite; + } - /** Ignite node pointer. */ - Ignite* ignite; - }; - } -} + /** Ignite node pointer. */ + Ignite* ignite; +}; +} // namespace compute +} // namespace ignite -#endif //_IGNITE_ODBC_COMPUTE_COMPUTE_FUNC +#endif //_IGNITE_ODBC_COMPUTE_COMPUTE_FUNC diff --git a/src/odbc/include/ignite/odbc/config/config_tools.h b/src/odbc/include/ignite/odbc/config/config_tools.h index 28e0e626e..d37a0acc0 100644 --- a/src/odbc/include/ignite/odbc/config/config_tools.h +++ b/src/odbc/include/ignite/odbc/config/config_tools.h @@ -85,4 +85,4 @@ uint16_t ParsePort(const std::string& value, } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_CONFIG_CONFIG_TOOLS \ No newline at end of file +#endif //_IGNITE_ODBC_CONFIG_CONFIG_TOOLS diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 0eacbf910..e2b424b5a 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -114,7 +114,7 @@ class Configuration { /** Default value for logPath attribute. */ static const std::string logPath; - + /** Default value for scanMethod attribute. */ static const ScanMethod::Type scanMethod; @@ -878,8 +878,7 @@ class Configuration { SettableValue< LogLevel::Type > logLevel = DefaultValue::logLevel; /** The logging file path. */ - SettableValue< std::string > logPath = - DefaultValue::logPath; + SettableValue< std::string > logPath = DefaultValue::logPath; /** Scan method. */ SettableValue< ScanMethod::Type > scanMethod = DefaultValue::scanMethod; diff --git a/src/odbc/include/ignite/odbc/config/connection_info.h b/src/odbc/include/ignite/odbc/config/connection_info.h index 870f2e108..43c21fbe7 100644 --- a/src/odbc/include/ignite/odbc/config/connection_info.h +++ b/src/odbc/include/ignite/odbc/config/connection_info.h @@ -95,4 +95,4 @@ class ConnectionInfo { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_CONFIG_CONNECTION_INFO \ No newline at end of file +#endif //_IGNITE_ODBC_CONFIG_CONNECTION_INFO diff --git a/src/odbc/include/ignite/odbc/config/settable_value.h b/src/odbc/include/ignite/odbc/config/settable_value.h index a2bcb5c49..149f56ff8 100644 --- a/src/odbc/include/ignite/odbc/config/settable_value.h +++ b/src/odbc/include/ignite/odbc/config/settable_value.h @@ -87,4 +87,4 @@ class SettableValue { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_CONFIG_SETTABLE_VALUE \ No newline at end of file +#endif //_IGNITE_ODBC_CONFIG_SETTABLE_VALUE diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index 2afe85d6d..9bfb03493 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -136,7 +136,8 @@ class Connection : public diagnostic::DiagnosableAdapter { * * @return SharedPointer to DocumentDbDatabaseMetadata. */ - SharedPointer< DocumentDbDatabaseMetadata > GetDatabaseMetadata(IgniteError& err); + SharedPointer< DocumentDbDatabaseMetadata > GetDatabaseMetadata( + IgniteError& err); /** * Gets the DocumentDB connection properties. @@ -251,7 +252,7 @@ class Connection : public diagnostic::DiagnosableAdapter { */ void SetAttribute(int attr, void* value, SQLINTEGER valueLen); - inline std::shared_ptr& GetMongoClient() { + inline std::shared_ptr< mongocxx::client >& GetMongoClient() { return mongoClient_; } diff --git a/src/odbc/include/ignite/odbc/diagnostic/diagnosable.h b/src/odbc/include/ignite/odbc/diagnostic/diagnosable.h index f9aec7ae5..7be1f4ee6 100644 --- a/src/odbc/include/ignite/odbc/diagnostic/diagnosable.h +++ b/src/odbc/include/ignite/odbc/diagnostic/diagnosable.h @@ -98,4 +98,4 @@ class Diagnosable { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSABLE \ No newline at end of file +#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSABLE diff --git a/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h b/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h index e8be3ed67..92a8bf596 100644 --- a/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h +++ b/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record.h @@ -178,4 +178,4 @@ class DiagnosticRecord { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSTIC_RECORD \ No newline at end of file +#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSTIC_RECORD diff --git a/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h b/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h index 5bc352c58..4c9bbbcea 100644 --- a/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h +++ b/src/odbc/include/ignite/odbc/diagnostic/diagnostic_record_storage.h @@ -216,4 +216,4 @@ class DiagnosticRecordStorage { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSTIC_RECORD_STORAGE \ No newline at end of file +#endif //_IGNITE_ODBC_DIAGNOSTIC_DIAGNOSTIC_RECORD_STORAGE diff --git a/src/odbc/include/ignite/odbc/documentdb_column.h b/src/odbc/include/ignite/odbc/documentdb_column.h index 53b4766f6..dca932aaa 100644 --- a/src/odbc/include/ignite/odbc/documentdb_column.h +++ b/src/odbc/include/ignite/odbc/documentdb_column.h @@ -25,9 +25,9 @@ #include using namespace ignite::odbc::impl::binary; -using ignite::odbc::jni::JdbcColumnMetadata; using ignite::odbc::app::ApplicationDataBuffer; using ignite::odbc::app::ConversionResult; +using ignite::odbc::jni::JdbcColumnMetadata; namespace ignite { namespace odbc { @@ -56,7 +56,7 @@ class DocumentDbColumn { */ DocumentDbColumn& operator=(const DocumentDbColumn& other) = delete; - /** + /** * Updates the reference to the current document. */ void Update(bsoncxx::document::view const& document); @@ -72,7 +72,7 @@ class DocumentDbColumn { * @param reader Reader to be used to retrieve column data. */ DocumentDbColumn(bsoncxx::document::view& document, - JdbcColumnMetadata& columnMetadata, std::string& path); + JdbcColumnMetadata& columnMetadata, std::string& path); /** * Get column size in bytes. @@ -90,11 +90,9 @@ class DocumentDbColumn { * @param dataBuf Application data buffer. * @return Operation result. */ - ConversionResult::Type ReadToBuffer( - ApplicationDataBuffer& dataBuf) const; + ConversionResult::Type ReadToBuffer(ApplicationDataBuffer& dataBuf) const; private: - /** Setter for int8 data type */ ConversionResult::Type PutInt8( ApplicationDataBuffer& dataBuf, diff --git a/src/odbc/include/ignite/odbc/documentdb_cursor.h b/src/odbc/include/ignite/odbc/documentdb_cursor.h index 172dec729..6d39eeb1f 100644 --- a/src/odbc/include/ignite/odbc/documentdb_cursor.h +++ b/src/odbc/include/ignite/odbc/documentdb_cursor.h @@ -40,7 +40,9 @@ class DocumentDbCursor { * Constructor. * @param queryId ID of the executed query. */ - DocumentDbCursor(mongocxx::cursor& cursor, std::vector< JdbcColumnMetadata >& columnMetadata, std::vector< std::string >& paths); + DocumentDbCursor(mongocxx::cursor& cursor, + std::vector< JdbcColumnMetadata >& columnMetadata, + std::vector< std::string >& paths); /** * Destructor. diff --git a/src/odbc/include/ignite/odbc/documentdb_row.h b/src/odbc/include/ignite/odbc/documentdb_row.h index 14ab04896..ea37b7d1d 100644 --- a/src/odbc/include/ignite/odbc/documentdb_row.h +++ b/src/odbc/include/ignite/odbc/documentdb_row.h @@ -45,8 +45,8 @@ class DocumentDbRow { * @param pageData Page data. */ DocumentDbRow(bsoncxx::document::view const& document, - std::vector< JdbcColumnMetadata >& columnMetadata, - std::vector< std::string >& paths); + std::vector< JdbcColumnMetadata >& columnMetadata, + std::vector< std::string >& paths); /** * Destructor. @@ -72,7 +72,7 @@ class DocumentDbRow { app::ConversionResult::Type ReadColumnToBuffer( uint32_t columnIdx, app::ApplicationDataBuffer& dataBuf); - /** + /** * Updates the row and columns with a new document. */ void Update(bsoncxx::document::view const& document); diff --git a/src/odbc/include/ignite/odbc/end_point.h b/src/odbc/include/ignite/odbc/end_point.h index 8acbcfdd7..e5a284cbf 100644 --- a/src/odbc/include/ignite/odbc/end_point.h +++ b/src/odbc/include/ignite/odbc/end_point.h @@ -61,4 +61,4 @@ struct EndPoint { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_END_POINT \ No newline at end of file +#endif //_IGNITE_ODBC_END_POINT diff --git a/src/odbc/include/ignite/odbc/environment.h b/src/odbc/include/ignite/odbc/environment.h index b44a9124f..c3a48a6b5 100644 --- a/src/odbc/include/ignite/odbc/environment.h +++ b/src/odbc/include/ignite/odbc/environment.h @@ -147,4 +147,4 @@ class Environment : public diagnostic::DiagnosableAdapter { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_ENVIRONMENT \ No newline at end of file +#endif //_IGNITE_ODBC_ENVIRONMENT diff --git a/src/odbc/include/ignite/odbc/future.h b/src/odbc/include/ignite/odbc/future.h index 49c986b6e..04dfebeca 100644 --- a/src/odbc/include/ignite/odbc/future.h +++ b/src/odbc/include/ignite/odbc/future.h @@ -20,268 +20,248 @@ * Declares ignite::odbc::Future class template. */ - #ifndef _IGNITE_FUTURE #define _IGNITE_FUTURE #include #include -namespace ignite -{ - namespace odbc - { - namespace common - { - // Forward declaration - template - class Promise; - } - - /** - * Future class template. Used to get result of the asynchroniously - * started computation. - * - * @tparam T Future value type. - */ - template - class Future - { - friend class common::Promise; - - public: - /** Template value type */ - typedef T ValueType; - - /** - * Copy constructor. - * - * @param src Instance to copy. - */ - Future(const Future& src) : - state(src.state) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - Future& operator=(const Future& other) - { - state = other.state; - - return *this; - } - - /** - * Wait for value to be set. - * Active thread will be blocked until value or error will be set. - */ - void Wait() const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->Wait(); - } - - /** - * Wait for value to be set for specified time. - * Active thread will be blocked until value or error will be set or timeout will end. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->WaitFor(msTimeout); - } - - /** - * Get the set value. - * Active thread will be blocked until value or error will be set. - * - * @throw IgniteError if error has been set. - * @return Value that has been set on success. - */ - const ValueType& GetValue() const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->GetValue(); - } - - /** - * Cancel related operation. - */ - void Cancel() - { - common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->Cancel(); - } - - /** - * Check if the future ready. - */ - bool IsReady() - { - common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->IsSet(); - } - - private: - /** - * Constructor. - * - * @param state0 Shared state instance. - */ - Future(common::concurrent::SharedPointer< common::SharedState > state0) : - state(state0) - { - // No-op. - } - - /** Shared state. */ - common::concurrent::SharedPointer< common::SharedState > state; - }; - - /** - * Specialization for void type. - */ - template<> - class Future - { - friend class common::Promise; - - public: - /** Template value type */ - typedef void ValueType; - - /** - * Copy constructor. - * - * @param src Instance to copy. - */ - Future(const Future& src) : - state(src.state) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - Future& operator=(const Future& other) - { - state = other.state; - - return *this; - } - - /** - * Wait for value to be set. - * Active thread will be blocked until value or error will be set. - */ - void Wait() const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->Wait(); - } - - /** - * Wait for value to be set for specified time. - * Active thread will be blocked until value or error will be set or timeout will end. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->WaitFor(msTimeout); - } - - /** - * Wait for operation complition or error. - * Active thread will be blocked until value or error will be set. - * - * @throw IgniteError if error has been set. - */ - void GetValue() const - { - const common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->GetValue(); - } - - /** - * Cancel related operation. - */ - void Cancel() - { - common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - state0->Cancel(); - } - - /** - * Check if the future ready. - */ - bool IsReady() - { - common::SharedState* state0 = state.Get(); - - assert(state0 != 0); - - return state0->IsSet(); - } - - private: - /** - * Constructor. - * - * @param state0 Shared state instance. - */ - Future(common::concurrent::SharedPointer< common::SharedState > state0) : - state(state0) - { - // No-op. - } - - /** Shared state. */ - common::concurrent::SharedPointer< common::SharedState > state; - }; - } -} - -#endif //_IGNITE_FUTURE +namespace ignite { +namespace odbc { +namespace common { +// Forward declaration +template < typename T > +class Promise; +} // namespace common + +/** + * Future class template. Used to get result of the asynchroniously + * started computation. + * + * @tparam T Future value type. + */ +template < typename T > +class Future { + friend class common::Promise< T >; + + public: + /** Template value type */ + typedef T ValueType; + + /** + * Copy constructor. + * + * @param src Instance to copy. + */ + Future(const Future< ValueType >& src) : state(src.state) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + Future& operator=(const Future< ValueType >& other) { + state = other.state; + + return *this; + } + + /** + * Wait for value to be set. + * Active thread will be blocked until value or error will be set. + */ + void Wait() const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->Wait(); + } + + /** + * Wait for value to be set for specified time. + * Active thread will be blocked until value or error will be set or timeout + * will end. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->WaitFor(msTimeout); + } + + /** + * Get the set value. + * Active thread will be blocked until value or error will be set. + * + * @throw IgniteError if error has been set. + * @return Value that has been set on success. + */ + const ValueType& GetValue() const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->GetValue(); + } + + /** + * Cancel related operation. + */ + void Cancel() { + common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->Cancel(); + } + + /** + * Check if the future ready. + */ + bool IsReady() { + common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->IsSet(); + } + + private: + /** + * Constructor. + * + * @param state0 Shared state instance. + */ + Future(common::concurrent::SharedPointer< common::SharedState< ValueType > > + state0) + : state(state0) { + // No-op. + } + + /** Shared state. */ + common::concurrent::SharedPointer< common::SharedState< ValueType > > state; +}; + +/** + * Specialization for void type. + */ +template <> +class Future< void > { + friend class common::Promise< void >; + + public: + /** Template value type */ + typedef void ValueType; + + /** + * Copy constructor. + * + * @param src Instance to copy. + */ + Future(const Future< ValueType >& src) : state(src.state) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + Future& operator=(const Future< ValueType >& other) { + state = other.state; + + return *this; + } + + /** + * Wait for value to be set. + * Active thread will be blocked until value or error will be set. + */ + void Wait() const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->Wait(); + } + + /** + * Wait for value to be set for specified time. + * Active thread will be blocked until value or error will be set or timeout + * will end. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->WaitFor(msTimeout); + } + + /** + * Wait for operation complition or error. + * Active thread will be blocked until value or error will be set. + * + * @throw IgniteError if error has been set. + */ + void GetValue() const { + const common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->GetValue(); + } + + /** + * Cancel related operation. + */ + void Cancel() { + common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + state0->Cancel(); + } + + /** + * Check if the future ready. + */ + bool IsReady() { + common::SharedState< ValueType >* state0 = state.Get(); + + assert(state0 != 0); + + return state0->IsSet(); + } + + private: + /** + * Constructor. + * + * @param state0 Shared state instance. + */ + Future(common::concurrent::SharedPointer< common::SharedState< ValueType > > + state0) + : state(state0) { + // No-op. + } + + /** Shared state. */ + common::concurrent::SharedPointer< common::SharedState< ValueType > > state; +}; +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_FUTURE diff --git a/src/odbc/include/ignite/odbc/ignite.h b/src/odbc/include/ignite/odbc/ignite.h index 28b5a6b44..794633988 100644 --- a/src/odbc/include/ignite/odbc/ignite.h +++ b/src/odbc/include/ignite/odbc/ignite.h @@ -31,254 +31,245 @@ #include #include -namespace ignite -{ - namespace odbc - { - /** - * Main interface to operate with %Ignite. - * - * This class is implemented as a reference to an implementation so copying - * of this class instance will only create another reference to the same - * underlying object. Underlying object will be released automatically once all - * the instances are destructed. - */ - class IGNITE_IMPORT_EXPORT Ignite - { - friend class impl::IgniteImpl; - public: - /** - * Default constructor. - */ - Ignite(); - - /** - * Constructor. - */ - Ignite(impl::IgniteImpl* impl); - - /** - * Get affinity service to provide information about data partitioning and distribution. - * - * @tparam K Cache affinity key type. - * - * @param cacheName Cache name. - * @return Cache data affinity service. - */ - template - cache::CacheAffinity GetAffinity(const std::string& cacheName) - { - IgniteError err; - - cache::CacheAffinity ret(impl.Get()->GetAffinity(cacheName, err)); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * Get Ignite instance name. - * - * @return Name. - */ - const char* GetName() const; - - /** - * Get node configuration. - * - * This method should only be used on the valid instance. - * - * @return Node configuration. - */ - const IgniteConfiguration& GetConfiguration() const; - - /** - * Get cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @return Cache. - */ - template - cache::Cache GetCache(const char* name) - { - IgniteError err; - - cache::Cache res = GetCache(name, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @param err Error; - * @return Cache. - */ - template - cache::Cache GetCache(const char* name, IgniteError& err) - { - impl::cache::CacheImpl* cacheImpl = impl.Get()->GetCache(name, err); - - return cache::Cache(cacheImpl); - } - - /** - * Get or create cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @return Cache. - */ - template - cache::Cache GetOrCreateCache(const char* name) - { - IgniteError err; - - cache::Cache res = GetOrCreateCache(name, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get or create cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @param err Error; - * @return Cache. - */ - template - cache::Cache GetOrCreateCache(const char* name, IgniteError& err) - { - impl::cache::CacheImpl* cacheImpl = impl.Get()->GetOrCreateCache(name, err); - - return cache::Cache(cacheImpl); - } - - /** - * Create cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @return Cache. - */ - template - cache::Cache CreateCache(const char* name) - { - IgniteError err; - - cache::Cache res = CreateCache(name, err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Create cache. - * - * This method should only be used on the valid instance. - * - * @param name Cache name. - * @param err Error; - * @return Cache. - */ - template - cache::Cache CreateCache(const char* name, IgniteError& err) - { - impl::cache::CacheImpl* cacheImpl = impl.Get()->CreateCache(name, err); - - return cache::Cache(cacheImpl); - } - - /** - * Check if the Ignite grid is active. - * - * @return True if grid is active and false otherwise. - */ - bool IsActive(); - - /** - * Change Ignite grid state to active or inactive. - * - * @param active If true start activation process. If false start - * deactivation process. - */ - void SetActive(bool active); - - /** - * Get cluster. - * - * This method should only be called on the valid instance. - * - * @return Cluster class instance. - */ - cluster::IgniteCluster GetCluster(); - - /** - * Gets compute instance over all cluster nodes started in server mode. - * - * This method should only be called on the valid instance. - * - * @return Compute class instance. - */ - compute::Compute GetCompute(); - - /** - * Gets compute instance over the specified cluster group. All operations - * on the returned compute instance will only include nodes from - * this cluster group. - * - * This method should only be called on the valid instance. - * - * @param grp Specified cluster group instance. - * @return Compute class instance over the specified cluster group. - */ - compute::Compute GetCompute(cluster::ClusterGroup grp); - - /** - * Get ignite binding. - * - * This method should only be used on the valid instance. - * - * @return IgniteBinding class instance. - */ - IgniteBinding GetBinding(); - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - /** Implementation delegate. */ - ignite::odbc::common::concurrent::SharedPointer impl; - }; - } -} - -#endif //_IGNITE_ODBC_IGNITE +namespace ignite { +namespace odbc { +/** + * Main interface to operate with %Ignite. + * + * This class is implemented as a reference to an implementation so copying + * of this class instance will only create another reference to the same + * underlying object. Underlying object will be released automatically once all + * the instances are destructed. + */ +class IGNITE_IMPORT_EXPORT Ignite { + friend class impl::IgniteImpl; + + public: + /** + * Default constructor. + */ + Ignite(); + + /** + * Constructor. + */ + Ignite(impl::IgniteImpl* impl); + + /** + * Get affinity service to provide information about data partitioning and + * distribution. + * + * @tparam K Cache affinity key type. + * + * @param cacheName Cache name. + * @return Cache data affinity service. + */ + template < typename K > + cache::CacheAffinity< K > GetAffinity(const std::string& cacheName) { + IgniteError err; + + cache::CacheAffinity< K > ret(impl.Get()->GetAffinity(cacheName, err)); + + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * Get Ignite instance name. + * + * @return Name. + */ + const char* GetName() const; + + /** + * Get node configuration. + * + * This method should only be used on the valid instance. + * + * @return Node configuration. + */ + const IgniteConfiguration& GetConfiguration() const; + + /** + * Get cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > GetCache(const char* name) { + IgniteError err; + + cache::Cache< K, V > res = GetCache< K, V >(name, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @param err Error; + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > GetCache(const char* name, IgniteError& err) { + impl::cache::CacheImpl* cacheImpl = impl.Get()->GetCache(name, err); + + return cache::Cache< K, V >(cacheImpl); + } + + /** + * Get or create cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > GetOrCreateCache(const char* name) { + IgniteError err; + + cache::Cache< K, V > res = GetOrCreateCache< K, V >(name, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get or create cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @param err Error; + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > GetOrCreateCache(const char* name, IgniteError& err) { + impl::cache::CacheImpl* cacheImpl = impl.Get()->GetOrCreateCache(name, err); + + return cache::Cache< K, V >(cacheImpl); + } + + /** + * Create cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > CreateCache(const char* name) { + IgniteError err; + + cache::Cache< K, V > res = CreateCache< K, V >(name, err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Create cache. + * + * This method should only be used on the valid instance. + * + * @param name Cache name. + * @param err Error; + * @return Cache. + */ + template < typename K, typename V > + cache::Cache< K, V > CreateCache(const char* name, IgniteError& err) { + impl::cache::CacheImpl* cacheImpl = impl.Get()->CreateCache(name, err); + + return cache::Cache< K, V >(cacheImpl); + } + + /** + * Check if the Ignite grid is active. + * + * @return True if grid is active and false otherwise. + */ + bool IsActive(); + + /** + * Change Ignite grid state to active or inactive. + * + * @param active If true start activation process. If false start + * deactivation process. + */ + void SetActive(bool active); + + /** + * Get cluster. + * + * This method should only be called on the valid instance. + * + * @return Cluster class instance. + */ + cluster::IgniteCluster GetCluster(); + + /** + * Gets compute instance over all cluster nodes started in server mode. + * + * This method should only be called on the valid instance. + * + * @return Compute class instance. + */ + compute::Compute GetCompute(); + + /** + * Gets compute instance over the specified cluster group. All operations + * on the returned compute instance will only include nodes from + * this cluster group. + * + * This method should only be called on the valid instance. + * + * @param grp Specified cluster group instance. + * @return Compute class instance over the specified cluster group. + */ + compute::Compute GetCompute(cluster::ClusterGroup grp); + + /** + * Get ignite binding. + * + * This method should only be used on the valid instance. + * + * @return IgniteBinding class instance. + */ + IgniteBinding GetBinding(); + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + /** Implementation delegate. */ + ignite::odbc::common::concurrent::SharedPointer< impl::IgniteImpl > impl; +}; +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IGNITE diff --git a/src/odbc/include/ignite/odbc/ignite_binding.h b/src/odbc/include/ignite/odbc/ignite_binding.h index 7a5dfe4af..a973a8ec0 100644 --- a/src/odbc/include/ignite/odbc/ignite_binding.h +++ b/src/odbc/include/ignite/odbc/ignite_binding.h @@ -29,149 +29,136 @@ #include #include -namespace ignite -{ - namespace odbc - { - /** - * %Ignite Binding. - * Used to register callable classes. - */ - class IGNITE_IMPORT_EXPORT IgniteBinding - { - public: - /** - * Default constructor. - */ - IgniteBinding() : - impl() - { - // No-op. - } - - /** - * Constructor. - * - * @param impl Implementation. - */ - IgniteBinding(common::concurrent::SharedPointer impl) : - impl(impl) - { - // No-op. - } - - /** - * Register type as Cache Entry Processor. - * - * Registred type should be a child of ignite::odbc::cache::CacheEntryProcessor - * class. - */ - template - void RegisterCacheEntryProcessor() - { - IgniteError err; - - RegisterCacheEntryProcessor

(err); - - IgniteError::ThrowIfNeeded(err); - } - - /** - * Register Type as Cache Entry Processor. - * - * Registred type should be a child of ignite::odbc::cache::CacheEntryProcessor - * class. - * - * @param err Error. - */ - template - void RegisterCacheEntryProcessor(IgniteError& err) - { - impl::IgniteBindingImpl *im = impl.Get(); - - if (im) - { - im->RegisterCallback(impl::IgniteBindingImpl::CallbackType::CACHE_ENTRY_PROCESSOR_APPLY, - binary::BinaryType

::GetTypeId(), impl::binding::ListenerApply, err); - } - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, +namespace ignite { +namespace odbc { +/** + * %Ignite Binding. + * Used to register callable classes. + */ +class IGNITE_IMPORT_EXPORT IgniteBinding { + public: + /** + * Default constructor. + */ + IgniteBinding() : impl() { + // No-op. + } + + /** + * Constructor. + * + * @param impl Implementation. + */ + IgniteBinding( + common::concurrent::SharedPointer< impl::IgniteBindingImpl > impl) + : impl(impl) { + // No-op. + } + + /** + * Register type as Cache Entry Processor. + * + * Registred type should be a child of + * ignite::odbc::cache::CacheEntryProcessor class. + */ + template < typename P > + void RegisterCacheEntryProcessor() { + IgniteError err; + + RegisterCacheEntryProcessor< P >(err); + + IgniteError::ThrowIfNeeded(err); + } + + /** + * Register Type as Cache Entry Processor. + * + * Registred type should be a child of + * ignite::odbc::cache::CacheEntryProcessor class. + * + * @param err Error. + */ + template < typename P > + void RegisterCacheEntryProcessor(IgniteError &err) { + impl::IgniteBindingImpl *im = impl.Get(); + + if (im) { + im->RegisterCallback( + impl::IgniteBindingImpl::CallbackType::CACHE_ENTRY_PROCESSOR_APPLY, + binary::BinaryType< P >::GetTypeId(), + impl::binding::ListenerApply< + P, typename P::KeyType, typename P::ValueType, + typename P::ReturnType, typename P::ArgumentType >, + err); + } else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Instance is not usable (did you check for error?)."); - } - } - - /** - * Register type as Cache Entry Event Filter. - * - * Registred type should be a child of ignite::odbc::cache::event::CacheEntryEventFilter - * class. - */ - template - void RegisterCacheEntryEventFilter() - { - impl::IgniteBindingImpl *im = impl.Get(); - - int32_t typeId = binary::BinaryType::GetTypeId(); - - if (im) - { - im->RegisterCallback(impl::IgniteBindingImpl::CallbackType::CACHE_ENTRY_FILTER_CREATE, - typeId, impl::binding::FilterCreate); - } - else - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + } + } + + /** + * Register type as Cache Entry Event Filter. + * + * Registred type should be a child of + * ignite::odbc::cache::event::CacheEntryEventFilter class. + */ + template < typename F > + void RegisterCacheEntryEventFilter() { + impl::IgniteBindingImpl *im = impl.Get(); + + int32_t typeId = binary::BinaryType< F >::GetTypeId(); + + if (im) { + im->RegisterCallback( + impl::IgniteBindingImpl::CallbackType::CACHE_ENTRY_FILTER_CREATE, + typeId, impl::binding::FilterCreate< F >); + } else { + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Instance is not usable (did you check for error?)."); - } - } - - /** - * Register type as Compute function. - * - * Registred type should be a child of ignite::odbc::compute::ComputeFunc - * class. - */ - template - void RegisterComputeFunc() - { - impl::IgniteBindingImpl *im = impl.Get(); - - int32_t typeId = binary::BinaryType::GetTypeId(); - - if (im) - { - im->RegisterCallback(impl::IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, - typeId, impl::binding::ComputeJobCreate); - } - else - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + } + } + + /** + * Register type as Compute function. + * + * Registred type should be a child of ignite::odbc::compute::ComputeFunc + * class. + */ + template < typename F > + void RegisterComputeFunc() { + impl::IgniteBindingImpl *im = impl.Get(); + + int32_t typeId = binary::BinaryType< F >::GetTypeId(); + + if (im) { + im->RegisterCallback( + impl::IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, typeId, + impl::binding::ComputeJobCreate< F, typename F::ReturnType >); + } else { + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Instance is not usable (did you check for error?)."); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() const - { - return impl.IsValid(); - } - - private: - /** Registered cache entry processors. */ - common::concurrent::SharedPointer impl; - }; } -} + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() const { + return impl.IsValid(); + } + + private: + /** Registered cache entry processors. */ + common::concurrent::SharedPointer< impl::IgniteBindingImpl > impl; +}; +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IGNITE_BINDING +#endif //_IGNITE_ODBC_IGNITE_BINDING diff --git a/src/odbc/include/ignite/odbc/ignite_binding_context.h b/src/odbc/include/ignite/odbc/ignite_binding_context.h index 4736b9a32..587163c7b 100644 --- a/src/odbc/include/ignite/odbc/ignite_binding_context.h +++ b/src/odbc/include/ignite/odbc/ignite_binding_context.h @@ -26,66 +26,60 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - class IgniteEnvironment; - } - - /** - * %Ignite binding context. - * - * Provides methods that can be used to get Ignite components which may be - * needed for initial module initialization. - */ - class IgniteBindingContext - { - friend class impl::IgniteEnvironment; - public: - /** - * Get binding. - * - * @return IgniteBinding instance. - */ - IgniteBinding GetBinding() const - { - return binding; - } - - /** - * Get configuration for current node. - * - * @return Configuration. - */ - const IgniteConfiguration& GetConfiguration() const - { - return cfg; - } - - private: - /** - * Constructor. - * - * @param cfg Configuration. - * @param binding Binding. - */ - IgniteBindingContext(const IgniteConfiguration& cfg, const IgniteBinding& binding) : - cfg(cfg), - binding(binding) - { - // No-op. - } - - /** Configuration */ - const IgniteConfiguration& cfg; - - /** Binding. */ - IgniteBinding binding; - }; - } +namespace ignite { +namespace odbc { +namespace impl { +class IgniteEnvironment; } -#endif //_IGNITE_ODBC_IGNITE_BINDING_CONTEXT +/** + * %Ignite binding context. + * + * Provides methods that can be used to get Ignite components which may be + * needed for initial module initialization. + */ +class IgniteBindingContext { + friend class impl::IgniteEnvironment; + + public: + /** + * Get binding. + * + * @return IgniteBinding instance. + */ + IgniteBinding GetBinding() const { + return binding; + } + + /** + * Get configuration for current node. + * + * @return Configuration. + */ + const IgniteConfiguration& GetConfiguration() const { + return cfg; + } + + private: + /** + * Constructor. + * + * @param cfg Configuration. + * @param binding Binding. + */ + IgniteBindingContext(const IgniteConfiguration& cfg, + const IgniteBinding& binding) + : cfg(cfg), binding(binding) { + // No-op. + } + + /** Configuration */ + const IgniteConfiguration& cfg; + + /** Binding. */ + IgniteBinding binding; +}; +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IGNITE_BINDING_CONTEXT diff --git a/src/odbc/include/ignite/odbc/ignite_configuration.h b/src/odbc/include/ignite/odbc/ignite_configuration.h index 65b73fa79..64a601717 100644 --- a/src/odbc/include/ignite/odbc/ignite_configuration.h +++ b/src/odbc/include/ignite/odbc/ignite_configuration.h @@ -27,46 +27,48 @@ #include #include -namespace ignite -{ - namespace odbc - { - /** - * %Ignite configuration. - */ - struct IgniteConfiguration - { - /** Path to Ignite home. */ - std::string igniteHome; - - /** Path to Spring configuration file. */ - std::string springCfgPath; - - /** Path ot JVM libbrary. */ - std::string jvmLibPath; - - /** JVM classpath. */ - std::string jvmClassPath; - - /** Initial amount of JVM memory. */ - int32_t jvmInitMem; - - /** Maximum amount of JVM memory. */ - int32_t jvmMaxMem; - - /** Additional JVM options. */ - std::list jvmOpts; - - /** - * Default constructor. - */ - IgniteConfiguration() : igniteHome(), springCfgPath(), jvmLibPath(), jvmClassPath(), - jvmInitMem(512), jvmMaxMem(1024), jvmOpts() - { - // No-op. - } - }; - } -} +namespace ignite { +namespace odbc { +/** + * %Ignite configuration. + */ +struct IgniteConfiguration { + /** Path to Ignite home. */ + std::string igniteHome; + + /** Path to Spring configuration file. */ + std::string springCfgPath; + + /** Path ot JVM libbrary. */ + std::string jvmLibPath; + + /** JVM classpath. */ + std::string jvmClassPath; + + /** Initial amount of JVM memory. */ + int32_t jvmInitMem; + + /** Maximum amount of JVM memory. */ + int32_t jvmMaxMem; + + /** Additional JVM options. */ + std::list< std::string > jvmOpts; + + /** + * Default constructor. + */ + IgniteConfiguration() + : igniteHome(), + springCfgPath(), + jvmLibPath(), + jvmClassPath(), + jvmInitMem(512), + jvmMaxMem(1024), + jvmOpts() { + // No-op. + } +}; +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IGNITE_CONFIGURATION +#endif //_IGNITE_ODBC_IGNITE_CONFIGURATION diff --git a/src/odbc/include/ignite/odbc/ignite_error.h b/src/odbc/include/ignite/odbc/ignite_error.h index ec7955c43..811979380 100644 --- a/src/odbc/include/ignite/odbc/ignite_error.h +++ b/src/odbc/include/ignite/odbc/ignite_error.h @@ -29,28 +29,28 @@ #include #include -//Define can be removed once the duplicated code was removed +// Define can be removed once the duplicated code was removed #ifndef _IGNITE_ERROR_MACRO #define _IGNITE_ERROR_MACRO -#define IGNITE_ERROR_1(code, part1) \ - { \ - std::stringstream stream; \ - stream << (part1); \ +#define IGNITE_ERROR_1(code, part1) \ + { \ + std::stringstream stream; \ + stream << (part1); \ throw IgniteError(code, stream.str().c_str()); \ } -#define IGNITE_ERROR_2(code, part1, part2) \ - { \ - std::stringstream stream; \ - stream << (part1) << (part2); \ +#define IGNITE_ERROR_2(code, part1, part2) \ + { \ + std::stringstream stream; \ + stream << (part1) << (part2); \ throw IgniteError(code, stream.str().c_str()); \ } -#define IGNITE_ERROR_3(code, part1, part2, part3) \ - { \ - std::stringstream stream; \ - stream << (part1) << (part2) << (part3); \ +#define IGNITE_ERROR_3(code, part1, part2, part3) \ + { \ + std::stringstream stream; \ + stream << (part1) << (part2) << (part3); \ throw IgniteError(code, stream.str().c_str()); \ } @@ -58,7 +58,7 @@ { \ std::stringstream stream; \ stream << msg << " [" << key1 << "=" << (val1) << "]"; \ - throw IgniteError(code, stream.str().c_str()); \ + throw IgniteError(code, stream.str().c_str()); \ } #define IGNITE_ERROR_FORMATTED_2(code, msg, key1, val1, key2, val2) \ @@ -66,7 +66,7 @@ std::stringstream stream; \ stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" \ << (val2) << "]"; \ - throw IgniteError(code, stream.str().c_str()); \ + throw IgniteError(code, stream.str().c_str()); \ } #define IGNITE_ERROR_FORMATTED_3(code, msg, key1, val1, key2, val2, key3, \ @@ -75,7 +75,7 @@ std::stringstream stream; \ stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" \ << (val2) << ", " << key3 << "=" << (val3) << "]"; \ - throw IgniteError(code, stream.str().c_str()); \ + throw IgniteError(code, stream.str().c_str()); \ } #define IGNITE_ERROR_FORMATTED_4(code, msg, key1, val1, key2, val2, key3, \ @@ -85,10 +85,10 @@ stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" \ << (val2) << ", " << key3 << "=" << (val3) << ", " << key4 << "=" \ << (val4) << "]"; \ - throw IgniteError(code, stream.str().c_str()); \ + throw IgniteError(code, stream.str().c_str()); \ } -#endif //_IGNITE_ERROR_MACRO +#endif //_IGNITE_ERROR_MACRO #ifdef _MSC_VER #pragma warning(push) diff --git a/src/odbc/include/ignite/odbc/ignite_predicate.h b/src/odbc/include/ignite/odbc/ignite_predicate.h index 40b2c17a2..9970dc3b1 100644 --- a/src/odbc/include/ignite/odbc/ignite_predicate.h +++ b/src/odbc/include/ignite/odbc/ignite_predicate.h @@ -45,4 +45,4 @@ class IGNITE_IMPORT_EXPORT IgnitePredicate { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_IGNITE_PREDICATE \ No newline at end of file +#endif //_IGNITE_ODBC_IGNITE_PREDICATE diff --git a/src/odbc/include/ignite/odbc/ignite_product_version.h b/src/odbc/include/ignite/odbc/ignite_product_version.h index ff91c83b5..4de989238 100644 --- a/src/odbc/include/ignite/odbc/ignite_product_version.h +++ b/src/odbc/include/ignite/odbc/ignite_product_version.h @@ -15,10 +15,10 @@ * limitations under the License. */ - /** - * @file - * Declares ignite::odbc::IgniteProductVersion class. - */ +/** + * @file + * Declares ignite::odbc::IgniteProductVersion class. + */ #ifndef _IGNITE_ODBC_IGNITE_PRODUCT_VERSION #define _IGNITE_ODBC_IGNITE_PRODUCT_VERSION @@ -28,46 +28,49 @@ #include -namespace ignite -{ - namespace odbc - { - /** - * %Ignite product version. - */ - struct IgniteProductVersion - { - /** Major version number. */ - int8_t majorNumber; - - /** Minor version number. */ - int8_t minorNumber; - - /** Maintenance version number. */ - int8_t maintenance; - - /** Stage of development. */ - std::string stage; - - /** Release date. */ - int64_t releaseDate; - - /** Revision hash. */ - std::vector revHash; - - /** SHA1 Length. */ - static const int SHA1_LENGTH = 20; - - /** - * Default constructor. - */ - IgniteProductVersion(int8_t majorNumber, int8_t minorNumber, int8_t maintenance, std::string stage, int64_t releaseDate, std::vector revHash) : - majorNumber(majorNumber), minorNumber(minorNumber), maintenance(maintenance), stage(stage), releaseDate(releaseDate), revHash(revHash) - { - assert(revHash.size() == SHA1_LENGTH); - } - }; - } -} +namespace ignite { +namespace odbc { +/** + * %Ignite product version. + */ +struct IgniteProductVersion { + /** Major version number. */ + int8_t majorNumber; + + /** Minor version number. */ + int8_t minorNumber; + + /** Maintenance version number. */ + int8_t maintenance; + + /** Stage of development. */ + std::string stage; + + /** Release date. */ + int64_t releaseDate; + + /** Revision hash. */ + std::vector< int8_t > revHash; + + /** SHA1 Length. */ + static const int SHA1_LENGTH = 20; + + /** + * Default constructor. + */ + IgniteProductVersion(int8_t majorNumber, int8_t minorNumber, + int8_t maintenance, std::string stage, + int64_t releaseDate, std::vector< int8_t > revHash) + : majorNumber(majorNumber), + minorNumber(minorNumber), + maintenance(maintenance), + stage(stage), + releaseDate(releaseDate), + revHash(revHash) { + assert(revHash.size() == SHA1_LENGTH); + } +}; +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IGNITE_PRODUCT_VERSION +#endif //_IGNITE_ODBC_IGNITE_PRODUCT_VERSION diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary.h b/src/odbc/include/ignite/odbc/impl/binary/binary.h index d4a62bddd..cdf8617ab 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary.h @@ -32,4 +32,4 @@ #include #include -#endif //_IGNITE_BINARY_BINARY +#endif //_IGNITE_BINARY_BINARY diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_object_impl.h b/src/odbc/include/ignite/odbc/impl/binary/binary_object_impl.h index ef4094b22..f0c149e59 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_object_impl.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_object_impl.h @@ -107,7 +107,8 @@ class IGNITE_IMPORT_EXPORT BinaryObjectImpl { template < typename T > T Deserialize() const { int32_t actualTypeId = GetTypeId(); - int32_t requestedTypeId = ignite::odbc::binary::BinaryType< T >::GetTypeId(); + int32_t requestedTypeId = + ignite::odbc::binary::BinaryType< T >::GetTypeId(); if (requestedTypeId != actualTypeId) { IGNITE_ERROR_FORMATTED_3( diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_reader_impl.h b/src/odbc/include/ignite/odbc/impl/binary/binary_reader_impl.h index 52e50bb21..cbd149100 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_reader_impl.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_reader_impl.h @@ -764,8 +764,8 @@ class IGNITE_IMPORT_EXPORT BinaryReaderImpl { * @param size Map size. * @return Read session ID. */ - int32_t ReadMap(const char* fieldName, ignite::odbc::binary::MapType::Type* typ, - int32_t* size); + int32_t ReadMap(const char* fieldName, + ignite::odbc::binary::MapType::Type* typ, int32_t* size); /** * Read type of the collection. @@ -1566,9 +1566,8 @@ BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, int16_t >( int16_t& res); template <> -void IGNITE_IMPORT_EXPORT -BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, uint16_t >( - uint16_t& res); +void IGNITE_IMPORT_EXPORT BinaryReaderImpl::ReadTopObject0< + ignite::odbc::binary::BinaryReader, uint16_t >(uint16_t& res); template <> void IGNITE_IMPORT_EXPORT @@ -1601,9 +1600,8 @@ BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, Date >( Date& res); template <> -void IGNITE_IMPORT_EXPORT -BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, Timestamp >( - Timestamp& res); +void IGNITE_IMPORT_EXPORT BinaryReaderImpl::ReadTopObject0< + ignite::odbc::binary::BinaryReader, Timestamp >(Timestamp& res); template <> void IGNITE_IMPORT_EXPORT @@ -1611,9 +1609,8 @@ BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, Time >( Time& res); template <> -void IGNITE_IMPORT_EXPORT -BinaryReaderImpl::ReadTopObject0< ignite::odbc::binary::BinaryReader, std::string >( - std::string& res); +void IGNITE_IMPORT_EXPORT BinaryReaderImpl::ReadTopObject0< + ignite::odbc::binary::BinaryReader, std::string >(std::string& res); template <> void IGNITE_IMPORT_EXPORT BinaryReaderImpl::ReadTopObject0< diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_type_impl.h b/src/odbc/include/ignite/odbc/impl/binary/binary_type_impl.h index c8b779935..772868562 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_type_impl.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_type_impl.h @@ -30,23 +30,24 @@ * * This macro declares checker for the method. */ -#define IGNITE_DECLARE_BINARY_TYPE_METHOD_CHECKER(method, sign) \ - template < typename T > \ - class IsDeclaredBinaryType##method { \ - typedef char one; \ - typedef char two[2]; \ - \ - template < class U, U > \ - struct test; \ - \ - template < typename C > \ - static one& helper(test< sign, &C::method >*); \ - template < typename C > \ - static two& helper(...); \ - \ - public: \ - const static bool value = \ - (sizeof(helper< ignite::odbc::binary::BinaryType< T > >(0)) == sizeof(one)); \ +#define IGNITE_DECLARE_BINARY_TYPE_METHOD_CHECKER(method, sign) \ + template < typename T > \ + class IsDeclaredBinaryType##method { \ + typedef char one; \ + typedef char two[2]; \ + \ + template < class U, U > \ + struct test; \ + \ + template < typename C > \ + static one& helper(test< sign, &C::method >*); \ + template < typename C > \ + static two& helper(...); \ + \ + public: \ + const static bool value = \ + (sizeof(helper< ignite::odbc::binary::BinaryType< T > >(0)) \ + == sizeof(one)); \ } namespace ignite { @@ -104,7 +105,8 @@ struct WriteHelper< T* > { if (!val) writer.WriteNull0(); else - writer.template WriteTopObject0< ignite::odbc::binary::BinaryWriter >(*val); + writer.template WriteTopObject0< ignite::odbc::binary::BinaryWriter >( + *val); } }; @@ -124,7 +126,8 @@ struct ReadHelper { template < typename R > static void Read(R& reader, T& val) { - reader.template ReadTopObject0< ignite::odbc::binary::BinaryReader, T >(val); + reader.template ReadTopObject0< ignite::odbc::binary::BinaryReader, T >( + val); } }; @@ -140,7 +143,8 @@ struct ReadHelper< T* > { std::unique_ptr< T > res(new T()); - reader.template ReadTopObject0< ignite::odbc::binary::BinaryReader, T >(*res); + reader.template ReadTopObject0< ignite::odbc::binary::BinaryReader, T >( + *res); return res.release(); } diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_type_updater_impl.h b/src/odbc/include/ignite/odbc/impl/binary/binary_type_updater_impl.h index dca19a7fc..46dd7197c 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_type_updater_impl.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_type_updater_impl.h @@ -21,48 +21,45 @@ #include "ignite/odbc/impl/ignite_environment.h" #include "ignite/odbc/impl/binary/binary_type_updater.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace binary - { - /** - * Type updater implementation. - */ - class IGNITE_IMPORT_EXPORT BinaryTypeUpdaterImpl : public BinaryTypeUpdater - { - public: - /** - * Constructor. - * - * @param env Environment. - * @param javaRef Reference to Java object which is able to process type request. - */ - BinaryTypeUpdaterImpl(IgniteEnvironment& env, jobject javaRef); - - /** - * Destructor. - */ - ~BinaryTypeUpdaterImpl(); - - virtual bool Update(const Snap& snap, IgniteError& err); - - virtual SPSnap GetMeta(int32_t typeId, IgniteError& err); - private: - /** Environment. */ - IgniteEnvironment& env; - - /** Handle to Java object. */ - jobject javaRef; - - IGNITE_NO_COPY_ASSIGNMENT(BinaryTypeUpdaterImpl); - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace binary { +/** + * Type updater implementation. + */ +class IGNITE_IMPORT_EXPORT BinaryTypeUpdaterImpl : public BinaryTypeUpdater { + public: + /** + * Constructor. + * + * @param env Environment. + * @param javaRef Reference to Java object which is able to process type + * request. + */ + BinaryTypeUpdaterImpl(IgniteEnvironment& env, jobject javaRef); + + /** + * Destructor. + */ + ~BinaryTypeUpdaterImpl(); + + virtual bool Update(const Snap& snap, IgniteError& err); + + virtual SPSnap GetMeta(int32_t typeId, IgniteError& err); + + private: + /** Environment. */ + IgniteEnvironment& env; + + /** Handle to Java object. */ + jobject javaRef; + + IGNITE_NO_COPY_ASSIGNMENT(BinaryTypeUpdaterImpl); +}; +} // namespace binary +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_BINARY_BINARY_TYPE_UPDATER_IMPL +#endif //_IGNITE_ODBC_IMPL_BINARY_BINARY_TYPE_UPDATER_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_utils.h b/src/odbc/include/ignite/odbc/impl/binary/binary_utils.h index 7447a57b5..2d2289b9c 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_utils.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_utils.h @@ -107,8 +107,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteInt8Array(InteropOutputStream* stream, - const int8_t* val, int32_t len); + static void WriteInt8Array(InteropOutputStream* stream, const int8_t* val, + int32_t len); /** * Utility method to read boolean from stream. @@ -133,8 +133,7 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param res Target array. * @param len Array length. */ - static void ReadBoolArray(InteropInputStream* stream, bool* res, - int32_t len); + static void ReadBoolArray(InteropInputStream* stream, bool* res, int32_t len); /** * Utility method to write bool array to stream. @@ -143,8 +142,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteBoolArray(InteropOutputStream* stream, - const bool* val, int32_t len); + static void WriteBoolArray(InteropOutputStream* stream, const bool* val, + int32_t len); /** * Utility method to read signed 16-bit integer from stream. @@ -199,8 +198,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteInt16Array(InteropOutputStream* stream, - const int16_t* val, int32_t len); + static void WriteInt16Array(InteropOutputStream* stream, const int16_t* val, + int32_t len); /** * Utility method to read unsigned 16-bit integer from stream. @@ -225,8 +224,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param res Target array. * @param len Array length. */ - static void ReadUInt16Array(InteropInputStream* stream, - uint16_t* res, int32_t len); + static void ReadUInt16Array(InteropInputStream* stream, uint16_t* res, + int32_t len); /** * Utility method to write unsigned 16-bit integer array to stream. @@ -235,8 +234,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteUInt16Array(InteropOutputStream* stream, - const uint16_t* val, int32_t len); + static void WriteUInt16Array(InteropOutputStream* stream, const uint16_t* val, + int32_t len); /** * Utility method to read signed 32-bit integer from stream. @@ -291,8 +290,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteInt32Array(InteropOutputStream* stream, - const int32_t* val, int32_t len); + static void WriteInt32Array(InteropOutputStream* stream, const int32_t* val, + int32_t len); /** * Utility method to read signed 64-bit integer from stream. @@ -327,8 +326,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteInt64Array(InteropOutputStream* stream, - const int64_t* val, int32_t len); + static void WriteInt64Array(InteropOutputStream* stream, const int64_t* val, + int32_t len); /** * Utility method to read float from stream. @@ -363,8 +362,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteFloatArray(InteropOutputStream* stream, - const float* val, int32_t len); + static void WriteFloatArray(InteropOutputStream* stream, const float* val, + int32_t len); /** * Utility method to read double from stream. @@ -399,8 +398,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param val Value. * @param len Array length. */ - static void WriteDoubleArray(InteropOutputStream* stream, - const double* val, int32_t len); + static void WriteDoubleArray(InteropOutputStream* stream, const double* val, + int32_t len); /** * Utility method to read Guid from stream. @@ -446,8 +445,7 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param stream Stream. * @param val Value. */ - static void WriteTimestamp(InteropOutputStream* stream, - Timestamp val); + static void WriteTimestamp(InteropOutputStream* stream, Timestamp val); /** * Utility method to read Time from stream. @@ -471,8 +469,7 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param stream Stream. * @return Value. */ - static BinaryEnumEntry ReadBinaryEnumEntry( - InteropInputStream* stream); + static BinaryEnumEntry ReadBinaryEnumEntry(InteropInputStream* stream); /** * Utility method to write BinaryEnumEntry to stream. @@ -492,8 +489,8 @@ class IGNITE_IMPORT_EXPORT BinaryUtils { * @param typeId Type ID. * @param ordinal Ordinal. */ - static void WriteBinaryEnumEntry(InteropOutputStream* stream, - int32_t typeId, int32_t ordinal); + static void WriteBinaryEnumEntry(InteropOutputStream* stream, int32_t typeId, + int32_t ordinal); /** * Utility method to write string to stream. @@ -581,8 +578,7 @@ inline Time BinaryUtils::GetDefaultValue< Time >() { } template <> -inline BinaryEnumEntry -BinaryUtils::GetDefaultValue< BinaryEnumEntry >() { +inline BinaryEnumEntry BinaryUtils::GetDefaultValue< BinaryEnumEntry >() { return BinaryEnumEntry(); } diff --git a/src/odbc/include/ignite/odbc/impl/binary/binary_writer_impl.h b/src/odbc/include/ignite/odbc/impl/binary/binary_writer_impl.h index 9357cea48..756e0abff 100644 --- a/src/odbc/include/ignite/odbc/impl/binary/binary_writer_impl.h +++ b/src/odbc/include/ignite/odbc/impl/binary/binary_writer_impl.h @@ -648,7 +648,8 @@ class IGNITE_IMPORT_EXPORT BinaryWriterImpl { * @param typ Map type. * @return Session ID. */ - int32_t WriteMap(const char* fieldName, ignite::odbc::binary::MapType::Type typ); + int32_t WriteMap(const char* fieldName, + ignite::odbc::binary::MapType::Type typ); /** * Write collection element. @@ -735,7 +736,7 @@ class IGNITE_IMPORT_EXPORT BinaryWriterImpl { } ignite::odbc::binary::BinaryEnumEntry entry(TypeMeta::GetTypeId(), - TypeMeta::GetOrdinal(val)); + TypeMeta::GetOrdinal(val)); WriteBinaryEnum(entry); } @@ -760,7 +761,7 @@ class IGNITE_IMPORT_EXPORT BinaryWriterImpl { } ignite::odbc::binary::BinaryEnumEntry entry(TypeMeta::GetTypeId(), - TypeMeta::GetOrdinal(val)); + TypeMeta::GetOrdinal(val)); WriteBinaryEnum(fieldName, entry); } @@ -978,8 +979,9 @@ class IGNITE_IMPORT_EXPORT BinaryWriterImpl { * @param typ Collection type. */ template < typename InputIterator > - void WriteCollectionWithinSession(InputIterator first, InputIterator last, - ignite::odbc::binary::CollectionType::Type typ) { + void WriteCollectionWithinSession( + InputIterator first, InputIterator last, + ignite::odbc::binary::CollectionType::Type typ) { stream->WriteInt8(IGNITE_TYPE_COLLECTION); stream->Position(stream->Position() + 4); stream->WriteInt8(typ); @@ -1053,24 +1055,20 @@ BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, bool >( const bool& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int16_t >( - const int16_t& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, int16_t >(const int16_t& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, uint16_t >( - const uint16_t& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, uint16_t >(const uint16_t& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int32_t >( - const int32_t& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, int32_t >(const int32_t& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int64_t >( - const int64_t& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, int64_t >(const int64_t& obj); template <> void IGNITE_IMPORT_EXPORT @@ -1093,9 +1091,8 @@ BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Date >( const Date& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Timestamp >( - const Timestamp& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, Timestamp >(const Timestamp& obj); template <> void IGNITE_IMPORT_EXPORT @@ -1103,9 +1100,8 @@ BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Time >( const Time& obj); template <> -void IGNITE_IMPORT_EXPORT -BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, std::string >( - const std::string& obj); +void IGNITE_IMPORT_EXPORT BinaryWriterImpl::WriteTopObject0< + ignite::odbc::binary::BinaryWriter, std::string >(const std::string& obj); } // namespace binary } // namespace impl } // namespace odbc diff --git a/src/odbc/include/ignite/odbc/impl/bindings.h b/src/odbc/include/ignite/odbc/impl/bindings.h index 05afdc77f..5c964d763 100644 --- a/src/odbc/include/ignite/odbc/impl/bindings.h +++ b/src/odbc/include/ignite/odbc/impl/bindings.h @@ -26,97 +26,96 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace binding - { - /** - * Binding for filter creation. - * - * @tparam F The filter which inherits from CacheEntryEventFilter. - * - * @param reader Reader. - * @param env Environment. - * @return Handle for the filter. - */ - template - int64_t FilterCreate(binary::BinaryReaderImpl& reader, binary::BinaryWriterImpl&, IgniteEnvironment& env) - { - using namespace common::concurrent; - using namespace cache::query::continuous; - - F filter = reader.ReadObject(); - - SharedPointer qry(new RemoteFilterHolder(MakeReferenceFromCopy(filter))); - - return env.GetHandleRegistry().Allocate(qry); - } - - /** - * Process input streaming data to produce output streaming data. - * - * Deserializes cache entry and processor using provided reader, invokes - * cache entry processor, gets result and serializes it using provided - * writer. - * - * @param reader Reader. - * @param writer Writer. - */ - template - int64_t ListenerApply(binary::BinaryReaderImpl& reader, binary::BinaryWriterImpl& writer, IgniteEnvironment&) - { - typedef cache::CacheEntryProcessorHolder ProcessorHolder; - - ProcessorHolder procHolder = reader.ReadObject(); - - K key = reader.ReadObject(); - - V value; - bool exists = reader.TryReadObject(value); - - cache::MutableCacheEntryState::Type entryState; - - R res = procHolder.template Process(key, value, exists, entryState); - - writer.WriteInt8(static_cast(entryState)); - - if (entryState == cache::MutableCacheEntryState::VALUE_SET) - writer.WriteTopObject(value); - - writer.WriteTopObject(res); - - return 0; - } - - /** - * Binding for compute job creation. - * - * @tparam F The job type. - * @tparam R The job return type. - * - * @param reader Reader. - * @param env Environment. - * @return Handle for the job. - */ - template - int64_t ComputeJobCreate(binary::BinaryReaderImpl& reader, binary::BinaryWriterImpl&, IgniteEnvironment& env) - { - using namespace common::concurrent; - using namespace compute; - - F job = reader.ReadObject(); - - SharedPointer jobPtr(new ComputeJobHolderImpl(job)); - - return env.GetHandleRegistry().Allocate(jobPtr); - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace binding { +/** + * Binding for filter creation. + * + * @tparam F The filter which inherits from CacheEntryEventFilter. + * + * @param reader Reader. + * @param env Environment. + * @return Handle for the filter. + */ +template < typename F > +int64_t FilterCreate(binary::BinaryReaderImpl& reader, + binary::BinaryWriterImpl&, IgniteEnvironment& env) { + using namespace common::concurrent; + using namespace cache::query::continuous; + + F filter = reader.ReadObject< F >(); + + SharedPointer< ContinuousQueryImplBase > qry( + new RemoteFilterHolder(MakeReferenceFromCopy(filter))); + + return env.GetHandleRegistry().Allocate(qry); +} + +/** + * Process input streaming data to produce output streaming data. + * + * Deserializes cache entry and processor using provided reader, invokes + * cache entry processor, gets result and serializes it using provided + * writer. + * + * @param reader Reader. + * @param writer Writer. + */ +template < typename P, typename K, typename V, typename R, typename A > +int64_t ListenerApply(binary::BinaryReaderImpl& reader, + binary::BinaryWriterImpl& writer, IgniteEnvironment&) { + typedef cache::CacheEntryProcessorHolder< P, A > ProcessorHolder; + + ProcessorHolder procHolder = reader.ReadObject< ProcessorHolder >(); + + K key = reader.ReadObject< K >(); + + V value; + bool exists = reader.TryReadObject< V >(value); + + cache::MutableCacheEntryState::Type entryState; + + R res = + procHolder.template Process< R, K, V >(key, value, exists, entryState); + + writer.WriteInt8(static_cast< int8_t >(entryState)); + + if (entryState == cache::MutableCacheEntryState::VALUE_SET) + writer.WriteTopObject(value); + + writer.WriteTopObject(res); + + return 0; +} + +/** + * Binding for compute job creation. + * + * @tparam F The job type. + * @tparam R The job return type. + * + * @param reader Reader. + * @param env Environment. + * @return Handle for the job. + */ +template < typename F, typename R > +int64_t ComputeJobCreate(binary::BinaryReaderImpl& reader, + binary::BinaryWriterImpl&, IgniteEnvironment& env) { + using namespace common::concurrent; + using namespace compute; + + F job = reader.ReadObject< F >(); + + SharedPointer< ComputeJobHolder > jobPtr( + new ComputeJobHolderImpl< F, R >(job)); + + return env.GetHandleRegistry().Allocate(jobPtr); } +} // namespace binding +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_BINDINGS +#endif //_IGNITE_ODBC_IMPL_BINDINGS diff --git a/src/odbc/include/ignite/odbc/impl/cache/cache_affinity_impl.h b/src/odbc/include/ignite/odbc/impl/cache/cache_affinity_impl.h index 3658674f6..2f9c1c4ab 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/cache_affinity_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/cache_affinity_impl.h @@ -24,384 +24,402 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - struct Command - { - enum Type - { - AFFINITY_KEY = 1, - - ALL_PARTITIONS = 2, - - BACKUP_PARTITIONS = 3, - - IS_BACKUP = 4, - - IS_PRIMARY = 5, - - IS_PRIMARY_OR_BACKUP = 6, - - MAP_KEY_TO_NODE = 7, - - MAP_KEY_TO_PRIMARY_AND_BACKUPS = 8, - - MAP_KEYS_TO_NODES = 9, - - MAP_PARTITION_TO_NODE = 10, - - MAP_PARTITION_TO_PRIMARY_AND_BACKUPS = 11, - - MAP_PARTITIONS_TO_NODES = 12, - - PARTITION = 13, - - PRIMARY_PARTITIONS = 14, - - PARTITIONS = 15, - }; - }; - - /* Forward declaration. */ - class CacheAffinityImpl; - - /* Shared pointer. */ - typedef common::concurrent::SharedPointer SP_CacheAffinityImpl; - - /** - * Cache affinity implementation. - */ - class IGNITE_FRIEND_EXPORT CacheAffinityImpl : private interop::InteropTarget - { - typedef common::concurrent::SharedPointer SP_IgniteEnvironment; - public: - /** - * Constructor used to create new instance. - * - * @param env Environment. - * @param javaRef Reference to java object. - */ - CacheAffinityImpl(SP_IgniteEnvironment env, jobject javaRef); - - /** - * Get number of partitions in cache according to configured affinity function. - * - * @return Number of partitions. - */ - int32_t GetPartitions(); - - /** - * Get partition id for the given key. - * - * @tparam K Key type. - * - * @param key Key to get partition id for. - * @return Partition id. - */ - template - int32_t GetPartition(const K& key) - { - IgniteError err; - In1Operation inOp(key); - - int32_t ret = static_cast(InStreamOutLong(Command::PARTITION, inOp, err)); - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * Return true if given node is the primary node for given key. - * - * @tparam K Key type. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if given node is primary node for given key. - */ - template - bool IsPrimary(ignite::odbc::cluster::ClusterNode node, const K& key) - { - common::concurrent::SharedPointer memIn = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteObject(node.GetId()); - writer.WriteObject(key); - - out.Synchronize(); - - IgniteError err; - - bool ret = OutOp(Command::IS_PRIMARY, *memIn.Get(), err); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * Return true if local node is one of the backup nodes for given key. - * - * @tparam K Key type. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if local node is one of the backup nodes for given key. - */ - template - bool IsBackup(ignite::odbc::cluster::ClusterNode node, const K &key) - { - common::concurrent::SharedPointer memIn = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteObject(node.GetId()); - writer.WriteObject(key); - - out.Synchronize(); - - IgniteError err; - - bool ret = OutOp(Command::IS_BACKUP, *memIn.Get(), err); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * Returns true if local node is primary or one of the backup nodes. - * This method is essentially equivalent to calling - * "isPrimary(ClusterNode, Object) || isBackup(ClusterNode, Object))", - * however it is more efficient as it makes both checks at once. - * - * @tparam K Key type. - * - * @param node Cluster node. - * @param key Key to check. - * @return True if local node is primary or one of the backup nodes. - */ - template - bool IsPrimaryOrBackup(ignite::odbc::cluster::ClusterNode node, const K& key) - { - common::concurrent::SharedPointer memIn = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteObject(node.GetId()); - writer.WriteObject(key); - - out.Synchronize(); - - IgniteError err; - - bool ret = OutOp(Command::IS_PRIMARY_OR_BACKUP, *memIn.Get(), err); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * Get partition ids for which the given cluster node has primary ownership. - * - * @param node Cluster node. - * @return Container of partition ids for which the given cluster node has primary ownership. - */ - std::vector GetPrimaryPartitions(ignite::odbc::cluster::ClusterNode node); - - /** - * Get partition ids for which given cluster node has backup ownership. - * - * @param node Cluster node. - * @return Container of partition ids for which given cluster node has backup ownership. - */ - std::vector GetBackupPartitions(ignite::odbc::cluster::ClusterNode node); - - /** - * Get partition ids for which given cluster node has any ownership (either primary or backup). - * - * @param node Cluster node. - * @return Container of partition ids for which given cluster node has any ownership (either primary or backup). - */ - std::vector GetAllPartitions(ignite::odbc::cluster::ClusterNode node); - - /** - * Map passed in key to a key which will be used for node affinity. - * - * @tparam TK Key to map type. - * @tparam TR Key to be used for node-to-affinity mapping type. - * - * @param key Key to map. - * @return Key to be used for node-to-affinity mapping (may be the same key as passed in). - */ - template - TR GetAffinityKey(const TK& key) - { - TR ret; - In1Operation inOp(key); - Out1Operation outOp(ret); - - IgniteError err; - InteropTarget::OutInOp(Command::AFFINITY_KEY, inOp, outOp, err); - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - /** - * This method provides ability to detect which keys are mapped to which nodes. - * Use it to determine which nodes are storing which keys prior to sending - * jobs that access these keys. - * - * @tparam TK Key to map type. - * - * @param keys Keys to map to nodes. - * @return Map of nodes to keys or empty map if there are no alive nodes for this cache. - */ - template - std::map > MapKeysToNodes(const std::vector& keys) - { - common::concurrent::SharedPointer memIn = GetEnvironment().AllocateMemory(); - common::concurrent::SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteInt32(static_cast(keys.size())); - for (typename std::vector::const_iterator it = keys.begin(); it != keys.end(); ++it) - writer.WriteObject(*it); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::MAP_KEYS_TO_NODES, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - std::map > ret; - - int32_t cnt = reader.ReadInt32(); - for (int32_t i = 0; i < cnt; i++) - { - std::vector val; - - ignite::odbc::cluster::ClusterNode key(GetEnvironment().GetNode(reader.ReadGuid())); - reader.ReadCollection(std::back_inserter(val)); - - ret.insert(std::pair >(key, val)); - } - - return ret; - } - - /** - * This method provides ability to detect to which primary node the given key is mapped. - * Use it to determine which nodes are storing which keys prior to sending - * jobs that access these keys. - * - * @tparam TK Key to map type. - * - * @param key Key to map to node. - * @return Primary node for the key. - */ - template - ignite::odbc::cluster::ClusterNode MapKeyToNode(const TK& key) - { - Guid nodeId; - In1Operation inOp(key); - Out1Operation outOp(nodeId); - - IgniteError err; - InteropTarget::OutInOp(Command::MAP_KEY_TO_NODE, inOp, outOp, err); - IgniteError::ThrowIfNeeded(err); - - return GetEnvironment().GetNode(nodeId); - } - - /** - * Get primary and backup nodes for the key. - * Note that primary node is always first in the returned collection. - * - * @tparam TK Key to map type. - * - * @param key Key to map to nodes. - * @return Collection of cluster nodes. - */ - template - std::vector MapKeyToPrimaryAndBackups(const TK& key) - { - common::concurrent::SharedPointer memIn = GetEnvironment().AllocateMemory(); - common::concurrent::SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteObject(key); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::MAP_KEY_TO_PRIMARY_AND_BACKUPS, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - std::vector ret; - int32_t cnt = reader.ReadInt32(); - ret.reserve(cnt); - for (int32_t i = 0; i < cnt; i++) - ret.push_back(GetEnvironment().GetNode(reader.ReadGuid())); - - return ret; - } - - /** - * Get primary node for the given partition. - * - * @param part Partition id. - * @return Primary node for the given partition. - */ - ignite::odbc::cluster::ClusterNode MapPartitionToNode(int32_t part); - - /** - * Get primary nodes for the given partitions. - * - * @param parts Partition ids. - * @return Mapping of given partitions to their primary nodes. - */ - std::map MapPartitionsToNodes(const std::vector& parts); - - /** - * Get primary and backup nodes for partition. - * Note that primary node is always first in the returned collection. - * - * @param part Partition to get affinity nodes for. - * @return Collection of primary and backup nodes for partition with primary node always first. - */ - std::vector MapPartitionToPrimaryAndBackups(int32_t part); - - private: - /** - * Get partition ids for which given cluster node has different ownership. - * - * @param opType Operation type. - * @param node Cluster node. - * @return Container of partition ids. - */ - std::vector GetPartitions(int32_t opType, ignite::odbc::cluster::ClusterNode node); - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +struct Command { + enum Type { + AFFINITY_KEY = 1, + + ALL_PARTITIONS = 2, + + BACKUP_PARTITIONS = 3, + + IS_BACKUP = 4, + + IS_PRIMARY = 5, + + IS_PRIMARY_OR_BACKUP = 6, + + MAP_KEY_TO_NODE = 7, + + MAP_KEY_TO_PRIMARY_AND_BACKUPS = 8, + + MAP_KEYS_TO_NODES = 9, + + MAP_PARTITION_TO_NODE = 10, + + MAP_PARTITION_TO_PRIMARY_AND_BACKUPS = 11, + + MAP_PARTITIONS_TO_NODES = 12, + + PARTITION = 13, + + PRIMARY_PARTITIONS = 14, + + PARTITIONS = 15, + }; +}; + +/* Forward declaration. */ +class CacheAffinityImpl; + +/* Shared pointer. */ +typedef common::concurrent::SharedPointer< CacheAffinityImpl > + SP_CacheAffinityImpl; + +/** + * Cache affinity implementation. + */ +class IGNITE_FRIEND_EXPORT CacheAffinityImpl : private interop::InteropTarget { + typedef common::concurrent::SharedPointer< IgniteEnvironment > + SP_IgniteEnvironment; + + public: + /** + * Constructor used to create new instance. + * + * @param env Environment. + * @param javaRef Reference to java object. + */ + CacheAffinityImpl(SP_IgniteEnvironment env, jobject javaRef); + + /** + * Get number of partitions in cache according to configured affinity + * function. + * + * @return Number of partitions. + */ + int32_t GetPartitions(); + + /** + * Get partition id for the given key. + * + * @tparam K Key type. + * + * @param key Key to get partition id for. + * @return Partition id. + */ + template < typename K > + int32_t GetPartition(const K& key) { + IgniteError err; + In1Operation< K > inOp(key); + + int32_t ret = + static_cast< int32_t >(InStreamOutLong(Command::PARTITION, inOp, err)); + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * Return true if given node is the primary node for given key. + * + * @tparam K Key type. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if given node is primary node for given key. + */ + template < typename K > + bool IsPrimary(ignite::odbc::cluster::ClusterNode node, const K& key) { + common::concurrent::SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteObject(node.GetId()); + writer.WriteObject< K >(key); + + out.Synchronize(); + + IgniteError err; + + bool ret = OutOp(Command::IS_PRIMARY, *memIn.Get(), err); + + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * Return true if local node is one of the backup nodes for given key. + * + * @tparam K Key type. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if local node is one of the backup nodes for given key. + */ + template < typename K > + bool IsBackup(ignite::odbc::cluster::ClusterNode node, const K& key) { + common::concurrent::SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteObject(node.GetId()); + writer.WriteObject< K >(key); + + out.Synchronize(); + + IgniteError err; + + bool ret = OutOp(Command::IS_BACKUP, *memIn.Get(), err); + + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * Returns true if local node is primary or one of the backup nodes. + * This method is essentially equivalent to calling + * "isPrimary(ClusterNode, Object) || isBackup(ClusterNode, Object))", + * however it is more efficient as it makes both checks at once. + * + * @tparam K Key type. + * + * @param node Cluster node. + * @param key Key to check. + * @return True if local node is primary or one of the backup nodes. + */ + template < typename K > + bool IsPrimaryOrBackup(ignite::odbc::cluster::ClusterNode node, + const K& key) { + common::concurrent::SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteObject(node.GetId()); + writer.WriteObject< K >(key); + + out.Synchronize(); + + IgniteError err; + + bool ret = OutOp(Command::IS_PRIMARY_OR_BACKUP, *memIn.Get(), err); + + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * Get partition ids for which the given cluster node has primary ownership. + * + * @param node Cluster node. + * @return Container of partition ids for which the given cluster node has + * primary ownership. + */ + std::vector< int32_t > GetPrimaryPartitions( + ignite::odbc::cluster::ClusterNode node); + + /** + * Get partition ids for which given cluster node has backup ownership. + * + * @param node Cluster node. + * @return Container of partition ids for which given cluster node has backup + * ownership. + */ + std::vector< int32_t > GetBackupPartitions( + ignite::odbc::cluster::ClusterNode node); + + /** + * Get partition ids for which given cluster node has any ownership (either + * primary or backup). + * + * @param node Cluster node. + * @return Container of partition ids for which given cluster node has any + * ownership (either primary or backup). + */ + std::vector< int32_t > GetAllPartitions( + ignite::odbc::cluster::ClusterNode node); + + /** + * Map passed in key to a key which will be used for node affinity. + * + * @tparam TK Key to map type. + * @tparam TR Key to be used for node-to-affinity mapping type. + * + * @param key Key to map. + * @return Key to be used for node-to-affinity mapping (may be the same key as + * passed in). + */ + template < typename TK, typename TR > + TR GetAffinityKey(const TK& key) { + TR ret; + In1Operation< TK > inOp(key); + Out1Operation< TR > outOp(ret); + + IgniteError err; + InteropTarget::OutInOp(Command::AFFINITY_KEY, inOp, outOp, err); + IgniteError::ThrowIfNeeded(err); + + return ret; + } + + /** + * This method provides ability to detect which keys are mapped to which + * nodes. Use it to determine which nodes are storing which keys prior to + * sending jobs that access these keys. + * + * @tparam TK Key to map type. + * + * @param keys Keys to map to nodes. + * @return Map of nodes to keys or empty map if there are no alive nodes for + * this cache. + */ + template < typename TK > + std::map< ignite::odbc::cluster::ClusterNode, std::vector< TK > > + MapKeysToNodes(const std::vector< TK >& keys) { + common::concurrent::SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + common::concurrent::SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteInt32(static_cast< int32_t >(keys.size())); + for (typename std::vector< TK >::const_iterator it = keys.begin(); + it != keys.end(); ++it) + writer.WriteObject< TK >(*it); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::MAP_KEYS_TO_NODES, *memIn.Get(), *memOut.Get(), + err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + std::map< ignite::odbc::cluster::ClusterNode, std::vector< TK > > ret; + + int32_t cnt = reader.ReadInt32(); + for (int32_t i = 0; i < cnt; i++) { + std::vector< TK > val; + + ignite::odbc::cluster::ClusterNode key( + GetEnvironment().GetNode(reader.ReadGuid())); + reader.ReadCollection< TK >(std::back_inserter(val)); + + ret.insert( + std::pair< ignite::odbc::cluster::ClusterNode, std::vector< TK > >( + key, val)); } -} -#endif // _IGNITE_ODBC_CACHE_AFFINITY_IMPL + return ret; + } + + /** + * This method provides ability to detect to which primary node the given key + * is mapped. Use it to determine which nodes are storing which keys prior to + * sending jobs that access these keys. + * + * @tparam TK Key to map type. + * + * @param key Key to map to node. + * @return Primary node for the key. + */ + template < typename TK > + ignite::odbc::cluster::ClusterNode MapKeyToNode(const TK& key) { + Guid nodeId; + In1Operation< TK > inOp(key); + Out1Operation< Guid > outOp(nodeId); + + IgniteError err; + InteropTarget::OutInOp(Command::MAP_KEY_TO_NODE, inOp, outOp, err); + IgniteError::ThrowIfNeeded(err); + + return GetEnvironment().GetNode(nodeId); + } + + /** + * Get primary and backup nodes for the key. + * Note that primary node is always first in the returned collection. + * + * @tparam TK Key to map type. + * + * @param key Key to map to nodes. + * @return Collection of cluster nodes. + */ + template < typename TK > + std::vector< ignite::odbc::cluster::ClusterNode > MapKeyToPrimaryAndBackups( + const TK& key) { + common::concurrent::SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + common::concurrent::SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteObject(key); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::MAP_KEY_TO_PRIMARY_AND_BACKUPS, *memIn.Get(), + *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + std::vector< ignite::odbc::cluster::ClusterNode > ret; + int32_t cnt = reader.ReadInt32(); + ret.reserve(cnt); + for (int32_t i = 0; i < cnt; i++) + ret.push_back(GetEnvironment().GetNode(reader.ReadGuid())); + + return ret; + } + + /** + * Get primary node for the given partition. + * + * @param part Partition id. + * @return Primary node for the given partition. + */ + ignite::odbc::cluster::ClusterNode MapPartitionToNode(int32_t part); + + /** + * Get primary nodes for the given partitions. + * + * @param parts Partition ids. + * @return Mapping of given partitions to their primary nodes. + */ + std::map< int32_t, ignite::odbc::cluster::ClusterNode > MapPartitionsToNodes( + const std::vector< int32_t >& parts); + + /** + * Get primary and backup nodes for partition. + * Note that primary node is always first in the returned collection. + * + * @param part Partition to get affinity nodes for. + * @return Collection of primary and backup nodes for partition with primary + * node always first. + */ + std::vector< ignite::odbc::cluster::ClusterNode > + MapPartitionToPrimaryAndBackups(int32_t part); + + private: + /** + * Get partition ids for which given cluster node has different ownership. + * + * @param opType Operation type. + * @param node Cluster node. + * @return Container of partition ids. + */ + std::vector< int32_t > GetPartitions(int32_t opType, + ignite::odbc::cluster::ClusterNode node); +}; +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif // _IGNITE_ODBC_CACHE_AFFINITY_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cache/cache_entry_processor_holder.h b/src/odbc/include/ignite/odbc/impl/cache/cache_entry_processor_holder.h index 55b1c6796..b07273109 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/cache_entry_processor_holder.h +++ b/src/odbc/include/ignite/odbc/impl/cache/cache_entry_processor_holder.h @@ -22,262 +22,242 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - /** - * Mutable Cache entry state. - */ - struct MutableCacheEntryState - { - enum Type - { - /** No changes have been committed to entry. */ - INTACT = 0, - - /** Value of the entry has been changed. */ - VALUE_SET = 1, - - /** Entry has been removed from cache. */ - VALUE_REMOVED = 2, - - /** Error occured. Represented in binary form. */ - ERR_BINARY = 3, - - /** Error occured. Represented in string form. */ - ERR_STRING = 4 - }; - }; - - /** - * Get state of the mutable cache entry. - * - * @param valueBefore Cache entry value before mutation. - * @param existsBefore Flag for entry existence before mutation. - * @param valueBefore Cache entry value after mutation. - * @param existsBefore Flag for entry existence after mutation. - * @return Cache entry state. - */ - template - MutableCacheEntryState::Type GetMutableCacheEntryState(const V& valueBefore, bool existsBefore, - const V& valueAfter, bool existsAfter) - { - if ((!existsBefore && existsAfter) || - (existsBefore && existsAfter && !(valueBefore == valueAfter))) - return MutableCacheEntryState::VALUE_SET; - - if (existsBefore && !existsAfter) - return MutableCacheEntryState::VALUE_REMOVED; - - return MutableCacheEntryState::INTACT; - } - - /** - * Holder for the Cache Entry Processor and its argument. Used as a convenient way to - * transmit Cache Entry Processor between nodes. - */ - template - class CacheEntryProcessorHolder - { - public: - typedef P ProcessorType; - typedef A ArgumentType; - - /** - * Default constructor. - */ - CacheEntryProcessorHolder() : - proc(), - arg() - { - // No-op. - } - - /** - * Constructor. - * - * @param proc Processor. - * @param arg Argument. - */ - CacheEntryProcessorHolder(const P& proc, const A& arg) : - proc(proc), - arg(arg) - { - // No-op. - } - - /** - * Destructor. - */ - ~CacheEntryProcessorHolder() - { - // No-op. - } - - /** - * Get processor. - * - * @return Processor. - */ - const ProcessorType& getProcessor() const - { - return proc; - } - - /** - * Get argument. - * - * @return Argument. - */ - const ArgumentType& getArgument() const - { - return arg; - } - - /** - * Process key-value pair by the underlying Cache Entry Processor - * using binded argument. - * - * Equality operator should be defined for the value type. - * - * @param key Cache entry key. - * @param value Cache entry value. New value is stored here upon completion. - * @param exists Entry existance indicator. - * @param state State of the entry after the processing. - * @return Result of the processing. - */ - template - R Process(const K& key, V& value, bool exists, MutableCacheEntryState::Type &state) - { - typedef ignite::odbc::cache::MutableCacheEntry Entry; - - Entry entry; - - if (exists) - entry = Entry(key, value); - else - entry = Entry(key); - - R res = proc.Process(entry, arg); - - state = GetMutableCacheEntryState(value, exists, entry.GetValue(), entry.IsExists()); - - value = entry.GetValue(); - - return res; - } - - private: - /** Stored processor. */ - ProcessorType proc; - - /** Stored argument. */ - ArgumentType arg; - }; - } - } - - namespace binary - { - /** - * Binary type specialization for CacheEntryProcessorHolder. - */ - template - struct BinaryType > : - BinaryTypeNonNullableType< impl::cache::CacheEntryProcessorHolder > - { - typedef impl::cache::CacheEntryProcessorHolder UnderlyingType; - - IGNITE_BINARY_GET_FIELD_ID_AS_HASH - - static int32_t GetTypeId() - { - static bool typeIdInited = false; - static int32_t typeId; - static common::concurrent::CriticalSection initLock; - - if (typeIdInited) - return typeId; - - common::concurrent::CsLockGuard guard(initLock); - - if (typeIdInited) - return typeId; - - std::string typeName; - GetTypeName(typeName); - - typeId = GetBinaryStringHashCode(typeName.c_str()); - typeIdInited = true; - - return typeId; - } - - static void GetTypeName(std::string& dst) - { - // Using static variable and only initialize it once for better - // performance. Type name can't change in the course of the - // program flow. - static std::string name; - static common::concurrent::CriticalSection initLock; - - // Name has been constructed already. Return it. - if (!name.empty()) - { - dst = name; - - return; - } - - common::concurrent::CsLockGuard guard(initLock); - - if (!name.empty()) - { - dst = name; - - return; - } - - // Constructing name here. - std::string procName; - - BinaryType

::GetTypeName(procName); - - // -1 is for unnessecary null byte at the end of the C-string. - name.reserve(sizeof("CacheEntryProcessorHolder<>") - 1 + procName.size()); - - // Processor name is enough for identification as it is - // forbidden to register the same processor type several times. - name.append("CacheEntryProcessorHolder<").append(procName).push_back('>'); - - dst = name; - } - - static void Write(BinaryWriter& writer, const UnderlyingType& obj) - { - BinaryRawWriter raw = writer.RawWriter(); - - raw.WriteObject(obj.getProcessor()); - raw.WriteObject(obj.getArgument()); - } - - static void Read(BinaryReader& reader, UnderlyingType& dst) - { - BinaryRawReader raw = reader.RawReader(); - - const P& proc = raw.ReadObject

(); - const A& arg = raw.ReadObject(); - - dst = UnderlyingType(proc, arg); - } - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +/** + * Mutable Cache entry state. + */ +struct MutableCacheEntryState { + enum Type { + /** No changes have been committed to entry. */ + INTACT = 0, + + /** Value of the entry has been changed. */ + VALUE_SET = 1, + + /** Entry has been removed from cache. */ + VALUE_REMOVED = 2, + + /** Error occured. Represented in binary form. */ + ERR_BINARY = 3, + + /** Error occured. Represented in string form. */ + ERR_STRING = 4 + }; +}; + +/** + * Get state of the mutable cache entry. + * + * @param valueBefore Cache entry value before mutation. + * @param existsBefore Flag for entry existence before mutation. + * @param valueBefore Cache entry value after mutation. + * @param existsBefore Flag for entry existence after mutation. + * @return Cache entry state. + */ +template < typename V > +MutableCacheEntryState::Type GetMutableCacheEntryState(const V& valueBefore, + bool existsBefore, + const V& valueAfter, + bool existsAfter) { + if ((!existsBefore && existsAfter) + || (existsBefore && existsAfter && !(valueBefore == valueAfter))) + return MutableCacheEntryState::VALUE_SET; + + if (existsBefore && !existsAfter) + return MutableCacheEntryState::VALUE_REMOVED; + + return MutableCacheEntryState::INTACT; } -#endif //_IGNITE_ODBC_IMPL_CACHE_CACHE_ENTRY_PROCESSOR_HOLDER +/** + * Holder for the Cache Entry Processor and its argument. Used as a convenient + * way to transmit Cache Entry Processor between nodes. + */ +template < typename P, typename A > +class CacheEntryProcessorHolder { + public: + typedef P ProcessorType; + typedef A ArgumentType; + + /** + * Default constructor. + */ + CacheEntryProcessorHolder() : proc(), arg() { + // No-op. + } + + /** + * Constructor. + * + * @param proc Processor. + * @param arg Argument. + */ + CacheEntryProcessorHolder(const P& proc, const A& arg) + : proc(proc), arg(arg) { + // No-op. + } + + /** + * Destructor. + */ + ~CacheEntryProcessorHolder() { + // No-op. + } + + /** + * Get processor. + * + * @return Processor. + */ + const ProcessorType& getProcessor() const { + return proc; + } + + /** + * Get argument. + * + * @return Argument. + */ + const ArgumentType& getArgument() const { + return arg; + } + + /** + * Process key-value pair by the underlying Cache Entry Processor + * using binded argument. + * + * Equality operator should be defined for the value type. + * + * @param key Cache entry key. + * @param value Cache entry value. New value is stored here upon completion. + * @param exists Entry existance indicator. + * @param state State of the entry after the processing. + * @return Result of the processing. + */ + template < typename R, typename K, typename V > + R Process(const K& key, V& value, bool exists, + MutableCacheEntryState::Type& state) { + typedef ignite::odbc::cache::MutableCacheEntry< K, V > Entry; + + Entry entry; + + if (exists) + entry = Entry(key, value); + else + entry = Entry(key); + + R res = proc.Process(entry, arg); + + state = GetMutableCacheEntryState(value, exists, entry.GetValue(), + entry.IsExists()); + + value = entry.GetValue(); + + return res; + } + + private: + /** Stored processor. */ + ProcessorType proc; + + /** Stored argument. */ + ArgumentType arg; +}; +} // namespace cache +} // namespace impl + +namespace binary { +/** + * Binary type specialization for CacheEntryProcessorHolder. + */ +template < typename P, typename A > +struct BinaryType< impl::cache::CacheEntryProcessorHolder< P, A > > + : BinaryTypeNonNullableType< + impl::cache::CacheEntryProcessorHolder< P, A > > { + typedef impl::cache::CacheEntryProcessorHolder< P, A > UnderlyingType; + + IGNITE_BINARY_GET_FIELD_ID_AS_HASH + + static int32_t GetTypeId() { + static bool typeIdInited = false; + static int32_t typeId; + static common::concurrent::CriticalSection initLock; + + if (typeIdInited) + return typeId; + + common::concurrent::CsLockGuard guard(initLock); + + if (typeIdInited) + return typeId; + + std::string typeName; + GetTypeName(typeName); + + typeId = GetBinaryStringHashCode(typeName.c_str()); + typeIdInited = true; + + return typeId; + } + + static void GetTypeName(std::string& dst) { + // Using static variable and only initialize it once for better + // performance. Type name can't change in the course of the + // program flow. + static std::string name; + static common::concurrent::CriticalSection initLock; + + // Name has been constructed already. Return it. + if (!name.empty()) { + dst = name; + + return; + } + + common::concurrent::CsLockGuard guard(initLock); + + if (!name.empty()) { + dst = name; + + return; + } + + // Constructing name here. + std::string procName; + + BinaryType< P >::GetTypeName(procName); + + // -1 is for unnessecary null byte at the end of the C-string. + name.reserve(sizeof("CacheEntryProcessorHolder<>") - 1 + procName.size()); + + // Processor name is enough for identification as it is + // forbidden to register the same processor type several times. + name.append("CacheEntryProcessorHolder<").append(procName).push_back('>'); + + dst = name; + } + + static void Write(BinaryWriter& writer, const UnderlyingType& obj) { + BinaryRawWriter raw = writer.RawWriter(); + + raw.WriteObject(obj.getProcessor()); + raw.WriteObject(obj.getArgument()); + } + + static void Read(BinaryReader& reader, UnderlyingType& dst) { + BinaryRawReader raw = reader.RawReader(); + + const P& proc = raw.ReadObject< P >(); + const A& arg = raw.ReadObject< A >(); + + dst = UnderlyingType(proc, arg); + } +}; +} // namespace binary +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CACHE_CACHE_ENTRY_PROCESSOR_HOLDER diff --git a/src/odbc/include/ignite/odbc/impl/cache/cache_impl.h b/src/odbc/include/ignite/odbc/impl/cache/cache_impl.h index 841bf4ca4..4f80399ea 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/cache_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/cache_impl.h @@ -27,415 +27,434 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - namespace continuous - { - /* Forward declaration. */ - class ContinuousQueryHandleImpl; - } - } - - /** - * Cache implementation. - */ - class IGNITE_IMPORT_EXPORT CacheImpl : private interop::InteropTarget - { - public: - /** - * Constructor used to create new instance. - * - * @param name Name. - * @param env Environment. - * @param javaRef Reference to java object. - */ - CacheImpl(char* name, ignite::odbc::common::concurrent::SharedPointer env, jobject javaRef); - - /** - * Destructor. - */ - ~CacheImpl(); - - /** - * Get name. - * - * @return Cache name. - */ - const char* GetName() const; - - /** - * Perform ContainsKey. - * - * @param inOp Input. - * @param err Error. - * @return Result. - */ - bool ContainsKey(InputOperation& inOp, IgniteError& err); - - /** - * Perform ContainsKeys. - * - * @param inOp Input. - * @param err Error. - * @return Result. - */ - bool ContainsKeys(InputOperation& inOp, IgniteError& err); - - /** - * Perform LocalPeek. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void LocalPeek(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform Get. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void Get(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform GetAll. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform Put. - * - * @param inOp Input. - * @param err Error. - */ - void Put(InputOperation& inOp, IgniteError& err); - - /** - * Perform PutAll. - * - * @param inOp Input. - * @param err Error. - */ - void PutAll(InputOperation& inOp, IgniteError& err); - - /** - * Perform GetAndPut. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform GetAndReplace. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform GetAndRemove. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform PutIfAbsent. - * - * @param inOp Input. - * @param err Error. - * @return Result - */ - bool PutIfAbsent(InputOperation& inOp, IgniteError& err); - - /** - * Perform GetAndPutIfAbsent. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform Replace(K, V). - * - * @param inOp Input. - * @param err Error. - * @return Result - */ - bool Replace(InputOperation& inOp, IgniteError& err); - - /** - * Perform Replace(K, V, V). - * - * @param inOp Input. - * @param err Error. - * @return Result - */ - bool ReplaceIfEqual(InputOperation& inOp, IgniteError& err); - - /** - * Perform LocalEvict. - * - * @param inOp Input. - * @param err Error. - */ - void LocalEvict(InputOperation& inOp, IgniteError& err); - - /** - * Perform Clear. - * - * @param err Error. - */ - void Clear(IgniteError& err); - - /** - * Perform Clear. - * - * @param inOp Input. - * @param err Error. - */ - void Clear(InputOperation& inOp, IgniteError& err); - - /** - * Perform ClearAll. - * - * @param inOp Input. - * @param err Error. - */ - void ClearAll(InputOperation& inOp, IgniteError& err); - - /** - * Perform LocalClear. - * - * @param inOp Input. - * @param err Error. - */ - void LocalClear(InputOperation& inOp, IgniteError& err); - - /** - * Perform LocalClearAll. - * - * @param inOp Input. - * @param err Error. - */ - void LocalClearAll(InputOperation& inOp, IgniteError& err); - - /** - * Perform Remove(K). - * - * @param inOp Input. - * @param err Error. - * @return Result - */ - bool Remove(InputOperation& inOp, IgniteError& err); - - /** - * Perform Remove(K, V). - * - * @param inOp Input. - * @param err Error. - * @return Result - */ - bool RemoveIfEqual(InputOperation& inOp, IgniteError& err); - - /** - * Perform RemoveAll. - * - * @param inOp Input. - * @param err Error. - */ - void RemoveAll(InputOperation& inOp, IgniteError& err); - - /** - * Perform RemoveAll. - * - * @param err Error. - */ - void RemoveAll(IgniteError& err); - - /** - * Perform Size. - * - * @param peekModes Peek modes. - * @param local Local flag. - * @param err Error. - */ - int32_t Size(int32_t peekModes, bool local, IgniteError& err); - - /** - * Invoke query. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursorImpl* QuerySql(const ignite::odbc::cache::query::SqlQuery& qry, IgniteError& err); - - /** - * Invoke text query. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursorImpl* QueryText(const ignite::odbc::cache::query::TextQuery& qry, IgniteError& err); - - /** - * Invoke scan query. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursorImpl* QueryScan(const ignite::odbc::cache::query::ScanQuery& qry, IgniteError& err); - - /** - * Invoke sql fields query. - * - * @param qry Query. - * @param err Error. - * @return Query cursor. - */ - query::QueryCursorImpl* QuerySqlFields(const ignite::odbc::cache::query::SqlFieldsQuery& qry, IgniteError& err); - - /** - * Perform Invoke. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void Invoke(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Perform Invoke of Java entry processor. - * - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void InvokeJava(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Start continuous query execution. - * - * @param qry Continuous query. - * @param err Error. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandleImpl* QueryContinuous( - const common::concurrent::SharedPointer qry, - IgniteError& err); - - /** - * Start continuous query execution with initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query. - * @param err Error. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandleImpl* QueryContinuous( - const common::concurrent::SharedPointer qry, - const ignite::odbc::cache::query::SqlQuery& initialQry, IgniteError& err); - - /** - * Start continuous query execution with initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query. - * @param err Error. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandleImpl* QueryContinuous( - const common::concurrent::SharedPointer qry, - const ignite::odbc::cache::query::TextQuery& initialQry, IgniteError& err); - - /** - * Start continuous query execution with initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query. - * @param err Error. - * @return Continuous query handle. - */ - query::continuous::ContinuousQueryHandleImpl* QueryContinuous( - const common::concurrent::SharedPointer qry, - const ignite::odbc::cache::query::ScanQuery& initialQry, IgniteError& err); - - /** - * Executes LocalLoadCache on all cache nodes. - * - * @param err Error. - */ - void LoadCache(IgniteError& err); - - /** - * Loads state from the underlying persistent storage. - * - * This method is not transactional and may end up loading a stale value into - * cache if another thread has updated the value immediately after it has been - * loaded. It is mostly useful when pre-loading the cache from underlying - * data store before start, or for read-only caches. - * - * @param err Error. - */ - void LocalLoadCache(IgniteError& err); - - private: - IGNITE_NO_COPY_ASSIGNMENT(CacheImpl); - - /** Name. */ - char* name; - - /** - * Internal query execution routine. - * - * @param qry Query. - * @param typ Query type. - * @param err Error. - */ - template - query::QueryCursorImpl* QueryInternal(const T& qry, int32_t typ, IgniteError& err); - - /** - * Start continuous query execution with the initial query. - * - * @param qry Continuous query. - * @param initialQry Initial query to be executed. - * @param err Error. - * @return Continuous query handle. - */ - template - query::continuous::ContinuousQueryHandleImpl* QueryContinuous( - const common::concurrent::SharedPointer qry, - const T& initialQry, int32_t typ, int32_t cmd, IgniteError& err); - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +namespace continuous { +/* Forward declaration. */ +class ContinuousQueryHandleImpl; +} // namespace continuous +} // namespace query + +/** + * Cache implementation. + */ +class IGNITE_IMPORT_EXPORT CacheImpl : private interop::InteropTarget { + public: + /** + * Constructor used to create new instance. + * + * @param name Name. + * @param env Environment. + * @param javaRef Reference to java object. + */ + CacheImpl( + char* name, + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > env, + jobject javaRef); + + /** + * Destructor. + */ + ~CacheImpl(); + + /** + * Get name. + * + * @return Cache name. + */ + const char* GetName() const; + + /** + * Perform ContainsKey. + * + * @param inOp Input. + * @param err Error. + * @return Result. + */ + bool ContainsKey(InputOperation& inOp, IgniteError& err); + + /** + * Perform ContainsKeys. + * + * @param inOp Input. + * @param err Error. + * @return Result. + */ + bool ContainsKeys(InputOperation& inOp, IgniteError& err); + + /** + * Perform LocalPeek. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void LocalPeek(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Perform Get. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void Get(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); + + /** + * Perform GetAll. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); + + /** + * Perform Put. + * + * @param inOp Input. + * @param err Error. + */ + void Put(InputOperation& inOp, IgniteError& err); + + /** + * Perform PutAll. + * + * @param inOp Input. + * @param err Error. + */ + void PutAll(InputOperation& inOp, IgniteError& err); + + /** + * Perform GetAndPut. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void GetAndPut(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Perform GetAndReplace. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void GetAndReplace(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Perform GetAndRemove. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void GetAndRemove(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Perform PutIfAbsent. + * + * @param inOp Input. + * @param err Error. + * @return Result + */ + bool PutIfAbsent(InputOperation& inOp, IgniteError& err); + + /** + * Perform GetAndPutIfAbsent. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Perform Replace(K, V). + * + * @param inOp Input. + * @param err Error. + * @return Result + */ + bool Replace(InputOperation& inOp, IgniteError& err); + + /** + * Perform Replace(K, V, V). + * + * @param inOp Input. + * @param err Error. + * @return Result + */ + bool ReplaceIfEqual(InputOperation& inOp, IgniteError& err); + + /** + * Perform LocalEvict. + * + * @param inOp Input. + * @param err Error. + */ + void LocalEvict(InputOperation& inOp, IgniteError& err); + + /** + * Perform Clear. + * + * @param err Error. + */ + void Clear(IgniteError& err); + + /** + * Perform Clear. + * + * @param inOp Input. + * @param err Error. + */ + void Clear(InputOperation& inOp, IgniteError& err); + + /** + * Perform ClearAll. + * + * @param inOp Input. + * @param err Error. + */ + void ClearAll(InputOperation& inOp, IgniteError& err); + + /** + * Perform LocalClear. + * + * @param inOp Input. + * @param err Error. + */ + void LocalClear(InputOperation& inOp, IgniteError& err); + + /** + * Perform LocalClearAll. + * + * @param inOp Input. + * @param err Error. + */ + void LocalClearAll(InputOperation& inOp, IgniteError& err); + + /** + * Perform Remove(K). + * + * @param inOp Input. + * @param err Error. + * @return Result + */ + bool Remove(InputOperation& inOp, IgniteError& err); + + /** + * Perform Remove(K, V). + * + * @param inOp Input. + * @param err Error. + * @return Result + */ + bool RemoveIfEqual(InputOperation& inOp, IgniteError& err); + + /** + * Perform RemoveAll. + * + * @param inOp Input. + * @param err Error. + */ + void RemoveAll(InputOperation& inOp, IgniteError& err); + + /** + * Perform RemoveAll. + * + * @param err Error. + */ + void RemoveAll(IgniteError& err); + + /** + * Perform Size. + * + * @param peekModes Peek modes. + * @param local Local flag. + * @param err Error. + */ + int32_t Size(int32_t peekModes, bool local, IgniteError& err); + + /** + * Invoke query. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursorImpl* QuerySql( + const ignite::odbc::cache::query::SqlQuery& qry, IgniteError& err); + + /** + * Invoke text query. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursorImpl* QueryText( + const ignite::odbc::cache::query::TextQuery& qry, IgniteError& err); + + /** + * Invoke scan query. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursorImpl* QueryScan( + const ignite::odbc::cache::query::ScanQuery& qry, IgniteError& err); + + /** + * Invoke sql fields query. + * + * @param qry Query. + * @param err Error. + * @return Query cursor. + */ + query::QueryCursorImpl* QuerySqlFields( + const ignite::odbc::cache::query::SqlFieldsQuery& qry, IgniteError& err); + + /** + * Perform Invoke. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void Invoke(InputOperation& inOp, OutputOperation& outOp, IgniteError& err); + + /** + * Perform Invoke of Java entry processor. + * + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void InvokeJava(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Start continuous query execution. + * + * @param qry Continuous query. + * @param err Error. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandleImpl* QueryContinuous( + const common::concurrent::SharedPointer< + query::continuous::ContinuousQueryImplBase > + qry, + IgniteError& err); + + /** + * Start continuous query execution with initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query. + * @param err Error. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandleImpl* QueryContinuous( + const common::concurrent::SharedPointer< + query::continuous::ContinuousQueryImplBase > + qry, + const ignite::odbc::cache::query::SqlQuery& initialQry, IgniteError& err); + + /** + * Start continuous query execution with initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query. + * @param err Error. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandleImpl* QueryContinuous( + const common::concurrent::SharedPointer< + query::continuous::ContinuousQueryImplBase > + qry, + const ignite::odbc::cache::query::TextQuery& initialQry, + IgniteError& err); + + /** + * Start continuous query execution with initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query. + * @param err Error. + * @return Continuous query handle. + */ + query::continuous::ContinuousQueryHandleImpl* QueryContinuous( + const common::concurrent::SharedPointer< + query::continuous::ContinuousQueryImplBase > + qry, + const ignite::odbc::cache::query::ScanQuery& initialQry, + IgniteError& err); + + /** + * Executes LocalLoadCache on all cache nodes. + * + * @param err Error. + */ + void LoadCache(IgniteError& err); + + /** + * Loads state from the underlying persistent storage. + * + * This method is not transactional and may end up loading a stale value into + * cache if another thread has updated the value immediately after it has been + * loaded. It is mostly useful when pre-loading the cache from underlying + * data store before start, or for read-only caches. + * + * @param err Error. + */ + void LocalLoadCache(IgniteError& err); + + private: + IGNITE_NO_COPY_ASSIGNMENT(CacheImpl); + + /** Name. */ + char* name; + + /** + * Internal query execution routine. + * + * @param qry Query. + * @param typ Query type. + * @param err Error. + */ + template < typename T > + query::QueryCursorImpl* QueryInternal(const T& qry, int32_t typ, + IgniteError& err); + + /** + * Start continuous query execution with the initial query. + * + * @param qry Continuous query. + * @param initialQry Initial query to be executed. + * @param err Error. + * @return Continuous query handle. + */ + template < typename T > + query::continuous::ContinuousQueryHandleImpl* QueryContinuous( + const common::concurrent::SharedPointer< + query::continuous::ContinuousQueryImplBase > + qry, + const T& initialQry, int32_t typ, int32_t cmd, IgniteError& err); +}; +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite #endif diff --git a/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_base.h b/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_base.h index bb911ca60..318df02b5 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_base.h +++ b/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_base.h @@ -20,50 +20,43 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace event - { - /** - * Base for the Cache Entry Event Filter. - */ - class CacheEntryEventFilterBase - { - public: - /** - * Default constructor. - */ - CacheEntryEventFilterBase() - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEventFilterBase() - { - // No-op. - } - - /** - * Process serialized events. - * - * @param reader Reader for a serialized event. - * @return Filter evaluation result. - */ - virtual bool ReadAndProcessEvent(ignite::odbc::binary::BinaryRawReader& reader) = 0; - }; - } - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace event { +/** + * Base for the Cache Entry Event Filter. + */ +class CacheEntryEventFilterBase { + public: + /** + * Default constructor. + */ + CacheEntryEventFilterBase() { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEventFilterBase() { + // No-op. + } + + /** + * Process serialized events. + * + * @param reader Reader for a serialized event. + * @return Filter evaluation result. + */ + virtual bool ReadAndProcessEvent( + ignite::odbc::binary::BinaryRawReader& reader) = 0; +}; +} // namespace event +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER_BASE +#endif //_IGNITE_ODBC_IMPL_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER_BASE diff --git a/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_holder.h b/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_holder.h index 11d0b40ac..75d803308 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_holder.h +++ b/src/odbc/include/ignite/odbc/impl/cache/event/cache_entry_event_filter_holder.h @@ -20,169 +20,147 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace event - { - /* Forward declaration. */ - class CacheEntryEventFilterBase; - - class CacheEntryEventFilterHolderBase - { - public: - /** - * Destructor. - */ - virtual ~CacheEntryEventFilterHolderBase() - { - // No-op. - } - - /** - * Write. - * - * @param writer Writer. - */ - virtual void Write(binary::BinaryWriterImpl& writer) = 0; - - /** - * Get filter pointer. - * - * @return Filter. - */ - virtual CacheEntryEventFilterBase* GetFilter() = 0; - }; - - /** - * Holder for the Cache Entry Event Filter. - */ - template - class CacheEntryEventFilterHolder : public CacheEntryEventFilterHolderBase - { - public: - typedef F FilterType; - - /** - * Default constructor. - */ - CacheEntryEventFilterHolder() : - filter() - { - // No-op. - } - - /** - * Constructor. - * - * @param filter Filter. - */ - CacheEntryEventFilterHolder(const Reference& filter) : - filter(filter) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEventFilterHolder() - { - // No-op. - } - - /** - * Process input. - * - * @param writer Writer. - */ - virtual void Write(binary::BinaryWriterImpl& writer) - { - if (!filter.IsNull()) - { - writer.WriteBool(true); - writer.WriteObject(*filter.Get()); - } - else - { - writer.WriteBool(false); - writer.WriteNull(); - } - } - - /** - * Get filter pointer. - * - * @return Filter. - */ - virtual CacheEntryEventFilterBase* GetFilter() - { - return filter.Get(); - } - - private: - /** Stored filter. */ - Reference filter; - }; - - template<> - class CacheEntryEventFilterHolder : public CacheEntryEventFilterHolderBase - { - public: - /** - * Default constructor. - */ - CacheEntryEventFilterHolder() - { - // No-op. - } - - /** - * Constructor. - */ - CacheEntryEventFilterHolder(const Reference&) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~CacheEntryEventFilterHolder() - { - // No-op. - } - - /** - * Process input. - * - * @param writer Writer. - */ - virtual void Write(binary::BinaryWriterImpl& writer) - { - writer.WriteBool(false); - writer.WriteNull(); - } - - /** - * Get filter pointer. - * - * @return Filter. - */ - virtual CacheEntryEventFilterBase* GetFilter() - { - return 0; - } - }; - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace event { +/* Forward declaration. */ +class CacheEntryEventFilterBase; + +class CacheEntryEventFilterHolderBase { + public: + /** + * Destructor. + */ + virtual ~CacheEntryEventFilterHolderBase() { + // No-op. + } + + /** + * Write. + * + * @param writer Writer. + */ + virtual void Write(binary::BinaryWriterImpl& writer) = 0; + + /** + * Get filter pointer. + * + * @return Filter. + */ + virtual CacheEntryEventFilterBase* GetFilter() = 0; +}; + +/** + * Holder for the Cache Entry Event Filter. + */ +template < typename F > +class CacheEntryEventFilterHolder : public CacheEntryEventFilterHolderBase { + public: + typedef F FilterType; + + /** + * Default constructor. + */ + CacheEntryEventFilterHolder() : filter() { + // No-op. + } + + /** + * Constructor. + * + * @param filter Filter. + */ + CacheEntryEventFilterHolder(const Reference< FilterType >& filter) + : filter(filter) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEventFilterHolder() { + // No-op. + } + + /** + * Process input. + * + * @param writer Writer. + */ + virtual void Write(binary::BinaryWriterImpl& writer) { + if (!filter.IsNull()) { + writer.WriteBool(true); + writer.WriteObject< FilterType >(*filter.Get()); + } else { + writer.WriteBool(false); + writer.WriteNull(); } -} + } + + /** + * Get filter pointer. + * + * @return Filter. + */ + virtual CacheEntryEventFilterBase* GetFilter() { + return filter.Get(); + } + + private: + /** Stored filter. */ + Reference< FilterType > filter; +}; + +template <> +class CacheEntryEventFilterHolder< void > + : public CacheEntryEventFilterHolderBase { + public: + /** + * Default constructor. + */ + CacheEntryEventFilterHolder() { + // No-op. + } + + /** + * Constructor. + */ + CacheEntryEventFilterHolder(const Reference< void >&) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~CacheEntryEventFilterHolder() { + // No-op. + } + + /** + * Process input. + * + * @param writer Writer. + */ + virtual void Write(binary::BinaryWriterImpl& writer) { + writer.WriteBool(false); + writer.WriteNull(); + } + + /** + * Get filter pointer. + * + * @return Filter. + */ + virtual CacheEntryEventFilterBase* GetFilter() { + return 0; + } +}; +} // namespace event +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER_HOLDER +#endif //_IGNITE_ODBC_IMPL_CACHE_EVENT_CACHE_ENTRY_EVENT_FILTER_HOLDER diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_handle_impl.h b/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_handle_impl.h index 4e09ae5a3..1039e990d 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_handle_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_handle_impl.h @@ -17,7 +17,9 @@ /** * @file - * Declares ignite::odbc::impl::cache::query::continuous::ContinuousQueryHandleImpl class. + * Declares + * ignite::odbc::impl::cache::query::continuous::ContinuousQueryHandleImpl + * class. */ #ifndef _IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_HANDLE_IMPL @@ -26,69 +28,66 @@ #include "ignite/odbc/cache/query/query_cursor.h" #include "ignite/odbc/impl/cache/query/continuous/continuous_query_impl.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - namespace continuous - { - /** - * Continuous query handle implementation. - */ - class IGNITE_IMPORT_EXPORT ContinuousQueryHandleImpl - { - typedef common::concurrent::SharedPointer SP_IgniteEnvironment; - typedef common::concurrent::SharedPointer SP_ContinuousQueryImplBase; - public: - /** - * Default constructor. - * - * @param env Environment. - * @param javaRef Java reference. - */ - ContinuousQueryHandleImpl(SP_IgniteEnvironment env, int64_t handle, jobject javaRef); - - /** - * Destructor. - */ - ~ContinuousQueryHandleImpl(); - - /** - * Gets the cursor for initial query. - * Can be called only once, throws exception on consequent calls. - * - * @param err Error. - * @return Initial query cursor. - */ - QueryCursorImpl* GetInitialQueryCursor(IgniteError& err); - - private: - /** Environment. */ - SP_IgniteEnvironment env; - - /** Local handle for handle registry. */ - int64_t handle; - - /** Handle to Java object. */ - jobject javaRef; - - /** Mutex. */ - common::concurrent::CriticalSection mutex; - - /** Cursor extracted. */ - bool extracted; - }; - } - } - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +namespace continuous { +/** + * Continuous query handle implementation. + */ +class IGNITE_IMPORT_EXPORT ContinuousQueryHandleImpl { + typedef common::concurrent::SharedPointer< IgniteEnvironment > + SP_IgniteEnvironment; + typedef common::concurrent::SharedPointer< ContinuousQueryImplBase > + SP_ContinuousQueryImplBase; + + public: + /** + * Default constructor. + * + * @param env Environment. + * @param javaRef Java reference. + */ + ContinuousQueryHandleImpl(SP_IgniteEnvironment env, int64_t handle, + jobject javaRef); + + /** + * Destructor. + */ + ~ContinuousQueryHandleImpl(); + + /** + * Gets the cursor for initial query. + * Can be called only once, throws exception on consequent calls. + * + * @param err Error. + * @return Initial query cursor. + */ + QueryCursorImpl* GetInitialQueryCursor(IgniteError& err); + + private: + /** Environment. */ + SP_IgniteEnvironment env; + + /** Local handle for handle registry. */ + int64_t handle; + + /** Handle to Java object. */ + jobject javaRef; + + /** Mutex. */ + common::concurrent::CriticalSection mutex; + + /** Cursor extracted. */ + bool extracted; +}; +} // namespace continuous +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_HANDLE_IMPL +#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_HANDLE_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_impl.h b/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_impl.h index b9329f55e..6142919cf 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/continuous/continuous_query_impl.h @@ -17,7 +17,8 @@ /** * @file - * Declares ignite::odbc::impl::cache::query::continuous::ContinuousQueryImpl class. + * Declares ignite::odbc::impl::cache::query::continuous::ContinuousQueryImpl + * class. */ #ifndef _IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_IMPL @@ -32,367 +33,353 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - namespace continuous - { - /** - * Continuous query base implementation class. - * - * Continuous queries allow to register a remote and a listener - * for cache update events. On any update to the related cache - * an event is sent to the node that has executed the query and - * listener is notified on that node. - * - * Continuous query can either be executed on the whole topology - * or only on local node. - * - * To execute the query over the cache use method - * ignite::odbc::cache::Cache::QueryContinuous(). - */ - class ContinuousQueryImplBase - { - public: - /** - * Destructor. - */ - virtual ~ContinuousQueryImplBase() - { - // No-op. - } - - /** - * Default value for the buffer size. - */ - enum { DEFAULT_BUFFER_SIZE = 1 }; - - /** - * Default value for the time interval. - */ - enum { DEFAULT_TIME_INTERVAL = 0 }; - - /** - * Constructor. - * - * @param loc Whether query should be executed locally. - */ - explicit ContinuousQueryImplBase(bool loc, event::CacheEntryEventFilterHolderBase* filterOp) : - local(loc), - bufferSize(DEFAULT_BUFFER_SIZE), - timeInterval(DEFAULT_TIME_INTERVAL), - filterOp(filterOp) - { - // No-op. - } - - /** - * Set local flag. - * - * @param val Value of the flag. If true, query will be - * executed only on local node, so only local entries - * will be returned as query result. - */ - void SetLocal(bool val) - { - local = val; - } - - /** - * Get local flag. - * - * @return Value of the flag. If true, query will be - * executed only on local node, so only local entries - * will be returned as query result. - */ - bool GetLocal() const - { - return local; - } - - /** - * Set buffer size. - * - * When a cache update happens, entry is first - * put into a buffer. Entries from buffer will be sent to - * the master node only if the buffer is full or time - * provided via timeInterval is exceeded. - * - * @param val Buffer size. - */ - void SetBufferSize(int32_t val) - { - bufferSize = val; - } - - /** - * Get buffer size. - * - * When a cache update happens, entry is first - * put into a buffer. Entries from buffer will be sent to - * the master node only if the buffer is full or time - * provided via timeInterval is exceeded. - * - * @return Buffer size. - */ - int32_t GetBufferSize() const - { - return bufferSize; - } - - /** - * Set time interval. - * - * When a cache update happens, entry is first put into - * a buffer. Entries from buffer are sent to the master node - * only if the buffer is full (its size can be changed via - * SetBufferSize) or time provided via this method is - * exceeded. - * - * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which - * means that time check is disabled and entries will be - * sent only when buffer is full. - * - * @param val Time interval in miliseconds. - */ - void SetTimeInterval(int64_t val) - { - timeInterval = val; - } - - /** - * Get time interval. - * - * When a cache update happens, entry is first put into - * a buffer. Entries from buffer are sent to the master node - * only if the buffer is full (its size can be changed via - * SetBufferSize) or time provided via SetTimeInterval - * method is exceeded. - * - * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which - * means that time check is disabled and entries will be - * sent only when buffer is full. - * - * @return Time interval. - */ - int64_t GetTimeInterval() const - { - return timeInterval; - } - - /** - * Get remote filter holder. - * - * @return Filter holder. - */ - event::CacheEntryEventFilterHolderBase& GetFilterHolder() const - { - return *filterOp; - } - - /** - * Callback that reads and processes cache events. - * - * @param reader Reader to use. - */ - virtual void ReadAndProcessEvents(ignite::odbc::binary::BinaryRawReader& reader) = 0; - - private: - /** - * Local flag. When set query will be executed only on local - * node, so only local entries will be returned as query - * result. - * - * Default value is false. - */ - bool local; - - /** - * Buffer size. When a cache update happens, entry is first - * put into a buffer. Entries from buffer will be sent to - * the master node only if the buffer is full or time - * provided via timeInterval is exceeded. - * - * Default value is DEFAULT_BUFFER_SIZE. - */ - int32_t bufferSize; - - /** - * Time interval in miliseconds. When a cache update - * happens, entry is first put into a buffer. Entries from - * buffer will be sent to the master node only if the buffer - * is full (its size can be changed via SetBufferSize) or - * time provided via SetTimeInterval method is exceeded. - * - * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which - * means that time check is disabled and entries will be - * sent only when buffer is full. - */ - int64_t timeInterval; - - /** Cache entry event filter holder. */ - std::unique_ptr filterOp; - }; - - /** - * Continuous query implementation. - * - * Continuous queries allow to register a remote and a listener - * for cache update events. On any update to the related cache - * an event is sent to the node that has executed the query and - * listener is notified on that node. - * - * Continuous query can either be executed on the whole topology - * or only on local node. - * - * To execute the query over the cache use method - * ignite::odbc::cache::Cache::QueryContinuous(). - */ - template - class ContinuousQueryImpl : public ContinuousQueryImplBase - { - public: - /** - * Destructor. - */ - virtual ~ContinuousQueryImpl() - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener Invoked on the node where - * continuous query execution has been started. - * @param loc Whether query should be executed locally. - */ - ContinuousQueryImpl(Reference >& lsnr, - bool loc) : - ContinuousQueryImplBase(loc, new event::CacheEntryEventFilterHolder()), - lsnr(lsnr) - { - // No-op. - } - - /** - * Constructor. - * - * @param lsnr Event listener Invoked on the node where - * continuous query execution has been started. - * @param loc Whether query should be executed locally. - */ - template - ContinuousQueryImpl(Reference >& lsnr, - bool loc, const Reference& filter) : - ContinuousQueryImplBase(loc, new event::CacheEntryEventFilterHolder(filter)), - lsnr(lsnr) - { - // No-op. - } - - /** - * Set cache entry event listener. - * - * @param val Cache entry event listener. Invoked on the - * node where continuous query execution has been - * started. - */ - void SetListener(Reference >& val) - { - lsnr = val; - } - - /** - * Check if the query has listener. - * - * @return True if the query has listener. - */ - bool HasListener() const - { - return !lsnr.IsNull(); - } - - /** - * Get cache entry event listener. - * - * @return Cache entry event listener. - */ - const ignite::odbc::cache::event::CacheEntryEventListener& GetListener() const - { - return lsnr.Get(); - } - - /** - * Get cache entry event listener. - * - * @return Cache entry event listener. - */ - ignite::odbc::cache::event::CacheEntryEventListener& GetListener() - { - return lsnr.Get(); - } - - /** - * Callback that reads and processes cache events. - * - * @param reader Reader to use. - */ - virtual void ReadAndProcessEvents(ignite::odbc::binary::BinaryRawReader& reader) - { - // Number of events. - int32_t cnt = reader.ReadInt32(); - - // Storing events here. - std::vector< ignite::odbc::cache::CacheEntryEvent > events; - events.resize(cnt); - - for (int32_t i = 0; i < cnt; ++i) - events[i].Read(reader); - - lsnr.Get()->OnEvent(events.data(), cnt); - } - - private: - /** Cache entry event listener. */ - Reference > lsnr; - }; - - /** - * Used to store filter on remote nodes where no - * ContinuousQuery instance were really created. - */ - class RemoteFilterHolder : public ContinuousQueryImplBase - { - public: - /** - * Constructor. - */ - template - RemoteFilterHolder(const Reference& filter): - ContinuousQueryImplBase(false, new event::CacheEntryEventFilterHolder(filter)) - { - // No-op. - } - - virtual void ReadAndProcessEvents(ignite::odbc::binary::BinaryRawReader&) - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "No listener is registered for the ContinuousQuery instance"); - } - }; - } - } - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_IMPL +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +namespace continuous { +/** + * Continuous query base implementation class. + * + * Continuous queries allow to register a remote and a listener + * for cache update events. On any update to the related cache + * an event is sent to the node that has executed the query and + * listener is notified on that node. + * + * Continuous query can either be executed on the whole topology + * or only on local node. + * + * To execute the query over the cache use method + * ignite::odbc::cache::Cache::QueryContinuous(). + */ +class ContinuousQueryImplBase { + public: + /** + * Destructor. + */ + virtual ~ContinuousQueryImplBase() { + // No-op. + } + + /** + * Default value for the buffer size. + */ + enum { DEFAULT_BUFFER_SIZE = 1 }; + + /** + * Default value for the time interval. + */ + enum { DEFAULT_TIME_INTERVAL = 0 }; + + /** + * Constructor. + * + * @param loc Whether query should be executed locally. + */ + explicit ContinuousQueryImplBase( + bool loc, event::CacheEntryEventFilterHolderBase* filterOp) + : local(loc), + bufferSize(DEFAULT_BUFFER_SIZE), + timeInterval(DEFAULT_TIME_INTERVAL), + filterOp(filterOp) { + // No-op. + } + + /** + * Set local flag. + * + * @param val Value of the flag. If true, query will be + * executed only on local node, so only local entries + * will be returned as query result. + */ + void SetLocal(bool val) { + local = val; + } + + /** + * Get local flag. + * + * @return Value of the flag. If true, query will be + * executed only on local node, so only local entries + * will be returned as query result. + */ + bool GetLocal() const { + return local; + } + + /** + * Set buffer size. + * + * When a cache update happens, entry is first + * put into a buffer. Entries from buffer will be sent to + * the master node only if the buffer is full or time + * provided via timeInterval is exceeded. + * + * @param val Buffer size. + */ + void SetBufferSize(int32_t val) { + bufferSize = val; + } + + /** + * Get buffer size. + * + * When a cache update happens, entry is first + * put into a buffer. Entries from buffer will be sent to + * the master node only if the buffer is full or time + * provided via timeInterval is exceeded. + * + * @return Buffer size. + */ + int32_t GetBufferSize() const { + return bufferSize; + } + + /** + * Set time interval. + * + * When a cache update happens, entry is first put into + * a buffer. Entries from buffer are sent to the master node + * only if the buffer is full (its size can be changed via + * SetBufferSize) or time provided via this method is + * exceeded. + * + * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which + * means that time check is disabled and entries will be + * sent only when buffer is full. + * + * @param val Time interval in miliseconds. + */ + void SetTimeInterval(int64_t val) { + timeInterval = val; + } + + /** + * Get time interval. + * + * When a cache update happens, entry is first put into + * a buffer. Entries from buffer are sent to the master node + * only if the buffer is full (its size can be changed via + * SetBufferSize) or time provided via SetTimeInterval + * method is exceeded. + * + * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which + * means that time check is disabled and entries will be + * sent only when buffer is full. + * + * @return Time interval. + */ + int64_t GetTimeInterval() const { + return timeInterval; + } + + /** + * Get remote filter holder. + * + * @return Filter holder. + */ + event::CacheEntryEventFilterHolderBase& GetFilterHolder() const { + return *filterOp; + } + + /** + * Callback that reads and processes cache events. + * + * @param reader Reader to use. + */ + virtual void ReadAndProcessEvents( + ignite::odbc::binary::BinaryRawReader& reader) = 0; + + private: + /** + * Local flag. When set query will be executed only on local + * node, so only local entries will be returned as query + * result. + * + * Default value is false. + */ + bool local; + + /** + * Buffer size. When a cache update happens, entry is first + * put into a buffer. Entries from buffer will be sent to + * the master node only if the buffer is full or time + * provided via timeInterval is exceeded. + * + * Default value is DEFAULT_BUFFER_SIZE. + */ + int32_t bufferSize; + + /** + * Time interval in miliseconds. When a cache update + * happens, entry is first put into a buffer. Entries from + * buffer will be sent to the master node only if the buffer + * is full (its size can be changed via SetBufferSize) or + * time provided via SetTimeInterval method is exceeded. + * + * Default value is DEFAULT_TIME_INTERVAL, i.e. 0, which + * means that time check is disabled and entries will be + * sent only when buffer is full. + */ + int64_t timeInterval; + + /** Cache entry event filter holder. */ + std::unique_ptr< event::CacheEntryEventFilterHolderBase > filterOp; +}; + +/** + * Continuous query implementation. + * + * Continuous queries allow to register a remote and a listener + * for cache update events. On any update to the related cache + * an event is sent to the node that has executed the query and + * listener is notified on that node. + * + * Continuous query can either be executed on the whole topology + * or only on local node. + * + * To execute the query over the cache use method + * ignite::odbc::cache::Cache::QueryContinuous(). + */ +template < typename K, typename V > +class ContinuousQueryImpl : public ContinuousQueryImplBase { + public: + /** + * Destructor. + */ + virtual ~ContinuousQueryImpl() { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener Invoked on the node where + * continuous query execution has been started. + * @param loc Whether query should be executed locally. + */ + ContinuousQueryImpl( + Reference< ignite::odbc::cache::event::CacheEntryEventListener< K, V > >& + lsnr, + bool loc) + : ContinuousQueryImplBase( + loc, new event::CacheEntryEventFilterHolder< void >()), + lsnr(lsnr) { + // No-op. + } + + /** + * Constructor. + * + * @param lsnr Event listener Invoked on the node where + * continuous query execution has been started. + * @param loc Whether query should be executed locally. + */ + template < typename F > + ContinuousQueryImpl( + Reference< ignite::odbc::cache::event::CacheEntryEventListener< K, V > >& + lsnr, + bool loc, const Reference< F >& filter) + : ContinuousQueryImplBase( + loc, new event::CacheEntryEventFilterHolder< F >(filter)), + lsnr(lsnr) { + // No-op. + } + + /** + * Set cache entry event listener. + * + * @param val Cache entry event listener. Invoked on the + * node where continuous query execution has been + * started. + */ + void SetListener( + Reference< ignite::odbc::cache::event::CacheEntryEventListener< K, V > >& + val) { + lsnr = val; + } + + /** + * Check if the query has listener. + * + * @return True if the query has listener. + */ + bool HasListener() const { + return !lsnr.IsNull(); + } + + /** + * Get cache entry event listener. + * + * @return Cache entry event listener. + */ + const ignite::odbc::cache::event::CacheEntryEventListener< K, V >& + GetListener() const { + return lsnr.Get(); + } + + /** + * Get cache entry event listener. + * + * @return Cache entry event listener. + */ + ignite::odbc::cache::event::CacheEntryEventListener< K, V >& GetListener() { + return lsnr.Get(); + } + + /** + * Callback that reads and processes cache events. + * + * @param reader Reader to use. + */ + virtual void ReadAndProcessEvents( + ignite::odbc::binary::BinaryRawReader& reader) { + // Number of events. + int32_t cnt = reader.ReadInt32(); + + // Storing events here. + std::vector< ignite::odbc::cache::CacheEntryEvent< K, V > > events; + events.resize(cnt); + + for (int32_t i = 0; i < cnt; ++i) + events[i].Read(reader); + + lsnr.Get()->OnEvent(events.data(), cnt); + } + + private: + /** Cache entry event listener. */ + Reference< ignite::odbc::cache::event::CacheEntryEventListener< K, V > > lsnr; +}; + +/** + * Used to store filter on remote nodes where no + * ContinuousQuery instance were really created. + */ +class RemoteFilterHolder : public ContinuousQueryImplBase { + public: + /** + * Constructor. + */ + template < typename F > + RemoteFilterHolder(const Reference< F >& filter) + : ContinuousQueryImplBase( + false, new event::CacheEntryEventFilterHolder< F >(filter)) { + // No-op. + } + + virtual void ReadAndProcessEvents(ignite::odbc::binary::BinaryRawReader&) { + throw IgniteError( + IgniteError::IGNITE_ERR_GENERIC, + "No listener is registered for the ContinuousQuery instance"); + } +}; +} // namespace continuous +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CONTINUOUS_CONTINUOUS_QUERY_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/query_argument.h b/src/odbc/include/ignite/odbc/impl/cache/query/query_argument.h index 15122cde8..d7becb793 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/query_argument.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/query_argument.h @@ -26,178 +26,153 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - /** - * Base class for all query arguments. - */ - class QueryArgumentBase - { - public: - /** - * Destructor. - */ - virtual ~QueryArgumentBase() - { - // No-op. - } - - /** - * Copy argument. - * - * @return Copy of this argument instance. - */ - virtual QueryArgumentBase* Copy() const = 0; - - /** - * Write argument using provided writer. - * - * @param writer Writer to use to write this argument. - */ - virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) = 0; - }; - - /** - * Query argument class template. - * - * Template argument type should be copy-constructable and - * assignable. Also BinaryType class template should be specialized - * for this type. - */ - template - class QueryArgument : public QueryArgumentBase - { - public: - /** - * Constructor. - * - * @param val Value. - */ - QueryArgument(const T& val) : - val(val) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - QueryArgument(const QueryArgument& other) : - val(other.val) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - QueryArgument& operator=(const QueryArgument& other) - { - if (this != &other) - val = other.val; - - return *this; - } - - virtual ~QueryArgument() - { - // No-op. - } - - virtual QueryArgumentBase* Copy() const - { - return new QueryArgument(val); - } - - virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) - { - writer.WriteObject(val); - } - - private: - /** Value. */ - T val; - }; - - /** - * Query bytes array argument class. - */ - class QueryInt8ArrayArgument : public QueryArgumentBase - { - public: - /** - * Constructor. - * - * @param src Array. - * @param len Array length. - */ - QueryInt8ArrayArgument(const int8_t* src, int32_t len) : - val(src, src + len) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - QueryInt8ArrayArgument(const QueryInt8ArrayArgument& other) : - val(other.val) - { - // No-op. - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - QueryInt8ArrayArgument& operator=(const QueryInt8ArrayArgument& other) - { - if (this != &other) - val = other.val; - - return *this; - } - - virtual ~QueryInt8ArrayArgument() - { - // No-op. - } - - virtual QueryArgumentBase* Copy() const - { - return new QueryInt8ArrayArgument(*this); - } - - virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) - { - writer.WriteInt8Array(&val[0], static_cast(val.size())); - } - - private: - /** Value. */ - std::vector val; - }; - } - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_QUERY_ARGUMENT +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +/** + * Base class for all query arguments. + */ +class QueryArgumentBase { + public: + /** + * Destructor. + */ + virtual ~QueryArgumentBase() { + // No-op. + } + + /** + * Copy argument. + * + * @return Copy of this argument instance. + */ + virtual QueryArgumentBase* Copy() const = 0; + + /** + * Write argument using provided writer. + * + * @param writer Writer to use to write this argument. + */ + virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) = 0; +}; + +/** + * Query argument class template. + * + * Template argument type should be copy-constructable and + * assignable. Also BinaryType class template should be specialized + * for this type. + */ +template < typename T > +class QueryArgument : public QueryArgumentBase { + public: + /** + * Constructor. + * + * @param val Value. + */ + QueryArgument(const T& val) : val(val) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + QueryArgument(const QueryArgument& other) : val(other.val) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + QueryArgument& operator=(const QueryArgument& other) { + if (this != &other) + val = other.val; + + return *this; + } + + virtual ~QueryArgument() { + // No-op. + } + + virtual QueryArgumentBase* Copy() const { + return new QueryArgument(val); + } + + virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) { + writer.WriteObject< T >(val); + } + + private: + /** Value. */ + T val; +}; + +/** + * Query bytes array argument class. + */ +class QueryInt8ArrayArgument : public QueryArgumentBase { + public: + /** + * Constructor. + * + * @param src Array. + * @param len Array length. + */ + QueryInt8ArrayArgument(const int8_t* src, int32_t len) : val(src, src + len) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + QueryInt8ArrayArgument(const QueryInt8ArrayArgument& other) : val(other.val) { + // No-op. + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + QueryInt8ArrayArgument& operator=(const QueryInt8ArrayArgument& other) { + if (this != &other) + val = other.val; + + return *this; + } + + virtual ~QueryInt8ArrayArgument() { + // No-op. + } + + virtual QueryArgumentBase* Copy() const { + return new QueryInt8ArrayArgument(*this); + } + + virtual void Write(ignite::odbc::binary::BinaryRawWriter& writer) { + writer.WriteInt8Array(&val[0], static_cast< int32_t >(val.size())); + } + + private: + /** Value. */ + std::vector< int8_t > val; +}; +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_QUERY_ARGUMENT diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/query_batch.h b/src/odbc/include/ignite/odbc/impl/cache/query/query_batch.h index e3d675cc1..4ec7ece6d 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/query_batch.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/query_batch.h @@ -24,128 +24,117 @@ #include "ignite/odbc/impl/ignite_environment.h" #include "ignite/odbc/impl/operations.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - class QueryFieldsRowImpl; - - /** - * Query batch. - */ - class IGNITE_IMPORT_EXPORT QueryBatch - { - typedef common::concurrent::SharedPointer MemorySharedPtr; - - public: - /** - * Constructor. - * - * @param env Environment. - * @param mem Batch memory. - */ - QueryBatch(IgniteEnvironment& env, MemorySharedPtr mem) : - env(env), - mem(mem), - stream(mem.Get()), - reader(&stream), - size(reader.ReadInt32()), - pos(0) - { - // No-op. - } - - /** - * Destructor. - */ - ~QueryBatch() - { - // No-op. - } - - /** - * Check whether batch is empty. - * - * @return True if empty. - */ - bool IsEmpty() const - { - return size == 0; - } - - /** - * Get the number of the unread rows in the batch. - * - * @return Number of the unread rows in the batch. - */ - int32_t Left() const - { - return size - pos; - } - - /** - * Check whether next result exists. - * - * @param err Error. - * @return True if exists. - */ - int32_t Size() - { - return size; - } - - /** - * Get next object. - * - * @param op Operation. - */ - void GetNext(OutputOperation& op) - { - assert(Left() > 0); - - op.ProcessOutput(reader); - - ++pos; - } - - /** - * Get next row. - * - * @return Output row. - */ - QueryFieldsRowImpl* GetNextRow(); - - private: - /** Environment. */ - IgniteEnvironment& env; - - /** Memomy containing the batch. */ - MemorySharedPtr mem; - - /** Stream. */ - interop::InteropInputStream stream; - - /** Reader. */ - binary::BinaryReaderImpl reader; - - /** Result batch size. */ - int32_t size; - - /** Position in memory. */ - int32_t pos; - - IGNITE_NO_COPY_ASSIGNMENT(QueryBatch); - }; - } - } - } - } -} - -#endif // _IGNITE_ODBC_CACHE_QUERY_BATCH +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +class QueryFieldsRowImpl; + +/** + * Query batch. + */ +class IGNITE_IMPORT_EXPORT QueryBatch { + typedef common::concurrent::SharedPointer< interop::InteropMemory > + MemorySharedPtr; + + public: + /** + * Constructor. + * + * @param env Environment. + * @param mem Batch memory. + */ + QueryBatch(IgniteEnvironment& env, MemorySharedPtr mem) + : env(env), + mem(mem), + stream(mem.Get()), + reader(&stream), + size(reader.ReadInt32()), + pos(0) { + // No-op. + } + + /** + * Destructor. + */ + ~QueryBatch() { + // No-op. + } + + /** + * Check whether batch is empty. + * + * @return True if empty. + */ + bool IsEmpty() const { + return size == 0; + } + + /** + * Get the number of the unread rows in the batch. + * + * @return Number of the unread rows in the batch. + */ + int32_t Left() const { + return size - pos; + } + + /** + * Check whether next result exists. + * + * @param err Error. + * @return True if exists. + */ + int32_t Size() { + return size; + } + + /** + * Get next object. + * + * @param op Operation. + */ + void GetNext(OutputOperation& op) { + assert(Left() > 0); + + op.ProcessOutput(reader); + + ++pos; + } + + /** + * Get next row. + * + * @return Output row. + */ + QueryFieldsRowImpl* GetNextRow(); + + private: + /** Environment. */ + IgniteEnvironment& env; + + /** Memomy containing the batch. */ + MemorySharedPtr mem; + + /** Stream. */ + interop::InteropInputStream stream; + + /** Reader. */ + binary::BinaryReaderImpl reader; + + /** Result batch size. */ + int32_t size; + + /** Position in memory. */ + int32_t pos; + + IGNITE_NO_COPY_ASSIGNMENT(QueryBatch); +}; +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif // _IGNITE_ODBC_CACHE_QUERY_BATCH diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/query_fields_row_impl.h b/src/odbc/include/ignite/odbc/impl/cache/query/query_fields_row_impl.h index 68c48f4d8..2ea120384 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/query_fields_row_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/query_fields_row_impl.h @@ -21,180 +21,162 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - /** - * Query fields cursor implementation. - */ - class QueryFieldsRowImpl - { - public: - typedef common::concurrent::SharedPointer SP_InteropMemory; - - /** - * Constructor. - * - * @param mem Memory containig row data. - */ - QueryFieldsRowImpl(SP_InteropMemory mem, int32_t rowBegin, int32_t columnNum) : - mem(mem), - stream(mem.Get()), - reader(&stream), - columnNum(columnNum), - processed(0) - { - stream.Position(rowBegin); - } - - /** - * Check whether next entry exists. - * - * @return True if next entry exists. - */ - bool HasNext() - { - IgniteError err; - - bool res = HasNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Check whether next entry exists. - * - * @param err Error. - * @return True if next entry exists. - */ - bool HasNext(IgniteError& err) - { - if (IsValid()) - return processed < columnNum; - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return false; - } - } - - /** - * Get next entry. - * - * @return Next entry. - */ - template - T GetNext() - { - IgniteError err; - - QueryFieldsRowImpl res = GetNext(err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - /** - * Get next entry. - * - * @param err Error. - * @return Next entry. - */ - template - T GetNext(IgniteError& err) - { - if (IsValid()) { - ++processed; - return reader.ReadTopObject(); - } - else - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - - return T(); - } - } - - /** - * Get next entry assuming it's an array of 8-byte signed - * integers. Maps to "byte[]" type in Java. - * - * @param dst Array to store data to. - * @param len Expected length of array. - * @return Actual amount of elements read. If "len" argument is less than actual - * array size or resulting array is set to null, nothing will be written - * to resulting array and returned value will contain required array length. - * -1 will be returned in case array in stream was null. - */ - int32_t GetNextInt8Array(int8_t* dst, int32_t len) - { - if (IsValid()) { - - int32_t actualLen = reader.ReadInt8Array(dst, len); - - if (actualLen == 0 || (dst && len >= actualLen)) - ++processed; - - return actualLen; - } - else - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Instance is not usable (did you check for error?)."); - } - } - - /** - * Check if the instance 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 the instance is valid and can be used. - */ - bool IsValid() - { - return mem.Get() != 0; - } - - private: - /** Row memory. */ - SP_InteropMemory mem; - - /** Row data stream. */ - interop::InteropInputStream stream; - - /** Row data reader. */ - binary::BinaryReaderImpl reader; - - /** Number of elements in a row. */ - int32_t columnNum; - - /** Number of elements that have been read by now. */ - int32_t processed; - - IGNITE_NO_COPY_ASSIGNMENT(QueryFieldsRowImpl); - }; - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +/** + * Query fields cursor implementation. + */ +class QueryFieldsRowImpl { + public: + typedef common::concurrent::SharedPointer< interop::InteropMemory > + SP_InteropMemory; + + /** + * Constructor. + * + * @param mem Memory containig row data. + */ + QueryFieldsRowImpl(SP_InteropMemory mem, int32_t rowBegin, int32_t columnNum) + : mem(mem), + stream(mem.Get()), + reader(&stream), + columnNum(columnNum), + processed(0) { + stream.Position(rowBegin); + } + + /** + * Check whether next entry exists. + * + * @return True if next entry exists. + */ + bool HasNext() { + IgniteError err; + + bool res = HasNext(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Check whether next entry exists. + * + * @param err Error. + * @return True if next entry exists. + */ + bool HasNext(IgniteError& err) { + if (IsValid()) + return processed < columnNum; + else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return false; + } + } + + /** + * Get next entry. + * + * @return Next entry. + */ + template < typename T > + T GetNext() { + IgniteError err; + + QueryFieldsRowImpl res = GetNext< T >(err); + + IgniteError::ThrowIfNeeded(err); + + return res; + } + + /** + * Get next entry. + * + * @param err Error. + * @return Next entry. + */ + template < typename T > + T GetNext(IgniteError& err) { + if (IsValid()) { + ++processed; + return reader.ReadTopObject< T >(); + } else { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + + return T(); } -} + } + + /** + * Get next entry assuming it's an array of 8-byte signed + * integers. Maps to "byte[]" type in Java. + * + * @param dst Array to store data to. + * @param len Expected length of array. + * @return Actual amount of elements read. If "len" argument is less than + * actual array size or resulting array is set to null, nothing will be + * written to resulting array and returned value will contain required array + * length. -1 will be returned in case array in stream was null. + */ + int32_t GetNextInt8Array(int8_t* dst, int32_t len) { + if (IsValid()) { + int32_t actualLen = reader.ReadInt8Array(dst, len); + + if (actualLen == 0 || (dst && len >= actualLen)) + ++processed; + + return actualLen; + } else { + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Instance is not usable (did you check for error?)."); + } + } + + /** + * Check if the instance 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 the instance is valid and can be used. + */ + bool IsValid() { + return mem.Get() != 0; + } + + private: + /** Row memory. */ + SP_InteropMemory mem; + + /** Row data stream. */ + interop::InteropInputStream stream; + + /** Row data reader. */ + binary::BinaryReaderImpl reader; + + /** Number of elements in a row. */ + int32_t columnNum; + + /** Number of elements that have been read by now. */ + int32_t processed; + + IGNITE_NO_COPY_ASSIGNMENT(QueryFieldsRowImpl); +}; +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CACHE_QUERY_FIELDS_ROW_IMPL +#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_CACHE_QUERY_FIELDS_ROW_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cache/query/query_impl.h b/src/odbc/include/ignite/odbc/impl/cache/query/query_impl.h index 11f5142e5..e6776948e 100644 --- a/src/odbc/include/ignite/odbc/impl/cache/query/query_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cache/query/query_impl.h @@ -24,125 +24,122 @@ #include "ignite/odbc/impl/operations.h" #include "ignite/odbc/impl/cache/query/query_batch.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - class QueryFieldsRowImpl; - - /** - * Query cursor implementation. - */ - class IGNITE_IMPORT_EXPORT QueryCursorImpl - { - public: - /** - * Constructor. - * - * @param env Environment. - * @param javaRef Java reference. - */ - QueryCursorImpl(ignite::odbc::common::concurrent::SharedPointer env, jobject javaRef); - - /** - * Destructor. - */ - ~QueryCursorImpl(); - - /** - * Check whether next result exists. - * - * @param err Error. - * @return True if exists. - */ - bool HasNext(IgniteError& err); - - /** - * Get next object. - * - * @param op Operation. - * @param err Error. - */ - void GetNext(OutputOperation& op, IgniteError& err); - - /** - * Get next row. - * - * @param err Error. - * @return Output row. - */ - QueryFieldsRowImpl* GetNextRow(IgniteError& err); - - /** - * Get all cursor entries. - * - * @param op Operation. - * @param err Error. - */ - void GetAll(OutputOperation& op, IgniteError& err); - - /** - * Get all cursor entries. - * - * @param op Operation. - */ - void GetAll(OutputOperation& op); - - private: - /** Environment. */ - ignite::odbc::common::concurrent::SharedPointer env; - - /** Handle to Java object. */ - jobject javaRef; - - /** Current result batch. */ - QueryBatch* batch; - - /** Whether cursor has no more elements available. */ - bool endReached; - - /** Whether iteration methods were called. */ - bool iterCalled; - - /** Whether GetAll() method was called. */ - bool getAllCalled; - - IGNITE_NO_COPY_ASSIGNMENT(QueryCursorImpl); - - /** - * Create Java-side iterator if needed. - * - * @param err Error. - * @return True in case of success, false if an error is thrown. - */ - bool CreateIteratorIfNeeded(IgniteError& err); - - /** - * Get next result batch if update is needed. - * - * @param err Error. - * @return True if operation has been successful. - */ - bool GetNextBatchIfNeeded(IgniteError& err); - - /** - * Check whether Java-side iterator has next element. - * - * @param err Error. - * @return True if the next element is available. - */ - bool IteratorHasNext(IgniteError& err); - }; - } - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_QUERY_IMPL +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +class QueryFieldsRowImpl; + +/** + * Query cursor implementation. + */ +class IGNITE_IMPORT_EXPORT QueryCursorImpl { + public: + /** + * Constructor. + * + * @param env Environment. + * @param javaRef Java reference. + */ + QueryCursorImpl( + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > env, + jobject javaRef); + + /** + * Destructor. + */ + ~QueryCursorImpl(); + + /** + * Check whether next result exists. + * + * @param err Error. + * @return True if exists. + */ + bool HasNext(IgniteError& err); + + /** + * Get next object. + * + * @param op Operation. + * @param err Error. + */ + void GetNext(OutputOperation& op, IgniteError& err); + + /** + * Get next row. + * + * @param err Error. + * @return Output row. + */ + QueryFieldsRowImpl* GetNextRow(IgniteError& err); + + /** + * Get all cursor entries. + * + * @param op Operation. + * @param err Error. + */ + void GetAll(OutputOperation& op, IgniteError& err); + + /** + * Get all cursor entries. + * + * @param op Operation. + */ + void GetAll(OutputOperation& op); + + private: + /** Environment. */ + ignite::odbc::common::concurrent::SharedPointer< impl::IgniteEnvironment > + env; + + /** Handle to Java object. */ + jobject javaRef; + + /** Current result batch. */ + QueryBatch* batch; + + /** Whether cursor has no more elements available. */ + bool endReached; + + /** Whether iteration methods were called. */ + bool iterCalled; + + /** Whether GetAll() method was called. */ + bool getAllCalled; + + IGNITE_NO_COPY_ASSIGNMENT(QueryCursorImpl); + + /** + * Create Java-side iterator if needed. + * + * @param err Error. + * @return True in case of success, false if an error is thrown. + */ + bool CreateIteratorIfNeeded(IgniteError& err); + + /** + * Get next result batch if update is needed. + * + * @param err Error. + * @return True if operation has been successful. + */ + bool GetNextBatchIfNeeded(IgniteError& err); + + /** + * Check whether Java-side iterator has next element. + * + * @param err Error. + * @return True if the next element is available. + */ + bool IteratorHasNext(IgniteError& err); +}; +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CACHE_QUERY_QUERY_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cluster/cluster_group_impl.h b/src/odbc/include/ignite/odbc/impl/cluster/cluster_group_impl.h index 3683d86ae..11e9834fb 100644 --- a/src/odbc/include/ignite/odbc/impl/cluster/cluster_group_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cluster/cluster_group_impl.h @@ -26,406 +26,425 @@ #include #include -namespace ignite -{ - namespace odbc - { - /* Forward declaration of interfaces. */ - namespace cluster - { - class ClusterGroup; - class ClusterNode; - } - - namespace impl - { - namespace cluster - { - /* Forward declaration. */ - class ClusterGroupImpl; - class ClusterNodePredicateHolder; - - /* Shared pointer. */ - typedef common::concurrent::SharedPointer SP_ClusterGroupImpl; - - /** - * Cluster group implementation. - */ - class IGNITE_FRIEND_EXPORT ClusterGroupImpl : private interop::InteropTarget - { - typedef common::concurrent::SharedPointer SP_IgniteEnvironment; - typedef common::concurrent::SharedPointer > SP_ClusterNodes; - typedef common::concurrent::SharedPointer SP_PredicateHolder; - public: - /** - * Constructor used to create new instance. - * - * @param env Environment. - * @param javaRef Reference to java object. - */ - ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef); - - /** - * Destructor. - */ - ~ClusterGroupImpl(); - - /** - * Get cluster group for nodes containing given name and value specified in user attributes. - * - * @param name Name of the attribute. - * @param val Optional attribute value to match. - * @return Pointer to cluster group for nodes containing specified attribute. - */ - SP_ClusterGroupImpl ForAttribute(std::string name, std::string val); - - /** - * Get cluster group for all nodes that have cache with specified name, either in client or server modes. - * - * @param cacheName Cache name. - * @return Pointer to cluster group over nodes that have the cache with the specified name running. - */ - SP_ClusterGroupImpl ForCacheNodes(std::string cacheName); - - /** - * Get cluster group for all client nodes that access cache with the specified name. - * - * @param cacheName Cache name. - * @return Pointer to cluster group over nodes that have the cache with the specified name running. - */ - SP_ClusterGroupImpl ForClientNodes(std::string cacheName); - - /** - * Get a cluster group of nodes started in client mode. - * - * @return Pointer to cluster group over nodes that started in client mode. - */ - SP_ClusterGroupImpl ForClients(); - - /** - * Get a cluster group consisting from the daemon nodes - * - * @return Pointer to cluster group over nodes started in daemon mode. - */ - SP_ClusterGroupImpl ForDaemons(); - - /** - * Get cluster group for all data nodes that have the cache with the specified name running. - * - * @param cacheName Cache name. - * @return Pointer to cluster group over nodes that have the cache with the specified name running. - */ - SP_ClusterGroupImpl ForDataNodes(std::string cacheName); - - /** - * Get cluster group consisting from the nodes in this cluster group residing on the same host as the given node. - * - * @param node Cluster node. - * @return Pointer to cluster group residing on the same host as the given node. - */ - SP_ClusterGroupImpl ForHost(ignite::odbc::cluster::ClusterNode node); - - /** - * Get cluster group consisting from the nodes running on the host specified. - * - * @param hostName Host name. - * @return Pointer to cluster group over nodes that have requested host name. - */ - SP_ClusterGroupImpl ForHost(std::string hostName); - - /** - * Get cluster group consisting from the nodes running on the hosts specified. - * - * @param hostNames Container of host names. - * @return Pointer to cluster group over nodes that have requested host names. - */ - SP_ClusterGroupImpl ForHosts(std::vector hostNames); - - /** - * Get cluster group for the given node. - * - * @param node Cluster node. - * @return Pointer to cluster group for the given node. - */ - SP_ClusterGroupImpl ForNode(ignite::odbc::cluster::ClusterNode node); - - /** - * Get cluster group for a node with the specified ID. - * - * @param id Cluster node ID. - * @return Pointer to cluster group for a node with the specified ID. - */ - SP_ClusterGroupImpl ForNodeId(Guid id); - - /** - * Get cluster group over nodes with specified node IDs. - * - * @param ids Cluster node IDs. - * @return Pointer to cluster group over nodes with specified node IDs. - */ - SP_ClusterGroupImpl ForNodeIds(std::vector ids); - - /** - * Get cluster group over a given set of nodes. - * - * @param nodes Cluster nodes. - * @return Pointer to cluster group over a given set of nodes. - */ - SP_ClusterGroupImpl ForNodes(std::vector nodes); - - /** - * Get cluster group with one oldest node from the current cluster group. - * - * @return Pointer to cluster group with one oldest node from the current cluster group. - */ - SP_ClusterGroupImpl ForOldest(); - - /** - * Create a new cluster group which includes all nodes that pass the given predicate filter. - * - * @param pred Pointer to predicate heap object. - * @return Pointer to newly created cluster group. - * - * @throw IgniteError if there are no nodes in the cluster group. - */ - SP_ClusterGroupImpl ForPredicate(IgnitePredicate* pred); - - /** - * Get cluster group with one random node from the current cluster group. - * - * @return Pointer to cluster group with one random node from the current cluster group. - */ - SP_ClusterGroupImpl ForRandom(); - - /** - * Get cluster group consisting from the nodes in this cluster group excluding the local node. - * - * @return Pointer to cluster group consisting from the nodes in this cluster group excluding the local node. - */ - SP_ClusterGroupImpl ForRemotes(); - - /** - * Creates a cluster group of nodes started in server mode. - * - * @return Pointer to cluster group of nodes started in server mode. - */ - SP_ClusterGroupImpl ForServers(); - - /** - * Get cluster group with one youngest node in the current cluster group. - * - * @return Pointer to cluster group with one youngest node in the current cluster group. - */ - SP_ClusterGroupImpl ForYoungest(); - - /** - * Creates a cluster group of cpp nodes. - * - * @return Pointer to cluster group of cpp nodes. - */ - SP_ClusterGroupImpl ForCpp(); - - /** - * Get a cluster group consisting from the local node. - * - * @return Pointer to cluster group consisting from the local node. - */ - SP_ClusterGroupImpl ForLocal(); - - /** - * Get local grid node. - * - * @return Local node. - */ - ignite::odbc::cluster::ClusterNode GetLocalNode(); - - /** - * Get first node from the list of nodes in this cluster group. - * - * @return Cluster node in this cluster group. - * - * @throw IgniteError if there are no nodes in the cluster group. - */ - ignite::odbc::cluster::ClusterNode GetNode(); - - /** - * Get node for given ID from this cluster group. - * - * @param nid Cluster node ID. - * @return Cluster node in this cluster group. - * - * @throw IgniteError if there is no node with specified ID. - */ - ignite::odbc::cluster::ClusterNode GetNode(Guid nid); - - /** - * Get the vector of nodes in this cluster group. - * - * @return All nodes in this cluster group. - */ - std::vector GetNodes(); - - /** - * Check if the Ignite grid is active. - * - * @return True if grid is active and false otherwise. - */ - bool IsActive(); - - /** - * Change Ignite grid state to active or inactive. - * - * @param active If true start activation process. If false start - * deactivation process. - */ - void SetActive(bool active); - - /** - * Disable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void DisableWal(std::string cacheName); - - /** - * Enable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void EnableWal(std::string cacheName); - - /** - * Check if write - ahead logging is enabled for specified cache. - * - * @param cacheName Cache name. - * - * @return True if enabled. - */ - bool IsWalEnabled(std::string cacheName); - - /** - * Set baseline topology constructed from the cluster topology of the given version. - * The method succeeds only if the cluster topology has not changed. - * - * @param topVer Topology version. - */ - void SetBaselineTopologyVersion(int64_t topVer); - - /** - * Set transaction timeout on partition map exchange. - * - * @param timeout Timeout in milliseconds. - */ - void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); - - /** - * Ping node. - * - * @param nid Cluster node ID. - * @return True in case of success. - */ - bool PingNode(Guid nid); - - /** - * Get predicate that defines a subset of nodes for this cluster group. - * - * @return Pointer to predicate. - */ - IgnitePredicate* GetPredicate(); - - /** - * Get predicate that defines a subset of nodes for this cluster group. - * - * @return Pointer to predicate. - */ - const IgnitePredicate* GetPredicate() const; - - /** - * Get a topology by version. - * - * @param version Topology version. - * @return Nodes collection for the requested topology version. - */ - std::vector GetTopology(int64_t version); - - /** - * Get current topology version. - * - * @return Current topology version. - */ - int64_t GetTopologyVersion(); - - /** - * Get a compute processor for the cluster group. - * - * @return Compute processor instance reference. - */ - jobject GetComputeProcessor(); - - private: - IGNITE_NO_COPY_ASSIGNMENT(ClusterGroupImpl); - - /** - * Get cluster group without cluster nodes. - * - * @return Pointer to cluster group. - */ - SP_ClusterGroupImpl GetEmptyClusterGroup(); - - /** - * Cluster group over nodes that have specified cache running. - * - * @param cache name to include into cluster group. - * @param operation id. - * @return Pointer to cluster group. - */ - SP_ClusterGroupImpl ForCacheNodes(std::string name, int32_t op); - - /** - * Make cluster group using java reference and - * internal state of this cluster group. - * - * @param javaRef Java reference to cluster group to be created. - * @return Pointer to cluster group. - */ - SP_ClusterGroupImpl FromTarget(jobject javaRef); - - /** - * Read cluster nodes from stream. - * - * @return Pointer to container of cluster nodes. - */ - SP_ClusterNodes ReadNodes(binary::BinaryReaderImpl& reader); - - /** - * Set predicate holder for given cluster group. - * - * @param predHolder Pointer to cluster node predicate - */ - void SetPredicate(SP_PredicateHolder predHolder); - - /** - * Get container of refreshed cluster nodes over this cluster group. - * - * @return Cluster nodes. - */ - std::vector RefreshNodes(); - - /** Cluster node predicate. */ - SP_PredicateHolder predHolder; - - /** Cluster nodes. */ - SP_ClusterNodes nodes; - - /** Cluster nodes lock. */ - common::concurrent::CriticalSection nodesLock; - - /** Cluster nodes top version. */ - int64_t topVer; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_CLUSTER_CLUSTER_GROUP_IMPL +namespace ignite { +namespace odbc { +/* Forward declaration of interfaces. */ +namespace cluster { +class ClusterGroup; +class ClusterNode; +} // namespace cluster + +namespace impl { +namespace cluster { +/* Forward declaration. */ +class ClusterGroupImpl; +class ClusterNodePredicateHolder; + +/* Shared pointer. */ +typedef common::concurrent::SharedPointer< ClusterGroupImpl > + SP_ClusterGroupImpl; + +/** + * Cluster group implementation. + */ +class IGNITE_FRIEND_EXPORT ClusterGroupImpl : private interop::InteropTarget { + typedef common::concurrent::SharedPointer< IgniteEnvironment > + SP_IgniteEnvironment; + typedef common::concurrent::SharedPointer< + std::vector< ignite::odbc::cluster::ClusterNode > > + SP_ClusterNodes; + typedef common::concurrent::SharedPointer< ClusterNodePredicateHolder > + SP_PredicateHolder; + + public: + /** + * Constructor used to create new instance. + * + * @param env Environment. + * @param javaRef Reference to java object. + */ + ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef); + + /** + * Destructor. + */ + ~ClusterGroupImpl(); + + /** + * Get cluster group for nodes containing given name and value specified in + * user attributes. + * + * @param name Name of the attribute. + * @param val Optional attribute value to match. + * @return Pointer to cluster group for nodes containing specified attribute. + */ + SP_ClusterGroupImpl ForAttribute(std::string name, std::string val); + + /** + * Get cluster group for all nodes that have cache with specified name, either + * in client or server modes. + * + * @param cacheName Cache name. + * @return Pointer to cluster group over nodes that have the cache with the + * specified name running. + */ + SP_ClusterGroupImpl ForCacheNodes(std::string cacheName); + + /** + * Get cluster group for all client nodes that access cache with the specified + * name. + * + * @param cacheName Cache name. + * @return Pointer to cluster group over nodes that have the cache with the + * specified name running. + */ + SP_ClusterGroupImpl ForClientNodes(std::string cacheName); + + /** + * Get a cluster group of nodes started in client mode. + * + * @return Pointer to cluster group over nodes that started in client mode. + */ + SP_ClusterGroupImpl ForClients(); + + /** + * Get a cluster group consisting from the daemon nodes + * + * @return Pointer to cluster group over nodes started in daemon mode. + */ + SP_ClusterGroupImpl ForDaemons(); + + /** + * Get cluster group for all data nodes that have the cache with the specified + * name running. + * + * @param cacheName Cache name. + * @return Pointer to cluster group over nodes that have the cache with the + * specified name running. + */ + SP_ClusterGroupImpl ForDataNodes(std::string cacheName); + + /** + * Get cluster group consisting from the nodes in this cluster group residing + * on the same host as the given node. + * + * @param node Cluster node. + * @return Pointer to cluster group residing on the same host as the given + * node. + */ + SP_ClusterGroupImpl ForHost(ignite::odbc::cluster::ClusterNode node); + + /** + * Get cluster group consisting from the nodes running on the host specified. + * + * @param hostName Host name. + * @return Pointer to cluster group over nodes that have requested host name. + */ + SP_ClusterGroupImpl ForHost(std::string hostName); + + /** + * Get cluster group consisting from the nodes running on the hosts specified. + * + * @param hostNames Container of host names. + * @return Pointer to cluster group over nodes that have requested host names. + */ + SP_ClusterGroupImpl ForHosts(std::vector< std::string > hostNames); + + /** + * Get cluster group for the given node. + * + * @param node Cluster node. + * @return Pointer to cluster group for the given node. + */ + SP_ClusterGroupImpl ForNode(ignite::odbc::cluster::ClusterNode node); + + /** + * Get cluster group for a node with the specified ID. + * + * @param id Cluster node ID. + * @return Pointer to cluster group for a node with the specified ID. + */ + SP_ClusterGroupImpl ForNodeId(Guid id); + + /** + * Get cluster group over nodes with specified node IDs. + * + * @param ids Cluster node IDs. + * @return Pointer to cluster group over nodes with specified node IDs. + */ + SP_ClusterGroupImpl ForNodeIds(std::vector< Guid > ids); + + /** + * Get cluster group over a given set of nodes. + * + * @param nodes Cluster nodes. + * @return Pointer to cluster group over a given set of nodes. + */ + SP_ClusterGroupImpl ForNodes( + std::vector< ignite::odbc::cluster::ClusterNode > nodes); + + /** + * Get cluster group with one oldest node from the current cluster group. + * + * @return Pointer to cluster group with one oldest node from the current + * cluster group. + */ + SP_ClusterGroupImpl ForOldest(); + + /** + * Create a new cluster group which includes all nodes that pass the given + * predicate filter. + * + * @param pred Pointer to predicate heap object. + * @return Pointer to newly created cluster group. + * + * @throw IgniteError if there are no nodes in the cluster group. + */ + SP_ClusterGroupImpl ForPredicate( + IgnitePredicate< ignite::odbc::cluster::ClusterNode >* pred); + + /** + * Get cluster group with one random node from the current cluster group. + * + * @return Pointer to cluster group with one random node from the current + * cluster group. + */ + SP_ClusterGroupImpl ForRandom(); + + /** + * Get cluster group consisting from the nodes in this cluster group excluding + * the local node. + * + * @return Pointer to cluster group consisting from the nodes in this cluster + * group excluding the local node. + */ + SP_ClusterGroupImpl ForRemotes(); + + /** + * Creates a cluster group of nodes started in server mode. + * + * @return Pointer to cluster group of nodes started in server mode. + */ + SP_ClusterGroupImpl ForServers(); + + /** + * Get cluster group with one youngest node in the current cluster group. + * + * @return Pointer to cluster group with one youngest node in the current + * cluster group. + */ + SP_ClusterGroupImpl ForYoungest(); + + /** + * Creates a cluster group of cpp nodes. + * + * @return Pointer to cluster group of cpp nodes. + */ + SP_ClusterGroupImpl ForCpp(); + + /** + * Get a cluster group consisting from the local node. + * + * @return Pointer to cluster group consisting from the local node. + */ + SP_ClusterGroupImpl ForLocal(); + + /** + * Get local grid node. + * + * @return Local node. + */ + ignite::odbc::cluster::ClusterNode GetLocalNode(); + + /** + * Get first node from the list of nodes in this cluster group. + * + * @return Cluster node in this cluster group. + * + * @throw IgniteError if there are no nodes in the cluster group. + */ + ignite::odbc::cluster::ClusterNode GetNode(); + + /** + * Get node for given ID from this cluster group. + * + * @param nid Cluster node ID. + * @return Cluster node in this cluster group. + * + * @throw IgniteError if there is no node with specified ID. + */ + ignite::odbc::cluster::ClusterNode GetNode(Guid nid); + + /** + * Get the vector of nodes in this cluster group. + * + * @return All nodes in this cluster group. + */ + std::vector< ignite::odbc::cluster::ClusterNode > GetNodes(); + + /** + * Check if the Ignite grid is active. + * + * @return True if grid is active and false otherwise. + */ + bool IsActive(); + + /** + * Change Ignite grid state to active or inactive. + * + * @param active If true start activation process. If false start + * deactivation process. + */ + void SetActive(bool active); + + /** + * Disable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void DisableWal(std::string cacheName); + + /** + * Enable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void EnableWal(std::string cacheName); + + /** + * Check if write - ahead logging is enabled for specified cache. + * + * @param cacheName Cache name. + * + * @return True if enabled. + */ + bool IsWalEnabled(std::string cacheName); + + /** + * Set baseline topology constructed from the cluster topology of the given + * version. The method succeeds only if the cluster topology has not changed. + * + * @param topVer Topology version. + */ + void SetBaselineTopologyVersion(int64_t topVer); + + /** + * Set transaction timeout on partition map exchange. + * + * @param timeout Timeout in milliseconds. + */ + void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); + + /** + * Ping node. + * + * @param nid Cluster node ID. + * @return True in case of success. + */ + bool PingNode(Guid nid); + + /** + * Get predicate that defines a subset of nodes for this cluster group. + * + * @return Pointer to predicate. + */ + IgnitePredicate< ignite::odbc::cluster::ClusterNode >* GetPredicate(); + + /** + * Get predicate that defines a subset of nodes for this cluster group. + * + * @return Pointer to predicate. + */ + const IgnitePredicate< ignite::odbc::cluster::ClusterNode >* GetPredicate() + const; + + /** + * Get a topology by version. + * + * @param version Topology version. + * @return Nodes collection for the requested topology version. + */ + std::vector< ignite::odbc::cluster::ClusterNode > GetTopology( + int64_t version); + + /** + * Get current topology version. + * + * @return Current topology version. + */ + int64_t GetTopologyVersion(); + + /** + * Get a compute processor for the cluster group. + * + * @return Compute processor instance reference. + */ + jobject GetComputeProcessor(); + + private: + IGNITE_NO_COPY_ASSIGNMENT(ClusterGroupImpl); + + /** + * Get cluster group without cluster nodes. + * + * @return Pointer to cluster group. + */ + SP_ClusterGroupImpl GetEmptyClusterGroup(); + + /** + * Cluster group over nodes that have specified cache running. + * + * @param cache name to include into cluster group. + * @param operation id. + * @return Pointer to cluster group. + */ + SP_ClusterGroupImpl ForCacheNodes(std::string name, int32_t op); + + /** + * Make cluster group using java reference and + * internal state of this cluster group. + * + * @param javaRef Java reference to cluster group to be created. + * @return Pointer to cluster group. + */ + SP_ClusterGroupImpl FromTarget(jobject javaRef); + + /** + * Read cluster nodes from stream. + * + * @return Pointer to container of cluster nodes. + */ + SP_ClusterNodes ReadNodes(binary::BinaryReaderImpl& reader); + + /** + * Set predicate holder for given cluster group. + * + * @param predHolder Pointer to cluster node predicate + */ + void SetPredicate(SP_PredicateHolder predHolder); + + /** + * Get container of refreshed cluster nodes over this cluster group. + * + * @return Cluster nodes. + */ + std::vector< ignite::odbc::cluster::ClusterNode > RefreshNodes(); + + /** Cluster node predicate. */ + SP_PredicateHolder predHolder; + + /** Cluster nodes. */ + SP_ClusterNodes nodes; + + /** Cluster nodes lock. */ + common::concurrent::CriticalSection nodesLock; + + /** Cluster nodes top version. */ + int64_t topVer; +}; +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CLUSTER_CLUSTER_GROUP_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cluster/cluster_node_impl.h b/src/odbc/include/ignite/odbc/impl/cluster/cluster_node_impl.h index 6e5c62f12..b4a106073 100644 --- a/src/odbc/include/ignite/odbc/impl/cluster/cluster_node_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cluster/cluster_node_impl.h @@ -26,216 +26,212 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cluster - { - /* Forward declaration. */ - class ClusterNodeImpl; - - /* Shared pointer. */ - typedef common::concurrent::SharedPointer SP_ClusterNodeImpl; - - /** - * Cluster node implementation. - */ - class IGNITE_FRIEND_EXPORT ClusterNodeImpl - { - public: - /** - * Constructor used to create new instance. - * - * @param mem Memory to read Cluster Node. - */ - ClusterNodeImpl(common::concurrent::SharedPointer mem); - - /** - * Destructor. - */ - ~ClusterNodeImpl(); - - /** - * Get collection of addresses this node is known by. - * - * @return Collection of addresses this node is known by. - */ - const std::vector& GetAddresses() const; - - /** - * Check if node attribute is set. - * - * @param name Node attribute name. - * @return True if set. - */ - bool IsAttributeSet(std::string name) const; - - /** - * Get a node attribute. - * - * @param name Node attribute name. - * @return Node attribute. - * - * @throw IgniteError in case of attribute name does not exist - * or if template type is not compatible with attribute. - */ - template - T GetAttribute(std::string name) const - { - if (attrs.Get()->find(name) == attrs.Get()->end()) - { - const char* msg = "There is no Cluster Node attribute with name requested"; - throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); - } - - interop::InteropInputStream stream(const_cast(mem.Get())); - stream.Position(attrs.Get()->find(name)->second); - - binary::BinaryReaderImpl reader(&stream); - - return reader.ReadObject(); - } - - /** - * Get collection of all Cluster Node attributes names. - * - * @return Node attributes names collection. - */ - std::vector GetAttributes() const; - - /** - * Get Cluster Node consistent ID. - * - * @return Cluster Node consistent ID. - */ - std::string GetConsistentId() const; - - /** - * Get collection of host names this node is known by. - * - * @return Collection of host names this node is known by. - */ - const std::vector& GetHostNames() const; - - /** - * Get globally unique ID. - * - * @return Cluster Node Guid. - */ - Guid GetId() const; - - /** - * Check if cluster node started in client mode. - * - * @return True if in client mode and false otherwise. - */ - bool IsClient() const; - - /** - * Check whether or not this node is a daemon. - * - * @return True if is daemon and false otherwise. - */ - bool IsDaemon() const; - - /** - * Check whether or not this node is a local. - * - * @return True if is local and false otherwise. - */ - bool IsLocal() const; - - /** - * Node order within grid topology. - * - * @return Node order. - */ - int64_t GetOrder() const; - - /** - * Get node version. - * - * @return Prodcut version. - */ - const IgniteProductVersion& GetVersion() const; - - private: - IGNITE_NO_COPY_ASSIGNMENT(ClusterNodeImpl); - - /** - * Read Cluster Node addresses. - * - * @param reader Binary Reader. - */ - void ReadAddresses(binary::BinaryReaderImpl& reader); - - /** - * Read Cluster Node attributes. - * - * @param reader Binary Reader. - */ - void ReadAttributes(binary::BinaryReaderImpl& reader); - - /** - * Read Cluster Node hosts. - * - * @param reader Binary Reader. - */ - void ReadHosts(binary::BinaryReaderImpl& reader); - - /** - * Read Cluster Node consistent ID. - * - * @param reader Binary Reader. - */ - void ReadConsistentId(binary::BinaryReaderImpl& reader); - - /** - * Read Cluster Node product version. - * - * @param reader Binary Reader. - */ - void ReadProductVersion(binary::BinaryReaderImpl& reader); - - /** Cluster Node mem */ - common::concurrent::SharedPointer mem; - - /** Addresses. */ - common::concurrent::SharedPointer > addrs; - - /** Attributes. */ - common::concurrent::SharedPointer > attrs; - - /** Hosts. */ - common::concurrent::SharedPointer > hosts; - - /** Node ID. */ - Guid id; - - /** Is node started in client mode. */ - bool isClient; - - /** Is node started in daemon mode. */ - bool isDaemon; - - /** Is node local. */ - bool isLocal; - - /** Order. */ - int64_t order; - - /** Consistent ID */ - common::concurrent::SharedPointer consistentId; - - /** Product version. */ - common::concurrent::SharedPointer ver; - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cluster { +/* Forward declaration. */ +class ClusterNodeImpl; + +/* Shared pointer. */ +typedef common::concurrent::SharedPointer< ClusterNodeImpl > SP_ClusterNodeImpl; + +/** + * Cluster node implementation. + */ +class IGNITE_FRIEND_EXPORT ClusterNodeImpl { + public: + /** + * Constructor used to create new instance. + * + * @param mem Memory to read Cluster Node. + */ + ClusterNodeImpl( + common::concurrent::SharedPointer< interop::InteropMemory > mem); + + /** + * Destructor. + */ + ~ClusterNodeImpl(); + + /** + * Get collection of addresses this node is known by. + * + * @return Collection of addresses this node is known by. + */ + const std::vector< std::string >& GetAddresses() const; + + /** + * Check if node attribute is set. + * + * @param name Node attribute name. + * @return True if set. + */ + bool IsAttributeSet(std::string name) const; + + /** + * Get a node attribute. + * + * @param name Node attribute name. + * @return Node attribute. + * + * @throw IgniteError in case of attribute name does not exist + * or if template type is not compatible with attribute. + */ + template < typename T > + T GetAttribute(std::string name) const { + if (attrs.Get()->find(name) == attrs.Get()->end()) { + const char* msg = + "There is no Cluster Node attribute with name requested"; + throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); } -} -#endif //_IGNITE_ODBC_IMPL_CLUSTER_CLUSTER_NODE_IMPL + interop::InteropInputStream stream( + const_cast< interop::InteropMemory* >(mem.Get())); + stream.Position(attrs.Get()->find(name)->second); + + binary::BinaryReaderImpl reader(&stream); + + return reader.ReadObject< T >(); + } + + /** + * Get collection of all Cluster Node attributes names. + * + * @return Node attributes names collection. + */ + std::vector< std::string > GetAttributes() const; + + /** + * Get Cluster Node consistent ID. + * + * @return Cluster Node consistent ID. + */ + std::string GetConsistentId() const; + + /** + * Get collection of host names this node is known by. + * + * @return Collection of host names this node is known by. + */ + const std::vector< std::string >& GetHostNames() const; + + /** + * Get globally unique ID. + * + * @return Cluster Node Guid. + */ + Guid GetId() const; + + /** + * Check if cluster node started in client mode. + * + * @return True if in client mode and false otherwise. + */ + bool IsClient() const; + + /** + * Check whether or not this node is a daemon. + * + * @return True if is daemon and false otherwise. + */ + bool IsDaemon() const; + + /** + * Check whether or not this node is a local. + * + * @return True if is local and false otherwise. + */ + bool IsLocal() const; + + /** + * Node order within grid topology. + * + * @return Node order. + */ + int64_t GetOrder() const; + + /** + * Get node version. + * + * @return Prodcut version. + */ + const IgniteProductVersion& GetVersion() const; + + private: + IGNITE_NO_COPY_ASSIGNMENT(ClusterNodeImpl); + + /** + * Read Cluster Node addresses. + * + * @param reader Binary Reader. + */ + void ReadAddresses(binary::BinaryReaderImpl& reader); + + /** + * Read Cluster Node attributes. + * + * @param reader Binary Reader. + */ + void ReadAttributes(binary::BinaryReaderImpl& reader); + + /** + * Read Cluster Node hosts. + * + * @param reader Binary Reader. + */ + void ReadHosts(binary::BinaryReaderImpl& reader); + + /** + * Read Cluster Node consistent ID. + * + * @param reader Binary Reader. + */ + void ReadConsistentId(binary::BinaryReaderImpl& reader); + + /** + * Read Cluster Node product version. + * + * @param reader Binary Reader. + */ + void ReadProductVersion(binary::BinaryReaderImpl& reader); + + /** Cluster Node mem */ + common::concurrent::SharedPointer< interop::InteropMemory > mem; + + /** Addresses. */ + common::concurrent::SharedPointer< std::vector< std::string > > addrs; + + /** Attributes. */ + common::concurrent::SharedPointer< std::map< std::string, int32_t > > attrs; + + /** Hosts. */ + common::concurrent::SharedPointer< std::vector< std::string > > hosts; + + /** Node ID. */ + Guid id; + + /** Is node started in client mode. */ + bool isClient; + + /** Is node started in daemon mode. */ + bool isDaemon; + + /** Is node local. */ + bool isLocal; + + /** Order. */ + int64_t order; + + /** Consistent ID */ + common::concurrent::SharedPointer< std::string > consistentId; + + /** Product version. */ + common::concurrent::SharedPointer< IgniteProductVersion > ver; +}; +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CLUSTER_CLUSTER_NODE_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/cluster/ignite_cluster_impl.h b/src/odbc/include/ignite/odbc/impl/cluster/ignite_cluster_impl.h index 3fcd372c8..e116b2f26 100644 --- a/src/odbc/include/ignite/odbc/impl/cluster/ignite_cluster_impl.h +++ b/src/odbc/include/ignite/odbc/impl/cluster/ignite_cluster_impl.h @@ -26,138 +26,134 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cluster - { - /** - * Ignite cluster implementation. - */ - class IGNITE_FRIEND_EXPORT IgniteClusterImpl - { - public: - /** - * Constructor used to create new instance. - * - * @param impl Pointer to ClusterGroupImpl. - */ - IgniteClusterImpl(SP_ClusterGroupImpl impl); - - /** - * Destructor. - */ - ~IgniteClusterImpl(); - - /** - * Check if the Ignite grid is active. - * - * @return True if grid is active and false otherwise. - */ - bool IsActive(); - - /** - * Change Ignite grid state to active or inactive. - * - * @param active If true start activation process. If false start - * deactivation process. - */ - void SetActive(bool active); - - /** - * Disable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void DisableWal(std::string cacheName); - - /** - * Enable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void EnableWal(std::string cacheName); - - /** - * Check if write - ahead logging is enabled for specified cache. - * - * @param cacheName Cache name. - * - * @return True if enabled. - */ - bool IsWalEnabled(std::string cacheName); - - /** - * Get a cluster group consisting from the local node. - * - * @return Cluster group consisting from the local node. - */ - ignite::odbc::cluster::ClusterGroup ForLocal(); - - /** - * Get local grid node. - * - * @return Local node. - */ - ignite::odbc::cluster::ClusterNode GetLocalNode(); - - /** - * Set baseline topology constructed from the cluster topology of the given version. - * The method succeeds only if the cluster topology has not changed. - * - * @param topVer Topology version. - */ - void SetBaselineTopologyVersion(int64_t topVer); - - /** - * Set transaction timeout on partition map exchange. - * - * @param timeout Timeout in milliseconds. - */ - void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); - - /** - * Ping node. - * - * @param nid Cluster node ID. - * @return True in case of success. - */ - bool PingNode(Guid nid); - - /** - * Get a topology by version. - * - * @param version Topology version. - * @return Nodes collection for the requested topology version. - */ - std::vector GetTopology(int64_t version); - - /** - * Get current topology version. - * - * @return Current topology version. - */ - int64_t GetTopologyVersion(); - - /** - * Get cluster group consisting of all cluster nodes. - * - * @return ClusterGroupImpl instance. - */ - SP_ClusterGroupImpl AsClusterGroup(); - - private: - IGNITE_NO_COPY_ASSIGNMENT(IgniteClusterImpl); - - /** Implementation. */ - SP_ClusterGroupImpl impl; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_CLUSTER_IGNITE_ODBC_CLUSTER_IMPL +namespace ignite { +namespace odbc { +namespace impl { +namespace cluster { +/** + * Ignite cluster implementation. + */ +class IGNITE_FRIEND_EXPORT IgniteClusterImpl { + public: + /** + * Constructor used to create new instance. + * + * @param impl Pointer to ClusterGroupImpl. + */ + IgniteClusterImpl(SP_ClusterGroupImpl impl); + + /** + * Destructor. + */ + ~IgniteClusterImpl(); + + /** + * Check if the Ignite grid is active. + * + * @return True if grid is active and false otherwise. + */ + bool IsActive(); + + /** + * Change Ignite grid state to active or inactive. + * + * @param active If true start activation process. If false start + * deactivation process. + */ + void SetActive(bool active); + + /** + * Disable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void DisableWal(std::string cacheName); + + /** + * Enable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void EnableWal(std::string cacheName); + + /** + * Check if write - ahead logging is enabled for specified cache. + * + * @param cacheName Cache name. + * + * @return True if enabled. + */ + bool IsWalEnabled(std::string cacheName); + + /** + * Get a cluster group consisting from the local node. + * + * @return Cluster group consisting from the local node. + */ + ignite::odbc::cluster::ClusterGroup ForLocal(); + + /** + * Get local grid node. + * + * @return Local node. + */ + ignite::odbc::cluster::ClusterNode GetLocalNode(); + + /** + * Set baseline topology constructed from the cluster topology of the given + * version. The method succeeds only if the cluster topology has not changed. + * + * @param topVer Topology version. + */ + void SetBaselineTopologyVersion(int64_t topVer); + + /** + * Set transaction timeout on partition map exchange. + * + * @param timeout Timeout in milliseconds. + */ + void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); + + /** + * Ping node. + * + * @param nid Cluster node ID. + * @return True in case of success. + */ + bool PingNode(Guid nid); + + /** + * Get a topology by version. + * + * @param version Topology version. + * @return Nodes collection for the requested topology version. + */ + std::vector< ignite::odbc::cluster::ClusterNode > GetTopology( + int64_t version); + + /** + * Get current topology version. + * + * @return Current topology version. + */ + int64_t GetTopologyVersion(); + + /** + * Get cluster group consisting of all cluster nodes. + * + * @return ClusterGroupImpl instance. + */ + SP_ClusterGroupImpl AsClusterGroup(); + + private: + IGNITE_NO_COPY_ASSIGNMENT(IgniteClusterImpl); + + /** Implementation. */ + SP_ClusterGroupImpl impl; +}; +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_CLUSTER_IGNITE_ODBC_CLUSTER_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/compute/cancelable_impl.h b/src/odbc/include/ignite/odbc/impl/compute/cancelable_impl.h index 58d641f48..c807b62d7 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/cancelable_impl.h +++ b/src/odbc/include/ignite/odbc/impl/compute/cancelable_impl.h @@ -27,47 +27,43 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute implementation. - */ - class IGNITE_IMPORT_EXPORT CancelableImpl : public interop::InteropTarget, public common::Cancelable - { - public: - /** - * Constructor. - * - * @param env Environment. - * @param javaRef Java object reference. - */ - CancelableImpl(common::concurrent::SharedPointer env, jobject javaRef); - - /** - * Destructor. - */ - virtual ~CancelableImpl() - { - // No-op. - } - - /** - * Cancels the operation. - */ - virtual void Cancel(); - - private: - IGNITE_NO_COPY_ASSIGNMENT(CancelableImpl); - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute implementation. + */ +class IGNITE_IMPORT_EXPORT CancelableImpl : public interop::InteropTarget, + public common::Cancelable { + public: + /** + * Constructor. + * + * @param env Environment. + * @param javaRef Java object reference. + */ + CancelableImpl(common::concurrent::SharedPointer< IgniteEnvironment > env, + jobject javaRef); + + /** + * Destructor. + */ + virtual ~CancelableImpl() { + // No-op. + } + + /** + * Cancels the operation. + */ + virtual void Cancel(); + + private: + IGNITE_NO_COPY_ASSIGNMENT(CancelableImpl); +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_CANCELABLE_IMPL +#endif //_IGNITE_ODBC_IMPL_COMPUTE_CANCELABLE_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/compute/compute_impl.h b/src/odbc/include/ignite/odbc/impl/compute/compute_impl.h index a08b1f46c..2f635533e 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/compute_impl.h +++ b/src/odbc/include/ignite/odbc/impl/compute/compute_impl.h @@ -35,557 +35,570 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute implementation. - */ - class IGNITE_IMPORT_EXPORT ComputeImpl : public interop::InteropTarget - { - public: - /** - * Operation type. - */ - struct Operation - { - enum Type - { - BROADCAST = 2, - - EXEC = 3, - - EXEC_ASYNC = 4, - - UNICAST = 5, - - AFFINITY_CALL = 13, - - AFFINITY_RUN = 14 - }; - }; - - /** - * Constructor. - * - * @param env Environment. - * @param clusterGroup Cluster group for the compute. - */ - ComputeImpl(common::concurrent::SharedPointer env, - cluster::SP_ClusterGroupImpl clusterGroup); - - /** - * Executes given job asynchronously on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::AffinityRun(). - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache name to use for affinity co-location. - * @param key Affinity key. - * @param func Compute function to call. - * @return Future that can be used to access computation result once - * it's ready. - * @throw IgniteError in case of error. - */ - template - Future AffinityCallAsync(const std::string& cacheName, const K& key, const F& func) - { - typedef ComputeJobHolderImpl JobType; - typedef SingleJobComputeTaskHolder TaskType; - - return PerformAffinityTask(cacheName, key, func, Operation::AFFINITY_CALL); - } - - /** - * Executes given job asynchronously on the node where data for - * provided affinity key is located (a.k.a. affinity co-location). - * - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement ComputeFunc - * class. - * @param cacheName Cache names to use for affinity co-location. - * @param key Affinity key. - * @param action Compute action to call. - * @return Future that can be used to access computation result once - * it's ready. - * @throw IgniteError in case of error. - */ - template - Future AffinityRunAsync(const std::string& cacheName, const K& key, const F& action) - { - typedef ComputeJobHolderImpl JobType; - typedef SingleJobComputeTaskHolder TaskType; - - return PerformAffinityTask(cacheName, key, action, Operation::AFFINITY_RUN); - } - - /** - * Asynchronously calls provided ComputeFunc on a node within - * the underlying cluster group. - * - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * @tparam R Call return type. BinaryType should be specialized - * for the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::Run(). - * @param func Compute function to call. - * @return Future that can be used to access computation result - * once it's ready. - */ - template - Future CallAsync(const F& func) - { - typedef ComputeJobHolderImpl JobType; - typedef SingleJobComputeTaskHolder TaskType; - - return PerformTask(Operation::UNICAST, func); - } - - /** - * Asynchronously runs provided ComputeFunc on a node within - * the underlying cluster group. - * - * @tparam F Compute action type. Should implement - * ComputeFunc class. - * @param action Compute action to call. - * @return Future that can be used to wait for action - * to complete. - */ - template - Future RunAsync(const F& action) - { - typedef ComputeJobHolderImpl JobType; - typedef SingleJobComputeTaskHolder TaskType; - - return PerformTask(Operation::UNICAST, action); - } - - /** - * Asynchronously broadcasts provided ComputeFunc to all nodes - * in the underlying cluster group. - * - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * @tparam R Call return type. BinaryType should be specialized - * for the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::Run(). - * @param func Compute function to call. - * @return Future that can be used to access computation result - * once it's ready. - */ - template - Future< std::vector > BroadcastAsync(const F& func) - { - typedef ComputeJobHolderImpl JobType; - typedef MultipleJobComputeTaskHolder TaskType; - - return PerformTask, F, JobType, TaskType>(Operation::BROADCAST, func); - } - - /** - * Asynchronously broadcasts provided ComputeFunc to all nodes - * in the underlying cluster group. - * - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * @param func Compute function to call. - * @return Future that can be used to access computation result - * once it's ready. - */ - template - Future BroadcastAsync(const F& func) - { - typedef ComputeJobHolderImpl JobType; - typedef MultipleJobComputeTaskHolder TaskType; - - return PerformTask(Operation::BROADCAST, func); - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - R ExecuteJavaTask(const std::string& taskName, const A& taskArg) - { - return PerformJavaTask(taskName, &taskArg); - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - */ - template - R ExecuteJavaTask(const std::string& taskName) - { - return PerformJavaTask(taskName, 0); - } - - /** - * Asynchronously executes given Java task on the grid projection. If task for given name has not been - * deployed yet, then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @return Future containing a result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - Future ExecuteJavaTaskAsync(const std::string& taskName, const A& taskArg) - { - return PerformJavaTaskAsync(taskName, &taskArg); - } - - /** - * Asynchronously executes given Java task on the grid projection. If task for given name has not been - * deployed yet, then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @return Future containing a result of type @c R. - * - * @tparam R Type of task result. - */ - template - Future ExecuteJavaTaskAsync(const std::string& taskName) - { - return PerformJavaTaskAsync(taskName, 0); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ComputeImpl); - - struct FutureType - { - enum Type - { - F_BYTE = 1, - F_BOOL = 2, - F_SHORT = 3, - F_CHAR = 4, - F_INT = 5, - F_FLOAT = 6, - F_LONG = 7, - F_DOUBLE = 8, - F_OBJECT = 9, - }; - }; - - template struct FutureTypeForType { static const int32_t value = FutureType::F_OBJECT; }; - - /** - * @return True if projection for the compute contains predicate. - */ - bool ProjectionContainsPredicate() const; - - /** - * @return Nodes for the compute. - */ - std::vector GetNodes(); - - /** - * Write Java task using provided writer. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @param writer Binary writer. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - void WriteJavaTask(const std::string& taskName, const A* arg, binary::BinaryWriterImpl& writer) { - writer.WriteString(taskName); - - // Keep binary flag - writer.WriteBool(false); - if (arg) - writer.WriteObject(*arg); - else - writer.WriteNull(); - - if (!ProjectionContainsPredicate()) - writer.WriteBool(false); - else - { - typedef std::vector ClusterNodes; - ClusterNodes nodes = GetNodes(); - - writer.WriteBool(true); - writer.WriteInt32(static_cast(nodes.size())); - for (ClusterNodes::iterator it = nodes.begin(); it != nodes.end(); ++it) - writer.WriteGuid(it->GetId()); - } - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param taskArg Argument of task execution of type A. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - R PerformJavaTask(const std::string& taskName, const A* arg) - { - using namespace common::concurrent; - - SharedPointer memIn = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - WriteJavaTask(taskName, arg, writer); - - out.Synchronize(); - - SharedPointer memOut = GetEnvironment().AllocateMemory(); - - IgniteError err; - InStreamOutStream(Operation::EXEC, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - return reader.ReadObject(); - } - - /** - * Executes given Java task on the grid projection. If task for given name has not been deployed yet, - * then 'taskName' will be used as task class name to auto-deploy the task. - * - * @param taskName Java task name. - * @param arg Argument of task execution of type A. - * @return Task result of type @c R. - * - * @tparam R Type of task result. - * @tparam A Type of task argument. - */ - template - Future PerformJavaTaskAsync(const std::string& taskName, const A* arg) - { - typedef JavaComputeTaskHolder TaskHolder; - common::concurrent::SharedPointer task(new TaskHolder()); - int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); - - common::concurrent::SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - WriteJavaTask(taskName, arg, writer); - - writer.WriteInt64(taskHandle); - writer.WriteInt32(FutureTypeForType::value); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(Operation::EXEC_ASYNC, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - std::shared_ptr cancelable(new CancelableImpl(GetEnvironmentPointer(), target)); - - common::Promise& promise = task.Get()->GetPromise(); - promise.SetCancelTarget(cancelable); - - return promise.GetFuture(); - } - - /** - * Perform job. - * - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * @tparam R Call return type. BinaryType should be specialized - * for the type if it is not primitive. - * @tparam J Job type. - * @tparam T Task type. - * - * @param operation Operation type. - * @param func Function. - * @return Future that can be used to access computation result - * once it's ready. - */ - template - Future PerformTask(Operation::Type operation, const F& func) - { - common::concurrent::SharedPointer job(new J(func)); - - int64_t jobHandle = GetEnvironment().GetHandleRegistry().Allocate(job); - - T* taskPtr = new T(jobHandle); - common::concurrent::SharedPointer task(taskPtr); - - int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); - - std::shared_ptr cancelable = PerformTask(operation, jobHandle, taskHandle, func); - - common::Promise& promise = taskPtr->GetPromise(); - promise.SetCancelTarget(cancelable); - - return promise.GetFuture(); - } - - /** - * Perform job. - * - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * - * @param operation Operation type. - * @param jobHandle Job Handle. - * @param taskHandle Task Handle. - * @param func Function. - * @return Cancelable auto pointer. - */ - template - std::shared_ptr PerformTask(Operation::Type operation, int64_t jobHandle, - int64_t taskHandle, const F& func) - { - common::concurrent::SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteInt64(taskHandle); - writer.WriteInt32(1); - writer.WriteInt64(jobHandle); - writer.WriteObject(func); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(operation, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - std::shared_ptr cancelable(new CancelableImpl(GetEnvironmentPointer(), target)); - - return cancelable; - } - - /** - * Perform job in case of cache affinity. - * - * @tparam R Call return type. BinaryType should be specialized for - * the type if it is not primitive. Should not be void. For - * non-returning methods see Compute::AffinityRun(). - * @tparam K Affinity key type. - * @tparam F Compute function type. Should implement - * ComputeFunc class. - * @tparam J Job type. - * @tparam T Task type. - * @param cacheName Cache name to use for affinity co-location. - * @param key Affinity key. - * @param func Function. - * @param opType Type of the operation. - * @return Future that can be used to access computation result - * once it's ready. - */ - template - Future PerformAffinityTask(const std::string& cacheName, - const K& key, const F& func, Operation::Type opType) - { - enum { TYP_OBJ = 9 }; - - common::concurrent::SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - common::concurrent::SharedPointer job(new J(func)); - - int64_t jobHandle = GetEnvironment().GetHandleRegistry().Allocate(job); - - T* taskPtr = new T(jobHandle); - common::concurrent::SharedPointer task(taskPtr); - - int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); - - writer.WriteString(cacheName); - writer.WriteObject(key); - writer.WriteObject(func); - writer.WriteInt64(jobHandle); - writer.WriteInt64(taskHandle); - writer.WriteInt32(TYP_OBJ); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(opType, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - std::shared_ptr cancelable(new CancelableImpl(GetEnvironmentPointer(), target)); - - common::Promise& promise = taskPtr->GetPromise(); - promise.SetCancelTarget(cancelable); - - return promise.GetFuture(); - } - - /** Cluster group */ - cluster::SP_ClusterGroupImpl clusterGroup; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_BYTE; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_BOOL; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_SHORT; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_CHAR; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_INT; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_LONG; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_FLOAT; - }; - - template<> struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType { - static const int32_t value = FutureType::F_DOUBLE; - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute implementation. + */ +class IGNITE_IMPORT_EXPORT ComputeImpl : public interop::InteropTarget { + public: + /** + * Operation type. + */ + struct Operation { + enum Type { + BROADCAST = 2, + + EXEC = 3, + + EXEC_ASYNC = 4, + + UNICAST = 5, + + AFFINITY_CALL = 13, + + AFFINITY_RUN = 14 + }; + }; + + /** + * Constructor. + * + * @param env Environment. + * @param clusterGroup Cluster group for the compute. + */ + ComputeImpl(common::concurrent::SharedPointer< IgniteEnvironment > env, + cluster::SP_ClusterGroupImpl clusterGroup); + + /** + * Executes given job asynchronously on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::AffinityRun(). + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache name to use for affinity co-location. + * @param key Affinity key. + * @param func Compute function to call. + * @return Future that can be used to access computation result once + * it's ready. + * @throw IgniteError in case of error. + */ + template < typename R, typename K, typename F > + Future< R > AffinityCallAsync(const std::string& cacheName, const K& key, + const F& func) { + typedef ComputeJobHolderImpl< F, R > JobType; + typedef SingleJobComputeTaskHolder< F, R > TaskType; + + return PerformAffinityTask< R, K, F, JobType, TaskType >( + cacheName, key, func, Operation::AFFINITY_CALL); + } + + /** + * Executes given job asynchronously on the node where data for + * provided affinity key is located (a.k.a. affinity co-location). + * + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement ComputeFunc + * class. + * @param cacheName Cache names to use for affinity co-location. + * @param key Affinity key. + * @param action Compute action to call. + * @return Future that can be used to access computation result once + * it's ready. + * @throw IgniteError in case of error. + */ + template < typename K, typename F > + Future< void > AffinityRunAsync(const std::string& cacheName, const K& key, + const F& action) { + typedef ComputeJobHolderImpl< F, void > JobType; + typedef SingleJobComputeTaskHolder< F, void > TaskType; + + return PerformAffinityTask< void, K, F, JobType, TaskType >( + cacheName, key, action, Operation::AFFINITY_RUN); + } + + /** + * Asynchronously calls provided ComputeFunc on a node within + * the underlying cluster group. + * + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * @tparam R Call return type. BinaryType should be specialized + * for the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::Run(). + * @param func Compute function to call. + * @return Future that can be used to access computation result + * once it's ready. + */ + template < typename R, typename F > + Future< R > CallAsync(const F& func) { + typedef ComputeJobHolderImpl< F, R > JobType; + typedef SingleJobComputeTaskHolder< F, R > TaskType; + + return PerformTask< R, F, JobType, TaskType >(Operation::UNICAST, func); + } + + /** + * Asynchronously runs provided ComputeFunc on a node within + * the underlying cluster group. + * + * @tparam F Compute action type. Should implement + * ComputeFunc class. + * @param action Compute action to call. + * @return Future that can be used to wait for action + * to complete. + */ + template < typename F > + Future< void > RunAsync(const F& action) { + typedef ComputeJobHolderImpl< F, void > JobType; + typedef SingleJobComputeTaskHolder< F, void > TaskType; + + return PerformTask< void, F, JobType, TaskType >(Operation::UNICAST, + action); + } + + /** + * Asynchronously broadcasts provided ComputeFunc to all nodes + * in the underlying cluster group. + * + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * @tparam R Call return type. BinaryType should be specialized + * for the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::Run(). + * @param func Compute function to call. + * @return Future that can be used to access computation result + * once it's ready. + */ + template < typename R, typename F > + Future< std::vector< R > > BroadcastAsync(const F& func) { + typedef ComputeJobHolderImpl< F, R > JobType; + typedef MultipleJobComputeTaskHolder< F, R > TaskType; + + return PerformTask< std::vector< R >, F, JobType, TaskType >( + Operation::BROADCAST, func); + } + + /** + * Asynchronously broadcasts provided ComputeFunc to all nodes + * in the underlying cluster group. + * + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * @param func Compute function to call. + * @return Future that can be used to access computation result + * once it's ready. + */ + template < typename F, bool > + Future< void > BroadcastAsync(const F& func) { + typedef ComputeJobHolderImpl< F, void > JobType; + typedef MultipleJobComputeTaskHolder< F, void > TaskType; + + return PerformTask< void, F, JobType, TaskType >(Operation::BROADCAST, + func); + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + R ExecuteJavaTask(const std::string& taskName, const A& taskArg) { + return PerformJavaTask< R, A >(taskName, &taskArg); + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + */ + template < typename R > + R ExecuteJavaTask(const std::string& taskName) { + return PerformJavaTask< R, int >(taskName, 0); + } + + /** + * Asynchronously executes given Java task on the grid projection. If task for + * given name has not been deployed yet, then 'taskName' will be used as task + * class name to auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @return Future containing a result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + Future< R > ExecuteJavaTaskAsync(const std::string& taskName, + const A& taskArg) { + return PerformJavaTaskAsync< R, A >(taskName, &taskArg); + } + + /** + * Asynchronously executes given Java task on the grid projection. If task for + * given name has not been deployed yet, then 'taskName' will be used as task + * class name to auto-deploy the task. + * + * @param taskName Java task name. + * @return Future containing a result of type @c R. + * + * @tparam R Type of task result. + */ + template < typename R > + Future< R > ExecuteJavaTaskAsync(const std::string& taskName) { + return PerformJavaTaskAsync< R, int >(taskName, 0); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ComputeImpl); + + struct FutureType { + enum Type { + F_BYTE = 1, + F_BOOL = 2, + F_SHORT = 3, + F_CHAR = 4, + F_INT = 5, + F_FLOAT = 6, + F_LONG = 7, + F_DOUBLE = 8, + F_OBJECT = 9, + }; + }; + + template < typename T > + struct FutureTypeForType { + static const int32_t value = FutureType::F_OBJECT; + }; + + /** + * @return True if projection for the compute contains predicate. + */ + bool ProjectionContainsPredicate() const; + + /** + * @return Nodes for the compute. + */ + std::vector< ignite::odbc::cluster::ClusterNode > GetNodes(); + + /** + * Write Java task using provided writer. If task for given name has not been + * deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @param writer Binary writer. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename A > + void WriteJavaTask(const std::string& taskName, const A* arg, + binary::BinaryWriterImpl& writer) { + writer.WriteString(taskName); + + // Keep binary flag + writer.WriteBool(false); + if (arg) + writer.WriteObject< A >(*arg); + else + writer.WriteNull(); + + if (!ProjectionContainsPredicate()) + writer.WriteBool(false); + else { + typedef std::vector< ignite::odbc::cluster::ClusterNode > ClusterNodes; + ClusterNodes nodes = GetNodes(); + + writer.WriteBool(true); + writer.WriteInt32(static_cast< int32_t >(nodes.size())); + for (ClusterNodes::iterator it = nodes.begin(); it != nodes.end(); ++it) + writer.WriteGuid(it->GetId()); } -} + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @param taskArg Argument of task execution of type A. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + R PerformJavaTask(const std::string& taskName, const A* arg) { + using namespace common::concurrent; + + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + WriteJavaTask(taskName, arg, writer); + + out.Synchronize(); + + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + + IgniteError err; + InStreamOutStream(Operation::EXEC, *memIn.Get(), *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + return reader.ReadObject< R >(); + } + + /** + * Executes given Java task on the grid projection. If task for given name has + * not been deployed yet, then 'taskName' will be used as task class name to + * auto-deploy the task. + * + * @param taskName Java task name. + * @param arg Argument of task execution of type A. + * @return Task result of type @c R. + * + * @tparam R Type of task result. + * @tparam A Type of task argument. + */ + template < typename R, typename A > + Future< R > PerformJavaTaskAsync(const std::string& taskName, const A* arg) { + typedef JavaComputeTaskHolder< R > TaskHolder; + common::concurrent::SharedPointer< TaskHolder > task(new TaskHolder()); + int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); + + common::concurrent::SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + WriteJavaTask(taskName, arg, writer); + + writer.WriteInt64(taskHandle); + writer.WriteInt32(FutureTypeForType< R >::value); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(Operation::EXEC_ASYNC, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + std::shared_ptr< common::Cancelable > cancelable( + new CancelableImpl(GetEnvironmentPointer(), target)); + + common::Promise< R >& promise = task.Get()->GetPromise(); + promise.SetCancelTarget(cancelable); + + return promise.GetFuture(); + } + + /** + * Perform job. + * + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * @tparam R Call return type. BinaryType should be specialized + * for the type if it is not primitive. + * @tparam J Job type. + * @tparam T Task type. + * + * @param operation Operation type. + * @param func Function. + * @return Future that can be used to access computation result + * once it's ready. + */ + template < typename R, typename F, typename J, typename T > + Future< R > PerformTask(Operation::Type operation, const F& func) { + common::concurrent::SharedPointer< ComputeJobHolder > job(new J(func)); + + int64_t jobHandle = GetEnvironment().GetHandleRegistry().Allocate(job); + + T* taskPtr = new T(jobHandle); + common::concurrent::SharedPointer< ComputeTaskHolder > task(taskPtr); + + int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); + + std::shared_ptr< common::Cancelable > cancelable = + PerformTask(operation, jobHandle, taskHandle, func); + + common::Promise< R >& promise = taskPtr->GetPromise(); + promise.SetCancelTarget(cancelable); + + return promise.GetFuture(); + } + + /** + * Perform job. + * + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * + * @param operation Operation type. + * @param jobHandle Job Handle. + * @param taskHandle Task Handle. + * @param func Function. + * @return Cancelable auto pointer. + */ + template < typename F > + std::shared_ptr< common::Cancelable > PerformTask(Operation::Type operation, + int64_t jobHandle, + int64_t taskHandle, + const F& func) { + common::concurrent::SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteInt64(taskHandle); + writer.WriteInt32(1); + writer.WriteInt64(jobHandle); + writer.WriteObject< F >(func); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(operation, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + std::shared_ptr< common::Cancelable > cancelable( + new CancelableImpl(GetEnvironmentPointer(), target)); + + return cancelable; + } + + /** + * Perform job in case of cache affinity. + * + * @tparam R Call return type. BinaryType should be specialized for + * the type if it is not primitive. Should not be void. For + * non-returning methods see Compute::AffinityRun(). + * @tparam K Affinity key type. + * @tparam F Compute function type. Should implement + * ComputeFunc class. + * @tparam J Job type. + * @tparam T Task type. + * @param cacheName Cache name to use for affinity co-location. + * @param key Affinity key. + * @param func Function. + * @param opType Type of the operation. + * @return Future that can be used to access computation result + * once it's ready. + */ + template < typename R, typename K, typename F, typename J, typename T > + Future< R > PerformAffinityTask(const std::string& cacheName, const K& key, + const F& func, Operation::Type opType) { + enum { TYP_OBJ = 9 }; + + common::concurrent::SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + common::concurrent::SharedPointer< ComputeJobHolder > job(new J(func)); + + int64_t jobHandle = GetEnvironment().GetHandleRegistry().Allocate(job); + + T* taskPtr = new T(jobHandle); + common::concurrent::SharedPointer< ComputeTaskHolder > task(taskPtr); + + int64_t taskHandle = GetEnvironment().GetHandleRegistry().Allocate(task); + + writer.WriteString(cacheName); + writer.WriteObject< K >(key); + writer.WriteObject< F >(func); + writer.WriteInt64(jobHandle); + writer.WriteInt64(taskHandle); + writer.WriteInt32(TYP_OBJ); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(opType, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + std::shared_ptr< common::Cancelable > cancelable( + new CancelableImpl(GetEnvironmentPointer(), target)); + + common::Promise< R >& promise = taskPtr->GetPromise(); + promise.SetCancelTarget(cancelable); + + return promise.GetFuture(); + } + + /** Cluster group */ + cluster::SP_ClusterGroupImpl clusterGroup; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< int8_t > { + static const int32_t value = FutureType::F_BYTE; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< bool > { + static const int32_t value = FutureType::F_BOOL; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< int16_t > { + static const int32_t value = FutureType::F_SHORT; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< uint16_t > { + static const int32_t value = FutureType::F_CHAR; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< int32_t > { + static const int32_t value = FutureType::F_INT; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< int64_t > { + static const int32_t value = FutureType::F_LONG; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< float > { + static const int32_t value = FutureType::F_FLOAT; +}; + +template <> +struct IGNITE_IMPORT_EXPORT ComputeImpl::FutureTypeForType< double > { + static const int32_t value = FutureType::F_DOUBLE; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_IMPL +#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/compute/compute_job_holder.h b/src/odbc/include/ignite/odbc/impl/compute/compute_job_holder.h index c47be3960..11e0176ac 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/compute_job_holder.h +++ b/src/odbc/include/ignite/odbc/impl/compute/compute_job_holder.h @@ -26,192 +26,161 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute job holder. Internal helper class. - * Used to handle jobs in general way, without specific types. - */ - class ComputeJobHolder - { - public: - /** - * Destructor. - */ - virtual ~ComputeJobHolder() - { - // No-op. - } - - /** - * Execute job locally. - */ - virtual void ExecuteLocal(IgniteEnvironment* env) = 0; - - /** - * Execute job remote. - * - * @param writer Writer. - */ - virtual void ExecuteRemote(IgniteEnvironment* env, binary::BinaryWriterImpl& writer) = 0; - }; - - /** - * Compute job holder. Internal class. - * - * @tparam F Actual job type. - * @tparam R Job return type. - */ - template - class ComputeJobHolderImpl : public ComputeJobHolder - { - public: - typedef R ResultType; - typedef F JobType; - - /** - * Constructor. - * - * @param job Job. - */ - ComputeJobHolderImpl(JobType job) : - job(job) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~ComputeJobHolderImpl() - { - // No-op. - } - - const ComputeJobResult& GetResult() - { - return res; - } - - virtual void ExecuteLocal(IgniteEnvironment* env) - { - try - { - job.SetIgnite(env->GetIgnite()); - res.SetResult(job.Call()); - } - catch (const IgniteError& err) - { - res.SetError(err); - } - catch (const std::exception& err) - { - res.SetError(IgniteError(IgniteError::IGNITE_ERR_STD, err.what())); - } - catch (...) - { - res.SetError(IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, - "Unknown error occurred during call.")); - } - } - - virtual void ExecuteRemote(IgniteEnvironment* env, binary::BinaryWriterImpl& writer) - { - ExecuteLocal(env); - - res.Write(writer); - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Job. */ - JobType job; - }; - - /** - * Compute job holder. Internal class. - * Specialisation for void return type - * - * @tparam F Actual job type. - */ - template - class ComputeJobHolderImpl : public ComputeJobHolder - { - public: - typedef F JobType; - - /** - * Constructor. - * - * @param job Job. - */ - ComputeJobHolderImpl(JobType job) : - job(job) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~ComputeJobHolderImpl() - { - // No-op. - } - - const ComputeJobResult& GetResult() - { - return res; - } - - virtual void ExecuteLocal(IgniteEnvironment* env) - { - try - { - job.SetIgnite(env->GetIgnite()); - job.Call(); - res.SetResult(); - } - catch (const IgniteError& err) - { - res.SetError(err); - } - catch (const std::exception& err) - { - res.SetError(IgniteError(IgniteError::IGNITE_ERR_STD, err.what())); - } - catch (...) - { - res.SetError(IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, - "Unknown error occurred during call.")); - } - } - - virtual void ExecuteRemote(IgniteEnvironment* env, binary::BinaryWriterImpl& writer) - { - ExecuteLocal(env); - - res.Write(writer); - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Job. */ - JobType job; - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute job holder. Internal helper class. + * Used to handle jobs in general way, without specific types. + */ +class ComputeJobHolder { + public: + /** + * Destructor. + */ + virtual ~ComputeJobHolder() { + // No-op. + } + + /** + * Execute job locally. + */ + virtual void ExecuteLocal(IgniteEnvironment* env) = 0; + + /** + * Execute job remote. + * + * @param writer Writer. + */ + virtual void ExecuteRemote(IgniteEnvironment* env, + binary::BinaryWriterImpl& writer) = 0; +}; + +/** + * Compute job holder. Internal class. + * + * @tparam F Actual job type. + * @tparam R Job return type. + */ +template < typename F, typename R > +class ComputeJobHolderImpl : public ComputeJobHolder { + public: + typedef R ResultType; + typedef F JobType; + + /** + * Constructor. + * + * @param job Job. + */ + ComputeJobHolderImpl(JobType job) : job(job) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~ComputeJobHolderImpl() { + // No-op. + } + + const ComputeJobResult< ResultType >& GetResult() { + return res; + } + + virtual void ExecuteLocal(IgniteEnvironment* env) { + try { + job.SetIgnite(env->GetIgnite()); + res.SetResult(job.Call()); + } catch (const IgniteError& err) { + res.SetError(err); + } catch (const std::exception& err) { + res.SetError(IgniteError(IgniteError::IGNITE_ERR_STD, err.what())); + } catch (...) { + res.SetError(IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, + "Unknown error occurred during call.")); } -} + } + + virtual void ExecuteRemote(IgniteEnvironment* env, + binary::BinaryWriterImpl& writer) { + ExecuteLocal(env); + + res.Write(writer); + } + + private: + /** Result. */ + ComputeJobResult< ResultType > res; + + /** Job. */ + JobType job; +}; + +/** + * Compute job holder. Internal class. + * Specialisation for void return type + * + * @tparam F Actual job type. + */ +template < typename F > +class ComputeJobHolderImpl< F, void > : public ComputeJobHolder { + public: + typedef F JobType; + + /** + * Constructor. + * + * @param job Job. + */ + ComputeJobHolderImpl(JobType job) : job(job) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~ComputeJobHolderImpl() { + // No-op. + } + + const ComputeJobResult< void >& GetResult() { + return res; + } + + virtual void ExecuteLocal(IgniteEnvironment* env) { + try { + job.SetIgnite(env->GetIgnite()); + job.Call(); + res.SetResult(); + } catch (const IgniteError& err) { + res.SetError(err); + } catch (const std::exception& err) { + res.SetError(IgniteError(IgniteError::IGNITE_ERR_STD, err.what())); + } catch (...) { + res.SetError(IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, + "Unknown error occurred during call.")); + } + } + + virtual void ExecuteRemote(IgniteEnvironment* env, + binary::BinaryWriterImpl& writer) { + ExecuteLocal(env); + + res.Write(writer); + } + + private: + /** Result. */ + ComputeJobResult< void > res; + + /** Job. */ + JobType job; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_JOB_HOLDER +#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_JOB_HOLDER diff --git a/src/odbc/include/ignite/odbc/impl/compute/compute_job_result.h b/src/odbc/include/ignite/odbc/impl/compute/compute_job_result.h index 8ac57f0de..f18f8b0dc 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/compute_job_result.h +++ b/src/odbc/include/ignite/odbc/impl/compute/compute_job_result.h @@ -30,299 +30,261 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - struct ComputeJobResultPolicy - { - enum Type - { - /** - * Wait for results if any are still expected. If all results have been received - - * it will start reducing results. - */ - WAIT = 0, - - /** - * Ignore all not yet received results and start reducing results. - */ - REDUCE = 1, - - /** - * Fail-over job to execute on another node. - */ - FAILOVER = 2 - }; - }; - - /** - * Used to hold compute job result. - */ - template - class ComputeJobResult - { - public: - typedef R ResultType; - /** - * Default constructor. - */ - ComputeJobResult() : - res(), - err() - { - // No-op. - } - - /** - * Set result value. - * - * @param val Value to set as a result. - */ - void SetResult(const ResultType& val) - { - res = val; - } - - /** - * Get result value. - * - * @return Result. - */ - const ResultType& GetResult() const - { - return res; - } - - /** - * Set error. - * - * @param error Error to set. - */ - void SetError(const IgniteError& error) - { - err = error; - } - - /** - * Get error. - * - * @return Error. - */ - const IgniteError& GetError() const - { - return err; - } - - /** - * Set promise to a state which corresponds to result. - * - * @param promise Promise, which state to set. - */ - void SetPromise(common::Promise& promise) - { - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - promise.SetError(err); - else - promise.SetValue(std::shared_ptr(new ResultType(res))); - } - - /** - * Write using writer. - * - * @param writer Writer. - */ - void Write(binary::BinaryWriterImpl& writer) - { - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - { - // Fail - writer.WriteBool(false); - - // Native Exception - writer.WriteBool(true); - - writer.WriteObject(err); - } - else - { - // Success - writer.WriteBool(true); - - writer.WriteObject(res); - } - } - - /** - * Read using reader. - * - * @param reader Reader. - */ - void Read(binary::BinaryReaderImpl& reader) - { - bool success = reader.ReadBool(); - - if (success) - { - res = reader.ReadObject(); - - err = IgniteError(); - } - else - { - bool native = reader.ReadBool(); - - if (native) - err = reader.ReadObject(); - else - { - std::stringstream buf; - - buf << reader.ReadObject() << " : "; - buf << reader.ReadObject() << ", "; - buf << reader.ReadObject(); - - std::string msg = buf.str(); - - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); - } - } - } - - private: - /** Result. */ - ResultType res; - - /** Erorr. */ - IgniteError err; - }; - - /** - * Used to hold compute job result. - */ - template<> - class ComputeJobResult - { - public: - /** - * Default constructor. - */ - ComputeJobResult() : - err() - { - // No-op. - } - - /** - * Mark as complete. - */ - void SetResult() - { - err = IgniteError(); - } - - /** - * Set error. - * - * @param error Error to set. - */ - void SetError(const IgniteError error) - { - err = error; - } - - /** - * Get error. - * - * @return Error. - */ - const IgniteError& GetError() const - { - return err; - } - - /** - * Set promise to a state which corresponds to result. - * - * @param promise Promise, which state to set. - */ - void SetPromise(common::Promise& promise) - { - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - promise.SetError(err); - else - promise.SetValue(); - } - - /** - * Write using writer. - * - * @param writer Writer. - */ - void Write(binary::BinaryWriterImpl& writer) - { - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - { - // Fail - writer.WriteBool(false); - - // Native Exception - writer.WriteBool(true); - - writer.WriteObject(err); - } - else - { - // Success - writer.WriteBool(true); - - writer.WriteNull(); - } - } - - /** - * Read using reader. - * - * @param reader Reader. - */ - void Read(binary::BinaryReaderImpl& reader) - { - bool success = reader.ReadBool(); - - if (success) - err = IgniteError(); - else - { - bool native = reader.ReadBool(); - - if (native) - err = reader.ReadObject(); - else - { - std::stringstream buf; - - buf << reader.ReadObject() << " : "; - buf << reader.ReadObject() << ", "; - buf << reader.ReadObject(); - - std::string msg = buf.str(); - - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); - } - } - } - - private: - /** Erorr. */ - IgniteError err; - }; - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +struct ComputeJobResultPolicy { + enum Type { + /** + * Wait for results if any are still expected. If all results have been + * received - it will start reducing results. + */ + WAIT = 0, + + /** + * Ignore all not yet received results and start reducing results. + */ + REDUCE = 1, + + /** + * Fail-over job to execute on another node. + */ + FAILOVER = 2 + }; +}; + +/** + * Used to hold compute job result. + */ +template < typename R > +class ComputeJobResult { + public: + typedef R ResultType; + /** + * Default constructor. + */ + ComputeJobResult() : res(), err() { + // No-op. + } + + /** + * Set result value. + * + * @param val Value to set as a result. + */ + void SetResult(const ResultType& val) { + res = val; + } + + /** + * Get result value. + * + * @return Result. + */ + const ResultType& GetResult() const { + return res; + } + + /** + * Set error. + * + * @param error Error to set. + */ + void SetError(const IgniteError& error) { + err = error; + } + + /** + * Get error. + * + * @return Error. + */ + const IgniteError& GetError() const { + return err; + } + + /** + * Set promise to a state which corresponds to result. + * + * @param promise Promise, which state to set. + */ + void SetPromise(common::Promise< ResultType >& promise) { + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + promise.SetError(err); + else + promise.SetValue(std::shared_ptr< ResultType >(new ResultType(res))); + } + + /** + * Write using writer. + * + * @param writer Writer. + */ + void Write(binary::BinaryWriterImpl& writer) { + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) { + // Fail + writer.WriteBool(false); + + // Native Exception + writer.WriteBool(true); + + writer.WriteObject< IgniteError >(err); + } else { + // Success + writer.WriteBool(true); + + writer.WriteObject< ResultType >(res); + } + } + + /** + * Read using reader. + * + * @param reader Reader. + */ + void Read(binary::BinaryReaderImpl& reader) { + bool success = reader.ReadBool(); + + if (success) { + res = reader.ReadObject< ResultType >(); + + err = IgniteError(); + } else { + bool native = reader.ReadBool(); + + if (native) + err = reader.ReadObject< IgniteError >(); + else { + std::stringstream buf; + + buf << reader.ReadObject< std::string >() << " : "; + buf << reader.ReadObject< std::string >() << ", "; + buf << reader.ReadObject< std::string >(); + + std::string msg = buf.str(); + + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); + } } -} + } + + private: + /** Result. */ + ResultType res; + + /** Erorr. */ + IgniteError err; +}; + +/** + * Used to hold compute job result. + */ +template <> +class ComputeJobResult< void > { + public: + /** + * Default constructor. + */ + ComputeJobResult() : err() { + // No-op. + } + + /** + * Mark as complete. + */ + void SetResult() { + err = IgniteError(); + } + + /** + * Set error. + * + * @param error Error to set. + */ + void SetError(const IgniteError error) { + err = error; + } + + /** + * Get error. + * + * @return Error. + */ + const IgniteError& GetError() const { + return err; + } + + /** + * Set promise to a state which corresponds to result. + * + * @param promise Promise, which state to set. + */ + void SetPromise(common::Promise< void >& promise) { + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + promise.SetError(err); + else + promise.SetValue(); + } + + /** + * Write using writer. + * + * @param writer Writer. + */ + void Write(binary::BinaryWriterImpl& writer) { + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) { + // Fail + writer.WriteBool(false); + + // Native Exception + writer.WriteBool(true); + + writer.WriteObject< IgniteError >(err); + } else { + // Success + writer.WriteBool(true); + + writer.WriteNull(); + } + } + + /** + * Read using reader. + * + * @param reader Reader. + */ + void Read(binary::BinaryReaderImpl& reader) { + bool success = reader.ReadBool(); + + if (success) + err = IgniteError(); + else { + bool native = reader.ReadBool(); + + if (native) + err = reader.ReadObject< IgniteError >(); + else { + std::stringstream buf; + + buf << reader.ReadObject< std::string >() << " : "; + buf << reader.ReadObject< std::string >() << ", "; + buf << reader.ReadObject< std::string >(); + + std::string msg = buf.str(); + + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); + } + } + } + + private: + /** Erorr. */ + IgniteError err; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_JOB_RESULT +#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_JOB_RESULT diff --git a/src/odbc/include/ignite/odbc/impl/compute/compute_task_holder.h b/src/odbc/include/ignite/odbc/impl/compute/compute_task_holder.h index c6229bcde..aa3dde308 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/compute_task_holder.h +++ b/src/odbc/include/ignite/odbc/impl/compute/compute_task_holder.h @@ -28,163 +28,154 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute task holder. Internal helper class. - * Used to handle tasks in general way, without specific types. - */ - class ComputeTaskHolder - { - public: - /** - * Constructor. - * - * @param handle Job handle. - */ - ComputeTaskHolder(int64_t handle) : - handle(handle) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~ComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder& job) = 0; - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) = 0; - - /** - * Process error. - * - * @param err Error. - */ - virtual void JobResultError(const IgniteError& err) = 0; - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t value) = 0; - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) = 0; - - /** - * Process successful result. - */ - virtual void JobNullResultSuccess() = 0; - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() = 0; - - /** - * Get related job handle. - * - * @return Job handle. - */ - int64_t GetJobHandle() - { - return handle; - } - - private: - /** Related job handle. */ - int64_t handle; - }; - - - /** - * Read future result. - * @tparam T Type of the result. - * @param value Value. - * @return Result. - */ - template T PrimitiveFutureResult(int64_t value) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, - "Primitive value passed to non-primitive future", "value", value); - } - - template<> inline int8_t PrimitiveFutureResult(int64_t value) - { - return static_cast(value); - } - - template<> inline int16_t PrimitiveFutureResult(int64_t value) - { - return static_cast(value); - } - - template<> inline int32_t PrimitiveFutureResult(int64_t value) - { - return static_cast(value); - } - - template<> inline int64_t PrimitiveFutureResult(int64_t value) - { - return static_cast(value); - } - - template<> inline bool PrimitiveFutureResult(int64_t value) - { - return value != 0; - } - - template<> inline uint16_t PrimitiveFutureResult(int64_t value) - { - return static_cast(value); - } - - template<> inline float PrimitiveFutureResult(int64_t value) - { - impl::interop::BinaryFloatInt32 u; - - u.i = static_cast(value); - return u.f; - } - - template<> inline double PrimitiveFutureResult(int64_t value) - { - impl::interop::BinaryDoubleInt64 u; - - u.i = value; - return u.d; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute task holder. Internal helper class. + * Used to handle tasks in general way, without specific types. + */ +class ComputeTaskHolder { + public: + /** + * Constructor. + * + * @param handle Job handle. + */ + ComputeTaskHolder(int64_t handle) : handle(handle) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~ComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder& job) = 0; + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) = 0; + + /** + * Process error. + * + * @param err Error. + */ + virtual void JobResultError(const IgniteError& err) = 0; + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t value) = 0; + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) = 0; + + /** + * Process successful result. + */ + virtual void JobNullResultSuccess() = 0; + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() = 0; + + /** + * Get related job handle. + * + * @return Job handle. + */ + int64_t GetJobHandle() { + return handle; + } + + private: + /** Related job handle. */ + int64_t handle; +}; + +/** + * Read future result. + * @tparam T Type of the result. + * @param value Value. + * @return Result. + */ +template < typename T > +T PrimitiveFutureResult(int64_t value) { + IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, + "Primitive value passed to non-primitive future", + "value", value); +} + +template <> +inline int8_t PrimitiveFutureResult< int8_t >(int64_t value) { + return static_cast< int8_t >(value); +} + +template <> +inline int16_t PrimitiveFutureResult< int16_t >(int64_t value) { + return static_cast< int16_t >(value); +} + +template <> +inline int32_t PrimitiveFutureResult< int32_t >(int64_t value) { + return static_cast< int32_t >(value); +} + +template <> +inline int64_t PrimitiveFutureResult< int64_t >(int64_t value) { + return static_cast< int64_t >(value); +} + +template <> +inline bool PrimitiveFutureResult< bool >(int64_t value) { + return value != 0; +} + +template <> +inline uint16_t PrimitiveFutureResult< uint16_t >(int64_t value) { + return static_cast< uint16_t >(value); +} + +template <> +inline float PrimitiveFutureResult< float >(int64_t value) { + impl::interop::BinaryFloatInt32 u; + + u.i = static_cast< int32_t >(value); + return u.f; +} + +template <> +inline double PrimitiveFutureResult< double >(int64_t value) { + impl::interop::BinaryDoubleInt64 u; + + u.i = value; + return u.d; } +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_TASK_HOLDER +#endif //_IGNITE_ODBC_IMPL_COMPUTE_COMPUTE_TASK_HOLDER diff --git a/src/odbc/include/ignite/odbc/impl/compute/java_compute_task_holder.h b/src/odbc/include/ignite/odbc/impl/compute/java_compute_task_holder.h index c6210ac2c..6fce4f08f 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/java_compute_task_holder.h +++ b/src/odbc/include/ignite/odbc/impl/compute/java_compute_task_holder.h @@ -29,238 +29,210 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute task holder type-specific implementation. - */ - template - class JavaComputeTaskHolder : public ComputeTaskHolder - { - public: - typedef R ResultType; - - /** - * Constructor. - */ - JavaComputeTaskHolder() : - ComputeTaskHolder(-1) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~JavaComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder&) - { - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl&) - { - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - res.SetError(err); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t value) - { - res.SetResult(PrimitiveFutureResult(value)); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) - { - res.SetResult(reader.ReadObject()); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - res.SetResult(impl::binary::BinaryUtils::GetDefaultValue()); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - res.SetPromise(promise); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise& GetPromise() - { - return promise; - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Task result promise. */ - common::Promise promise; - }; - - /** - * Compute task holder type-specific implementation. - */ - template<> - class JavaComputeTaskHolder : public ComputeTaskHolder - { - public: - /** - * Constructor. - */ - JavaComputeTaskHolder() : - ComputeTaskHolder(-1) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~JavaComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder&) - { - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl&) - { - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - res.SetError(err); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t) - { - res.SetResult(); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl&) - { - res.SetResult(); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - res.SetResult(); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - res.SetPromise(promise); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise& GetPromise() - { - return promise; - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Task result promise. */ - common::Promise promise; - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute task holder type-specific implementation. + */ +template < typename R > +class JavaComputeTaskHolder : public ComputeTaskHolder { + public: + typedef R ResultType; + + /** + * Constructor. + */ + JavaComputeTaskHolder() : ComputeTaskHolder(-1) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~JavaComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder&) { + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl&) { + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + res.SetError(err); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t value) { + res.SetResult(PrimitiveFutureResult< ResultType >(value)); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) { + res.SetResult(reader.ReadObject< ResultType >()); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + res.SetResult(impl::binary::BinaryUtils::GetDefaultValue< ResultType >()); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + res.SetPromise(promise); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< ResultType >& GetPromise() { + return promise; + } + + private: + /** Result. */ + ComputeJobResult< ResultType > res; + + /** Task result promise. */ + common::Promise< ResultType > promise; +}; + +/** + * Compute task holder type-specific implementation. + */ +template <> +class JavaComputeTaskHolder< void > : public ComputeTaskHolder { + public: + /** + * Constructor. + */ + JavaComputeTaskHolder() : ComputeTaskHolder(-1) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~JavaComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder&) { + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl&) { + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + res.SetError(err); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t) { + res.SetResult(); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl&) { + res.SetResult(); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + res.SetResult(); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + res.SetPromise(promise); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< void >& GetPromise() { + return promise; + } + + private: + /** Result. */ + ComputeJobResult< void > res; + + /** Task result promise. */ + common::Promise< void > promise; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_COMPUTE_JAVA_COMPUTE_TASK_HOLDER +#endif //_IGNITE_ODBC_IMPL_COMPUTE_JAVA_COMPUTE_TASK_HOLDER diff --git a/src/odbc/include/ignite/odbc/impl/compute/multiple_job_compute_task_holder.h b/src/odbc/include/ignite/odbc/impl/compute/multiple_job_compute_task_holder.h index a60d26250..20cced446 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/multiple_job_compute_task_holder.h +++ b/src/odbc/include/ignite/odbc/impl/compute/multiple_job_compute_task_holder.h @@ -17,7 +17,8 @@ /** * @file - * Declares ignite::odbc::impl::compute::MultipleJobComputeTaskHolder class template. + * Declares ignite::odbc::impl::compute::MultipleJobComputeTaskHolder class + * template. */ #ifndef _IGNITE_ODBC_IMPL_COMPUTE_MULTIPLE_JOB_COMPUTE_TASK @@ -30,345 +31,316 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Multiple Job Compute task holder type-specific implementation. - * Used for broadcast. - * - * @tparam F Function type. - * @tparam R Function result type. - */ - template - class MultipleJobComputeTaskHolder : public ComputeTaskHolder - { - public: - typedef F JobType; - typedef R ResultType; - - /** - * Constructor. - * - * @param handle Job handle. - */ - MultipleJobComputeTaskHolder(int64_t handle) : - ComputeTaskHolder(handle), - result(new std::vector()), - error(), - promise() - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~MultipleJobComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder& job) - { - typedef ComputeJobHolderImpl ActualComputeJobHolder; - - ActualComputeJobHolder& job0 = static_cast(job); - - ProcessResult(job0.GetResult()); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) - { - ComputeJobResult res; - - res.Read(reader); - - ProcessResult(res); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - ComputeJobResult res; - - res.SetError(err); - - ProcessResult(res); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t value) - { - ComputeJobResult res; - - res.SetResult(PrimitiveFutureResult(value)); - - ProcessResult(res); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) - { - ComputeJobResult res; - - res.SetResult(reader.ReadObject()); - - ProcessResult(res); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - ComputeJobResult res; - - res.SetResult(impl::binary::BinaryUtils::GetDefaultValue()); - - ProcessResult(res); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - if (error.GetCode() == IgniteError::IGNITE_SUCCESS) - promise.SetValue(result); - else - promise.SetError(error); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise< std::vector >& GetPromise() - { - return promise; - } - - private: - /** - * Process result. - * - * @param res Result. - */ - void ProcessResult(const ComputeJobResult& res) - { - const IgniteError& err = res.GetError(); - - if (err.GetCode() == IgniteError::IGNITE_SUCCESS) - result->push_back(res.GetResult()); - else - error = err; - } - - /** Result. */ - std::shared_ptr< std::vector > result; - - /** Error. */ - IgniteError error; - - /** Task result promise. */ - common::Promise< std::vector > promise; - }; - - /** - * Compute task holder type-specific implementation. - */ - template - class MultipleJobComputeTaskHolder : public ComputeTaskHolder - { - public: - typedef F JobType; - - /** - * Constructor. - * - * @param handle Job handle. - */ - MultipleJobComputeTaskHolder(int64_t handle) : - ComputeTaskHolder(handle) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~MultipleJobComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder& job) - { - typedef ComputeJobHolderImpl ActualComputeJobHolder; - - ActualComputeJobHolder& job0 = static_cast(job); - - ProcessResult(job0.GetResult()); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) - { - ComputeJobResult res; - - res.Read(reader); - - ProcessResult(res); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - ComputeJobResult res; - - res.SetError(err); - - ProcessResult(res); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t) - { - ComputeJobResult res; - - res.SetResult(); - - ProcessResult(res); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl&) - { - ComputeJobResult res; - - res.SetResult(); - - ProcessResult(res); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - ComputeJobResult res; - - res.SetResult(); - - ProcessResult(res); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - if (error.GetCode() == IgniteError::IGNITE_SUCCESS) - promise.SetValue(); - else - promise.SetError(error); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise& GetPromise() - { - return promise; - } - - private: - /** - * Process result. - * - * @param res Result. - */ - void ProcessResult(const ComputeJobResult& res) - { - const IgniteError& err = res.GetError(); - - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - error = err; - } - - /** Error. */ - IgniteError error; - - /** Task result promise. */ - common::Promise promise; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_COMPUTE_MULTIPLE_JOB_COMPUTE_TASK +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Multiple Job Compute task holder type-specific implementation. + * Used for broadcast. + * + * @tparam F Function type. + * @tparam R Function result type. + */ +template < typename F, typename R > +class MultipleJobComputeTaskHolder : public ComputeTaskHolder { + public: + typedef F JobType; + typedef R ResultType; + + /** + * Constructor. + * + * @param handle Job handle. + */ + MultipleJobComputeTaskHolder(int64_t handle) + : ComputeTaskHolder(handle), + result(new std::vector< ResultType >()), + error(), + promise() { + // No-op. + } + + /** + * Destructor. + */ + virtual ~MultipleJobComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder& job) { + typedef ComputeJobHolderImpl< JobType, ResultType > ActualComputeJobHolder; + + ActualComputeJobHolder& job0 = static_cast< ActualComputeJobHolder& >(job); + + ProcessResult(job0.GetResult()); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) { + ComputeJobResult< ResultType > res; + + res.Read(reader); + + ProcessResult(res); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + ComputeJobResult< ResultType > res; + + res.SetError(err); + + ProcessResult(res); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t value) { + ComputeJobResult< ResultType > res; + + res.SetResult(PrimitiveFutureResult< ResultType >(value)); + + ProcessResult(res); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) { + ComputeJobResult< ResultType > res; + + res.SetResult(reader.ReadObject< ResultType >()); + + ProcessResult(res); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + ComputeJobResult< ResultType > res; + + res.SetResult(impl::binary::BinaryUtils::GetDefaultValue< ResultType >()); + + ProcessResult(res); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + if (error.GetCode() == IgniteError::IGNITE_SUCCESS) + promise.SetValue(result); + else + promise.SetError(error); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< std::vector< ResultType > >& GetPromise() { + return promise; + } + + private: + /** + * Process result. + * + * @param res Result. + */ + void ProcessResult(const ComputeJobResult< ResultType >& res) { + const IgniteError& err = res.GetError(); + + if (err.GetCode() == IgniteError::IGNITE_SUCCESS) + result->push_back(res.GetResult()); + else + error = err; + } + + /** Result. */ + std::shared_ptr< std::vector< ResultType > > result; + + /** Error. */ + IgniteError error; + + /** Task result promise. */ + common::Promise< std::vector< ResultType > > promise; +}; + +/** + * Compute task holder type-specific implementation. + */ +template < typename F > +class MultipleJobComputeTaskHolder< F, void > : public ComputeTaskHolder { + public: + typedef F JobType; + + /** + * Constructor. + * + * @param handle Job handle. + */ + MultipleJobComputeTaskHolder(int64_t handle) : ComputeTaskHolder(handle) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~MultipleJobComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder& job) { + typedef ComputeJobHolderImpl< JobType, void > ActualComputeJobHolder; + + ActualComputeJobHolder& job0 = static_cast< ActualComputeJobHolder& >(job); + + ProcessResult(job0.GetResult()); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) { + ComputeJobResult< void > res; + + res.Read(reader); + + ProcessResult(res); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + ComputeJobResult< void > res; + + res.SetError(err); + + ProcessResult(res); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t) { + ComputeJobResult< void > res; + + res.SetResult(); + + ProcessResult(res); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl&) { + ComputeJobResult< void > res; + + res.SetResult(); + + ProcessResult(res); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + ComputeJobResult< void > res; + + res.SetResult(); + + ProcessResult(res); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + if (error.GetCode() == IgniteError::IGNITE_SUCCESS) + promise.SetValue(); + else + promise.SetError(error); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< void >& GetPromise() { + return promise; + } + + private: + /** + * Process result. + * + * @param res Result. + */ + void ProcessResult(const ComputeJobResult< void >& res) { + const IgniteError& err = res.GetError(); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + error = err; + } + + /** Error. */ + IgniteError error; + + /** Task result promise. */ + common::Promise< void > promise; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_COMPUTE_MULTIPLE_JOB_COMPUTE_TASK diff --git a/src/odbc/include/ignite/odbc/impl/compute/single_job_compute_task_holder.h b/src/odbc/include/ignite/odbc/impl/compute/single_job_compute_task_holder.h index f45397119..458440a33 100644 --- a/src/odbc/include/ignite/odbc/impl/compute/single_job_compute_task_holder.h +++ b/src/odbc/include/ignite/odbc/impl/compute/single_job_compute_task_holder.h @@ -17,7 +17,8 @@ /** * @file - * Declares ignite::odbc::impl::compute::SingleJobComputeTaskHolder class template. + * Declares ignite::odbc::impl::compute::SingleJobComputeTaskHolder class + * template. */ #ifndef _IGNITE_ODBC_IMPL_COMPUTE_SINGLE_JOB_COMPUTE_TASK @@ -29,261 +30,233 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - /** - * Compute task holder type-specific implementation. - */ - template - class SingleJobComputeTaskHolder : public ComputeTaskHolder - { - public: - typedef F JobType; - typedef R ResultType; - - /** - * Constructor. - * - * @param handle Job handle. - */ - SingleJobComputeTaskHolder(int64_t handle) : - ComputeTaskHolder(handle) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~SingleJobComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder& job) - { - typedef ComputeJobHolderImpl ActualComputeJobHolder; - - ActualComputeJobHolder& job0 = static_cast(job); - - res = job0.GetResult(); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) - { - res.Read(reader); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - res.SetError(err); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t value) - { - res.SetResult(PrimitiveFutureResult(value)); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) - { - res.SetResult(reader.ReadObject()); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - res.SetResult(impl::binary::BinaryUtils::GetDefaultValue()); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - res.SetPromise(promise); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise& GetPromise() - { - return promise; - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Task result promise. */ - common::Promise promise; - }; - - /** - * Compute task holder type-specific implementation. - */ - template - class SingleJobComputeTaskHolder : public ComputeTaskHolder - { - public: - typedef F JobType; - - /** - * Constructor. - * - * @param handle Job handle. - */ - SingleJobComputeTaskHolder(int64_t handle) : - ComputeTaskHolder(handle) - { - // No-op. - } - - /** - * Destructor. - */ - virtual ~SingleJobComputeTaskHolder() - { - // No-op. - } - - /** - * Process local job result. - * - * @param job Job. - * @return Policy. - */ - virtual int32_t JobResultLocal(ComputeJobHolder& job) - { - typedef ComputeJobHolderImpl ActualComputeJobHolder; - - ActualComputeJobHolder& job0 = static_cast(job); - - res = job0.GetResult(); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - * @return Policy. - */ - virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) - { - res.Read(reader); - - return ComputeJobResultPolicy::WAIT; - } - - /** - * Process remote job result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultError(const IgniteError& err) - { - res.SetError(err); - } - - /** - * Process successful result. - * - * @param value Value. - */ - virtual void JobResultSuccess(int64_t) - { - res.SetResult(); - } - - /** - * Process successful result. - * - * @param reader Reader for stream with result. - */ - virtual void JobResultSuccess(binary::BinaryReaderImpl&) - { - res.SetResult(); - } - - /** - * Process successful null result. - */ - virtual void JobNullResultSuccess() - { - res.SetResult(); - } - - /** - * Reduce results of related jobs. - */ - virtual void Reduce() - { - res.SetPromise(promise); - } - - /** - * Get result promise. - * - * @return Reference to result promise. - */ - common::Promise& GetPromise() - { - return promise; - } - - private: - /** Result. */ - ComputeJobResult res; - - /** Task result promise. */ - common::Promise promise; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_COMPUTE_SINGLE_JOB_COMPUTE_TASK +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +/** + * Compute task holder type-specific implementation. + */ +template < typename F, typename R > +class SingleJobComputeTaskHolder : public ComputeTaskHolder { + public: + typedef F JobType; + typedef R ResultType; + + /** + * Constructor. + * + * @param handle Job handle. + */ + SingleJobComputeTaskHolder(int64_t handle) : ComputeTaskHolder(handle) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~SingleJobComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder& job) { + typedef ComputeJobHolderImpl< JobType, ResultType > ActualComputeJobHolder; + + ActualComputeJobHolder& job0 = static_cast< ActualComputeJobHolder& >(job); + + res = job0.GetResult(); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) { + res.Read(reader); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + res.SetError(err); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t value) { + res.SetResult(PrimitiveFutureResult< ResultType >(value)); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl& reader) { + res.SetResult(reader.ReadObject< ResultType >()); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + res.SetResult(impl::binary::BinaryUtils::GetDefaultValue< ResultType >()); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + res.SetPromise(promise); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< ResultType >& GetPromise() { + return promise; + } + + private: + /** Result. */ + ComputeJobResult< ResultType > res; + + /** Task result promise. */ + common::Promise< ResultType > promise; +}; + +/** + * Compute task holder type-specific implementation. + */ +template < typename F > +class SingleJobComputeTaskHolder< F, void > : public ComputeTaskHolder { + public: + typedef F JobType; + + /** + * Constructor. + * + * @param handle Job handle. + */ + SingleJobComputeTaskHolder(int64_t handle) : ComputeTaskHolder(handle) { + // No-op. + } + + /** + * Destructor. + */ + virtual ~SingleJobComputeTaskHolder() { + // No-op. + } + + /** + * Process local job result. + * + * @param job Job. + * @return Policy. + */ + virtual int32_t JobResultLocal(ComputeJobHolder& job) { + typedef ComputeJobHolderImpl< JobType, void > ActualComputeJobHolder; + + ActualComputeJobHolder& job0 = static_cast< ActualComputeJobHolder& >(job); + + res = job0.GetResult(); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + * @return Policy. + */ + virtual int32_t JobResultRemote(binary::BinaryReaderImpl& reader) { + res.Read(reader); + + return ComputeJobResultPolicy::WAIT; + } + + /** + * Process remote job result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultError(const IgniteError& err) { + res.SetError(err); + } + + /** + * Process successful result. + * + * @param value Value. + */ + virtual void JobResultSuccess(int64_t) { + res.SetResult(); + } + + /** + * Process successful result. + * + * @param reader Reader for stream with result. + */ + virtual void JobResultSuccess(binary::BinaryReaderImpl&) { + res.SetResult(); + } + + /** + * Process successful null result. + */ + virtual void JobNullResultSuccess() { + res.SetResult(); + } + + /** + * Reduce results of related jobs. + */ + virtual void Reduce() { + res.SetPromise(promise); + } + + /** + * Get result promise. + * + * @return Reference to result promise. + */ + common::Promise< void >& GetPromise() { + return promise; + } + + private: + /** Result. */ + ComputeJobResult< void > res; + + /** Task result promise. */ + common::Promise< void > promise; +}; +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_COMPUTE_SINGLE_JOB_COMPUTE_TASK diff --git a/src/odbc/include/ignite/odbc/impl/handle_registry.h b/src/odbc/include/ignite/odbc/impl/handle_registry.h index 343c04bd8..1222a9f6e 100644 --- a/src/odbc/include/ignite/odbc/impl/handle_registry.h +++ b/src/odbc/include/ignite/odbc/impl/handle_registry.h @@ -23,171 +23,170 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Handle registry segment containing thread-specific data for slow-path access. - */ - class HandleRegistrySegment - { - public: - /** - * Constructor. - */ - HandleRegistrySegment(); - - /** - * Destructor. - */ - ~HandleRegistrySegment(); - - /** - * Get entry from segment. - * - * @param hnd Handle. - * @return Associated entry or NULL if it doesn't exists. - */ - common::concurrent::SharedPointer Get(int64_t hnd); - - /** - * Put entry into segment. - * - * @param hnd Handle. - * @param entry Associated entry (cannot be NULL). - */ - void Put(int64_t hnd, const common::concurrent::SharedPointer& entry); - - /** - * Remove entry from the segment. - * - * @param hnd Handle. - */ - void Remove(int64_t hnd); - - /** - * Clear all entries from the segment. - */ - void Clear(); - private: - /** Map with data. */ - std::map > map; - - /** Mutex. */ - common::concurrent::CriticalSection mux; - - IGNITE_NO_COPY_ASSIGNMENT(HandleRegistrySegment); - }; - - /** - * Handle registry. - */ - class IGNITE_IMPORT_EXPORT HandleRegistry - { - public: - /** - * Constructor. - * - * @param fastCap Fast-path capacity. - * @param slowSegmentCnt Slow-path segments count. - */ - HandleRegistry(int32_t fastCap, int32_t slowSegmentCnt); - - /** - * Destructor. - */ - ~HandleRegistry(); - - /** - * Allocate handle. - * - * @param target Target. - * @return Handle. - */ - int64_t Allocate(const common::concurrent::SharedPointer& target); - - /** - * Allocate handle in critical mode. - * - * @param target Target. - * @return Handle. - */ - int64_t AllocateCritical(const common::concurrent::SharedPointer& target); - - /** - * Allocate handle in safe mode. - * - * @param target Target. - * @return Handle. - */ - int64_t AllocateSafe(const common::concurrent::SharedPointer& target); - - /** - * Allocate handle in critical and safe modes. - * - * @param target Target. - * @return Handle. - */ - int64_t AllocateCriticalSafe(const common::concurrent::SharedPointer& target); - - /** - * Release handle. - * - * @param hnd Handle. - */ - void Release(int64_t hnd); - - /** - * Get target. - * - * @param hnd Handle. - * @return Target. - */ - common::concurrent::SharedPointer Get(int64_t hnd); - - /** - * Close the registry. - */ - void Close(); - - private: - /** Fast-path container capacity. */ - int32_t fastCap; - - /** Fast-path counter. */ - int32_t fastCtr; - - /** Fast-path container. */ - common::concurrent::SharedPointer* fast; - - /** Amount of slow-path segments. */ - int32_t slowSegmentCnt; - - /** Slow-path counter. */ - int64_t slowCtr; - - /** Slow-path segments. */ - HandleRegistrySegment** slow; - - /** Close flag. */ - int32_t closed; - - IGNITE_NO_COPY_ASSIGNMENT(HandleRegistry); - - /** - * Internal allocation routine. - * - * @param target Target. - * @param critical mode flag. - * @param safe mode flag. - */ - int64_t Allocate0(const common::concurrent::SharedPointer& target, bool critical, bool safe); - }; - } - } -} - -#endif //_IGNITE_ODBC_IMPL_HANDLE_REGISTRY +namespace ignite { +namespace odbc { +namespace impl { +/** + * Handle registry segment containing thread-specific data for slow-path access. + */ +class HandleRegistrySegment { + public: + /** + * Constructor. + */ + HandleRegistrySegment(); + + /** + * Destructor. + */ + ~HandleRegistrySegment(); + + /** + * Get entry from segment. + * + * @param hnd Handle. + * @return Associated entry or NULL if it doesn't exists. + */ + common::concurrent::SharedPointer< void > Get(int64_t hnd); + + /** + * Put entry into segment. + * + * @param hnd Handle. + * @param entry Associated entry (cannot be NULL). + */ + void Put(int64_t hnd, const common::concurrent::SharedPointer< void >& entry); + + /** + * Remove entry from the segment. + * + * @param hnd Handle. + */ + void Remove(int64_t hnd); + + /** + * Clear all entries from the segment. + */ + void Clear(); + + private: + /** Map with data. */ + std::map< int64_t, common::concurrent::SharedPointer< void > > map; + + /** Mutex. */ + common::concurrent::CriticalSection mux; + + IGNITE_NO_COPY_ASSIGNMENT(HandleRegistrySegment); +}; + +/** + * Handle registry. + */ +class IGNITE_IMPORT_EXPORT HandleRegistry { + public: + /** + * Constructor. + * + * @param fastCap Fast-path capacity. + * @param slowSegmentCnt Slow-path segments count. + */ + HandleRegistry(int32_t fastCap, int32_t slowSegmentCnt); + + /** + * Destructor. + */ + ~HandleRegistry(); + + /** + * Allocate handle. + * + * @param target Target. + * @return Handle. + */ + int64_t Allocate(const common::concurrent::SharedPointer< void >& target); + + /** + * Allocate handle in critical mode. + * + * @param target Target. + * @return Handle. + */ + int64_t AllocateCritical( + const common::concurrent::SharedPointer< void >& target); + + /** + * Allocate handle in safe mode. + * + * @param target Target. + * @return Handle. + */ + int64_t AllocateSafe(const common::concurrent::SharedPointer< void >& target); + + /** + * Allocate handle in critical and safe modes. + * + * @param target Target. + * @return Handle. + */ + int64_t AllocateCriticalSafe( + const common::concurrent::SharedPointer< void >& target); + + /** + * Release handle. + * + * @param hnd Handle. + */ + void Release(int64_t hnd); + + /** + * Get target. + * + * @param hnd Handle. + * @return Target. + */ + common::concurrent::SharedPointer< void > Get(int64_t hnd); + + /** + * Close the registry. + */ + void Close(); + + private: + /** Fast-path container capacity. */ + int32_t fastCap; + + /** Fast-path counter. */ + int32_t fastCtr; + + /** Fast-path container. */ + common::concurrent::SharedPointer< void >* fast; + + /** Amount of slow-path segments. */ + int32_t slowSegmentCnt; + + /** Slow-path counter. */ + int64_t slowCtr; + + /** Slow-path segments. */ + HandleRegistrySegment** slow; + + /** Close flag. */ + int32_t closed; + + IGNITE_NO_COPY_ASSIGNMENT(HandleRegistry); + + /** + * Internal allocation routine. + * + * @param target Target. + * @param critical mode flag. + * @param safe mode flag. + */ + int64_t Allocate0(const common::concurrent::SharedPointer< void >& target, + bool critical, bool safe); +}; +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_HANDLE_REGISTRY diff --git a/src/odbc/include/ignite/odbc/impl/helpers.h b/src/odbc/include/ignite/odbc/impl/helpers.h index db1773340..f403cd886 100644 --- a/src/odbc/include/ignite/odbc/impl/helpers.h +++ b/src/odbc/include/ignite/odbc/impl/helpers.h @@ -23,38 +23,33 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Class-helper to properly write values of different type. - */ - template - struct ContainerEntryWriteHelper - { - template - static void Write(binary::BinaryWriterImpl& writer, const E& val) - { - writer.WriteTopObject(val); - } - - static void Write(binary::BinaryWriterImpl& writer, const typename std::map::value_type& val) - { - writer.WriteTopObject(val.first); - writer.WriteTopObject(val.second); - } - - static void Write(binary::BinaryWriterImpl& writer, const ignite::odbc::cache::CacheEntry& val) - { - writer.WriteTopObject(val.GetKey()); - writer.WriteTopObject(val.GetValue()); - } - }; - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +/** + * Class-helper to properly write values of different type. + */ +template < typename K, typename V > +struct ContainerEntryWriteHelper { + template < typename E > + static void Write(binary::BinaryWriterImpl& writer, const E& val) { + writer.WriteTopObject(val); + } + + static void Write(binary::BinaryWriterImpl& writer, + const typename std::map< K, V >::value_type& val) { + writer.WriteTopObject(val.first); + writer.WriteTopObject(val.second); + } + + static void Write(binary::BinaryWriterImpl& writer, + const ignite::odbc::cache::CacheEntry< K, V >& val) { + writer.WriteTopObject(val.GetKey()); + writer.WriteTopObject(val.GetValue()); + } +}; +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_HELPERS +#endif //_IGNITE_ODBC_IMPL_HELPERS diff --git a/src/odbc/include/ignite/odbc/impl/ignite_binding_impl.h b/src/odbc/include/ignite/odbc/impl/ignite_binding_impl.h index 29c4b6bc4..f5f104c86 100644 --- a/src/odbc/include/ignite/odbc/impl/ignite_binding_impl.h +++ b/src/odbc/include/ignite/odbc/impl/ignite_binding_impl.h @@ -26,114 +26,113 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - /* Forward declaration. */ - class IgniteEnvironment; - - /** - * Ignite binding implementation. - * - * Used to register and invoke callbacks. - */ - class IgniteBindingImpl - { - typedef int64_t(Callback)(binary::BinaryReaderImpl&, binary::BinaryWriterImpl&, IgniteEnvironment&); - - public: - struct CallbackType - { - enum Type - { - CACHE_ENTRY_PROCESSOR_APPLY = 1, - - CACHE_ENTRY_FILTER_CREATE = 2, - - CACHE_ENTRY_FILTER_APPLY = 3, - - COMPUTE_JOB_CREATE = 4 - }; - }; - - /** - * Constructor. - * - * @param env Environment. - */ - IgniteBindingImpl(IgniteEnvironment &env); - - /** - * Invoke callback using provided ID. - * - * Deserializes data and callback itself, invokes callback and - * serializes processing result using providede reader and writer. - * - * @param type Callback Type. - * @param id Callback ID. - * @param reader Reader. - * @param writer Writer. - * @param found Output param. True if callback was found and false otherwise. - * @return Callback return value. - */ - IGNITE_IMPORT_EXPORT int64_t InvokeCallback(bool& found, int32_t type, int32_t id, binary::BinaryReaderImpl& reader, - binary::BinaryWriterImpl& writer); - - /** - * Register cache entry processor and associate it with provided ID. - * - * @throw IgniteError another processor is already associated with - * the given ID. - * - * @param type Callback type. - * @param id Callback identifier. - * @param callback Callback. - * @param err Error. - */ - IGNITE_IMPORT_EXPORT void RegisterCallback(int32_t type, int32_t id, Callback* callback, IgniteError& err); - - /** - * Register cache entry processor and associate it with provided ID. - * - * @throw IgniteError another processor is already associated with - * the given ID. - * - * @param type Callback type. - * @param id Callback identifier. - * @param callback Callback. - */ - IGNITE_IMPORT_EXPORT void RegisterCallback(int32_t type, int32_t id, Callback* callback); - - private: - IGNITE_NO_COPY_ASSIGNMENT(IgniteBindingImpl); - - /** - * Make key out of callback's type and ID. - * - * @param type Callback Type. - * @param id Callback ID. - * @return Key for callback. - */ - int64_t makeKey(int32_t type, int32_t id) - { - return ((static_cast(type) & 0xFFFFFFFF) << 32) | - ((static_cast(id) & 0xFFFFFFFF)); - } - - /** Ignite environment. */ - IgniteEnvironment& env; - - /** Registered callbacks. */ - std::map callbacks; - - /** Callback lock. */ - common::concurrent::CriticalSection lock; - }; - } - } -} - -#endif //_IGNITE_ODBC_IMPL_IGNITE_BINDING_IMPL +namespace ignite { +namespace odbc { +namespace impl { +/* Forward declaration. */ +class IgniteEnvironment; + +/** + * Ignite binding implementation. + * + * Used to register and invoke callbacks. + */ +class IgniteBindingImpl { + typedef int64_t(Callback)(binary::BinaryReaderImpl&, + binary::BinaryWriterImpl&, IgniteEnvironment&); + + public: + struct CallbackType { + enum Type { + CACHE_ENTRY_PROCESSOR_APPLY = 1, + + CACHE_ENTRY_FILTER_CREATE = 2, + + CACHE_ENTRY_FILTER_APPLY = 3, + + COMPUTE_JOB_CREATE = 4 + }; + }; + + /** + * Constructor. + * + * @param env Environment. + */ + IgniteBindingImpl(IgniteEnvironment& env); + + /** + * Invoke callback using provided ID. + * + * Deserializes data and callback itself, invokes callback and + * serializes processing result using providede reader and writer. + * + * @param type Callback Type. + * @param id Callback ID. + * @param reader Reader. + * @param writer Writer. + * @param found Output param. True if callback was found and false otherwise. + * @return Callback return value. + */ + IGNITE_IMPORT_EXPORT int64_t InvokeCallback(bool& found, int32_t type, + int32_t id, + binary::BinaryReaderImpl& reader, + binary::BinaryWriterImpl& writer); + + /** + * Register cache entry processor and associate it with provided ID. + * + * @throw IgniteError another processor is already associated with + * the given ID. + * + * @param type Callback type. + * @param id Callback identifier. + * @param callback Callback. + * @param err Error. + */ + IGNITE_IMPORT_EXPORT void RegisterCallback(int32_t type, int32_t id, + Callback* callback, + IgniteError& err); + + /** + * Register cache entry processor and associate it with provided ID. + * + * @throw IgniteError another processor is already associated with + * the given ID. + * + * @param type Callback type. + * @param id Callback identifier. + * @param callback Callback. + */ + IGNITE_IMPORT_EXPORT void RegisterCallback(int32_t type, int32_t id, + Callback* callback); + + private: + IGNITE_NO_COPY_ASSIGNMENT(IgniteBindingImpl); + + /** + * Make key out of callback's type and ID. + * + * @param type Callback Type. + * @param id Callback ID. + * @return Key for callback. + */ + int64_t makeKey(int32_t type, int32_t id) { + return ((static_cast< int64_t >(type) & 0xFFFFFFFF) << 32) + | ((static_cast< int64_t >(id) & 0xFFFFFFFF)); + } + + /** Ignite environment. */ + IgniteEnvironment& env; + + /** Registered callbacks. */ + std::map< int64_t, Callback* > callbacks; + + /** Callback lock. */ + common::concurrent::CriticalSection lock; +}; +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_IGNITE_BINDING_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/ignite_environment.h b/src/odbc/include/ignite/odbc/impl/ignite_environment.h index cb92bc7f3..256c2e80d 100644 --- a/src/odbc/include/ignite/odbc/impl/ignite_environment.h +++ b/src/odbc/include/ignite/odbc/impl/ignite_environment.h @@ -28,380 +28,395 @@ #include #include -namespace ignite -{ - namespace odbc - { - /* Forward declaration. */ - class Ignite; - - namespace impl - { - /* Forward declarations. */ - class IgniteEnvironment; - class IgniteBindingImpl; - class ModuleManager; - class ClusterNodesHolder; - namespace cluster { - class ClusterNodeImpl; - } - - typedef common::concurrent::SharedPointer SP_IgniteEnvironment; - - /** - * Defines environment in which Ignite operates. - */ - class IGNITE_IMPORT_EXPORT IgniteEnvironment - { - typedef common::concurrent::SharedPointer SP_ClusterNodeImpl; - public: - /** - * Default memory block allocation size. - */ - enum { DEFAULT_ALLOCATION_SIZE = 1024 }; - - /** - * Default fast path handle registry containers capasity. - */ - enum { DEFAULT_FAST_PATH_CONTAINERS_CAP = 1024 }; - - /** - * Default slow path handle registry containers capasity. - */ - enum { DEFAULT_SLOW_PATH_CONTAINERS_CAP = 16 }; - - /** - * Constructor. - * - * @param cfg Node configuration. - */ - IgniteEnvironment(const IgniteConfiguration& cfg); - - /** - * Destructor. - */ - ~IgniteEnvironment(); - - /** - * Get node configuration. - * - * @return Node configuration. - */ - const IgniteConfiguration& GetConfiguration() const; - - /** - * Populate callback handlers. - * - * @param target (current env wrapped into a shared pointer). - * @return JNI handlers. - */ - jni::java::JniHandlers GetJniHandlers(common::concurrent::SharedPointer* target); - - /** - * Set context. - * - * @param ctx Context. - */ - void SetContext(common::concurrent::SharedPointer ctx); - - /** - * Perform initialization on successful start. - */ - void Initialize(); - - /** - * Start callback. - * - * @param memPtr Memory pointer. - * @param proc Processor instance. - */ - void OnStartCallback(int64_t memPtr, jobject proc); - - /** - * Continuous query listener apply callback. - * - * @param mem Memory with data. - */ - void OnContinuousQueryListenerApply(common::concurrent::SharedPointer& mem); - - /** - * Continuous query filter create callback. - * - * @param mem Memory with data. - * @return Filter handle. - */ - int64_t OnContinuousQueryFilterCreate(common::concurrent::SharedPointer& mem); - - /** - * Continuous query filter apply callback. - * - * @param mem Memory with data. - */ - int64_t OnContinuousQueryFilterApply(common::concurrent::SharedPointer& mem); - - /** - * Callback on future result received. - * - * @param handle Task handle. - * @param value Value. - */ - int64_t OnFuturePrimitiveResult(int64_t handle, int64_t value); - - /** - * Callback on future result received. - * - * @param handle Task handle. - * @param mem Memory with data. - */ - int64_t OnFutureObjectResult(int64_t handle, common::concurrent::SharedPointer &mem); - - /** - * Callback on future null result received. - * - * @param handle Task handle. - */ - int64_t OnFutureNullResult(int64_t handle); - - /** - * Callback on future error received. - * - * @param handle Task handle. - * @param mem Memory with data. - */ - int64_t OnFutureError(int64_t handle, common::concurrent::SharedPointer& mem); - - /** - * Callback on compute function execute request. - * - * @param mem Memory with data. - */ - int64_t OnComputeFuncExecute(common::concurrent::SharedPointer& mem); - - /** - * Cache Invoke callback. - * - * @param mem Input-output memory. - */ - void CacheInvokeCallback(common::concurrent::SharedPointer& mem); - - /** - * Get name of Ignite instance. - * - * @return Name. - */ - const char* InstanceName() const; - - /** - * Get processor associated with the instance. - * - * @return Processor. - */ - void* GetProcessor(); - - /** - * Get JNI context. - * - * @return Context. - */ - jni::java::JniContext* Context(); - - /** - * Get memory for interop operations. - * - * @return Memory. - */ - common::concurrent::SharedPointer AllocateMemory(); - - /** - * Get memory chunk for interop operations with desired capacity. - * - * @param cap Capacity. - * @return Memory. - */ - common::concurrent::SharedPointer AllocateMemory(int32_t cap); - - /** - * Get memory chunk located at the given pointer. - * - * @param memPtr Memory pointer. - * @retrun Memory. - */ - common::concurrent::SharedPointer GetMemory(int64_t memPtr); - - /** - * Get type manager. - * - * @return Type manager. - */ - binary::BinaryTypeManager* GetTypeManager(); - - /** - * Get type updater. - * - * @return Type updater. - */ - binary::BinaryTypeUpdater* GetTypeUpdater(); - - /** - * Get local cluster node implementation. - * - * @return Cluster node implementation or NULL if does not exist. - */ - SP_ClusterNodeImpl GetLocalNode(); - - /** - * Get cluster node implementation by id. - * - * @return Cluster node implementation or NULL if does not exist. - */ - SP_ClusterNodeImpl GetNode(Guid Id); - - /** - * Notify processor that Ignite instance has started. - */ - void ProcessorReleaseStart(); - - /** - * Get handle registry. - * - * @return Handle registry. - */ - HandleRegistry& GetHandleRegistry(); - - /** - * Get binding. - * - * @return IgniteBinding instance. - */ - common::concurrent::SharedPointer GetBinding() const; - - /** - * Get processor compute. - * - * @param proj Projection. - * @return Processor compute. - */ - jobject GetProcessorCompute(jobject proj); - - /** - * Locally execute compute job. - * - * @param jobHandle Job handle. - */ - void ComputeJobExecuteLocal(int64_t jobHandle); - - /** - * Locally commit job execution result for the task. - * - * @param taskHandle Task handle. - * @param jobHandle Job handle. - * @return Reduce politics. - */ - int32_t ComputeTaskLocalJobResult(int64_t taskHandle, int64_t jobHandle); - - /** - * Reduce compute task. - * - * @param taskHandle Task handle. - */ - void ComputeTaskReduce(int64_t taskHandle); - - /** - * Complete compute task. - * - * @param taskHandle Task handle. - */ - void ComputeTaskComplete(int64_t taskHandle); - - /** - * Create compute job. - * - * @param mem Memory. - * @return Job handle. - */ - int64_t ComputeJobCreate(common::concurrent::SharedPointer& mem); - - /** - * Execute compute job. - * - * @param mem Memory. - * @return Job handle. - */ - void ComputeJobExecute(common::concurrent::SharedPointer& mem); - - /** - * Destroy compute job. - * - * @param jobHandle Job handle to destroy. - */ - void ComputeJobDestroy(int64_t jobHandle); - - /** - * Consume result of remote job execution. - * - * @param mem Memory containing result. - * @return Reduce policy. - */ - int32_t ComputeTaskJobResult(common::concurrent::SharedPointer& mem); - - /** - * Get pointer to ignite node. - * - * @return Pointer to ignite node. - */ - ignite::odbc::Ignite* GetIgnite(); - - /** - * InLongOutLong callback. - * Allow access to private nodes member. - * - * @param target Target environment. - * @param type Operation type. - * @param val Value. - */ - friend int64_t IGNITE_CALL InLongOutLong(void* target, int type, int64_t val); - - private: - /** Node configuration. */ - IgniteConfiguration* cfg; - - /** Context to access Java. */ - common::concurrent::SharedPointer ctx; - - /** Startup latch. */ - common::concurrent::SingleLatch latch; - - /** Ignite name. */ - char* name; - - /** Processor instance. */ - jni::JavaGlobalRef proc; - - /** Handle registry. */ - HandleRegistry registry; - - /** Type manager. */ - binary::BinaryTypeManager* metaMgr; - - /** Type updater. */ - binary::BinaryTypeUpdater* metaUpdater; - - /** Ignite binding */ - common::concurrent::SharedPointer binding; - - /** Module manager. */ - common::concurrent::SharedPointer moduleMgr; - - /** Cluster nodes. */ - common::concurrent::SharedPointer nodes; - - /** Ignite node. */ - ignite::odbc::Ignite* ignite; - - IGNITE_NO_COPY_ASSIGNMENT(IgniteEnvironment); - }; - } - } +namespace ignite { +namespace odbc { +/* Forward declaration. */ +class Ignite; + +namespace impl { +/* Forward declarations. */ +class IgniteEnvironment; +class IgniteBindingImpl; +class ModuleManager; +class ClusterNodesHolder; +namespace cluster { +class ClusterNodeImpl; } -#endif //_IGNITE_ODBC_IMPL_IGNITE_ENVIRONMENT +typedef common::concurrent::SharedPointer< IgniteEnvironment > + SP_IgniteEnvironment; + +/** + * Defines environment in which Ignite operates. + */ +class IGNITE_IMPORT_EXPORT IgniteEnvironment { + typedef common::concurrent::SharedPointer< cluster::ClusterNodeImpl > + SP_ClusterNodeImpl; + + public: + /** + * Default memory block allocation size. + */ + enum { DEFAULT_ALLOCATION_SIZE = 1024 }; + + /** + * Default fast path handle registry containers capasity. + */ + enum { DEFAULT_FAST_PATH_CONTAINERS_CAP = 1024 }; + + /** + * Default slow path handle registry containers capasity. + */ + enum { DEFAULT_SLOW_PATH_CONTAINERS_CAP = 16 }; + + /** + * Constructor. + * + * @param cfg Node configuration. + */ + IgniteEnvironment(const IgniteConfiguration& cfg); + + /** + * Destructor. + */ + ~IgniteEnvironment(); + + /** + * Get node configuration. + * + * @return Node configuration. + */ + const IgniteConfiguration& GetConfiguration() const; + + /** + * Populate callback handlers. + * + * @param target (current env wrapped into a shared pointer). + * @return JNI handlers. + */ + jni::java::JniHandlers GetJniHandlers( + common::concurrent::SharedPointer< IgniteEnvironment >* target); + + /** + * Set context. + * + * @param ctx Context. + */ + void SetContext( + common::concurrent::SharedPointer< jni::java::JniContext > ctx); + + /** + * Perform initialization on successful start. + */ + void Initialize(); + + /** + * Start callback. + * + * @param memPtr Memory pointer. + * @param proc Processor instance. + */ + void OnStartCallback(int64_t memPtr, jobject proc); + + /** + * Continuous query listener apply callback. + * + * @param mem Memory with data. + */ + void OnContinuousQueryListenerApply( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Continuous query filter create callback. + * + * @param mem Memory with data. + * @return Filter handle. + */ + int64_t OnContinuousQueryFilterCreate( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Continuous query filter apply callback. + * + * @param mem Memory with data. + */ + int64_t OnContinuousQueryFilterApply( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Callback on future result received. + * + * @param handle Task handle. + * @param value Value. + */ + int64_t OnFuturePrimitiveResult(int64_t handle, int64_t value); + + /** + * Callback on future result received. + * + * @param handle Task handle. + * @param mem Memory with data. + */ + int64_t OnFutureObjectResult( + int64_t handle, + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Callback on future null result received. + * + * @param handle Task handle. + */ + int64_t OnFutureNullResult(int64_t handle); + + /** + * Callback on future error received. + * + * @param handle Task handle. + * @param mem Memory with data. + */ + int64_t OnFutureError( + int64_t handle, + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Callback on compute function execute request. + * + * @param mem Memory with data. + */ + int64_t OnComputeFuncExecute( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Cache Invoke callback. + * + * @param mem Input-output memory. + */ + void CacheInvokeCallback( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Get name of Ignite instance. + * + * @return Name. + */ + const char* InstanceName() const; + + /** + * Get processor associated with the instance. + * + * @return Processor. + */ + void* GetProcessor(); + + /** + * Get JNI context. + * + * @return Context. + */ + jni::java::JniContext* Context(); + + /** + * Get memory for interop operations. + * + * @return Memory. + */ + common::concurrent::SharedPointer< interop::InteropMemory > AllocateMemory(); + + /** + * Get memory chunk for interop operations with desired capacity. + * + * @param cap Capacity. + * @return Memory. + */ + common::concurrent::SharedPointer< interop::InteropMemory > AllocateMemory( + int32_t cap); + + /** + * Get memory chunk located at the given pointer. + * + * @param memPtr Memory pointer. + * @retrun Memory. + */ + common::concurrent::SharedPointer< interop::InteropMemory > GetMemory( + int64_t memPtr); + + /** + * Get type manager. + * + * @return Type manager. + */ + binary::BinaryTypeManager* GetTypeManager(); + + /** + * Get type updater. + * + * @return Type updater. + */ + binary::BinaryTypeUpdater* GetTypeUpdater(); + + /** + * Get local cluster node implementation. + * + * @return Cluster node implementation or NULL if does not exist. + */ + SP_ClusterNodeImpl GetLocalNode(); + + /** + * Get cluster node implementation by id. + * + * @return Cluster node implementation or NULL if does not exist. + */ + SP_ClusterNodeImpl GetNode(Guid Id); + + /** + * Notify processor that Ignite instance has started. + */ + void ProcessorReleaseStart(); + + /** + * Get handle registry. + * + * @return Handle registry. + */ + HandleRegistry& GetHandleRegistry(); + + /** + * Get binding. + * + * @return IgniteBinding instance. + */ + common::concurrent::SharedPointer< IgniteBindingImpl > GetBinding() const; + + /** + * Get processor compute. + * + * @param proj Projection. + * @return Processor compute. + */ + jobject GetProcessorCompute(jobject proj); + + /** + * Locally execute compute job. + * + * @param jobHandle Job handle. + */ + void ComputeJobExecuteLocal(int64_t jobHandle); + + /** + * Locally commit job execution result for the task. + * + * @param taskHandle Task handle. + * @param jobHandle Job handle. + * @return Reduce politics. + */ + int32_t ComputeTaskLocalJobResult(int64_t taskHandle, int64_t jobHandle); + + /** + * Reduce compute task. + * + * @param taskHandle Task handle. + */ + void ComputeTaskReduce(int64_t taskHandle); + + /** + * Complete compute task. + * + * @param taskHandle Task handle. + */ + void ComputeTaskComplete(int64_t taskHandle); + + /** + * Create compute job. + * + * @param mem Memory. + * @return Job handle. + */ + int64_t ComputeJobCreate( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Execute compute job. + * + * @param mem Memory. + * @return Job handle. + */ + void ComputeJobExecute( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Destroy compute job. + * + * @param jobHandle Job handle to destroy. + */ + void ComputeJobDestroy(int64_t jobHandle); + + /** + * Consume result of remote job execution. + * + * @param mem Memory containing result. + * @return Reduce policy. + */ + int32_t ComputeTaskJobResult( + common::concurrent::SharedPointer< interop::InteropMemory >& mem); + + /** + * Get pointer to ignite node. + * + * @return Pointer to ignite node. + */ + ignite::odbc::Ignite* GetIgnite(); + + /** + * InLongOutLong callback. + * Allow access to private nodes member. + * + * @param target Target environment. + * @param type Operation type. + * @param val Value. + */ + friend int64_t IGNITE_CALL InLongOutLong(void* target, int type, int64_t val); + + private: + /** Node configuration. */ + IgniteConfiguration* cfg; + + /** Context to access Java. */ + common::concurrent::SharedPointer< jni::java::JniContext > ctx; + + /** Startup latch. */ + common::concurrent::SingleLatch latch; + + /** Ignite name. */ + char* name; + + /** Processor instance. */ + jni::JavaGlobalRef proc; + + /** Handle registry. */ + HandleRegistry registry; + + /** Type manager. */ + binary::BinaryTypeManager* metaMgr; + + /** Type updater. */ + binary::BinaryTypeUpdater* metaUpdater; + + /** Ignite binding */ + common::concurrent::SharedPointer< IgniteBindingImpl > binding; + + /** Module manager. */ + common::concurrent::SharedPointer< ModuleManager > moduleMgr; + + /** Cluster nodes. */ + common::concurrent::SharedPointer< ClusterNodesHolder > nodes; + + /** Ignite node. */ + ignite::odbc::Ignite* ignite; + + IGNITE_NO_COPY_ASSIGNMENT(IgniteEnvironment); +}; +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_IGNITE_ENVIRONMENT diff --git a/src/odbc/include/ignite/odbc/impl/ignite_impl.h b/src/odbc/include/ignite/odbc/impl/ignite_impl.h index a58286259..c7780d769 100644 --- a/src/odbc/include/ignite/odbc/impl/ignite_impl.h +++ b/src/odbc/include/ignite/odbc/impl/ignite_impl.h @@ -32,234 +32,233 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Ignite implementation. - */ - class IGNITE_FRIEND_EXPORT IgniteImpl : private interop::InteropTarget - { - typedef common::concurrent::SharedPointer SP_IgniteClusterImpl; - typedef common::concurrent::SharedPointer SP_ComputeImpl; - typedef common::concurrent::SharedPointer SP_IgniteBindingImpl; - typedef common::concurrent::SharedPointer SP_CacheAffinityImpl; - public: - /** - * Constructor used to create new instance. - * - * @param env Environment. - */ - IgniteImpl(SP_IgniteEnvironment env); - - /** - * Get affinity service to provide information about data partitioning and distribution. - * - * @param name Cache name. - * @param err Error. - * @return Pointer to cache affinity implementation. - */ - SP_CacheAffinityImpl GetAffinity(const std::string& cacheName, IgniteError& err); - - /** - * Get name of the Ignite. - * - * @return Name. - */ - const char* GetName() const; - - /** - * Get node configuration. - * - * @return Node configuration. - */ - const IgniteConfiguration& GetConfiguration() const; - - /** - * Get JNI context associated with this instance. - * - * @return JNI context for this instance. - */ - jni::java::JniContext* GetContext(); - - /** - * Get cache. - * - * @param name Cache name. - * @param err Error. - */ - cache::CacheImpl* GetCache(const char* name, IgniteError& err); - - /** - * Get or create cache. - * - * @param name Cache name. - * @param err Error. - */ - cache::CacheImpl* GetOrCreateCache(const char* name, IgniteError& err); - - /** - * Create cache. - * - * @param name Cache name. - * @param err Error. - */ - cache::CacheImpl* CreateCache(const char* name, IgniteError& err); - - /** - * Get ignite binding. - * - * @return IgniteBinding class instance. - */ - SP_IgniteBindingImpl GetBinding(); - - /** - * Get instance of the implementation from the proxy class. - * Internal method. Should not be used by user. - * - * @param proxy Proxy instance containing IgniteImpl. - * @return IgniteImpl instance associated with the proxy or null-pointer. - */ - template - static IgniteImpl* GetFromProxy(T& proxy) - { - return proxy.impl.Get(); - } - - /** - * Get environment. - * Internal method. Should not be used by user. - * - * @return Environment pointer. - */ - IgniteEnvironment* GetEnvironment() - { - return env.Get(); - } - - /** - * Get projection. - * - * @return ClusterGroupImpl instance. - */ - cluster::SP_ClusterGroupImpl GetProjection() - { - return prjImpl.Get(); - } - - /** - * Get cluster. - * - * @return IgniteClusterImpl instance. - */ - SP_IgniteClusterImpl GetCluster(); - - /** - * Gets compute instance over all cluster nodes started in server mode. - * - * @return ComputeImpl instance. - */ - SP_ComputeImpl GetCompute(); - - /** - * Gets compute instance over the specified cluster group. All operations - * on the returned compute instance will only include nodes from - * this cluster group. - * - * @param grp Specified cluster group instance. - * @return ComputeImpl instance. - */ - SP_ComputeImpl GetCompute(ignite::odbc::cluster::ClusterGroup grp); - - /** - * Check if the Ignite grid is active. - * - * @return True if grid is active and false otherwise. - */ - bool IsActive() - { - return prjImpl.Get().Get()->IsActive(); - } - - /** - * Change Ignite grid state to active or inactive. - * - * @param active If true start activation process. If false start - * deactivation process. - */ - void SetActive(bool active) - { - prjImpl.Get().Get()->SetActive(active); - } - - /** - * Disable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void DisableWal(std::string cacheName); - - /** - * Enable write-ahead logging for specified cache. - * - * @param cacheName Cache name. - */ - void EnableWal(std::string cacheName); - - /** - * Check if write - ahead logging is enabled for specified cache. - * - * @param cacheName Cache name. - * - * @return True if enabled. - */ - bool IsWalEnabled(std::string cacheName); - - /** - * Set baseline topology constructed from the cluster topology of the given version. - * The method succeeds only if the cluster topology has not changed. - * - * @param topVer Topology version. - */ - void SetBaselineTopologyVersion(int64_t topVer); - - /** - * Set transaction timeout on partition map exchange. - * - * @param timeout Timeout in milliseconds. - */ - void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); - - private: - /** - * Get current projection internal call. - * - * @return ClusterGroupImpl instance. - */ - cluster::ClusterGroupImpl* InternalGetProjection(); - - /** Environment. */ - SP_IgniteEnvironment env; - - /** Projection implementation. */ - common::Lazy prjImpl; - - IGNITE_NO_COPY_ASSIGNMENT(IgniteImpl); - - /** - * Get or create cache. - * - * @param name Cache name. - * @param err Error. - * @param op Operation code. - */ - cache::CacheImpl* GetOrCreateCache(const char* name, IgniteError& err, int32_t op); - }; - } - } -} - -#endif //_IGNITE_ODBC_IMPL_IGNITE_ODBC_IMPL +namespace ignite { +namespace odbc { +namespace impl { +/** + * Ignite implementation. + */ +class IGNITE_FRIEND_EXPORT IgniteImpl : private interop::InteropTarget { + typedef common::concurrent::SharedPointer< cluster::IgniteClusterImpl > + SP_IgniteClusterImpl; + typedef common::concurrent::SharedPointer< compute::ComputeImpl > + SP_ComputeImpl; + typedef common::concurrent::SharedPointer< IgniteBindingImpl > + SP_IgniteBindingImpl; + typedef common::concurrent::SharedPointer< cache::CacheAffinityImpl > + SP_CacheAffinityImpl; + + public: + /** + * Constructor used to create new instance. + * + * @param env Environment. + */ + IgniteImpl(SP_IgniteEnvironment env); + + /** + * Get affinity service to provide information about data partitioning and + * distribution. + * + * @param name Cache name. + * @param err Error. + * @return Pointer to cache affinity implementation. + */ + SP_CacheAffinityImpl GetAffinity(const std::string& cacheName, + IgniteError& err); + + /** + * Get name of the Ignite. + * + * @return Name. + */ + const char* GetName() const; + + /** + * Get node configuration. + * + * @return Node configuration. + */ + const IgniteConfiguration& GetConfiguration() const; + + /** + * Get JNI context associated with this instance. + * + * @return JNI context for this instance. + */ + jni::java::JniContext* GetContext(); + + /** + * Get cache. + * + * @param name Cache name. + * @param err Error. + */ + cache::CacheImpl* GetCache(const char* name, IgniteError& err); + + /** + * Get or create cache. + * + * @param name Cache name. + * @param err Error. + */ + cache::CacheImpl* GetOrCreateCache(const char* name, IgniteError& err); + + /** + * Create cache. + * + * @param name Cache name. + * @param err Error. + */ + cache::CacheImpl* CreateCache(const char* name, IgniteError& err); + + /** + * Get ignite binding. + * + * @return IgniteBinding class instance. + */ + SP_IgniteBindingImpl GetBinding(); + + /** + * Get instance of the implementation from the proxy class. + * Internal method. Should not be used by user. + * + * @param proxy Proxy instance containing IgniteImpl. + * @return IgniteImpl instance associated with the proxy or null-pointer. + */ + template < typename T > + static IgniteImpl* GetFromProxy(T& proxy) { + return proxy.impl.Get(); + } + + /** + * Get environment. + * Internal method. Should not be used by user. + * + * @return Environment pointer. + */ + IgniteEnvironment* GetEnvironment() { + return env.Get(); + } + + /** + * Get projection. + * + * @return ClusterGroupImpl instance. + */ + cluster::SP_ClusterGroupImpl GetProjection() { + return prjImpl.Get(); + } + + /** + * Get cluster. + * + * @return IgniteClusterImpl instance. + */ + SP_IgniteClusterImpl GetCluster(); + + /** + * Gets compute instance over all cluster nodes started in server mode. + * + * @return ComputeImpl instance. + */ + SP_ComputeImpl GetCompute(); + + /** + * Gets compute instance over the specified cluster group. All operations + * on the returned compute instance will only include nodes from + * this cluster group. + * + * @param grp Specified cluster group instance. + * @return ComputeImpl instance. + */ + SP_ComputeImpl GetCompute(ignite::odbc::cluster::ClusterGroup grp); + + /** + * Check if the Ignite grid is active. + * + * @return True if grid is active and false otherwise. + */ + bool IsActive() { + return prjImpl.Get().Get()->IsActive(); + } + + /** + * Change Ignite grid state to active or inactive. + * + * @param active If true start activation process. If false start + * deactivation process. + */ + void SetActive(bool active) { + prjImpl.Get().Get()->SetActive(active); + } + + /** + * Disable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void DisableWal(std::string cacheName); + + /** + * Enable write-ahead logging for specified cache. + * + * @param cacheName Cache name. + */ + void EnableWal(std::string cacheName); + + /** + * Check if write - ahead logging is enabled for specified cache. + * + * @param cacheName Cache name. + * + * @return True if enabled. + */ + bool IsWalEnabled(std::string cacheName); + + /** + * Set baseline topology constructed from the cluster topology of the given + * version. The method succeeds only if the cluster topology has not changed. + * + * @param topVer Topology version. + */ + void SetBaselineTopologyVersion(int64_t topVer); + + /** + * Set transaction timeout on partition map exchange. + * + * @param timeout Timeout in milliseconds. + */ + void SetTxTimeoutOnPartitionMapExchange(int64_t timeout); + + private: + /** + * Get current projection internal call. + * + * @return ClusterGroupImpl instance. + */ + cluster::ClusterGroupImpl* InternalGetProjection(); + + /** Environment. */ + SP_IgniteEnvironment env; + + /** Projection implementation. */ + common::Lazy< cluster::ClusterGroupImpl > prjImpl; + + IGNITE_NO_COPY_ASSIGNMENT(IgniteImpl); + + /** + * Get or create cache. + * + * @param name Cache name. + * @param err Error. + * @param op Operation code. + */ + cache::CacheImpl* GetOrCreateCache(const char* name, IgniteError& err, + int32_t op); +}; +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_IGNITE_ODBC_IMPL diff --git a/src/odbc/include/ignite/odbc/impl/interop/interop_external_memory.h b/src/odbc/include/ignite/odbc/impl/interop/interop_external_memory.h index 6bc448e68..f1634361f 100644 --- a/src/odbc/include/ignite/odbc/impl/interop/interop_external_memory.h +++ b/src/odbc/include/ignite/odbc/impl/interop/interop_external_memory.h @@ -24,34 +24,30 @@ #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace interop - { - /** - * Interop external memory. - */ - class IGNITE_IMPORT_EXPORT InteropExternalMemory : public InteropMemory - { - public: - /** - * Constructor. - * - * @param memPtr External memory pointer. - */ - explicit InteropExternalMemory(int8_t* memPtr); - - virtual void Reallocate(int32_t cap); - private: - IGNITE_NO_COPY_ASSIGNMENT(InteropExternalMemory); - }; - } - } - } -} - -#endif //_IGNITE_ODBC_IMPL_INTEROP_INTEROP_EXTERNAL_MEMORY +namespace ignite { +namespace odbc { +namespace impl { +namespace interop { +/** + * Interop external memory. + */ +class IGNITE_IMPORT_EXPORT InteropExternalMemory : public InteropMemory { + public: + /** + * Constructor. + * + * @param memPtr External memory pointer. + */ + explicit InteropExternalMemory(int8_t* memPtr); + + virtual void Reallocate(int32_t cap); + + private: + IGNITE_NO_COPY_ASSIGNMENT(InteropExternalMemory); +}; +} // namespace interop +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_INTEROP_INTEROP_EXTERNAL_MEMORY diff --git a/src/odbc/include/ignite/odbc/impl/interop/interop_target.h b/src/odbc/include/ignite/odbc/impl/interop/interop_target.h index 8bc15e849..5a192665e 100644 --- a/src/odbc/include/ignite/odbc/impl/interop/interop_target.h +++ b/src/odbc/include/ignite/odbc/impl/interop/interop_target.h @@ -21,252 +21,253 @@ #include #include -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace interop - { - /** - * Interop target. - */ - class IGNITE_IMPORT_EXPORT InteropTarget - { - public: - /** - * Operation result. - */ - struct OperationResult - { - enum Type - { - /** Null. */ - AI_NULL = 0, - - /** Success. */ - AI_SUCCESS = 1, - - /** Error. */ - AI_ERROR = -1 - }; - }; - - /** - * Constructor used to create new instance. - * - * @param env Environment. - * @param javaRef Reference to java object. - */ - InteropTarget(ignite::odbc::common::concurrent::SharedPointer env, jobject javaRef); - - /** - * Constructor used to create new instance. - * - * @param env Environment. - * @param javaRef Reference to java object. - * @param javaRef Whether javaRef release in destructor should be skipped. - */ - InteropTarget(ignite::odbc::common::concurrent::SharedPointer env, jobject javaRef, - bool skipJavaRefRelease); - - /** - * Destructor. - */ - virtual ~InteropTarget(); - - /** - * Internal out operation. - * - * @param opType Operation type. - * @param inMem Input memory. - * @param err Error. - * @return Result. - */ - bool OutOp(int32_t opType, InteropMemory& inMem, IgniteError& err); - - /** - * Internal out operation. - * - * @param opType Operation type. - * @param inOp Input. - * @param err Error. - * @return Result. - */ - bool OutOp(int32_t opType, InputOperation& inOp, IgniteError& err); - - /** - * Internal out operation. - * - * @param opType Operation type. - * @param err Error. - * @return Result. - */ - bool OutOp(int32_t opType, IgniteError& err); - - /** - * Internal in operation. - * - * @param opType Operation type. - * @param outOp Output. - * @param err Error. - * @return Result. - */ - bool InOp(int32_t opType, OutputOperation& outOp, IgniteError& err); - - /** - * Internal in Object operation. - * - * @param opType Operation type. - * @param err Error. - * @return Object. - */ - jobject InOpObject(int32_t opType, IgniteError& err); - - /** - * Internal out-in operation. - * Uses two independent memory pieces to write and read data. - * - * @param opType Operation type. - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * Internal out-in operation. - * Uses single memory piece to write and read data. - * - * @param opType Operation type. - * @param inOp Input. - * @param outOp Output. - * @param err Error. - */ - void OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err); - - /** - * In stream out long operation. - * - * @param opType Type of operation. - * @param outInMem Input and output memory. - * @param err Error. - * @return Operation result. - */ - OperationResult::Type InStreamOutLong(int32_t opType, InteropMemory& outInMem, IgniteError& err); - - /** - * In stream out long operation. - * - * @param opType Type of operation. - * @param inOp Input opeartion. - * @param err Error. - * @return Operation result or long value. - */ - int64_t InStreamOutLong(int32_t opType, InputOperation& inOp, IgniteError& err); - - /** - * In stream out object operation. - * - * @param opType Type of operation. - * @param outInMem Input and output memory. - * @param err Error. - * @return Java object references. - */ - jobject InStreamOutObject(int32_t opType, InteropMemory& outInMem, IgniteError& err); - - /** - * In stream out stream operation. - * - * @param opType Type of operation. - * @param inMem Input memory. - * @param outMem Output memory. - * @param err Error. - */ - void InStreamOutStream(int32_t opType, InteropMemory& inMem, InteropMemory& outMem, IgniteError& err); - - /** - * Internal out-in operation. - * - * @param opType Operation type. - * @param val Value. - * @param err Error. - */ - int64_t OutInOpLong(int32_t opType, int64_t val, IgniteError& err); - - /** - * Get environment shared pointer. - * - * @return Environment shared pointer. - */ - ignite::odbc::common::concurrent::SharedPointer GetEnvironmentPointer() - { - return env; - } - - protected: - /** - * Get raw target. - * - * @return Underlying java object reference. - */ - jobject GetTarget() - { - return javaRef; - } - - /** - * Get environment reference. - * - * @return Environment reference. - */ - IgniteEnvironment& GetEnvironment() - { - return *env.Get(); - } - - private: - /** Environment. */ - ignite::odbc::common::concurrent::SharedPointer env; - - /** Handle to Java object. */ - jobject javaRef; - - /** javaRef release flag. */ - bool skipJavaRefRelease; - - IGNITE_NO_COPY_ASSIGNMENT(InteropTarget); - - /** - * Write data to memory. - * - * @param mem Memory. - * @param inOp Input opeartion. - * @param err Error. - * @return Memory pointer. - */ - int64_t WriteTo(interop::InteropMemory* mem, InputOperation& inOp, IgniteError& err); - - /** - * Read data from memory. - * - * @param mem Memory. - * @param outOp Output operation. - */ - void ReadFrom(interop::InteropMemory* mem, OutputOperation& outOp); - - /** - * Read error data from memory. - * - * @param mem Memory. - * @param err Error. - */ - void ReadError(interop::InteropMemory* mem, IgniteError& err); - }; - } - } - } -} +namespace ignite { +namespace odbc { +namespace impl { +namespace interop { +/** + * Interop target. + */ +class IGNITE_IMPORT_EXPORT InteropTarget { + public: + /** + * Operation result. + */ + struct OperationResult { + enum Type { + /** Null. */ + AI_NULL = 0, + + /** Success. */ + AI_SUCCESS = 1, + + /** Error. */ + AI_ERROR = -1 + }; + }; + + /** + * Constructor used to create new instance. + * + * @param env Environment. + * @param javaRef Reference to java object. + */ + InteropTarget( + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > env, + jobject javaRef); + + /** + * Constructor used to create new instance. + * + * @param env Environment. + * @param javaRef Reference to java object. + * @param javaRef Whether javaRef release in destructor should be skipped. + */ + InteropTarget( + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > env, + jobject javaRef, bool skipJavaRefRelease); + + /** + * Destructor. + */ + virtual ~InteropTarget(); + + /** + * Internal out operation. + * + * @param opType Operation type. + * @param inMem Input memory. + * @param err Error. + * @return Result. + */ + bool OutOp(int32_t opType, InteropMemory& inMem, IgniteError& err); + + /** + * Internal out operation. + * + * @param opType Operation type. + * @param inOp Input. + * @param err Error. + * @return Result. + */ + bool OutOp(int32_t opType, InputOperation& inOp, IgniteError& err); + + /** + * Internal out operation. + * + * @param opType Operation type. + * @param err Error. + * @return Result. + */ + bool OutOp(int32_t opType, IgniteError& err); + + /** + * Internal in operation. + * + * @param opType Operation type. + * @param outOp Output. + * @param err Error. + * @return Result. + */ + bool InOp(int32_t opType, OutputOperation& outOp, IgniteError& err); + + /** + * Internal in Object operation. + * + * @param opType Operation type. + * @param err Error. + * @return Object. + */ + jobject InOpObject(int32_t opType, IgniteError& err); + + /** + * Internal out-in operation. + * Uses two independent memory pieces to write and read data. + * + * @param opType Operation type. + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * Internal out-in operation. + * Uses single memory piece to write and read data. + * + * @param opType Operation type. + * @param inOp Input. + * @param outOp Output. + * @param err Error. + */ + void OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, + IgniteError& err); + + /** + * In stream out long operation. + * + * @param opType Type of operation. + * @param outInMem Input and output memory. + * @param err Error. + * @return Operation result. + */ + OperationResult::Type InStreamOutLong(int32_t opType, InteropMemory& outInMem, + IgniteError& err); + + /** + * In stream out long operation. + * + * @param opType Type of operation. + * @param inOp Input opeartion. + * @param err Error. + * @return Operation result or long value. + */ + int64_t InStreamOutLong(int32_t opType, InputOperation& inOp, + IgniteError& err); + + /** + * In stream out object operation. + * + * @param opType Type of operation. + * @param outInMem Input and output memory. + * @param err Error. + * @return Java object references. + */ + jobject InStreamOutObject(int32_t opType, InteropMemory& outInMem, + IgniteError& err); + + /** + * In stream out stream operation. + * + * @param opType Type of operation. + * @param inMem Input memory. + * @param outMem Output memory. + * @param err Error. + */ + void InStreamOutStream(int32_t opType, InteropMemory& inMem, + InteropMemory& outMem, IgniteError& err); + + /** + * Internal out-in operation. + * + * @param opType Operation type. + * @param val Value. + * @param err Error. + */ + int64_t OutInOpLong(int32_t opType, int64_t val, IgniteError& err); + + /** + * Get environment shared pointer. + * + * @return Environment shared pointer. + */ + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > + GetEnvironmentPointer() { + return env; + } + + protected: + /** + * Get raw target. + * + * @return Underlying java object reference. + */ + jobject GetTarget() { + return javaRef; + } + + /** + * Get environment reference. + * + * @return Environment reference. + */ + IgniteEnvironment& GetEnvironment() { + return *env.Get(); + } + + private: + /** Environment. */ + ignite::odbc::common::concurrent::SharedPointer< IgniteEnvironment > env; + + /** Handle to Java object. */ + jobject javaRef; + + /** javaRef release flag. */ + bool skipJavaRefRelease; + + IGNITE_NO_COPY_ASSIGNMENT(InteropTarget); + + /** + * Write data to memory. + * + * @param mem Memory. + * @param inOp Input opeartion. + * @param err Error. + * @return Memory pointer. + */ + int64_t WriteTo(interop::InteropMemory* mem, InputOperation& inOp, + IgniteError& err); + + /** + * Read data from memory. + * + * @param mem Memory. + * @param outOp Output operation. + */ + void ReadFrom(interop::InteropMemory* mem, OutputOperation& outOp); + + /** + * Read error data from memory. + * + * @param mem Memory. + * @param err Error. + */ + void ReadError(interop::InteropMemory* mem, IgniteError& err); +}; +} // namespace interop +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_INTEROP_INTEROP_TARGET +#endif //_IGNITE_ODBC_IMPL_INTEROP_INTEROP_TARGET diff --git a/src/odbc/include/ignite/odbc/impl/module_manager.h b/src/odbc/include/ignite/odbc/impl/module_manager.h index 2d194e160..a4ea66d9e 100644 --- a/src/odbc/include/ignite/odbc/impl/module_manager.h +++ b/src/odbc/include/ignite/odbc/impl/module_manager.h @@ -37,125 +37,115 @@ */ #define IGNITE_MODULE_ADDITIONAL_INIT_CALLBACKS_MAX_NUM 100 -#define IGNITE_EXPORTED_CALL \ - extern "C" IGNITE_IMPORT_EXPORT - -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Module manager. - * Provides methods to manipulate loadable modules. - */ - class ModuleManager - { - typedef common::dynamic::Module Module; - typedef void (ModuleInitCallback)(IgniteBindingContext&); - - public: - /** - * Constructor. - * - * @param context Ignite binding context. - */ - ModuleManager(const IgniteBindingContext& context) : - loadedModules(), - bindingContext(context) - { - // No-op. - } - - /** - * Destructor. - */ - ~ModuleManager() - { - for (std::vector::iterator it = loadedModules.begin(); it != loadedModules.end(); ++it) - it->Unload(); - } - - /** - * Load module. - * - * @param path Module path. - * @param err Error. - */ - void LoadModule(const std::wstring& path, IgniteError& err) - { - common::dynamic::Module module = common::dynamic::LoadModule(path); - - if (!module.IsLoaded()) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - ("Can not load module [path=" + utility::ToUtf8(path) + ']').c_str()); - - return; - } - - RegisterModule(module); - } - - /** - * Register module in ModuleManager. - * - * @param module Module to register. - */ - void RegisterModule(Module& module) - { - loadedModules.push_back(module); - - ModuleInitCallback* callback = GetModuleInitCallback(module); - - if (callback) - callback(bindingContext); - - for (int i = 0; i < IGNITE_MODULE_ADDITIONAL_INIT_CALLBACKS_MAX_NUM; ++i) - { - ModuleInitCallback* callback0 = GetAdditionalModuleInitCallback(module, i); - - if (!callback0) - break; - - callback0(bindingContext); - } - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ModuleManager); - - /** - * Get callback that inits Ignite module. - * - * @param module Module for which callback should be retrieved. - * @return Callback if found and null-pointer otherwise. - */ - static ModuleInitCallback* GetModuleInitCallback(Module& module) - { - return reinterpret_cast( - module.FindSymbol(IGNITE_MODULE_INIT_CALLBACK_NAME)); - } - - static ModuleInitCallback* GetAdditionalModuleInitCallback(Module& module, int num) - { - std::stringstream tmp; - - tmp << IGNITE_MODULE_INIT_CALLBACK_NAME << num; - - return reinterpret_cast( - module.FindSymbol(tmp.str())); - } - - /** Collection of loaded modules. */ - std::vector loadedModules; - - /** Ignite environment. */ - IgniteBindingContext bindingContext; - }; - } +#define IGNITE_EXPORTED_CALL extern "C" IGNITE_IMPORT_EXPORT + +namespace ignite { +namespace odbc { +namespace impl { +/** + * Module manager. + * Provides methods to manipulate loadable modules. + */ +class ModuleManager { + typedef common::dynamic::Module Module; + typedef void(ModuleInitCallback)(IgniteBindingContext&); + + public: + /** + * Constructor. + * + * @param context Ignite binding context. + */ + ModuleManager(const IgniteBindingContext& context) + : loadedModules(), bindingContext(context) { + // No-op. + } + + /** + * Destructor. + */ + ~ModuleManager() { + for (std::vector< Module >::iterator it = loadedModules.begin(); + it != loadedModules.end(); ++it) + it->Unload(); + } + + /** + * Load module. + * + * @param path Module path. + * @param err Error. + */ + void LoadModule(const std::wstring& path, IgniteError& err) { + common::dynamic::Module module = common::dynamic::LoadModule(path); + + if (!module.IsLoaded()) { + err = IgniteError( + IgniteError::IGNITE_ERR_GENERIC, + ("Can not load module [path=" + utility::ToUtf8(path) + ']').c_str()); + + return; } -} -#endif //_IGNITE_ODBC_IMPL_MODULE_MANAGER + RegisterModule(module); + } + + /** + * Register module in ModuleManager. + * + * @param module Module to register. + */ + void RegisterModule(Module& module) { + loadedModules.push_back(module); + + ModuleInitCallback* callback = GetModuleInitCallback(module); + + if (callback) + callback(bindingContext); + + for (int i = 0; i < IGNITE_MODULE_ADDITIONAL_INIT_CALLBACKS_MAX_NUM; ++i) { + ModuleInitCallback* callback0 = + GetAdditionalModuleInitCallback(module, i); + + if (!callback0) + break; + + callback0(bindingContext); + } + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ModuleManager); + + /** + * Get callback that inits Ignite module. + * + * @param module Module for which callback should be retrieved. + * @return Callback if found and null-pointer otherwise. + */ + static ModuleInitCallback* GetModuleInitCallback(Module& module) { + return reinterpret_cast< ModuleInitCallback* >( + module.FindSymbol(IGNITE_MODULE_INIT_CALLBACK_NAME)); + } + + static ModuleInitCallback* GetAdditionalModuleInitCallback(Module& module, + int num) { + std::stringstream tmp; + + tmp << IGNITE_MODULE_INIT_CALLBACK_NAME << num; + + return reinterpret_cast< ModuleInitCallback* >( + module.FindSymbol(tmp.str())); + } + + /** Collection of loaded modules. */ + std::vector< Module > loadedModules; + + /** Ignite environment. */ + IgniteBindingContext bindingContext; +}; +} // namespace impl +} // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_IMPL_MODULE_MANAGER diff --git a/src/odbc/include/ignite/odbc/impl/operations.h b/src/odbc/include/ignite/odbc/impl/operations.h index c99c66413..7cfe33d85 100644 --- a/src/odbc/include/ignite/odbc/impl/operations.h +++ b/src/odbc/include/ignite/odbc/impl/operations.h @@ -31,647 +31,600 @@ #include "ignite/odbc/impl/helpers.h" #include "ignite/odbc/binary/binary.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Input operation. - */ - class InputOperation - { - public: - /** - * Destructor. - */ - virtual ~InputOperation() - { - // No-op. - } - - /** - * Process input. - * - * @param writer Writer. - */ - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) = 0; - }; - - /** - * Input operation accepting a single argument. - */ - template - class In1Operation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val Value. - */ - In1Operation(const T& val) : val(val) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.WriteTopObject(val); - } - private: - /** Value. */ - const T& val; - - IGNITE_NO_COPY_ASSIGNMENT(In1Operation); - }; - - /** - * Input operation accepting two single objects. - */ - template - class In2Operation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val1 First value. - * @param val2 Second value. - */ - In2Operation(const T1& val1, const T2& val2) : val1(val1), val2(val2) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.WriteTopObject(val1); - writer.WriteTopObject(val2); - } - private: - /** First value. */ - const T1& val1; - - /** Second value. */ - const T2& val2; - - IGNITE_NO_COPY_ASSIGNMENT(In2Operation); - }; - - /** - * Input operation accepting three single objects. - */ - template - class In3Operation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val1 First value. - * @param val2 Second value. - * @param val3 Third value. - */ - In3Operation(const T1& val1, const T2& val2, const T3& val3) : val1(val1), val2(val2), val3(val3) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.WriteTopObject(val1); - writer.WriteTopObject(val2); - writer.WriteTopObject(val3); - } - private: - /** First value. */ - const T1& val1; - - /** Second value. */ - const T2& val2; - - /** Third value. */ - const T3& val3; - - IGNITE_NO_COPY_ASSIGNMENT(In3Operation); - }; - - /** - * Input set operation. - */ - template - class InSetOperation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val Value. - */ - InSetOperation(const std::set& val) : val(val) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.GetStream()->WriteInt32(static_cast(val.size())); - - for (typename std::set::const_iterator it = val.begin(); it != val.end(); ++it) - writer.WriteTopObject(*it); - } - private: - /** Value. */ - const std::set& val; - - IGNITE_NO_COPY_ASSIGNMENT(InSetOperation); - }; - - /** - * Input map operation. - */ - template - class InMapOperation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val Value. - */ - InMapOperation(const std::map& val) : val(val) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.GetStream()->WriteInt32(static_cast(val.size())); - - for (typename std::map::const_iterator it = val.begin(); it != val.end(); ++it) { - writer.WriteTopObject(it->first); - writer.WriteTopObject(it->second); - } - } - private: - /** Value. */ - const std::map& val; - - IGNITE_NO_COPY_ASSIGNMENT(InMapOperation); - }; - - /** - * Cache LocalPeek input operation. - */ - template - class InCacheLocalPeekOperation : public InputOperation - { - public: - /** - * Constructor. - * - * @param key Key. - * @param peekModes Peek modes. - */ - InCacheLocalPeekOperation(const T& key, int32_t peekModes) : key(key), peekModes(peekModes) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.WriteTopObject(key); - writer.GetStream()->WriteInt32(peekModes); - } - private: - /** Key. */ - const T& key; - - /** Peek modes. */ - int32_t peekModes; - - IGNITE_NO_COPY_ASSIGNMENT(InCacheLocalPeekOperation); - }; - - /** - * Cache Invoke input operation. - */ - template - class InCacheInvokeOperation : public InputOperation - { - public: - /** - * Constructor. - * - * @param val1 First value. - * @param val2 Second value. - */ - InCacheInvokeOperation(const T1& val1, const T2& val2) : val1(val1), val2(val2) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - writer.WriteTopObject(val1); - writer.WriteInt64(0); - writer.WriteTopObject(val2); - } - private: - /** First value. */ - const T1& val1; - - /** Second value. */ - const T2& val2; - - IGNITE_NO_COPY_ASSIGNMENT(InCacheInvokeOperation); - }; - - /** - * Input iterator operation. - */ - template - class InIterOperation : public InputOperation - { - public: - /** - * Constructor. - * - * @param begin Iterator pointing to the beggining of the sequence. - * @param end Iterator pointing to the end of the key sequence. - */ - InIterOperation(Iter begin, Iter end) : - begin(begin), - end(end) - { - // No-op. - } - - virtual void ProcessInput(ignite::odbc::impl::binary::BinaryWriterImpl& writer) - { - interop::InteropOutputStream& stream = *writer.GetStream(); - int32_t sizePos = stream.Reserve(4); - - int32_t size = 0; - for (Iter it = begin; it != end; ++it) - { - ContainerEntryWriteHelper::Write(writer, *it); - ++size; - } - - stream.WriteInt32(sizePos, size); - } - private: - /** Sequence begining. */ - Iter begin; - - /** Sequence end. */ - Iter end; - - IGNITE_NO_COPY_ASSIGNMENT(InIterOperation); - }; - - /** - * Output operation. - */ - class OutputOperation - { - public: - /** - * Destructor. - */ - virtual ~OutputOperation() - { - // No-op. - } - - /** - * Process output. - * - * @param reader Reader. - */ - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) = 0; - - /** - * Sets result to null value. - */ - virtual void SetNull() = 0; - }; - - /** - * Output operation returning single object. - */ - template - class Out1Operation : public OutputOperation - { - public: - /** - * Constructor. - * - * @param val Value. - */ - Out1Operation(T& val) : - val(val) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - reader.ReadTopObject(val); - } - - virtual void SetNull() - { - val = binary::BinaryUtils::GetDefaultValue(); - } - - private: - /** Value. */ - T& val; - - IGNITE_NO_COPY_ASSIGNMENT(Out1Operation); - }; - - /** - * Output operation returning two objects. - */ - template - class Out2Operation : public OutputOperation - { - public: - /** - * Constructor. - * - * @param val1 Value 1. - * @param val2 Value 2. - */ - Out2Operation(T1& val1, T2& val2) : - val1(val1), - val2(val2) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - reader.ReadTopObject(val1); - reader.ReadTopObject(val2); - } - - virtual void SetNull() - { - val1 = binary::BinaryUtils::GetDefaultValue(); - val2 = binary::BinaryUtils::GetDefaultValue(); - } - - private: - /** Value 1. */ - T1& val1; - - /** Value 2. */ - T2& val2; - - IGNITE_NO_COPY_ASSIGNMENT(Out2Operation); - }; - - /** - * Output operation returning four objects. - */ - template - class Out4Operation : public OutputOperation - { - public: - /** - * Constructor. - * - * @param val1 Value 1. - * @param val2 Value 2. - * @param val3 Value 3. - * @param val4 Value 4. - */ - Out4Operation(T1& val1, T2& val2, T3& val3, T4& val4) : - val1(val1), - val2(val2), - val3(val3), - val4(val4) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - reader.ReadTopObject(val1); - reader.ReadTopObject(val2); - reader.ReadTopObject(val3); - reader.ReadTopObject(val4); - } - - virtual void SetNull() - { - val1 = binary::BinaryUtils::GetDefaultValue(); - val2 = binary::BinaryUtils::GetDefaultValue(); - val3 = binary::BinaryUtils::GetDefaultValue(); - val4 = binary::BinaryUtils::GetDefaultValue(); - } - - private: - /** Value 1. */ - T1& val1; - - /** Value 2. */ - T2& val2; - - /** Value 3. */ - T3& val3; - - /** Value 4. */ - T4& val4; - - IGNITE_NO_COPY_ASSIGNMENT(Out4Operation); - }; - - /** - * Output map operation. - */ - template - class OutMapOperation :public OutputOperation - { - public: - /** - * Constructor. - * - * @param val Value. - */ - OutMapOperation(std::map& val) : - val(val) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - bool exists = reader.GetStream()->ReadBool(); - - if (exists) - { - int32_t cnt = reader.GetStream()->ReadInt32(); - - std::map val0; - - for (int i = 0; i < cnt; i++) { - T1 t1 = reader.ReadTopObject(); - T2 t2 = reader.ReadTopObject(); - - val0[t1] = t2; - } - - std::swap(val, val0); - } - } - - virtual void SetNull() - { - // No-op. - } - - private: - /** Value. */ - std::map& val; - - IGNITE_NO_COPY_ASSIGNMENT(OutMapOperation); - }; - - /** - * Output query GET ALL operation. - */ - template - class OutQueryGetAllOperation : public OutputOperation - { - public: - /** - * Constructor. - */ - OutQueryGetAllOperation(std::vector >& res) : res(res) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - int32_t cnt = reader.ReadInt32(); - - res.reserve(res.size() + cnt); - - for (int i = 0; i < cnt; i++) - { - K key = reader.ReadTopObject(); - V val = reader.ReadTopObject(); - - res.push_back(ignite::odbc::cache::CacheEntry(key, val)); - } - } - - virtual void SetNull() - { - res.clear(); - } - - private: - /** Entries. */ - std::vector >& res; - - IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperation); - }; - - /** - * Output query GET ALL operation. - */ - template > - class OutQueryGetAllOperationIter : public OutputOperation - { - public: - /** - * Constructor. - */ - OutQueryGetAllOperationIter(Iter iter) : iter(iter) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - int32_t cnt = reader.ReadInt32(); - - for (int32_t i = 0; i < cnt; i++) - { - K key = reader.ReadTopObject(); - V val = reader.ReadTopObject(); - - *iter = Pair(key, val); - ++iter; - } - } - - virtual void SetNull() - { - // No-op. - } - - private: - /** Out iter. */ - Iter iter; - - IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperationIter); - }; - - /** - * Output iter operation. - */ - template - class OutMapIterOperation :public OutputOperation - { - public: - /** - * Constructor. - */ - OutMapIterOperation(Iter iter) : iter(iter) - { - // No-op. - } - - virtual void ProcessOutput(binary::BinaryReaderImpl& reader) - { - bool exists = reader.GetStream()->ReadBool(); - - if (exists) - { - int32_t cnt = reader.GetStream()->ReadInt32(); - - for (int32_t i = 0; i < cnt; i++) { - K key = reader.ReadTopObject(); - V val = reader.ReadTopObject(); - - *iter = std::pair(key, val); - ++iter; - } - } - } - - virtual void SetNull() - { - // No-op. - } - private: - /** Out iter. */ - Iter iter; - - IGNITE_NO_COPY_ASSIGNMENT(OutMapIterOperation); - }; - } +namespace ignite { +namespace odbc { +namespace impl { +/** + * Input operation. + */ +class InputOperation { + public: + /** + * Destructor. + */ + virtual ~InputOperation() { + // No-op. + } + + /** + * Process input. + * + * @param writer Writer. + */ + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) = 0; +}; + +/** + * Input operation accepting a single argument. + */ +template < typename T > +class In1Operation : public InputOperation { + public: + /** + * Constructor. + * + * @param val Value. + */ + In1Operation(const T& val) : val(val) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.WriteTopObject< T >(val); + } + + private: + /** Value. */ + const T& val; + + IGNITE_NO_COPY_ASSIGNMENT(In1Operation); +}; + +/** + * Input operation accepting two single objects. + */ +template < typename T1, typename T2 > +class In2Operation : public InputOperation { + public: + /** + * Constructor. + * + * @param val1 First value. + * @param val2 Second value. + */ + In2Operation(const T1& val1, const T2& val2) : val1(val1), val2(val2) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.WriteTopObject< T1 >(val1); + writer.WriteTopObject< T2 >(val2); + } + + private: + /** First value. */ + const T1& val1; + + /** Second value. */ + const T2& val2; + + IGNITE_NO_COPY_ASSIGNMENT(In2Operation); +}; + +/** + * Input operation accepting three single objects. + */ +template < typename T1, typename T2, typename T3 > +class In3Operation : public InputOperation { + public: + /** + * Constructor. + * + * @param val1 First value. + * @param val2 Second value. + * @param val3 Third value. + */ + In3Operation(const T1& val1, const T2& val2, const T3& val3) + : val1(val1), val2(val2), val3(val3) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.WriteTopObject< T1 >(val1); + writer.WriteTopObject< T2 >(val2); + writer.WriteTopObject< T3 >(val3); + } + + private: + /** First value. */ + const T1& val1; + + /** Second value. */ + const T2& val2; + + /** Third value. */ + const T3& val3; + + IGNITE_NO_COPY_ASSIGNMENT(In3Operation); +}; + +/** + * Input set operation. + */ +template < typename T > +class InSetOperation : public InputOperation { + public: + /** + * Constructor. + * + * @param val Value. + */ + InSetOperation(const std::set< T >& val) : val(val) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.GetStream()->WriteInt32(static_cast< int32_t >(val.size())); + + for (typename std::set< T >::const_iterator it = val.begin(); + it != val.end(); ++it) + writer.WriteTopObject< T >(*it); + } + + private: + /** Value. */ + const std::set< T >& val; + + IGNITE_NO_COPY_ASSIGNMENT(InSetOperation); +}; + +/** + * Input map operation. + */ +template < typename K, typename V > +class InMapOperation : public InputOperation { + public: + /** + * Constructor. + * + * @param val Value. + */ + InMapOperation(const std::map< K, V >& val) : val(val) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.GetStream()->WriteInt32(static_cast< int32_t >(val.size())); + + for (typename std::map< K, V >::const_iterator it = val.begin(); + it != val.end(); ++it) { + writer.WriteTopObject< K >(it->first); + writer.WriteTopObject< V >(it->second); + } + } + + private: + /** Value. */ + const std::map< K, V >& val; + + IGNITE_NO_COPY_ASSIGNMENT(InMapOperation); +}; + +/** + * Cache LocalPeek input operation. + */ +template < typename T > +class InCacheLocalPeekOperation : public InputOperation { + public: + /** + * Constructor. + * + * @param key Key. + * @param peekModes Peek modes. + */ + InCacheLocalPeekOperation(const T& key, int32_t peekModes) + : key(key), peekModes(peekModes) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.WriteTopObject< T >(key); + writer.GetStream()->WriteInt32(peekModes); + } + + private: + /** Key. */ + const T& key; + + /** Peek modes. */ + int32_t peekModes; + + IGNITE_NO_COPY_ASSIGNMENT(InCacheLocalPeekOperation); +}; + +/** + * Cache Invoke input operation. + */ +template < typename T1, typename T2 > +class InCacheInvokeOperation : public InputOperation { + public: + /** + * Constructor. + * + * @param val1 First value. + * @param val2 Second value. + */ + InCacheInvokeOperation(const T1& val1, const T2& val2) + : val1(val1), val2(val2) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + writer.WriteTopObject< T1 >(val1); + writer.WriteInt64(0); + writer.WriteTopObject< T2 >(val2); + } + + private: + /** First value. */ + const T1& val1; + + /** Second value. */ + const T2& val2; + + IGNITE_NO_COPY_ASSIGNMENT(InCacheInvokeOperation); +}; + +/** + * Input iterator operation. + */ +template < typename K, typename V, typename Iter > +class InIterOperation : public InputOperation { + public: + /** + * Constructor. + * + * @param begin Iterator pointing to the beggining of the sequence. + * @param end Iterator pointing to the end of the key sequence. + */ + InIterOperation(Iter begin, Iter end) : begin(begin), end(end) { + // No-op. + } + + virtual void ProcessInput( + ignite::odbc::impl::binary::BinaryWriterImpl& writer) { + interop::InteropOutputStream& stream = *writer.GetStream(); + int32_t sizePos = stream.Reserve(4); + + int32_t size = 0; + for (Iter it = begin; it != end; ++it) { + ContainerEntryWriteHelper< K, V >::Write(writer, *it); + ++size; + } + + stream.WriteInt32(sizePos, size); + } + + private: + /** Sequence begining. */ + Iter begin; + + /** Sequence end. */ + Iter end; + + IGNITE_NO_COPY_ASSIGNMENT(InIterOperation); +}; + +/** + * Output operation. + */ +class OutputOperation { + public: + /** + * Destructor. + */ + virtual ~OutputOperation() { + // No-op. + } + + /** + * Process output. + * + * @param reader Reader. + */ + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) = 0; + + /** + * Sets result to null value. + */ + virtual void SetNull() = 0; +}; + +/** + * Output operation returning single object. + */ +template < typename T > +class Out1Operation : public OutputOperation { + public: + /** + * Constructor. + * + * @param val Value. + */ + Out1Operation(T& val) : val(val) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + reader.ReadTopObject< T >(val); + } + + virtual void SetNull() { + val = binary::BinaryUtils::GetDefaultValue< T >(); + } + + private: + /** Value. */ + T& val; + + IGNITE_NO_COPY_ASSIGNMENT(Out1Operation); +}; + +/** + * Output operation returning two objects. + */ +template < typename T1, typename T2 > +class Out2Operation : public OutputOperation { + public: + /** + * Constructor. + * + * @param val1 Value 1. + * @param val2 Value 2. + */ + Out2Operation(T1& val1, T2& val2) : val1(val1), val2(val2) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + reader.ReadTopObject< T1 >(val1); + reader.ReadTopObject< T2 >(val2); + } + + virtual void SetNull() { + val1 = binary::BinaryUtils::GetDefaultValue< T1 >(); + val2 = binary::BinaryUtils::GetDefaultValue< T2 >(); + } + + private: + /** Value 1. */ + T1& val1; + + /** Value 2. */ + T2& val2; + + IGNITE_NO_COPY_ASSIGNMENT(Out2Operation); +}; + +/** + * Output operation returning four objects. + */ +template < typename T1, typename T2, typename T3, typename T4 > +class Out4Operation : public OutputOperation { + public: + /** + * Constructor. + * + * @param val1 Value 1. + * @param val2 Value 2. + * @param val3 Value 3. + * @param val4 Value 4. + */ + Out4Operation(T1& val1, T2& val2, T3& val3, T4& val4) + : val1(val1), val2(val2), val3(val3), val4(val4) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + reader.ReadTopObject< T1 >(val1); + reader.ReadTopObject< T2 >(val2); + reader.ReadTopObject< T3 >(val3); + reader.ReadTopObject< T4 >(val4); + } + + virtual void SetNull() { + val1 = binary::BinaryUtils::GetDefaultValue< T1 >(); + val2 = binary::BinaryUtils::GetDefaultValue< T2 >(); + val3 = binary::BinaryUtils::GetDefaultValue< T3 >(); + val4 = binary::BinaryUtils::GetDefaultValue< T4 >(); + } + + private: + /** Value 1. */ + T1& val1; + + /** Value 2. */ + T2& val2; + + /** Value 3. */ + T3& val3; + + /** Value 4. */ + T4& val4; + + IGNITE_NO_COPY_ASSIGNMENT(Out4Operation); +}; + +/** + * Output map operation. + */ +template < typename T1, typename T2 > +class OutMapOperation : public OutputOperation { + public: + /** + * Constructor. + * + * @param val Value. + */ + OutMapOperation(std::map< T1, T2 >& val) : val(val) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + bool exists = reader.GetStream()->ReadBool(); + + if (exists) { + int32_t cnt = reader.GetStream()->ReadInt32(); + + std::map< T1, T2 > val0; + + for (int i = 0; i < cnt; i++) { + T1 t1 = reader.ReadTopObject< T1 >(); + T2 t2 = reader.ReadTopObject< T2 >(); + + val0[t1] = t2; + } + + std::swap(val, val0); + } + } + + virtual void SetNull() { + // No-op. + } + + private: + /** Value. */ + std::map< T1, T2 >& val; + + IGNITE_NO_COPY_ASSIGNMENT(OutMapOperation); +}; + +/** + * Output query GET ALL operation. + */ +template < typename K, typename V > +class OutQueryGetAllOperation : public OutputOperation { + public: + /** + * Constructor. + */ + OutQueryGetAllOperation( + std::vector< ignite::odbc::cache::CacheEntry< K, V > >& res) + : res(res) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + int32_t cnt = reader.ReadInt32(); + + res.reserve(res.size() + cnt); + + for (int i = 0; i < cnt; i++) { + K key = reader.ReadTopObject< K >(); + V val = reader.ReadTopObject< V >(); + + res.push_back(ignite::odbc::cache::CacheEntry< K, V >(key, val)); + } + } + + virtual void SetNull() { + res.clear(); + } + + private: + /** Entries. */ + std::vector< ignite::odbc::cache::CacheEntry< K, V > >& res; + + IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperation); +}; + +/** + * Output query GET ALL operation. + */ +template < typename K, typename V, typename Iter, + typename Pair = ignite::odbc::cache::CacheEntry< K, V > > +class OutQueryGetAllOperationIter : public OutputOperation { + public: + /** + * Constructor. + */ + OutQueryGetAllOperationIter(Iter iter) : iter(iter) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + int32_t cnt = reader.ReadInt32(); + + for (int32_t i = 0; i < cnt; i++) { + K key = reader.ReadTopObject< K >(); + V val = reader.ReadTopObject< V >(); + + *iter = Pair(key, val); + ++iter; } -} + } + + virtual void SetNull() { + // No-op. + } + + private: + /** Out iter. */ + Iter iter; + + IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperationIter); +}; + +/** + * Output iter operation. + */ +template < typename K, typename V, typename Iter > +class OutMapIterOperation : public OutputOperation { + public: + /** + * Constructor. + */ + OutMapIterOperation(Iter iter) : iter(iter) { + // No-op. + } + + virtual void ProcessOutput(binary::BinaryReaderImpl& reader) { + bool exists = reader.GetStream()->ReadBool(); + + if (exists) { + int32_t cnt = reader.GetStream()->ReadInt32(); + + for (int32_t i = 0; i < cnt; i++) { + K key = reader.ReadTopObject< K >(); + V val = reader.ReadTopObject< V >(); + + *iter = std::pair< K, V >(key, val); + ++iter; + } + } + } + + virtual void SetNull() { + // No-op. + } + + private: + /** Out iter. */ + Iter iter; + + IGNITE_NO_COPY_ASSIGNMENT(OutMapIterOperation); +}; +} // namespace impl +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_IMPL_OPERATIONS +#endif //_IGNITE_ODBC_IMPL_OPERATIONS diff --git a/src/odbc/include/ignite/odbc/jni/database_metadata.h b/src/odbc/include/ignite/odbc/jni/database_metadata.h index 972b1a706..6fb265ed9 100644 --- a/src/odbc/include/ignite/odbc/jni/database_metadata.h +++ b/src/odbc/include/ignite/odbc/jni/database_metadata.h @@ -48,42 +48,43 @@ class DatabaseMetaData { * critera in catalog (not supported), schemaPattern, tablePattern * and types of tables. */ - SharedPointer< ResultSet > GetTables(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schemaPattern, - const std::string& tableNamePattern, - const boost::optional< std::vector< std::string > >& types, - JniErrorInfo& errInfo); + SharedPointer< ResultSet > GetTables( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schemaPattern, + const std::string& tableNamePattern, + const boost::optional< std::vector< std::string > >& types, + JniErrorInfo& errInfo); /** * Query the columns in the database according to the given * search critera in catalog (not supported), schemaPattern (nullable), * tablePattern and columnPattern. */ - SharedPointer< ResultSet > GetColumns(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schemaPattern, - const std::string& tableNamePattern, - const std::string& columnNamePattern, - JniErrorInfo& errInfo); + SharedPointer< ResultSet > GetColumns( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schemaPattern, + const std::string& tableNamePattern, const std::string& columnNamePattern, + JniErrorInfo& errInfo); /** * Query the primary keys in the database according to the given * search critera in catalog (not supported), schema, and * table. */ - SharedPointer< ResultSet > GetPrimaryKeys(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const boost::optional< std::string >& table, - JniErrorInfo& errInfo); + SharedPointer< ResultSet > GetPrimaryKeys( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, + const boost::optional< std::string >& table, JniErrorInfo& errInfo); /** * Query the foreign keys in the database according to the given * search critera in catalog (not supported), schema, and * table. */ - SharedPointer< ResultSet > GetImportedKeys(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - JniErrorInfo& errInfo); + SharedPointer< ResultSet > GetImportedKeys( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + JniErrorInfo& errInfo); private: /** diff --git a/src/odbc/include/ignite/odbc/jni/documentdb_connection.h b/src/odbc/include/ignite/odbc/jni/documentdb_connection.h index 098f516a9..437d225e5 100644 --- a/src/odbc/include/ignite/odbc/jni/documentdb_connection.h +++ b/src/odbc/include/ignite/odbc/jni/documentdb_connection.h @@ -91,16 +91,18 @@ class DocumentDbConnection { */ JniErrorCode GetSshLocalPort(int32_t& localPort, JniErrorInfo& errInfo); - /** + /** * Gets the connection properties. - * + * * @return the connection properties */ - SharedPointer< DocumentDbConnectionProperties > GetConnectionProperties(JniErrorInfo& errInfo); + SharedPointer< DocumentDbConnectionProperties > GetConnectionProperties( + JniErrorInfo& errInfo); - /** - * Gets the DocumentDb Database Metadata (different from JDBC Database MetaData) - * + /** + * Gets the DocumentDb Database Metadata (different from JDBC Database + * MetaData) + * * @return the DocumentDb database metadata. */ SharedPointer< DocumentDbDatabaseMetadata > GetDatabaseMetadata( diff --git a/src/odbc/include/ignite/odbc/jni/documentdb_database_metadata.h b/src/odbc/include/ignite/odbc/jni/documentdb_database_metadata.h index 2e7ea54ab..6fc42824e 100644 --- a/src/odbc/include/ignite/odbc/jni/documentdb_database_metadata.h +++ b/src/odbc/include/ignite/odbc/jni/documentdb_database_metadata.h @@ -50,9 +50,8 @@ class DocumentDbDatabaseMetadata { /** * Constructs an instance of the DocumentDbDatabaseMetadata class. */ - DocumentDbDatabaseMetadata( - SharedPointer< JniContext >& jniContext, - SharedPointer< GlobalJObject >& databaseMetadata) + DocumentDbDatabaseMetadata(SharedPointer< JniContext >& jniContext, + SharedPointer< GlobalJObject >& databaseMetadata) : jniContext_(jniContext), databaseMetadata_(databaseMetadata) { } diff --git a/src/odbc/include/ignite/odbc/jni/documentdb_query_mapping_service.h b/src/odbc/include/ignite/odbc/jni/documentdb_query_mapping_service.h index 07013f6e3..360484c55 100644 --- a/src/odbc/include/ignite/odbc/jni/documentdb_query_mapping_service.h +++ b/src/odbc/include/ignite/odbc/jni/documentdb_query_mapping_service.h @@ -47,18 +47,21 @@ class DocumentDbQueryMappingService { */ ~DocumentDbQueryMappingService() = default; - /** - * Creates an instance of DocumentDbQueryMappingService from connection properties and database metadata. - * + /** + * Creates an instance of DocumentDbQueryMappingService from connection + * properties and database metadata. + * * @return an new instance of DocumentDbQueryMappingService. */ static SharedPointer< DocumentDbQueryMappingService > Create( - const SharedPointer< DocumentDbConnectionProperties >& connectionProperties, - const SharedPointer< DocumentDbDatabaseMetadata >& databaseMetadata, JniErrorInfo& errInfo); + const SharedPointer< DocumentDbConnectionProperties >& + connectionProperties, + const SharedPointer< DocumentDbDatabaseMetadata >& databaseMetadata, + JniErrorInfo& errInfo); - /** + /** * Getst the MQL query context for a SQL query. - * + * * @return a pointer to DocumentDbMqlQueryContext. */ SharedPointer< DocumentDbMqlQueryContext > GetMqlQueryContext( @@ -68,18 +71,19 @@ class DocumentDbQueryMappingService { /** * Constructs an instance of the DocumentDbQueryMappingService class. */ - DocumentDbQueryMappingService(SharedPointer< JniContext >& jniContext, - SharedPointer< GlobalJObject >& queryMappingService) + DocumentDbQueryMappingService( + SharedPointer< JniContext >& jniContext, + SharedPointer< GlobalJObject >& queryMappingService) : jniContext_(jniContext), queryMappingService_(queryMappingService) { } /** * Reads the JDBC column metadata into a vector of JdbcColumnMetadata. - * + * * @return true if able to read the metadata, false, otherwise. */ bool ReadJdbcColumnMetadata( - SharedPointer< GlobalJObject > const& columnMetadata, + SharedPointer< GlobalJObject > const& columnMetadata, std::vector< JdbcColumnMetadata >& columnMetadataList, JniErrorInfo& errInfo); diff --git a/src/odbc/include/ignite/odbc/jni/java.h b/src/odbc/include/ignite/odbc/jni/java.h index 9f53f0f91..cd66d209a 100644 --- a/src/odbc/include/ignite/odbc/jni/java.h +++ b/src/odbc/include/ignite/odbc/jni/java.h @@ -401,7 +401,8 @@ class IGNITE_IMPORT_EXPORT JniJvm { * @param javaMembers Java members. * @param members Members. */ - JniJvm(JavaVM* jvm, JniJavaMembers const& javaMembers, JniMembers const& members); + JniJvm(JavaVM* jvm, JniJavaMembers const& javaMembers, + JniMembers const& members); /** * Get JVM. @@ -483,7 +484,8 @@ struct IGNITE_IMPORT_EXPORT JniErrorInfo { */ class IGNITE_IMPORT_EXPORT JniContext { public: - static JniContext* Create(char** opts, int optsLen, JniHandlers const& hnds, JniErrorInfo& errInfo); + static JniContext* Create(char** opts, int optsLen, JniHandlers const& hnds, + JniErrorInfo& errInfo); static int Reallocate(int64_t memPtr, int cap); static void Detach(); static void Release(jobject obj); @@ -495,8 +497,7 @@ class IGNITE_IMPORT_EXPORT JniContext { JniErrorInfo* errInfo); int64_t TargetInStreamOutLong(jobject obj, int type, int64_t memPtr, JniErrorInfo* errInfo); - jobject TargetOutObject(jobject obj, int opType, - JniErrorInfo* errInfo); + jobject TargetOutObject(jobject obj, int opType, JniErrorInfo* errInfo); void TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* errInfo); jobject TargetInStreamOutObject(jobject obj, int type, int64_t memPtr, @@ -524,7 +525,8 @@ class IGNITE_IMPORT_EXPORT JniContext { SharedPointer< GlobalJObject >& metadata, JniErrorInfo& errInfo); JniErrorCode DocumentDbConnectionGetConnectionProperties( const SharedPointer< GlobalJObject >& connection, - SharedPointer< GlobalJObject >& connectionProperties, JniErrorInfo& errInfo); + SharedPointer< GlobalJObject >& connectionProperties, + JniErrorInfo& errInfo); JniErrorCode DocumentDbDatabaseSchemaMetadataGetSchemaName( const SharedPointer< GlobalJObject >& databaseMetadata, @@ -550,15 +552,13 @@ class IGNITE_IMPORT_EXPORT JniContext { const boost::optional< std::string >& catalog, const boost::optional< std::string >& schema, const boost::optional< std::string >& table, - SharedPointer< GlobalJObject >& resultSet, - JniErrorInfo& errInfo); + SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo); JniErrorCode DatabaseMetaDataGetImportedKeys( const SharedPointer< GlobalJObject >& databaseMetaData, const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, SharedPointer< GlobalJObject >& resultSet, - JniErrorInfo& errInfo); + const boost::optional< std::string >& schema, const std::string& table, + SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo); JniErrorCode ResultSetClose(const SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo); @@ -585,8 +585,8 @@ class IGNITE_IMPORT_EXPORT JniContext { JniErrorCode ResultSetWasNull(const SharedPointer< GlobalJObject >& resultSet, bool& value, JniErrorInfo& errInfo); - JniErrorCode ListSize(const SharedPointer< GlobalJObject >& list, int32_t& size, - JniErrorInfo& errInfo); + JniErrorCode ListSize(const SharedPointer< GlobalJObject >& list, + int32_t& size, JniErrorInfo& errInfo); JniErrorCode ListGet(const SharedPointer< GlobalJObject >& list, int32_t index, SharedPointer< GlobalJObject >& array, JniErrorInfo& errInfo); @@ -611,8 +611,7 @@ class IGNITE_IMPORT_EXPORT JniContext { JniErrorInfo& errInfo); JniErrorCode DocumentDbQueryMappingServiceGet( const SharedPointer< GlobalJObject >& queryMappingService, - const std::string sql, - int64_t maxRowCount, + const std::string sql, int64_t maxRowCount, SharedPointer< GlobalJObject >& mqlQueryContext, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetOrdinal( @@ -631,8 +630,8 @@ class IGNITE_IMPORT_EXPORT JniContext { const SharedPointer< GlobalJObject >& jdbcColumnMetadata, bool& currency, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetNullable( - const SharedPointer< GlobalJObject >& jdbcColumnMetadata, int32_t& nullable, - JniErrorInfo& errInfo); + const SharedPointer< GlobalJObject >& jdbcColumnMetadata, + int32_t& nullable, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataIsSigned( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, bool& isSigned, JniErrorInfo& errInfo); @@ -641,56 +640,43 @@ class IGNITE_IMPORT_EXPORT JniContext { int32_t& columnDisplaySize, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetColumnLabel( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& columnLabel, - JniErrorInfo& errInfo); + boost::optional< std::string >& columnLabel, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetColumnName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& columnName, - JniErrorInfo& errInfo); + boost::optional< std::string >& columnName, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetSchemaName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& schemaName, - JniErrorInfo& errInfo); + boost::optional< std::string >& schemaName, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetPrecision( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - int32_t& precision, - JniErrorInfo& errInfo); + int32_t& precision, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetScale( - const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - int32_t& scale, + const SharedPointer< GlobalJObject >& jdbcColumnMetadata, int32_t& scale, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetTableName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& tableName, - JniErrorInfo& errInfo); + boost::optional< std::string >& tableName, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetCatalogName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& catalogName, - JniErrorInfo& errInfo); + boost::optional< std::string >& catalogName, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetColumnType( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - int32_t& columnType, - JniErrorInfo& errInfo); + int32_t& columnType, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetColumnTypeName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& columnTypeName, - JniErrorInfo& errInfo); + boost::optional< std::string >& columnTypeName, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataIsReadOnly( - const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - bool& readOnly, + const SharedPointer< GlobalJObject >& jdbcColumnMetadata, bool& readOnly, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataIsWritable( - const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - bool& writable, + const SharedPointer< GlobalJObject >& jdbcColumnMetadata, bool& writable, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataIsDefinitelyWritable( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - bool& definitelyWritable, - JniErrorInfo& errInfo); + bool& definitelyWritable, JniErrorInfo& errInfo); JniErrorCode JdbcColumnMetadataGetColumnClassName( const SharedPointer< GlobalJObject >& jdbcColumnMetadata, - boost::optional< std::string >& columnClassName, - JniErrorInfo& errInfo); + boost::optional< std::string >& columnClassName, JniErrorInfo& errInfo); jobject CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, JniErrorInfo* errInfo); diff --git a/src/odbc/include/ignite/odbc/jni/jdbc_column_metadata.h b/src/odbc/include/ignite/odbc/jni/jdbc_column_metadata.h index a717a524b..b531d6b81 100644 --- a/src/odbc/include/ignite/odbc/jni/jdbc_column_metadata.h +++ b/src/odbc/include/ignite/odbc/jni/jdbc_column_metadata.h @@ -88,7 +88,8 @@ class JdbcColumnMetadata { } /** - * Gets the indicator of whether the column is nullable, non-nullable or unknown-nullable. + * Gets the indicator of whether the column is nullable, non-nullable or + * unknown-nullable. */ int32_t GetNullable() const { return nullable_; @@ -177,7 +178,7 @@ class JdbcColumnMetadata { bool IsReadOnly() const { return readOnly_; } - + /** * Gets the indicator of whether the column is writable. */ @@ -199,7 +200,6 @@ class JdbcColumnMetadata { return columnClassName_; } - private: /** * Constructs an instance of the JdbcColumnMetadata class. @@ -238,7 +238,7 @@ class JdbcColumnMetadata { writable_(writable), definitelyWritable_(definitelyWritable), columnClassName_(columnClassName) { - // No-op + // No-op } int32_t ordinal_; diff --git a/src/odbc/include/ignite/odbc/log_level.h b/src/odbc/include/ignite/odbc/log_level.h index d03fb7c52..b4ecbc82b 100644 --- a/src/odbc/include/ignite/odbc/log_level.h +++ b/src/odbc/include/ignite/odbc/log_level.h @@ -23,13 +23,7 @@ namespace ignite { namespace odbc { /** Log Level enum. */ struct LogLevel { - enum class Type { - DEBUG_LEVEL, - INFO_LEVEL, - ERROR_LEVEL, - OFF, - UNKNOWN - }; + enum class Type { DEBUG_LEVEL, INFO_LEVEL, ERROR_LEVEL, OFF, UNKNOWN }; /** * Convert log level from string. diff --git a/src/odbc/include/ignite/odbc/message.h b/src/odbc/include/ignite/odbc/message.h index a5044c904..57400c6d5 100644 --- a/src/odbc/include/ignite/odbc/message.h +++ b/src/odbc/include/ignite/odbc/message.h @@ -91,8 +91,7 @@ class HandshakeRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Configuration. */ @@ -127,8 +126,7 @@ class QueryExecuteRequest { * @param writer Writer. * @param ver Version. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion& ver) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion& ver) const; private: /** Schema name. */ @@ -178,8 +176,7 @@ class QueryExecuteBatchRequest { * @param writer Writer. * @param ver Version. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion& ver) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion& ver) const; private: /** Schema name. */ @@ -228,8 +225,7 @@ class QueryCloseRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Query ID. */ @@ -258,8 +254,7 @@ class QueryFetchRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Query ID. */ @@ -294,8 +289,7 @@ class QueryGetColumnsMetaRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Schema search pattern. */ @@ -331,8 +325,7 @@ class QueryGetResultsetMetaRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Schema. */ @@ -368,8 +361,7 @@ class QueryGetTablesMetaRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Column search pattern. */ @@ -413,8 +405,7 @@ class QueryGetParamsMetaRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Schema. */ @@ -451,8 +442,7 @@ class QueryMoreResultsRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Query ID. */ @@ -488,8 +478,7 @@ class StreamingBatchRequest { * Write request using provided writer. * @param writer Writer. */ - void Write(BinaryWriterImpl& writer, - const ProtocolVersion&) const; + void Write(BinaryWriterImpl& writer, const ProtocolVersion&) const; private: /** Schema name. */ @@ -547,8 +536,7 @@ class Response { /** * Read data if response status is ResponseStatus::SUCCESS. */ - virtual void ReadOnSuccess(BinaryReaderImpl&, - const ProtocolVersion&); + virtual void ReadOnSuccess(BinaryReaderImpl&, const ProtocolVersion&); private: /** Request processing status. */ @@ -642,8 +630,7 @@ class QueryCloseResponse : public Response { * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(BinaryReaderImpl& reader, - const ProtocolVersion&); + virtual void ReadOnSuccess(BinaryReaderImpl& reader, const ProtocolVersion&); /** Query ID. */ int64_t queryId; @@ -844,8 +831,7 @@ class QueryFetchResponse : public Response { * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(BinaryReaderImpl& reader, - const ProtocolVersion&); + virtual void ReadOnSuccess(BinaryReaderImpl& reader, const ProtocolVersion&); /** Query ID. */ int64_t queryId; @@ -910,8 +896,7 @@ class QueryGetParamsMetaResponse : public Response { * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(BinaryReaderImpl& reader, - const ProtocolVersion&); + virtual void ReadOnSuccess(BinaryReaderImpl& reader, const ProtocolVersion&); /** Columns metadata. */ std::vector< int8_t > typeIds; @@ -946,8 +931,7 @@ class QueryMoreResultsResponse : public Response { * Read response using provided reader. * @param reader Reader. */ - virtual void ReadOnSuccess(BinaryReaderImpl& reader, - const ProtocolVersion&); + virtual void ReadOnSuccess(BinaryReaderImpl& reader, const ProtocolVersion&); /** Query ID. */ int64_t queryId; diff --git a/src/odbc/include/ignite/odbc/meta/column_meta.h b/src/odbc/include/ignite/odbc/meta/column_meta.h index 376753a02..dff0ddf94 100644 --- a/src/odbc/include/ignite/odbc/meta/column_meta.h +++ b/src/odbc/include/ignite/odbc/meta/column_meta.h @@ -31,9 +31,9 @@ #include "ignite/odbc/protocol_version.h" #include "ignite/odbc/utility.h" +using ignite::odbc::jni::JdbcColumnMetadata; using ignite::odbc::jni::ResultSet; using ignite::odbc::jni::java::JniErrorInfo; -using ignite::odbc::jni::JdbcColumnMetadata; namespace ignite { namespace odbc { @@ -169,7 +169,8 @@ class ColumnMeta { * @param prevPosition the ordinal position of the previous column. * @paran err IgniteError. */ - void ReadJdbcMetadata(JdbcColumnMetadata& jdbcMetadata, int32_t& prevPosition); + void ReadJdbcMetadata(JdbcColumnMetadata& jdbcMetadata, + int32_t& prevPosition); /** * Get catalog name. diff --git a/src/odbc/include/ignite/odbc/meta/table_meta.h b/src/odbc/include/ignite/odbc/meta/table_meta.h index 1039b558e..916fe36c7 100644 --- a/src/odbc/include/ignite/odbc/meta/table_meta.h +++ b/src/odbc/include/ignite/odbc/meta/table_meta.h @@ -106,7 +106,7 @@ class TableMeta { * Get catalog name. * @return Catalog name. */ - const boost::optional& GetCatalogName() const { + const boost::optional< std::string >& GetCatalogName() const { return catalogName; } @@ -114,7 +114,7 @@ class TableMeta { * Get schema name. * @return Schema name. */ - const boost::optional& GetSchemaName() const { + const boost::optional< std::string >& GetSchemaName() const { return schemaName; } @@ -122,7 +122,7 @@ class TableMeta { * Get table name. * @return Table name. */ - const boost::optional& GetTableName() const { + const boost::optional< std::string >& GetTableName() const { return tableName; } @@ -130,7 +130,7 @@ class TableMeta { * Get table type. * @return Table type. */ - const boost::optional& GetTableType() const { + const boost::optional< std::string >& GetTableType() const { return tableType; } @@ -138,25 +138,25 @@ class TableMeta { * Get the remarks. * @return Remarks. */ - const boost::optional& GetRemarks() const { + const boost::optional< std::string >& GetRemarks() const { return remarks; } private: /** Catalog name. */ - boost::optional catalogName; + boost::optional< std::string > catalogName; /** Schema name. */ - boost::optional schemaName; + boost::optional< std::string > schemaName; /** Table name. */ - boost::optional tableName; + boost::optional< std::string > tableName; /** Table type. */ - boost::optional tableType; + boost::optional< std::string > tableType; /** Remarks */ - boost::optional remarks; + boost::optional< std::string > remarks; }; /** Table metadata vector alias. */ @@ -173,4 +173,4 @@ void ReadTableMetaVector(SharedPointer< ResultSet >& resultSet, } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_META_TABLE_META \ No newline at end of file +#endif //_IGNITE_ODBC_META_TABLE_META diff --git a/src/odbc/include/ignite/odbc/nested_tx_mode.h b/src/odbc/include/ignite/odbc/nested_tx_mode.h index f6787e668..05b462251 100644 --- a/src/odbc/include/ignite/odbc/nested_tx_mode.h +++ b/src/odbc/include/ignite/odbc/nested_tx_mode.h @@ -74,4 +74,4 @@ struct NestedTxMode { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_NESTED_TX_MODE \ No newline at end of file +#endif //_IGNITE_ODBC_NESTED_TX_MODE diff --git a/src/odbc/include/ignite/odbc/odbc_error.h b/src/odbc/include/ignite/odbc/odbc_error.h index 8f273c160..f4b0fcf81 100644 --- a/src/odbc/include/ignite/odbc/odbc_error.h +++ b/src/odbc/include/ignite/odbc/odbc_error.h @@ -108,4 +108,4 @@ struct OdbcExpected : odbc::common::Expected< R, OdbcError > { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_ODBC_ERROR \ No newline at end of file +#endif //_IGNITE_ODBC_ODBC_ERROR diff --git a/src/odbc/include/ignite/odbc/parser.h b/src/odbc/include/ignite/odbc/parser.h index 23cb70594..a6f43e304 100644 --- a/src/odbc/include/ignite/odbc/parser.h +++ b/src/odbc/include/ignite/odbc/parser.h @@ -140,4 +140,4 @@ class Parser { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_PARSER \ No newline at end of file +#endif //_IGNITE_ODBC_PARSER diff --git a/src/odbc/include/ignite/odbc/query/column_metadata_query.h b/src/odbc/include/ignite/odbc/query/column_metadata_query.h index 69f368820..f68bb2f8e 100644 --- a/src/odbc/include/ignite/odbc/query/column_metadata_query.h +++ b/src/odbc/include/ignite/odbc/query/column_metadata_query.h @@ -46,8 +46,7 @@ class ColumnMetadataQuery : public Query { Connection& connection, const boost::optional< std::string >& catalog, const boost::optional< std::string >& schema, - const std::string& table, - const std::string& column); + const std::string& table, const std::string& column); /** * Destructor. diff --git a/src/odbc/include/ignite/odbc/query/data_query.h b/src/odbc/include/ignite/odbc/query/data_query.h index 7877b578b..f896b43ab 100644 --- a/src/odbc/include/ignite/odbc/query/data_query.h +++ b/src/odbc/include/ignite/odbc/query/data_query.h @@ -156,7 +156,6 @@ class DataQuery : public Query { */ SqlResult::Type MakeRequestFetch(); - /** * Gets the MQL query context. * @@ -193,13 +192,12 @@ class DataQuery : public Query { ; /** - * Set result set meta. + * Set result set meta. * * @param value Metadata value. */ void SetResultsetMeta(const meta::ColumnMetaVector& value); - /** * Set result set meta by reading Jdbc column metadata vector. * diff --git a/src/odbc/include/ignite/odbc/query/foreign_keys_query.h b/src/odbc/include/ignite/odbc/query/foreign_keys_query.h index 718a2f7c1..3c688f959 100644 --- a/src/odbc/include/ignite/odbc/query/foreign_keys_query.h +++ b/src/odbc/include/ignite/odbc/query/foreign_keys_query.h @@ -30,7 +30,6 @@ namespace query { */ class ForeignKeysQuery : public Query { public: - /** * Constructor. * @@ -150,5 +149,4 @@ class ForeignKeysQuery : public Query { } // namespace query } // namespace odbc } // namespace ignite - -#endif //_IGNITE_ODBC_QUERY_FOREIGN_KEYS_QUERY \ No newline at end of file +#endif //_IGNITE_ODBC_QUERY_FOREIGN_KEYS_QUERY diff --git a/src/odbc/include/ignite/odbc/query/primary_keys_query.h b/src/odbc/include/ignite/odbc/query/primary_keys_query.h index eaf1a9988..bd3f753e1 100644 --- a/src/odbc/include/ignite/odbc/query/primary_keys_query.h +++ b/src/odbc/include/ignite/odbc/query/primary_keys_query.h @@ -111,7 +111,7 @@ class PrimaryKeysQuery : public Query { private: IGNITE_NO_COPY_ASSIGNMENT(PrimaryKeysQuery); - /** + /** * Make get primary keys metadata requets and use response to set internal * state. * @@ -119,7 +119,6 @@ class PrimaryKeysQuery : public Query { */ virtual SqlResult::Type MakeRequestGetPrimaryKeysMeta(); - /** Connection associated with the statement. */ Connection& connection; @@ -151,4 +150,4 @@ class PrimaryKeysQuery : public Query { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_QUERY_PRIMARY_KEYS_QUERY \ No newline at end of file +#endif //_IGNITE_ODBC_QUERY_PRIMARY_KEYS_QUERY diff --git a/src/odbc/include/ignite/odbc/query/special_columns_query.h b/src/odbc/include/ignite/odbc/query/special_columns_query.h index 2c3673741..e49ae9953 100644 --- a/src/odbc/include/ignite/odbc/query/special_columns_query.h +++ b/src/odbc/include/ignite/odbc/query/special_columns_query.h @@ -143,4 +143,4 @@ class SpecialColumnsQuery : public Query { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_QUERY_SPECIAL_COLUMNS_QUERY \ No newline at end of file +#endif //_IGNITE_ODBC_QUERY_SPECIAL_COLUMNS_QUERY diff --git a/src/odbc/include/ignite/odbc/query/table_metadata_query.h b/src/odbc/include/ignite/odbc/query/table_metadata_query.h index ee2babed6..75703c90d 100644 --- a/src/odbc/include/ignite/odbc/query/table_metadata_query.h +++ b/src/odbc/include/ignite/odbc/query/table_metadata_query.h @@ -123,31 +123,32 @@ class TableMetadataQuery : public Query { */ SqlResult::Type MakeRequestGetTablesMeta(); - /** + /** * Trims leading space from a string. - * + * * @return the string with leading spaces trimmed. */ std::string ltrim(const std::string& s); - /** + /** * Trims trailing space from a string. - * + * * @return the string with trailing spaces trimmed. */ std::string rtrim(const std::string& s); /** * Trims leading and trailing space from a string. - * + * * @return the string with leading and trailing spaces trimmed. */ std::string trim(const std::string& s); - /** - * Remove outer matching quotes from a string. They can be either single (') or double (") quotes. - * They must be the left- and right-most characters in the string. - * + /** + * Remove outer matching quotes from a string. They can be either single (') + * or double (") quotes. They must be the left- and right-most characters in + * the string. + * * @return the string with matched quotes removed. */ std::string dequote(const std::string& s); @@ -186,4 +187,4 @@ class TableMetadataQuery : public Query { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_QUERY_TABLE_METADATA_QUERY \ No newline at end of file +#endif //_IGNITE_ODBC_QUERY_TABLE_METADATA_QUERY diff --git a/src/odbc/include/ignite/odbc/query/type_info_query.h b/src/odbc/include/ignite/odbc/query/type_info_query.h index ad79bb39b..4f8db0055 100644 --- a/src/odbc/include/ignite/odbc/query/type_info_query.h +++ b/src/odbc/include/ignite/odbc/query/type_info_query.h @@ -122,4 +122,4 @@ class TypeInfoQuery : public Query { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_QUERY_TYPE_INFO_QUERY \ No newline at end of file +#endif //_IGNITE_ODBC_QUERY_TYPE_INFO_QUERY diff --git a/src/odbc/include/ignite/odbc/reference.h b/src/odbc/include/ignite/odbc/reference.h index fecb63d98..e928b6823 100644 --- a/src/odbc/include/ignite/odbc/reference.h +++ b/src/odbc/include/ignite/odbc/reference.h @@ -29,539 +29,515 @@ #include #include -namespace ignite -{ - namespace odbc - { - template - class Reference; - - /** - * Constant Reference class. - * - * Abstraction on any reference-type object, from simple raw pointers and - * references to standard library smart pointers. Provides only constant - * access to the underlying data. - * - * There are no requirements for the template type T. - */ - template - class ConstReference - { - template - friend class ConstReference; - - template - friend class Reference; - - public: - /** - * Default constructor. - */ - ConstReference() : - ptr(), - offset(0) - { - // No-op. - } - - /** - * Constructor. - * - * @param ptr ConstReference class implementation. - * @param offset Pointer offset. - */ - explicit ConstReference(common::ConstReferenceImplBase* ptr, ptrdiff_t offset = 0) : - ptr(ptr), - offset(offset) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Another instance. - */ - ConstReference(const ConstReference& other) : - ptr(other.ptr), - offset(other.offset) - { - // No-op. - } - - /** - * Copy constructor. - * - * Constant reference of type T2 should be static-castable to constant - * reference of type T. - * - * @param other Another instance. - */ - template - ConstReference(const ConstReference& other) : - ptr(other.ptr), - offset(other.offset) - { - T2* p0 = reinterpret_cast(common::POINTER_CAST_MAGIC_NUMBER); - T* p1 = static_cast(p0); - - ptrdiff_t diff = reinterpret_cast(p1) - reinterpret_cast(p0); - offset += diff; - } - - /** - * Assignment operator. - * - * @param other Another instance. - */ - ConstReference& operator=(const ConstReference& other) - { - ptr = other.ptr; - offset = other.offset; - - return *this; - } - - /** - * Assignment operator. - * - * Constant reference of type T2 should be static-castable to constant - * reference of type T. - * - * @param other Another instance. - */ - template - ConstReference& operator=(const ConstReference& other) - { - ptr = other.ptr; - offset = other.offset; - - T2* p0 = reinterpret_cast(common::POINTER_CAST_MAGIC_NUMBER); - T* p1 = static_cast(p0); - - ptrdiff_t diff = reinterpret_cast(p1) - reinterpret_cast(p0); - offset += diff; - - return *this; - } - - /** - * Destructor. - */ - ~ConstReference() - { - // No-op. - } - - /** - * Dereference the pointer. - * - * If the pointer is null then this operation causes undefined - * behaviour. - * - * @return Constant reference to underlying value. - */ - const T* Get() const - { - return reinterpret_cast(reinterpret_cast(ptr.Get()->Get()) + offset); - } - - /** - * Check if the pointer is null. - * - * @return True if the value is null. - */ - bool IsNull() const - { - const common::ConstReferenceImplBase* raw = ptr.Get(); - - return !raw || !raw->Get(); - } - - private: - /** Implementation. */ - common::concurrent::SharedPointer ptr; - - /** Address offset. */ - ptrdiff_t offset; - }; - - /** - * Reference class. - * - * Abstraction on any reference-type object, from simple raw pointers and - * references to standard library smart pointers. - * - * There are no requirements for the template type T. - */ - template - class Reference - { - template - friend class Reference; - public: - /** - * Default constructor. - */ - Reference() : - ptr(), - offset(0) - { - // No-op. - } - - /** - * Constructor. - * - * @param ptr Reference class implementation. - * @param offset Pointer offset. - */ - explicit Reference(common::ReferenceImplBase* ptr, ptrdiff_t offset = 0) : - ptr(ptr), - offset(offset) - { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Another instance. - */ - Reference(const Reference& other) : - ptr(other.ptr), - offset(other.offset) - { - // No-op. - } - - /** - * Copy constructor. - * - * Reference of type T2 should be static-castable to reference of type T. - * - * @param other Another instance. - */ - template - Reference(const Reference& other) : - ptr(other.ptr), - offset(other.offset) - { - T2* p0 = reinterpret_cast(common::POINTER_CAST_MAGIC_NUMBER); - T* p1 = static_cast(p0); - - ptrdiff_t diff = reinterpret_cast(p1) - reinterpret_cast(p0); - offset += diff; - } - - /** - * Assignment operator. - * - * @param other Another instance. - */ - Reference& operator=(const Reference& other) - { - ptr = other.ptr; - offset = other.offset; - - return *this; - } - - /** - * Assignment operator. - * - * Reference of type T2 should be static-castable to reference of type T. - * - * @param other Another instance. - */ - template - Reference& operator=(const Reference& other) - { - ptr = other.ptr; - offset = other.offset; - - T2* p0 = reinterpret_cast(common::POINTER_CAST_MAGIC_NUMBER); - T* p1 = static_cast(p0); - - ptrdiff_t diff = reinterpret_cast(p1) - reinterpret_cast(p0); - offset += diff; - - return *this; - } - - /** - * Destructor. - */ - ~Reference() - { - // No-op. - } - - /** - * Const cast operator. - * - * Reference of type T2 should be static-castable to reference of type T. - * - * Casts this instance to constant reference. - */ - template - operator ConstReference() - { - ConstReference cr; - - cr.ptr = ptr; - cr.offset = offset; - - T2* p0 = reinterpret_cast(common::POINTER_CAST_MAGIC_NUMBER); - const T* p1 = static_cast(p0); - - ptrdiff_t diff = reinterpret_cast(p1) - reinterpret_cast(p0); - cr.offset -= diff; - - return cr; - } - - /** - * Dereference the pointer. - * - * If the pointer is null then this operation causes undefined - * behaviour. - * - * @return Constant pointer to underlying value. - */ - const T* Get() const - { - return reinterpret_cast(reinterpret_cast(ptr.Get()->Get()) + offset); - } - - /** - * Dereference the pointer. - * - * If the pointer is null then this operation causes undefined - * behaviour. - * - * @return Reference to underlying value. - */ - T* Get() - { - return reinterpret_cast(reinterpret_cast(ptr.Get()->Get()) + offset); - } - - /** - * Check if the pointer is null. - * - * @return True if the value is null. - */ - bool IsNull() const - { - const common::ReferenceImplBase* raw = ptr.Get(); - - return !raw || !raw->Get(); - } - - private: - /** Implementation. */ - common::concurrent::SharedPointer ptr; - - /** Address offset. */ - ptrdiff_t offset; - }; - - /** - * Make ignite::odbc::Reference instance out of smart pointer. - * - * Template type 'T' should be a smart pointer and provide pointer semantics: - * - There should be defined type 'T::element_type', showing underlying type. - * - Type 'T' should be dereferencible (should have operators - * T::element_type& operator*() and const T::element_type& operator*() const). - * - Operation std::swap should result in valid result if applied to two - * instances of that type. - * - * @param ptr Pointer. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - Reference MakeReferenceFromSmartPointer(T ptr) - { - common::ReferenceSmartPointer* impl = new common::ReferenceSmartPointer(); - - Reference res(impl); - - impl->Swap(ptr); - - return res; - } - - /** - * Make ignite::ConstReference instance out of smart pointer. - * - * Template type 'T' should be a smart pointer and provide pointer semantics: - * - There should be defined type 'T::element_type', showing underlying type. - * - Type 'T' should be dereferencible (should have operators - * T::element_type& operator*() and const T::element_type& operator*() const). - * - Operation std::swap should result in valid result if applied to two - * instances of that type. - * - * @param ptr Pointer. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - ConstReference MakeConstReferenceFromSmartPointer(T ptr) - { - common::ReferenceSmartPointer* impl = new common::ReferenceSmartPointer(); - - ConstReference res(impl); - - impl->Swap(ptr); - - return res; - } - - /** - * Copy object and wrap it to make ignite::odbc::Reference instance. - * - * Template type 'T' should be copy-constructible. - * - * @param val Instance. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - Reference MakeReferenceFromCopy(const T& val) - { - common::ReferenceOwningRawPointer* impl = new common::ReferenceOwningRawPointer(new T(val)); - - return Reference(impl); - } - - /** - * Copy object and wrap it to make ignite::ConstReference instance. - * - * Template type 'T' should be copy-constructible. - * - * @param val Instance. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - ConstReference MakeConstReferenceFromCopy(const T& val) - { - common::ReferenceOwningRawPointer* impl = new common::ReferenceOwningRawPointer(new T(val)); - - return ConstReference(impl); - } - - /** - * Make ignite::odbc::Reference instance out of pointer and pass its ownership. - * Passed object deleted by Ignite when no longer needed. - * - * There are no requirements for the template type T. - * - * @param val Instance. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - Reference MakeReferenceFromOwningPointer(T* val) - { - common::ReferenceOwningRawPointer* impl = new common::ReferenceOwningRawPointer(val); - - return Reference(impl); - } - - /** - * Make ignite::ConstReference instance out of pointer and pass its ownership. - * Passed object deleted by Ignite when no longer needed. - * - * There are no requirements for the template type T. - * - * @param val Instance. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - ConstReference MakeConstReferenceFromOwningPointer(T* val) - { - common::ReferenceOwningRawPointer* impl = new common::ReferenceOwningRawPointer(val); - - return ConstReference(impl); - } - - /** - * Make ignite::odbc::Reference instance out of reference. - * Ignite do not manage passed object and does not affect its lifetime. - * - * There are no requirements for the template type T. - * - * @param val Reference. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - Reference MakeReference(T& val) - { - common::ReferenceNonOwningRawPointer* impl = new common::ReferenceNonOwningRawPointer(&val); - - return Reference(impl); - } - - /** - * Make ignite::odbc::Reference instance out of pointer. - * Ignite do not manage passed object and does not affect its lifetime. - * - * There are no requirements for the template type T. - * - * @param val Reference. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - Reference MakeReference(T* val) - { - common::ReferenceNonOwningRawPointer* impl = new common::ReferenceNonOwningRawPointer(val); - - return Reference(impl); - } - - /** - * Make ignite::ConstReference instance out of constant reference. - * Ignite do not manage passed object and does not affect its lifetime. - * - * There are no requirements for the template type T. - * - * @param val Reference. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - ConstReference MakeConstReference(const T& val) - { - common::ConstReferenceNonOwningRawPointer* impl = new common::ConstReferenceNonOwningRawPointer(&val); - - return ConstReference(impl); - } - - /** - * Make ignite::ConstReference instance out of constant pointer. - * Ignite do not manage passed object and does not affect its lifetime. - * - * There are no requirements for the template type T. - * - * @param val Reference. - * @return Implementation defined value. User should not explicitly use the - * returned value. - */ - template - ConstReference MakeConstReference(const T* val) - { - common::ConstReferenceNonOwningRawPointer* impl = new common::ConstReferenceNonOwningRawPointer(val); - - return ConstReference(impl); - } - } +namespace ignite { +namespace odbc { +template < typename T > +class Reference; + +/** + * Constant Reference class. + * + * Abstraction on any reference-type object, from simple raw pointers and + * references to standard library smart pointers. Provides only constant + * access to the underlying data. + * + * There are no requirements for the template type T. + */ +template < typename T > +class ConstReference { + template < typename > + friend class ConstReference; + + template < typename > + friend class Reference; + + public: + /** + * Default constructor. + */ + ConstReference() : ptr(), offset(0) { + // No-op. + } + + /** + * Constructor. + * + * @param ptr ConstReference class implementation. + * @param offset Pointer offset. + */ + explicit ConstReference(common::ConstReferenceImplBase* ptr, + ptrdiff_t offset = 0) + : ptr(ptr), offset(offset) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Another instance. + */ + ConstReference(const ConstReference& other) + : ptr(other.ptr), offset(other.offset) { + // No-op. + } + + /** + * Copy constructor. + * + * Constant reference of type T2 should be static-castable to constant + * reference of type T. + * + * @param other Another instance. + */ + template < typename T2 > + ConstReference(const ConstReference< T2 >& other) + : ptr(other.ptr), offset(other.offset) { + T2* p0 = reinterpret_cast< T2* >(common::POINTER_CAST_MAGIC_NUMBER); + T* p1 = static_cast< T* >(p0); + + ptrdiff_t diff = + reinterpret_cast< ptrdiff_t >(p1) - reinterpret_cast< ptrdiff_t >(p0); + offset += diff; + } + + /** + * Assignment operator. + * + * @param other Another instance. + */ + ConstReference& operator=(const ConstReference& other) { + ptr = other.ptr; + offset = other.offset; + + return *this; + } + + /** + * Assignment operator. + * + * Constant reference of type T2 should be static-castable to constant + * reference of type T. + * + * @param other Another instance. + */ + template < typename T2 > + ConstReference& operator=(const ConstReference< T2 >& other) { + ptr = other.ptr; + offset = other.offset; + + T2* p0 = reinterpret_cast< T2* >(common::POINTER_CAST_MAGIC_NUMBER); + T* p1 = static_cast< T* >(p0); + + ptrdiff_t diff = + reinterpret_cast< ptrdiff_t >(p1) - reinterpret_cast< ptrdiff_t >(p0); + offset += diff; + + return *this; + } + + /** + * Destructor. + */ + ~ConstReference() { + // No-op. + } + + /** + * Dereference the pointer. + * + * If the pointer is null then this operation causes undefined + * behaviour. + * + * @return Constant reference to underlying value. + */ + const T* Get() const { + return reinterpret_cast< const T* >( + reinterpret_cast< ptrdiff_t >(ptr.Get()->Get()) + offset); + } + + /** + * Check if the pointer is null. + * + * @return True if the value is null. + */ + bool IsNull() const { + const common::ConstReferenceImplBase* raw = ptr.Get(); + + return !raw || !raw->Get(); + } + + private: + /** Implementation. */ + common::concurrent::SharedPointer< common::ConstReferenceImplBase > ptr; + + /** Address offset. */ + ptrdiff_t offset; +}; + +/** + * Reference class. + * + * Abstraction on any reference-type object, from simple raw pointers and + * references to standard library smart pointers. + * + * There are no requirements for the template type T. + */ +template < typename T > +class Reference { + template < typename > + friend class Reference; + + public: + /** + * Default constructor. + */ + Reference() : ptr(), offset(0) { + // No-op. + } + + /** + * Constructor. + * + * @param ptr Reference class implementation. + * @param offset Pointer offset. + */ + explicit Reference(common::ReferenceImplBase* ptr, ptrdiff_t offset = 0) + : ptr(ptr), offset(offset) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Another instance. + */ + Reference(const Reference& other) : ptr(other.ptr), offset(other.offset) { + // No-op. + } + + /** + * Copy constructor. + * + * Reference of type T2 should be static-castable to reference of type T. + * + * @param other Another instance. + */ + template < typename T2 > + Reference(const Reference< T2 >& other) + : ptr(other.ptr), offset(other.offset) { + T2* p0 = reinterpret_cast< T2* >(common::POINTER_CAST_MAGIC_NUMBER); + T* p1 = static_cast< T* >(p0); + + ptrdiff_t diff = + reinterpret_cast< ptrdiff_t >(p1) - reinterpret_cast< ptrdiff_t >(p0); + offset += diff; + } + + /** + * Assignment operator. + * + * @param other Another instance. + */ + Reference& operator=(const Reference& other) { + ptr = other.ptr; + offset = other.offset; + + return *this; + } + + /** + * Assignment operator. + * + * Reference of type T2 should be static-castable to reference of type T. + * + * @param other Another instance. + */ + template < typename T2 > + Reference& operator=(const Reference< T2 >& other) { + ptr = other.ptr; + offset = other.offset; + + T2* p0 = reinterpret_cast< T2* >(common::POINTER_CAST_MAGIC_NUMBER); + T* p1 = static_cast< T* >(p0); + + ptrdiff_t diff = + reinterpret_cast< ptrdiff_t >(p1) - reinterpret_cast< ptrdiff_t >(p0); + offset += diff; + + return *this; + } + + /** + * Destructor. + */ + ~Reference() { + // No-op. + } + + /** + * Const cast operator. + * + * Reference of type T2 should be static-castable to reference of type T. + * + * Casts this instance to constant reference. + */ + template < typename T2 > + operator ConstReference< T2 >() { + ConstReference< T2 > cr; + + cr.ptr = ptr; + cr.offset = offset; + + T2* p0 = reinterpret_cast< T2* >(common::POINTER_CAST_MAGIC_NUMBER); + const T* p1 = static_cast< T* >(p0); + + ptrdiff_t diff = + reinterpret_cast< ptrdiff_t >(p1) - reinterpret_cast< ptrdiff_t >(p0); + cr.offset -= diff; + + return cr; + } + + /** + * Dereference the pointer. + * + * If the pointer is null then this operation causes undefined + * behaviour. + * + * @return Constant pointer to underlying value. + */ + const T* Get() const { + return reinterpret_cast< const T* >( + reinterpret_cast< ptrdiff_t >(ptr.Get()->Get()) + offset); + } + + /** + * Dereference the pointer. + * + * If the pointer is null then this operation causes undefined + * behaviour. + * + * @return Reference to underlying value. + */ + T* Get() { + return reinterpret_cast< T* >( + reinterpret_cast< ptrdiff_t >(ptr.Get()->Get()) + offset); + } + + /** + * Check if the pointer is null. + * + * @return True if the value is null. + */ + bool IsNull() const { + const common::ReferenceImplBase* raw = ptr.Get(); + + return !raw || !raw->Get(); + } + + private: + /** Implementation. */ + common::concurrent::SharedPointer< common::ReferenceImplBase > ptr; + + /** Address offset. */ + ptrdiff_t offset; +}; + +/** + * Make ignite::odbc::Reference instance out of smart pointer. + * + * Template type 'T' should be a smart pointer and provide pointer semantics: + * - There should be defined type 'T::element_type', showing underlying type. + * - Type 'T' should be dereferencible (should have operators + * T::element_type& operator*() and const T::element_type& operator*() const). + * - Operation std::swap should result in valid result if applied to two + * instances of that type. + * + * @param ptr Pointer. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +Reference< typename T::element_type > MakeReferenceFromSmartPointer(T ptr) { + common::ReferenceSmartPointer< T >* impl = + new common::ReferenceSmartPointer< T >(); + + Reference< typename T::element_type > res(impl); + + impl->Swap(ptr); + + return res; +} + +/** + * Make ignite::ConstReference instance out of smart pointer. + * + * Template type 'T' should be a smart pointer and provide pointer semantics: + * - There should be defined type 'T::element_type', showing underlying type. + * - Type 'T' should be dereferencible (should have operators + * T::element_type& operator*() and const T::element_type& operator*() const). + * - Operation std::swap should result in valid result if applied to two + * instances of that type. + * + * @param ptr Pointer. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +ConstReference< typename T::element_type > MakeConstReferenceFromSmartPointer( + T ptr) { + common::ReferenceSmartPointer< T >* impl = + new common::ReferenceSmartPointer< T >(); + + ConstReference< typename T::element_type > res(impl); + + impl->Swap(ptr); + + return res; +} + +/** + * Copy object and wrap it to make ignite::odbc::Reference instance. + * + * Template type 'T' should be copy-constructible. + * + * @param val Instance. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +Reference< T > MakeReferenceFromCopy(const T& val) { + common::ReferenceOwningRawPointer< T >* impl = + new common::ReferenceOwningRawPointer< T >(new T(val)); + + return Reference< T >(impl); +} + +/** + * Copy object and wrap it to make ignite::ConstReference instance. + * + * Template type 'T' should be copy-constructible. + * + * @param val Instance. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +ConstReference< T > MakeConstReferenceFromCopy(const T& val) { + common::ReferenceOwningRawPointer< T >* impl = + new common::ReferenceOwningRawPointer< T >(new T(val)); + + return ConstReference< T >(impl); +} + +/** + * Make ignite::odbc::Reference instance out of pointer and pass its ownership. + * Passed object deleted by Ignite when no longer needed. + * + * There are no requirements for the template type T. + * + * @param val Instance. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +Reference< T > MakeReferenceFromOwningPointer(T* val) { + common::ReferenceOwningRawPointer< T >* impl = + new common::ReferenceOwningRawPointer< T >(val); + + return Reference< T >(impl); +} + +/** + * Make ignite::ConstReference instance out of pointer and pass its ownership. + * Passed object deleted by Ignite when no longer needed. + * + * There are no requirements for the template type T. + * + * @param val Instance. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +ConstReference< T > MakeConstReferenceFromOwningPointer(T* val) { + common::ReferenceOwningRawPointer< T >* impl = + new common::ReferenceOwningRawPointer< T >(val); + + return ConstReference< T >(impl); +} + +/** + * Make ignite::odbc::Reference instance out of reference. + * Ignite do not manage passed object and does not affect its lifetime. + * + * There are no requirements for the template type T. + * + * @param val Reference. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +Reference< T > MakeReference(T& val) { + common::ReferenceNonOwningRawPointer< T >* impl = + new common::ReferenceNonOwningRawPointer< T >(&val); + + return Reference< T >(impl); +} + +/** + * Make ignite::odbc::Reference instance out of pointer. + * Ignite do not manage passed object and does not affect its lifetime. + * + * There are no requirements for the template type T. + * + * @param val Reference. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +Reference< T > MakeReference(T* val) { + common::ReferenceNonOwningRawPointer< T >* impl = + new common::ReferenceNonOwningRawPointer< T >(val); + + return Reference< T >(impl); +} + +/** + * Make ignite::ConstReference instance out of constant reference. + * Ignite do not manage passed object and does not affect its lifetime. + * + * There are no requirements for the template type T. + * + * @param val Reference. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +ConstReference< T > MakeConstReference(const T& val) { + common::ConstReferenceNonOwningRawPointer< T >* impl = + new common::ConstReferenceNonOwningRawPointer< T >(&val); + + return ConstReference< T >(impl); +} + +/** + * Make ignite::ConstReference instance out of constant pointer. + * Ignite do not manage passed object and does not affect its lifetime. + * + * There are no requirements for the template type T. + * + * @param val Reference. + * @return Implementation defined value. User should not explicitly use the + * returned value. + */ +template < typename T > +ConstReference< T > MakeConstReference(const T* val) { + common::ConstReferenceNonOwningRawPointer< T >* impl = + new common::ConstReferenceNonOwningRawPointer< T >(val); + + return ConstReference< T >(impl); } +} // namespace odbc +} // namespace ignite -#endif //_IGNITE_ODBC_COMMON_REFERENCE +#endif //_IGNITE_ODBC_COMMON_REFERENCE diff --git a/src/odbc/include/ignite/odbc/result_page.h b/src/odbc/include/ignite/odbc/result_page.h index 1d37576bf..434a01e6b 100644 --- a/src/odbc/include/ignite/odbc/result_page.h +++ b/src/odbc/include/ignite/odbc/result_page.h @@ -88,4 +88,4 @@ class ResultPage { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_RESULT_PAGE \ No newline at end of file +#endif //_IGNITE_ODBC_RESULT_PAGE diff --git a/src/odbc/include/ignite/odbc/row.h b/src/odbc/include/ignite/odbc/row.h index 27a22c728..05bb11330 100644 --- a/src/odbc/include/ignite/odbc/row.h +++ b/src/odbc/include/ignite/odbc/row.h @@ -131,4 +131,4 @@ class Row { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_ROW \ No newline at end of file +#endif //_IGNITE_ODBC_ROW diff --git a/src/odbc/include/ignite/odbc/sql/sql_command.h b/src/odbc/include/ignite/odbc/sql/sql_command.h index 259258c05..d45f675b5 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_command.h +++ b/src/odbc/include/ignite/odbc/sql/sql_command.h @@ -73,4 +73,4 @@ class SqlCommand { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_COMMAND \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_COMMAND diff --git a/src/odbc/include/ignite/odbc/sql/sql_lexer.h b/src/odbc/include/ignite/odbc/sql/sql_lexer.h index edb0bb202..7021a61c2 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_lexer.h +++ b/src/odbc/include/ignite/odbc/sql/sql_lexer.h @@ -110,4 +110,4 @@ class SqlLexer { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_LEXER \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_LEXER diff --git a/src/odbc/include/ignite/odbc/sql/sql_parser.h b/src/odbc/include/ignite/odbc/sql/sql_parser.h index 4f2552b2a..62f593bab 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_parser.h +++ b/src/odbc/include/ignite/odbc/sql/sql_parser.h @@ -62,4 +62,4 @@ class SqlParser { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_PARSER \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_PARSER diff --git a/src/odbc/include/ignite/odbc/sql/sql_set_streaming_command.h b/src/odbc/include/ignite/odbc/sql/sql_set_streaming_command.h index 0b8e610af..997475da5 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_set_streaming_command.h +++ b/src/odbc/include/ignite/odbc/sql/sql_set_streaming_command.h @@ -187,4 +187,4 @@ class SqlSetStreamingCommand : public SqlCommand { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_SET_STREAMING_COMMAND \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_SET_STREAMING_COMMAND diff --git a/src/odbc/include/ignite/odbc/sql/sql_token.h b/src/odbc/include/ignite/odbc/sql/sql_token.h index 777f71712..eeed70a19 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_token.h +++ b/src/odbc/include/ignite/odbc/sql/sql_token.h @@ -143,4 +143,4 @@ class SqlToken { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_TOKEN \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_TOKEN diff --git a/src/odbc/include/ignite/odbc/sql/sql_utils.h b/src/odbc/include/ignite/odbc/sql/sql_utils.h index 767d92611..a98dcc1d2 100644 --- a/src/odbc/include/ignite/odbc/sql/sql_utils.h +++ b/src/odbc/include/ignite/odbc/sql/sql_utils.h @@ -56,4 +56,4 @@ bool IsInternalCommand(const std::string& sql); } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SQL_SQL_UTILS \ No newline at end of file +#endif //_IGNITE_ODBC_SQL_SQL_UTILS diff --git a/src/odbc/include/ignite/odbc/ssl_mode.h b/src/odbc/include/ignite/odbc/ssl_mode.h index 56cd6127d..f7031be12 100644 --- a/src/odbc/include/ignite/odbc/ssl_mode.h +++ b/src/odbc/include/ignite/odbc/ssl_mode.h @@ -56,4 +56,4 @@ struct SslMode { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SSL_SSL_MODE \ No newline at end of file +#endif //_IGNITE_ODBC_SSL_SSL_MODE diff --git a/src/odbc/include/ignite/odbc/statement.h b/src/odbc/include/ignite/odbc/statement.h index a4b7d3282..3eea7e678 100644 --- a/src/odbc/include/ignite/odbc/statement.h +++ b/src/odbc/include/ignite/odbc/statement.h @@ -183,10 +183,10 @@ class Statement : public diagnostic::DiagnosableAdapter { * @param table Table search pattern. * @param tableType Table type search pattern, nullable. */ - void ExecuteGetTablesMetaQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const boost::optional< std::string >& tableType); + void ExecuteGetTablesMetaQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const boost::optional< std::string >& tableType); /** * Get foreign keys. @@ -198,12 +198,12 @@ class Statement : public diagnostic::DiagnosableAdapter { * @param foreignSchema Foreign key schema name. * @param foreignTable Foreign key table name. */ - void ExecuteGetForeignKeysQuery(const std::string& primaryCatalog, - const std::string& primarySchema, - const std::string& primaryTable, - const boost::optional< std::string >& foreignCatalog, - const boost::optional< std::string >& foreignSchema, - const std::string& foreignTable); + void ExecuteGetForeignKeysQuery( + const std::string& primaryCatalog, const std::string& primarySchema, + const std::string& primaryTable, + const boost::optional< std::string >& foreignCatalog, + const boost::optional< std::string >& foreignSchema, + const std::string& foreignTable); /** * Get primary keys. @@ -539,10 +539,10 @@ class Statement : public diagnostic::DiagnosableAdapter { * @param column Column search pattern. * @return Operation result. */ - SqlResult::Type InternalExecuteGetColumnsMetaQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const std::string& column); + SqlResult::Type InternalExecuteGetColumnsMetaQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const std::string& column); /** * Get tables metadata. @@ -554,13 +554,13 @@ class Statement : public diagnostic::DiagnosableAdapter { * @return Operation result. */ SqlResult::Type InternalExecuteGetTablesMetaQuery( - const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, const std::string& table, - const boost::optional< std::string >& tableType); + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const boost::optional< std::string >& tableType); /** * Get foreign keys. - * Params primaryCatalog, primarySchema, and primaryTable are ignored. + * Params primaryCatalog, primarySchema, and primaryTable are ignored. * * @param primaryCatalog Primary key catalog name. * @param primarySchema Primary key schema name. @@ -585,9 +585,10 @@ class Statement : public diagnostic::DiagnosableAdapter { * @param table Table name. * @return Operation result. */ - SqlResult::Type InternalExecuteGetPrimaryKeysQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const boost::optional< std::string >& table); + SqlResult::Type InternalExecuteGetPrimaryKeysQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, + const boost::optional< std::string >& table); /** * Get special columns. diff --git a/src/odbc/include/ignite/odbc/type_traits.h b/src/odbc/include/ignite/odbc/type_traits.h index abadc827a..a956312ee 100644 --- a/src/odbc/include/ignite/odbc/type_traits.h +++ b/src/odbc/include/ignite/odbc/type_traits.h @@ -190,7 +190,7 @@ const boost::optional< std::string > BinaryTypeToSqlTypeName( * @param type Application type. * @return True if the type is supported. */ -bool IsApplicationTypeSupported(boost::optional type); +bool IsApplicationTypeSupported(boost::optional< int16_t > type); /** * Check if the SQL type supported by the current implementation. @@ -198,7 +198,7 @@ bool IsApplicationTypeSupported(boost::optional type); * @param type Application type. * @return True if the type is supported. */ -bool IsSqlTypeSupported(boost::optional type); +bool IsSqlTypeSupported(boost::optional< int16_t > type); /** * Get corresponding binary type for ODBC SQL type. @@ -206,7 +206,7 @@ bool IsSqlTypeSupported(boost::optional type); * @param sqlType SQL type. * @return Binary type. */ -boost::optional SqlTypeToBinary(boost::optional< int16_t > sqlType); +boost::optional< int16_t > SqlTypeToBinary(boost::optional< int16_t > sqlType); /** * Convert ODBC type to driver type alias. @@ -245,7 +245,8 @@ int16_t BinaryTypeNullability(int16_t); * zero-length string if it is not known whether the * column accepts NULL values. */ -boost::optional NullabilityToIsNullable(boost::optional nullability); +boost::optional< std::string > NullabilityToIsNullable( + boost::optional< int32_t > nullability); /** * Get SQL type display size. @@ -253,7 +254,7 @@ boost::optional NullabilityToIsNullable(boost::optional nu * @param type SQL type. * @return Display size. */ -boost::optional SqlTypeDisplaySize(boost::optional type); +boost::optional< int32_t > SqlTypeDisplaySize(boost::optional< int16_t > type); /** * Get binary type display size. @@ -261,7 +262,8 @@ boost::optional SqlTypeDisplaySize(boost::optional type); * @param type Binary type. * @return Display size. */ -boost::optional BinaryTypeDisplaySize(boost::optional type); +boost::optional< int32_t > BinaryTypeDisplaySize( + boost::optional< int16_t > type); /** * Get SQL type column size. @@ -269,7 +271,7 @@ boost::optional BinaryTypeDisplaySize(boost::optional type); * @param type SQL type. * @return Column size. */ -boost::optional SqlTypeColumnSize(boost::optional type); +boost::optional< int32_t > SqlTypeColumnSize(boost::optional< int16_t > type); /** * Get binary type column size. @@ -277,7 +279,8 @@ boost::optional SqlTypeColumnSize(boost::optional type); * @param type Binary type. * @return Column size. */ -boost::optional BinaryTypeColumnSize(boost::optional type); +boost::optional< int32_t > BinaryTypeColumnSize( + boost::optional< int16_t > type); /** * Get SQL type transfer octet length. @@ -285,7 +288,8 @@ boost::optional BinaryTypeColumnSize(boost::optional type); * @param type SQL type. * @return Transfer octet length. */ -boost::optional SqlTypeTransferLength(boost::optional type); +boost::optional< int32_t > SqlTypeTransferLength( + boost::optional< int16_t > type); /** * Get binary type transfer octet length. @@ -293,7 +297,8 @@ boost::optional SqlTypeTransferLength(boost::optional type); * @param type Binary type. * @return Transfer octet length. */ -boost::optional BinaryTypeTransferLength(boost::optional type); +boost::optional< int32_t > BinaryTypeTransferLength( + boost::optional< int16_t > type); /** * Get SQL type numeric precision radix. @@ -301,7 +306,7 @@ boost::optional BinaryTypeTransferLength(boost::optional type) * @param type SQL type. * @return Numeric precision radix. */ -boost::optional SqlTypeNumPrecRadix(boost::optional type); +boost::optional< int32_t > SqlTypeNumPrecRadix(boost::optional< int16_t > type); /** * Get binary type numeric precision radix. @@ -309,7 +314,8 @@ boost::optional SqlTypeNumPrecRadix(boost::optional type); * @param type Binary type. * @return Numeric precision radix. */ -boost::optional BinaryTypeNumPrecRadix(boost::optional type); +boost::optional< int32_t > BinaryTypeNumPrecRadix( + boost::optional< int16_t > type); /** * Get SQL type decimal digits. @@ -317,7 +323,8 @@ boost::optional BinaryTypeNumPrecRadix(boost::optional type); * @param type SQL type. * @return Decimal digits. */ -boost::optional SqlTypeDecimalDigits(boost::optional type); +boost::optional< int16_t > SqlTypeDecimalDigits( + boost::optional< int16_t > type); /** * Get binary type decimal digits. @@ -325,7 +332,8 @@ boost::optional SqlTypeDecimalDigits(boost::optional type); * @param type Binary type. * @return Decimal digits. */ -boost::optional BinaryTypeDecimalDigits(boost::optional type); +boost::optional< int16_t > BinaryTypeDecimalDigits( + boost::optional< int16_t > type); /** * Get SQL type char octet length. @@ -333,7 +341,8 @@ boost::optional BinaryTypeDecimalDigits(boost::optional type); * @param type SQL type. * @return Char octet length. */ -boost::optional SqlTypeCharOctetLength(boost::optional type); +boost::optional< int32_t > SqlTypeCharOctetLength( + boost::optional< int16_t > type); /** * Get binary type char octet length. @@ -341,7 +350,8 @@ boost::optional SqlTypeCharOctetLength(boost::optional type); * @param type Binary type. * @return Char octet length. */ -boost::optional BinaryTypeCharOctetLength(boost::optional type); +boost::optional< int32_t > BinaryTypeCharOctetLength( + boost::optional< int16_t > type); /** * Checks if the SQL type is unsigned. @@ -349,7 +359,7 @@ boost::optional BinaryTypeCharOctetLength(boost::optional type * @param type SQL type. * @return True if unsigned or non-numeric. */ -bool SqlTypeUnsigned(boost::optional type); +bool SqlTypeUnsigned(boost::optional< int16_t > type); /** * Checks if the binary type is unsigned. @@ -357,7 +367,7 @@ bool SqlTypeUnsigned(boost::optional type); * @param type Binary type. * @return True if unsigned or non-numeric. */ -bool BinaryTypeUnsigned(boost::optional type); +bool BinaryTypeUnsigned(boost::optional< int16_t > type); } // namespace type_traits } // namespace odbc } // namespace ignite diff --git a/src/odbc/include/ignite/odbc/utility.h b/src/odbc/include/ignite/odbc/utility.h index 8b33b5875..9cf18f5d1 100644 --- a/src/odbc/include/ignite/odbc/utility.h +++ b/src/odbc/include/ignite/odbc/utility.h @@ -38,7 +38,6 @@ #include #include - namespace ignite { namespace odbc { namespace utility { @@ -95,8 +94,7 @@ size_t CopyStringToBuffer(const std::string& str, SQLWCHAR* buf, size_t buflen, * @param reader Reader. * @param res Resulting vector. */ -void ReadByteArray(BinaryReaderImpl& reader, - std::vector< int8_t >& res); +void ReadByteArray(BinaryReaderImpl& reader, std::vector< int8_t >& res); /** * Read string from reader. @@ -110,8 +108,7 @@ void ReadString(BinaryReaderImpl& reader, std::string& str); * @param writer Writer. * @param str String. */ -void WriteString(BinaryWriterImpl& writer, - const std::string& str); +void WriteString(BinaryWriterImpl& writer, const std::string& str); /** * Read decimal value using reader. @@ -119,8 +116,7 @@ void WriteString(BinaryWriterImpl& writer, * @param reader Reader. * @param decimal Decimal value. */ -void ReadDecimal(BinaryReaderImpl& reader, - Decimal& decimal); +void ReadDecimal(BinaryReaderImpl& reader, Decimal& decimal); /** * Write decimal value using writer. @@ -128,18 +124,19 @@ void ReadDecimal(BinaryReaderImpl& reader, * @param writer Writer. * @param decimal Decimal value. */ -void WriteDecimal(BinaryWriterImpl& writer, - const Decimal& decimal); +void WriteDecimal(BinaryWriterImpl& writer, const Decimal& decimal); /** * Convert SQL string buffer to std::string. * * @param sqlStr SQL string buffer. * @param sqlStrLen SQL string length. - * @param isLenInBytes Indicator of whether the length indicates bytes or characters. + * @param isLenInBytes Indicator of whether the length indicates bytes or + * characters. * @return Standard string containing the same data. */ -std::string SqlStringToString(const SQLWCHAR* sqlStr, int32_t sqlStrLen = SQL_NTS, +std::string SqlStringToString(const SQLWCHAR* sqlStr, + int32_t sqlStrLen = SQL_NTS, bool isLenInBytes = false); /** @@ -147,7 +144,8 @@ std::string SqlStringToString(const SQLWCHAR* sqlStr, int32_t sqlStrLen = SQL_NT * * @param sqlStr SQL string buffer. * @param sqlStrLen SQL string length. - * @param isLenInBytes Indicator of whether given length is in bytes or characters. + * @param isLenInBytes Indicator of whether given length is in bytes or + * characters. * @return Standard optional string containing the same data. * If sqlStrLen indicates null string, boost::none is returned. */ @@ -203,17 +201,6 @@ std::vector< SQLWCHAR > ToWCHARVector(const std::string& value); */ std::vector< SQLWCHAR > ToWCHARVector(const char* value); -/** - * Convert SQL string buffer to boost::optional< std::string >. - * - * @param sqlStr SQL string buffer. - * @param sqlStrLen SQL string length. - * @return Standard optional string containing the same data. - * If sqlStrLen indicates null string, boost::none is returned. - */ -boost::optional< std::string > SqlStringToOptString(const unsigned char* sqlStr, - int32_t sqlStrLen); - /** * Convert binary data to hex dump form * @param data pointer to data @@ -226,7 +213,7 @@ std::string HexDump(const void* data, size_t count); } // namespace ignite namespace std { -/** +/** * Convert wstring to utf-8 encoding. */ inline std::ostream& operator<<(std::ostream& out, const std::wstring& value) { diff --git a/src/odbc/os/linux/include/ignite/odbc/common/dynamic_load_os.h b/src/odbc/os/linux/include/ignite/odbc/common/dynamic_load_os.h index 5bc68dff0..f9454c54b 100644 --- a/src/odbc/os/linux/include/ignite/odbc/common/dynamic_load_os.h +++ b/src/odbc/os/linux/include/ignite/odbc/common/dynamic_load_os.h @@ -22,113 +22,107 @@ #include "ignite/odbc/common/common.h" -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace dynamic - { - /** - * Represents dynamically loadable program module such as dymanic - * or shared library. - */ - class IGNITE_IMPORT_EXPORT Module - { - public: - /** - * Default constructor. - */ - Module(); - - /** - * Handle constructor. - * - * @param handle Os-specific Module handle. - */ - Module(void* handle); - - /** - * Destructor. - */ - ~Module(); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - Module(const Module& other); - - /** - * Copy constructor. - * - * @param other Other instance. - * @return This. - */ - Module& operator=(const Module& other); - - /** - * Load symbol from Module. - * - * @param name Name of the symbol to load. - * @return Pointer to symbol if found and NULL otherwise. - */ - void* FindSymbol(const char* name); - - /** - * Load symbol from Module. - * - * @param name Name of the symbol to load. - * @return Pointer to symbol if found and NULL otherwise. - */ - void* FindSymbol(const std::string& name) - { - return FindSymbol(name.c_str()); - } - - /** - * Check if the instance is loaded. - * - * @return True if the instance is loaded. - */ - bool IsLoaded() const; - - /** - * Unload module. - */ - void Unload(); - - private: - void* handle; - }; - - /** - * Load Module by the specified path. - * - * @param path Path to the Module to load. - * @return Module instance. - */ - IGNITE_IMPORT_EXPORT Module LoadModule(const wchar_t* path); - - /** - * Load Module by the specified path. - * - * @param path Path to the Module to load. - * @return Module instance. - */ - IGNITE_IMPORT_EXPORT Module LoadModule(const std::wstring& path); - - /** - * Returns Module associated with the calling process itself. - * - * @return Module for the calling process. - */ - IGNITE_IMPORT_EXPORT Module GetCurrent(); - } - } - } -} +namespace ignite { +namespace odbc { +namespace common { +namespace dynamic { +/** + * Represents dynamically loadable program module such as dymanic + * or shared library. + */ +class IGNITE_IMPORT_EXPORT Module { + public: + /** + * Default constructor. + */ + Module(); + + /** + * Handle constructor. + * + * @param handle Os-specific Module handle. + */ + Module(void* handle); + + /** + * Destructor. + */ + ~Module(); + + /** + * Copy constructor. + * + * @param other Other instance. + */ + Module(const Module& other); + + /** + * Copy constructor. + * + * @param other Other instance. + * @return This. + */ + Module& operator=(const Module& other); + + /** + * Load symbol from Module. + * + * @param name Name of the symbol to load. + * @return Pointer to symbol if found and NULL otherwise. + */ + void* FindSymbol(const char* name); + + /** + * Load symbol from Module. + * + * @param name Name of the symbol to load. + * @return Pointer to symbol if found and NULL otherwise. + */ + void* FindSymbol(const std::string& name) { + return FindSymbol(name.c_str()); + } + + /** + * Check if the instance is loaded. + * + * @return True if the instance is loaded. + */ + bool IsLoaded() const; + + /** + * Unload module. + */ + void Unload(); + + private: + void* handle; +}; + +/** + * Load Module by the specified path. + * + * @param path Path to the Module to load. + * @return Module instance. + */ +IGNITE_IMPORT_EXPORT Module LoadModule(const wchar_t* path); + +/** + * Load Module by the specified path. + * + * @param path Path to the Module to load. + * @return Module instance. + */ +IGNITE_IMPORT_EXPORT Module LoadModule(const std::wstring& path); + +/** + * Returns Module associated with the calling process itself. + * + * @return Module for the calling process. + */ +IGNITE_IMPORT_EXPORT Module GetCurrent(); +} // namespace dynamic +} // namespace common +} // namespace odbc +} // namespace ignite #endif diff --git a/src/odbc/os/linux/src/common/dynamic_load_os.cpp b/src/odbc/os/linux/src/common/dynamic_load_os.cpp index 7af69fa5f..d36e43a1e 100644 --- a/src/odbc/os/linux/src/common/dynamic_load_os.cpp +++ b/src/odbc/os/linux/src/common/dynamic_load_os.cpp @@ -21,75 +21,60 @@ #include "ignite/odbc/common/dynamic_load_os.h" #include "ignite/odbc/utility.h" -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace dynamic - { - Module::Module() : handle(NULL) - { - // No-op. - } - - Module::Module(void* handle) : handle(handle) - { - // No-op. - } - - Module::~Module() - { - // No-op. - } - - Module::Module(const Module& other) : handle(other.handle) - { - // No-op. - } - - Module& Module::operator=(const Module& other) - { - handle = other.handle; - - return *this; - } - - void* Module::FindSymbol(const char* name) - { - return dlsym(handle, name); - } - - bool Module::IsLoaded() const - { - return handle != NULL; - } - - void Module::Unload() - { - if (IsLoaded()) - dlclose(handle); - } - - Module LoadModule(const wchar_t* path) - { - std::string path0 = utility::ToUtf8(path); - void* handle = dlopen(path0.c_str(), RTLD_NOW); - - return Module(handle); - } - - Module LoadModule(const std::wstring& path) - { - return LoadModule(path.c_str()); - } - - Module GetCurrent() - { - return LoadModule(NULL); - } - } - } - } +namespace ignite { +namespace odbc { +namespace common { +namespace dynamic { +Module::Module() : handle(NULL) { + // No-op. } + +Module::Module(void* handle) : handle(handle) { + // No-op. +} + +Module::~Module() { + // No-op. +} + +Module::Module(const Module& other) : handle(other.handle) { + // No-op. +} + +Module& Module::operator=(const Module& other) { + handle = other.handle; + + return *this; +} + +void* Module::FindSymbol(const char* name) { + return dlsym(handle, name); +} + +bool Module::IsLoaded() const { + return handle != NULL; +} + +void Module::Unload() { + if (IsLoaded()) + dlclose(handle); +} + +Module LoadModule(const wchar_t* path) { + std::string path0 = utility::ToUtf8(path); + void* handle = dlopen(path0.c_str(), RTLD_NOW); + + return Module(handle); +} + +Module LoadModule(const std::wstring& path) { + return LoadModule(path.c_str()); +} + +Module GetCurrent() { + return LoadModule(NULL); +} +} // namespace dynamic +} // namespace common +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/os/win/include/ignite/odbc/common/dynamic_load_os.h b/src/odbc/os/win/include/ignite/odbc/common/dynamic_load_os.h index 1583582c6..49c8305f8 100644 --- a/src/odbc/os/win/include/ignite/odbc/common/dynamic_load_os.h +++ b/src/odbc/os/win/include/ignite/odbc/common/dynamic_load_os.h @@ -24,113 +24,107 @@ #include "ignite/odbc/common/common.h" -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace dynamic - { - /** - * Represents dynamically loadable program module such as dymanic - * or shared library. - */ - class IGNITE_IMPORT_EXPORT Module - { - public: - /** - * Default constructor. - */ - Module(); - - /** - * Handle constructor. - * - * @param handle Os-specific Module handle. - */ - Module(HMODULE handle); - - /** - * Destructor. - */ - ~Module(); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - Module(const Module& other); - - /** - * Copy constructor. - * - * @param other Other instance. - * @return This. - */ - Module& operator=(const Module& other); - - /** - * Load symbol from Module. - * - * @param name Name of the symbol to load. - * @return Pointer to symbol if found and NULL otherwise. - */ - void* FindSymbol(const char* name); - - /** - * Load symbol from Module. - * - * @param name Name of the symbol to load. - * @return Pointer to symbol if found and NULL otherwise. - */ - void* FindSymbol(const std::string& name) - { - return FindSymbol(name.c_str()); - } - - /** - * Check if the instance is loaded. - * - * @return True if the instance is loaded. - */ - bool IsLoaded() const; - - /** - * Unload module. - */ - void Unload(); - - private: - HMODULE handle; - }; - - /** - * Load Module by the specified path. - * - * @param path Path to the Module to load. - * @return Module instance. - */ - IGNITE_IMPORT_EXPORT Module LoadModule(const wchar_t* path); - - /** - * Load Module by the specified path. - * - * @param path Path to the Module to load. - * @return Module instance. - */ - IGNITE_IMPORT_EXPORT Module LoadModule(const std::wstring& path); - - /** - * Returns Module associated with the calling process itself. - * - * @return Module for the calling process. - */ - IGNITE_IMPORT_EXPORT Module GetCurrent(); - } - } - } -} +namespace ignite { +namespace odbc { +namespace common { +namespace dynamic { +/** + * Represents dynamically loadable program module such as dymanic + * or shared library. + */ +class IGNITE_IMPORT_EXPORT Module { + public: + /** + * Default constructor. + */ + Module(); + + /** + * Handle constructor. + * + * @param handle Os-specific Module handle. + */ + Module(HMODULE handle); + + /** + * Destructor. + */ + ~Module(); + + /** + * Copy constructor. + * + * @param other Other instance. + */ + Module(const Module& other); + + /** + * Copy constructor. + * + * @param other Other instance. + * @return This. + */ + Module& operator=(const Module& other); + + /** + * Load symbol from Module. + * + * @param name Name of the symbol to load. + * @return Pointer to symbol if found and NULL otherwise. + */ + void* FindSymbol(const char* name); + + /** + * Load symbol from Module. + * + * @param name Name of the symbol to load. + * @return Pointer to symbol if found and NULL otherwise. + */ + void* FindSymbol(const std::string& name) { + return FindSymbol(name.c_str()); + } + + /** + * Check if the instance is loaded. + * + * @return True if the instance is loaded. + */ + bool IsLoaded() const; + + /** + * Unload module. + */ + void Unload(); + + private: + HMODULE handle; +}; + +/** + * Load Module by the specified path. + * + * @param path Path to the Module to load. + * @return Module instance. + */ +IGNITE_IMPORT_EXPORT Module LoadModule(const wchar_t* path); + +/** + * Load Module by the specified path. + * + * @param path Path to the Module to load. + * @return Module instance. + */ +IGNITE_IMPORT_EXPORT Module LoadModule(const std::wstring& path); + +/** + * Returns Module associated with the calling process itself. + * + * @return Module for the calling process. + */ +IGNITE_IMPORT_EXPORT Module GetCurrent(); +} // namespace dynamic +} // namespace common +} // namespace odbc +} // namespace ignite #endif diff --git a/src/odbc/os/win/include/ignite/odbc/system/ui/custom_window.h b/src/odbc/os/win/include/ignite/odbc/system/ui/custom_window.h index 490854032..34278c797 100644 --- a/src/odbc/os/win/include/ignite/odbc/system/ui/custom_window.h +++ b/src/odbc/os/win/include/ignite/odbc/system/ui/custom_window.h @@ -88,7 +88,8 @@ class CustomWindow : public Window { * @return Auto pointer containing new window. */ std::unique_ptr< Window > CreateGroupBox(int posX, int posY, int sizeX, - int sizeY, const std::wstring& title, int id); + int sizeY, const std::wstring& title, + int id); /** * Create child label window. @@ -101,8 +102,9 @@ class CustomWindow : public Window { * @param id ID to be assigned to the created window. * @return Auto pointer containing new window. */ - std::unique_ptr< Window > CreateLabel(int posX, int posY, int sizeX, int sizeY, - const std::wstring& title, int id); + std::unique_ptr< Window > CreateLabel(int posX, int posY, int sizeX, + int sizeY, const std::wstring& title, + int id); /** * Create child Edit window. @@ -116,7 +118,8 @@ class CustomWindow : public Window { * @return Auto pointer containing new window. */ std::unique_ptr< Window > CreateEdit(int posX, int posY, int sizeX, int sizeY, - const std::wstring& title, int id, int style = 0); + const std::wstring& title, int id, + int style = 0); /** * Create child button window. @@ -129,7 +132,8 @@ class CustomWindow : public Window { * @param id ID to be assigned to the created window. * @return Auto pointer containing new window. */ - std::unique_ptr< Window > CreateButton(int posX, int posY, int sizeX, int sizeY, const std::wstring& title, + std::unique_ptr< Window > CreateButton(int posX, int posY, int sizeX, + int sizeY, const std::wstring& title, int id); /** @@ -182,4 +186,4 @@ class CustomWindow : public Window { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SYSTEM_UI_CUSTOM_WINDOW \ No newline at end of file +#endif //_IGNITE_ODBC_SYSTEM_UI_CUSTOM_WINDOW 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 5c7988d3a..02b189a51 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 @@ -45,7 +45,8 @@ class Window { * @param title Window title. * @param callback Event processing function. */ - Window(Window* parent, const std::wstring& className, const std::wstring& title); + Window(Window* parent, const std::wstring& className, + const std::wstring& title); /** * Constructor for the existing window. @@ -199,4 +200,4 @@ class Window { } // namespace odbc } // namespace ignite -#endif //_IGNITE_ODBC_SYSTEM_UI_WINDOW \ No newline at end of file +#endif //_IGNITE_ODBC_SYSTEM_UI_WINDOW diff --git a/src/odbc/os/win/src/common/dynamic_load_os.cpp b/src/odbc/os/win/src/common/dynamic_load_os.cpp index 024fefa1e..8e2b94695 100644 --- a/src/odbc/os/win/src/common/dynamic_load_os.cpp +++ b/src/odbc/os/win/src/common/dynamic_load_os.cpp @@ -20,99 +20,83 @@ #include "ignite/odbc/common/dynamic_load_os.h" -namespace -{ - std::wstring StringToWstring(const std::string& str) - { - int wslen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast(str.size()), NULL, 0); +namespace { +std::wstring StringToWstring(const std::string& str) { + int wslen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), + static_cast< int >(str.size()), NULL, 0); - if (!wslen) - return std::wstring(); + if (!wslen) + return std::wstring(); - std::vector converted(wslen); + std::vector< WCHAR > converted(wslen); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast(str.size()), &converted[0], wslen); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), static_cast< int >(str.size()), + &converted[0], wslen); - std::wstring res(converted.begin(), converted.end()); + std::wstring res(converted.begin(), converted.end()); - return res; - } + return res; } +} // namespace -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace dynamic - { - Module::Module() : handle(NULL) - { - // No-op. - } - - Module::Module(HMODULE handle) : handle(handle) - { - // No-op. - } - - Module::~Module() - { - // No-op. - } - - Module::Module(const Module& other) : handle(other.handle) - { - // No-op. - } - - Module& Module::operator=(const Module& other) - { - handle = other.handle; - - return *this; - } - - void* Module::FindSymbol(const char* name) - { - return GetProcAddress(handle, name); - } - - bool Module::IsLoaded() const - { - return handle != NULL; - } - - void Module::Unload() - { - if (IsLoaded()) - { - FreeLibrary(handle); - - handle = NULL; - } - } - - Module LoadModule(const wchar_t* path) - { - HMODULE handle = LoadLibrary(path); - - return Module(handle); - } - - Module LoadModule(const std::wstring& path) - { - return LoadModule(path.c_str()); - } - - Module GetCurrent() - { - HMODULE handle = GetModuleHandle(NULL); - - return Module(handle); - } - } - } - } +namespace ignite { +namespace odbc { +namespace common { +namespace dynamic { +Module::Module() : handle(NULL) { + // No-op. } + +Module::Module(HMODULE handle) : handle(handle) { + // No-op. +} + +Module::~Module() { + // No-op. +} + +Module::Module(const Module& other) : handle(other.handle) { + // No-op. +} + +Module& Module::operator=(const Module& other) { + handle = other.handle; + + return *this; +} + +void* Module::FindSymbol(const char* name) { + return GetProcAddress(handle, name); +} + +bool Module::IsLoaded() const { + return handle != NULL; +} + +void Module::Unload() { + if (IsLoaded()) { + FreeLibrary(handle); + + handle = NULL; + } +} + +Module LoadModule(const wchar_t* path) { + HMODULE handle = LoadLibrary(path); + + return Module(handle); +} + +Module LoadModule(const std::wstring& path) { + return LoadModule(path.c_str()); +} + +Module GetCurrent() { + HMODULE handle = GetModuleHandle(NULL); + + return Module(handle); +} +} // namespace dynamic +} // namespace common +} // namespace odbc +} // namespace ignite 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 dc5f8f1a7..5170e74b1 100644 --- a/src/odbc/os/win/src/system/ui/custom_window.cpp +++ b/src/odbc/os/win/src/system/ui/custom_window.cpp @@ -116,9 +116,10 @@ std::unique_ptr< Window > CustomWindow::CreateGroupBox( return child; } -std::unique_ptr< Window > CustomWindow::CreateLabel(int posX, int posY, int sizeX, - int sizeY, const std::wstring& title, - int id) { +std::unique_ptr< Window > CustomWindow::CreateLabel(int posX, int posY, + int sizeX, int sizeY, + const std::wstring& title, + int id) { std::unique_ptr< Window > child(new Window(this, L"Static", title)); child->Create(WS_CHILD | WS_VISIBLE, posX, posY, sizeX, sizeY, id); @@ -126,9 +127,10 @@ std::unique_ptr< Window > CustomWindow::CreateLabel(int posX, int posY, int size return child; } -std::unique_ptr< Window > CustomWindow::CreateEdit(int posX, int posY, int sizeX, - int sizeY, const std::wstring& title, - int id, int style) { +std::unique_ptr< Window > CustomWindow::CreateEdit(int posX, int posY, + int sizeX, int sizeY, + const std::wstring& title, + int id, int style) { std::unique_ptr< Window > child(new Window(this, L"Edit", title)); child->Create( 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 b8ac7de61..c5d8e070d 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 @@ -187,8 +187,7 @@ int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, wVal = utility::FromUtf8(config.GetHostname()); hostnameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Hostname*:", ChildId::HOST_NAME_LABEL); - hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - wVal, + hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, ChildId::HOST_NAME_EDIT); rowPos += INTERVAL + ROW_HEIGHT; @@ -204,8 +203,7 @@ int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, wVal = utility::FromUtf8(config.GetDatabase()); databaseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Database*:", ChildId::DATABASE_LABEL); - databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - wVal, + databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, ChildId::DATABASE_EDIT); rowPos += INTERVAL + ROW_HEIGHT; @@ -221,8 +219,7 @@ int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, wVal = utility::FromUtf8(config.GetPassword()); passwordLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Password*:", ChildId::PASSWORD_LABEL); - passwordEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - wVal, + passwordEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, ChildId::USER_EDIT, ES_PASSWORD); rowPos += INTERVAL + ROW_HEIGHT; @@ -270,8 +267,8 @@ int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, rowPos += INTERVAL + ROW_HEIGHT; wVal = utility::FromUtf8(config.GetSshPrivateKeyFile()); - sshPrivateKeyFileLabel = - CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"SSH Private Key File:", + sshPrivateKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, L"SSH Private Key File:", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); sshPrivateKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, ChildId::SSH_PRIVATE_KEY_FILE_EDIT); @@ -302,8 +299,8 @@ int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, rowPos += INTERVAL + ROW_HEIGHT; wVal = utility::FromUtf8(config.GetSshKnownHostsFile()); - sshKnownHostsFileLabel = - CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"SSH Known Hosts File:", + sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, L"SSH Known Hosts File:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, ChildId::SSH_KNOWN_HOSTS_FILE_EDIT); @@ -342,8 +339,7 @@ int DsnConfigurationWindow::CreateLogSettingsGroup(int posX, int posY, logLevelLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Log Level:", ChildId::LOG_LEVEL_LABEL); logLevelComboBox = CreateComboBox(editPosX, rowPos, comboSizeX, ROW_HEIGHT, - L"", - ChildId::LOG_LEVEL_COMBO_BOX); + L"", ChildId::LOG_LEVEL_COMBO_BOX); logLevelComboBox->AddString(L"Debug"); logLevelComboBox->AddString(L"Info"); @@ -373,7 +369,8 @@ int DsnConfigurationWindow::CreateLogSettingsGroup(int posX, int posY, std::wstring logLevelWStr; logLevelComboBox->GetText(logLevelWStr); - if (LogLevel::FromString(utility::ToUtf8(logLevelWStr), LogLevel::Type::UNKNOWN) + if (LogLevel::FromString(utility::ToUtf8(logLevelWStr), + LogLevel::Type::UNKNOWN) == LogLevel::Type::OFF) { logPathEdit->SetEnabled(false); } else { @@ -402,11 +399,11 @@ int DsnConfigurationWindow::CreateTlsSettingsGroup(int posX, int posY, rowPos += INTERVAL + ROW_HEIGHT; - tlsAllowInvalidHostnamesCheckBox = - CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - L"Allow Invalid Hostnames (enabling option is less secure)", - ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, - config.IsTlsAllowInvalidHostnames()); + tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + L"Allow Invalid Hostnames (enabling option is less secure)", + ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, + config.IsTlsAllowInvalidHostnames()); rowPos += INTERVAL + ROW_HEIGHT; @@ -487,7 +484,8 @@ int DsnConfigurationWindow::CreateSchemaSettingsGroup(int posX, int posY, std::wstring scanMethodWStr; scanMethodComboBox->GetText(scanMethodWStr); - if (ScanMethod::FromString(utility::ToUtf8(scanMethodWStr), ScanMethod::Type::UNKNOWN) + if (ScanMethod::FromString(utility::ToUtf8(scanMethodWStr), + ScanMethod::Type::UNKNOWN) == ScanMethod::Type::ALL) { scanLimitEdit->SetEnabled(false); } else { @@ -512,7 +510,7 @@ int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, retryReadsCheckBox = CreateCheckBox( labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, L"Retry Reads", - ChildId::RETRY_READS_CHECK_BOX, config.IsRetryReads()); + ChildId::RETRY_READS_CHECK_BOX, config.IsRetryReads()); rowPos += INTERVAL + ROW_HEIGHT; @@ -549,8 +547,9 @@ int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); - loginTimeoutSecEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, - ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); + loginTimeoutSecEdit = + CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, + ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); rowPos += INTERVAL + ROW_HEIGHT; @@ -564,8 +563,8 @@ int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, wVal = std::to_wstring(config.GetDefaultFetchSize()); defaultFetchSizeLabel = - CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - L"Fetch Size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); + CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, L"Fetch Size:", + ChildId::DEFAULT_FETCH_SIZE_LABEL); defaultFetchSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, wVal, @@ -667,7 +666,8 @@ bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { case ChildId::LOG_LEVEL_COMBO_BOX: { std::wstring logLevelWStr; logLevelComboBox->GetText(logLevelWStr); - if (LogLevel::FromString(utility::ToUtf8(logLevelWStr), LogLevel::Type::UNKNOWN) + if (LogLevel::FromString(utility::ToUtf8(logLevelWStr), + LogLevel::Type::UNKNOWN) == LogLevel::Type::OFF) { logPathEdit->SetEnabled(false); } else { @@ -679,7 +679,8 @@ bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { case ChildId::SCAN_METHOD_COMBO_BOX: { std::wstring scanMethodWStr; scanMethodComboBox->GetText(scanMethodWStr); - if (ScanMethod::FromString(utility::ToUtf8(scanMethodWStr), ScanMethod::Type::UNKNOWN) + if (ScanMethod::FromString(utility::ToUtf8(scanMethodWStr), + ScanMethod::Type::UNKNOWN) == ScanMethod::Type::ALL) { scanLimitEdit->SetEnabled(false); } else { @@ -797,7 +798,8 @@ void DsnConfigurationWindow::RetrieveSshParameters( std::string sshUserStr = utility::ToUtf8(sshUserWStr); std::string sshHostStr = utility::ToUtf8(sshHostWStr); std::string sshPrivateKeyFileStr = utility::ToUtf8(sshPrivateKeyFileWStr); - std::string sshPrivateKeyPassphraseStr = utility::ToUtf8(sshPrivateKeyPassphraseWStr); + std::string sshPrivateKeyPassphraseStr = + utility::ToUtf8(sshPrivateKeyPassphraseWStr); std::string sshKnownHostsFileStr = utility::ToUtf8(sshKnownHostsFileWStr); LOG_MSG("Retrieving arguments:"); diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index 06c6c334a..4165e37c6 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -24,7 +24,8 @@ namespace odbc { namespace system { namespace ui { HINSTANCE GetHInstance() { - HINSTANCE hInstance = GetModuleHandle(utility::FromUtf8(TARGET_MODULE_FULL_NAME).c_str()); + HINSTANCE hInstance = + GetModuleHandle(utility::FromUtf8(TARGET_MODULE_FULL_NAME).c_str()); if (hInstance == NULL) { std::stringstream buf; diff --git a/src/odbc/os/win/src/system_dsn.cpp b/src/odbc/os/win/src/system_dsn.cpp index 1ec9bb4f8..bd1c29789 100644 --- a/src/odbc/os/win/src/system_dsn.cpp +++ b/src/odbc/os/win/src/system_dsn.cpp @@ -122,8 +122,7 @@ bool UnregisterDsn(const std::string& dsn) { return true; } catch (ignite::odbc::IgniteError& err) { std::wstring errText = FromUtf8(err.GetText()); - MessageBox(NULL, errText.c_str(), L"Error!", - MB_ICONEXCLAMATION | MB_OK); + MessageBox(NULL, errText.c_str(), L"Error!", MB_ICONEXCLAMATION | MB_OK); SQLPostInstallerError(err.GetCode(), errText.c_str()); } diff --git a/src/odbc/src/app/application_data_buffer.cpp b/src/odbc/src/app/application_data_buffer.cpp index 3d7fa9451..dc5a3a6a2 100644 --- a/src/odbc/src/app/application_data_buffer.cpp +++ b/src/odbc/src/app/application_data_buffer.cpp @@ -280,7 +280,6 @@ ConversionResult::Type ApplicationDataBuffer::PutValToStrBuffer( template < typename OutCharT, typename InCharT > ConversionResult::Type ApplicationDataBuffer::PutStrToStrBuffer( const std::basic_string< InCharT >& value, int32_t& written) { - written = 0; SqlLen outCharSize = static_cast< SqlLen >(sizeof(OutCharT)); @@ -343,7 +342,8 @@ ConversionResult::Type ApplicationDataBuffer::PutRawDataToBuffer( : ConversionResult::Type::AI_SUCCESS; } -ConversionResult::Type ApplicationDataBuffer::PutInt8(boost::optional< int8_t > value) { +ConversionResult::Type ApplicationDataBuffer::PutInt8( + boost::optional< int8_t > value) { if (value) return PutInt8(*value); else @@ -925,7 +925,8 @@ ConversionResult::Type ApplicationDataBuffer::PutTimestamp( return ConversionResult::Type::AI_UNSUPPORTED_CONVERSION; } -ConversionResult::Type ApplicationDataBuffer::PutTime(const boost::optional< Time >& value) { +ConversionResult::Type ApplicationDataBuffer::PutTime( + const boost::optional< Time >& value) { if (value) return PutTime(*value); else diff --git a/src/odbc/src/binary/binary_raw_reader.cpp b/src/odbc/src/binary/binary_raw_reader.cpp index 407b1018a..867e494c0 100644 --- a/src/odbc/src/binary/binary_raw_reader.cpp +++ b/src/odbc/src/binary/binary_raw_reader.cpp @@ -148,4 +148,4 @@ int32_t BinaryRawReader::ReadCollectionSize() { } } // namespace binary } // namespace odbc -} // namespace ignite \ No newline at end of file +} // namespace ignite diff --git a/src/odbc/src/binary/binary_reader.cpp b/src/odbc/src/binary/binary_reader.cpp index fd70799c8..a15ddc4c8 100644 --- a/src/odbc/src/binary/binary_reader.cpp +++ b/src/odbc/src/binary/binary_reader.cpp @@ -168,4 +168,3 @@ BinaryRawReader BinaryReader::RawReader() { } // namespace binary } // namespace odbc } // namespace ignite - diff --git a/src/odbc/src/binary/binary_writer.cpp b/src/odbc/src/binary/binary_writer.cpp index 5464262d8..657882065 100644 --- a/src/odbc/src/binary/binary_writer.cpp +++ b/src/odbc/src/binary/binary_writer.cpp @@ -171,4 +171,3 @@ BinaryRawWriter BinaryWriter::RawWriter() { } // namespace binary } // namespace odbc } // namespace ignite - diff --git a/src/odbc/src/cluster/cluster_group.cpp b/src/odbc/src/cluster/cluster_group.cpp index e1116feb7..ba83d497c 100644 --- a/src/odbc/src/cluster/cluster_group.cpp +++ b/src/odbc/src/cluster/cluster_group.cpp @@ -22,142 +22,112 @@ using namespace ignite::odbc::common::concurrent; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace cluster - { - ClusterGroup::ClusterGroup(SP_ClusterGroupImpl impl) : - impl(impl) - { - // No-op. - } - - ClusterGroup ClusterGroup::ForAttribute(std::string name, std::string val) - { - return ClusterGroup(impl.Get()->ForAttribute(name, val)); - } - - ClusterGroup ClusterGroup::ForCacheNodes(std::string cacheName) - { - return ClusterGroup(impl.Get()->ForCacheNodes(cacheName)); - } - - ClusterGroup ClusterGroup::ForClientNodes(std::string cacheName) - { - return ClusterGroup(impl.Get()->ForClientNodes(cacheName)); - } - - ClusterGroup ClusterGroup::ForClients() - { - return ClusterGroup(impl.Get()->ForClients()); - } - - ClusterGroup ClusterGroup::ForDaemons() - { - return ClusterGroup(impl.Get()->ForDaemons()); - } - - ClusterGroup ClusterGroup::ForDataNodes(std::string cacheName) - { - return ClusterGroup(impl.Get()->ForDataNodes(cacheName)); - } - - ClusterGroup ClusterGroup::ForHost(ClusterNode node) - { - return ClusterGroup(impl.Get()->ForHost(node)); - } - - ClusterGroup ClusterGroup::ForHost(std::string hostName) - { - return ClusterGroup(impl.Get()->ForHost(hostName)); - } - - ClusterGroup ClusterGroup::ForHosts(std::vector hostNames) - { - return ClusterGroup(impl.Get()->ForHosts(hostNames)); - } - - ClusterGroup ClusterGroup::ForNode(ClusterNode node) - { - return ClusterGroup(impl.Get()->ForNode(node)); - } - - ClusterGroup ClusterGroup::ForNodeId(Guid id) - { - return ClusterGroup(impl.Get()->ForNodeId(id)); - } - - ClusterGroup ClusterGroup::ForNodeIds(std::vector ids) - { - return ClusterGroup(impl.Get()->ForNodeIds(ids)); - } - - ClusterGroup ClusterGroup::ForNodes(std::vector nodes) - { - return ClusterGroup(impl.Get()->ForNodes(nodes)); - } - - ClusterGroup ClusterGroup::ForOldest() - { - return ClusterGroup(impl.Get()->ForOldest()); - } - - ClusterGroup ClusterGroup::ForPredicate(IgnitePredicate* pred) - { - return ClusterGroup(impl.Get()->ForPredicate(pred)); - } - - ClusterGroup ClusterGroup::ForRandom() - { - return ClusterGroup(impl.Get()->ForRandom()); - } - - ClusterGroup ClusterGroup::ForRemotes() - { - return ClusterGroup(impl.Get()->ForRemotes()); - } - - ClusterGroup ClusterGroup::ForServers() - { - return ClusterGroup(impl.Get()->ForServers()); - } - - ClusterGroup ClusterGroup::ForYoungest() - { - return ClusterGroup(impl.Get()->ForYoungest()); - } - - ClusterGroup ClusterGroup::ForCpp() - { - return ClusterGroup(impl.Get()->ForCpp()); - } - - ClusterNode ClusterGroup::GetNode() - { - return impl.Get()->GetNode(); - } - - ClusterNode ClusterGroup::GetNode(Guid nid) - { - return impl.Get()->GetNode(nid); - } - - std::vector ClusterGroup::GetNodes() - { - return impl.Get()->GetNodes(); - } - - IgnitePredicate* ClusterGroup::GetPredicate() - { - return impl.Get()->GetPredicate(); - } - - SP_ClusterGroupImpl ClusterGroup::GetImpl() - { - return impl; - } - } - } +namespace ignite { +namespace odbc { +namespace cluster { +ClusterGroup::ClusterGroup(SP_ClusterGroupImpl impl) : impl(impl) { + // No-op. } + +ClusterGroup ClusterGroup::ForAttribute(std::string name, std::string val) { + return ClusterGroup(impl.Get()->ForAttribute(name, val)); +} + +ClusterGroup ClusterGroup::ForCacheNodes(std::string cacheName) { + return ClusterGroup(impl.Get()->ForCacheNodes(cacheName)); +} + +ClusterGroup ClusterGroup::ForClientNodes(std::string cacheName) { + return ClusterGroup(impl.Get()->ForClientNodes(cacheName)); +} + +ClusterGroup ClusterGroup::ForClients() { + return ClusterGroup(impl.Get()->ForClients()); +} + +ClusterGroup ClusterGroup::ForDaemons() { + return ClusterGroup(impl.Get()->ForDaemons()); +} + +ClusterGroup ClusterGroup::ForDataNodes(std::string cacheName) { + return ClusterGroup(impl.Get()->ForDataNodes(cacheName)); +} + +ClusterGroup ClusterGroup::ForHost(ClusterNode node) { + return ClusterGroup(impl.Get()->ForHost(node)); +} + +ClusterGroup ClusterGroup::ForHost(std::string hostName) { + return ClusterGroup(impl.Get()->ForHost(hostName)); +} + +ClusterGroup ClusterGroup::ForHosts(std::vector< std::string > hostNames) { + return ClusterGroup(impl.Get()->ForHosts(hostNames)); +} + +ClusterGroup ClusterGroup::ForNode(ClusterNode node) { + return ClusterGroup(impl.Get()->ForNode(node)); +} + +ClusterGroup ClusterGroup::ForNodeId(Guid id) { + return ClusterGroup(impl.Get()->ForNodeId(id)); +} + +ClusterGroup ClusterGroup::ForNodeIds(std::vector< Guid > ids) { + return ClusterGroup(impl.Get()->ForNodeIds(ids)); +} + +ClusterGroup ClusterGroup::ForNodes(std::vector< ClusterNode > nodes) { + return ClusterGroup(impl.Get()->ForNodes(nodes)); +} + +ClusterGroup ClusterGroup::ForOldest() { + return ClusterGroup(impl.Get()->ForOldest()); +} + +ClusterGroup ClusterGroup::ForPredicate(IgnitePredicate< ClusterNode >* pred) { + return ClusterGroup(impl.Get()->ForPredicate(pred)); +} + +ClusterGroup ClusterGroup::ForRandom() { + return ClusterGroup(impl.Get()->ForRandom()); +} + +ClusterGroup ClusterGroup::ForRemotes() { + return ClusterGroup(impl.Get()->ForRemotes()); +} + +ClusterGroup ClusterGroup::ForServers() { + return ClusterGroup(impl.Get()->ForServers()); +} + +ClusterGroup ClusterGroup::ForYoungest() { + return ClusterGroup(impl.Get()->ForYoungest()); +} + +ClusterGroup ClusterGroup::ForCpp() { + return ClusterGroup(impl.Get()->ForCpp()); +} + +ClusterNode ClusterGroup::GetNode() { + return impl.Get()->GetNode(); +} + +ClusterNode ClusterGroup::GetNode(Guid nid) { + return impl.Get()->GetNode(nid); +} + +std::vector< ClusterNode > ClusterGroup::GetNodes() { + return impl.Get()->GetNodes(); +} + +IgnitePredicate< ClusterNode >* ClusterGroup::GetPredicate() { + return impl.Get()->GetPredicate(); +} + +SP_ClusterGroupImpl ClusterGroup::GetImpl() { + return impl; +} +} // namespace cluster +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/cluster/cluster_node.cpp b/src/odbc/src/cluster/cluster_node.cpp index 7a610d7ff..c23e8c619 100644 --- a/src/odbc/src/cluster/cluster_node.cpp +++ b/src/odbc/src/cluster/cluster_node.cpp @@ -20,72 +20,56 @@ using namespace ignite::odbc::common::concurrent; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace cluster - { - ClusterNode::ClusterNode(SharedPointer impl) : - impl(impl) - { - // No-op. - } - - const std::vector& ClusterNode::GetAddresses() const - { - return impl.Get()->GetAddresses(); - } - - std::string ClusterNode::GetConsistentId() const - { - return impl.Get()->GetConsistentId(); - } - - const std::vector& ClusterNode::GetHostNames() const - { - return impl.Get()->GetHostNames(); - } - - bool ClusterNode::IsAttributeSet(std::string name) const - { - return impl.Get()->IsAttributeSet(name); - } - - std::vector ClusterNode::GetAttributes() const - { - return impl.Get()->GetAttributes(); - } - - Guid ClusterNode::GetId() const - { - return impl.Get()->GetId(); - } - - bool ClusterNode::IsClient() const - { - return impl.Get()->IsClient(); - } - - bool ClusterNode::IsDaemon() const - { - return impl.Get()->IsDaemon(); - } - - bool ClusterNode::IsLocal() const - { - return impl.Get()->IsLocal(); - } - - int64_t ClusterNode::GetOrder() const - { - return impl.Get()->GetOrder(); - } - - const IgniteProductVersion& ClusterNode::GetVersion() const - { - return impl.Get()->GetVersion(); - } - } - } +namespace ignite { +namespace odbc { +namespace cluster { +ClusterNode::ClusterNode(SharedPointer< ClusterNodeImpl > impl) : impl(impl) { + // No-op. } + +const std::vector< std::string >& ClusterNode::GetAddresses() const { + return impl.Get()->GetAddresses(); +} + +std::string ClusterNode::GetConsistentId() const { + return impl.Get()->GetConsistentId(); +} + +const std::vector< std::string >& ClusterNode::GetHostNames() const { + return impl.Get()->GetHostNames(); +} + +bool ClusterNode::IsAttributeSet(std::string name) const { + return impl.Get()->IsAttributeSet(name); +} + +std::vector< std::string > ClusterNode::GetAttributes() const { + return impl.Get()->GetAttributes(); +} + +Guid ClusterNode::GetId() const { + return impl.Get()->GetId(); +} + +bool ClusterNode::IsClient() const { + return impl.Get()->IsClient(); +} + +bool ClusterNode::IsDaemon() const { + return impl.Get()->IsDaemon(); +} + +bool ClusterNode::IsLocal() const { + return impl.Get()->IsLocal(); +} + +int64_t ClusterNode::GetOrder() const { + return impl.Get()->GetOrder(); +} + +const IgniteProductVersion& ClusterNode::GetVersion() const { + return impl.Get()->GetVersion(); +} +} // namespace cluster +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/cluster/ignite_cluster.cpp b/src/odbc/src/cluster/ignite_cluster.cpp index 1326d078a..d805385a6 100644 --- a/src/odbc/src/cluster/ignite_cluster.cpp +++ b/src/odbc/src/cluster/ignite_cluster.cpp @@ -21,82 +21,65 @@ using namespace ignite::odbc::common::concurrent; using namespace ignite::odbc::cluster; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace cluster - { - IgniteCluster::IgniteCluster(SharedPointer impl) : - impl(impl) - { - // No-op. - } - - bool IgniteCluster::IsActive() - { - return impl.Get()->IsActive(); - } - - void IgniteCluster::SetActive(bool active) - { - impl.Get()->SetActive(active); - } - - void IgniteCluster::DisableWal(std::string cacheName) - { - impl.Get()->DisableWal(cacheName); - } - - void IgniteCluster::EnableWal(std::string cacheName) - { - impl.Get()->EnableWal(cacheName); - } - - bool IgniteCluster::IsWalEnabled(std::string cacheName) - { - return impl.Get()->IsWalEnabled(cacheName); - } - - ClusterGroup IgniteCluster::ForLocal() - { - return impl.Get()->ForLocal(); - } - - ClusterNode IgniteCluster::GetLocalNode() - { - return impl.Get()->GetLocalNode(); - } - - void IgniteCluster::SetBaselineTopologyVersion(int64_t topVer) - { - impl.Get()->SetBaselineTopologyVersion(topVer); - } - - void IgniteCluster::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) - { - impl.Get()->SetTxTimeoutOnPartitionMapExchange(timeout); - } - - bool IgniteCluster::PingNode(Guid nid) - { - return impl.Get()->PingNode(nid); - } - - std::vector IgniteCluster::GetTopology(int64_t version) - { - return impl.Get()->GetTopology(version); - } - - int64_t IgniteCluster::GetTopologyVersion() - { - return impl.Get()->GetTopologyVersion(); - } - - ClusterGroup IgniteCluster::AsClusterGroup() - { - return ClusterGroup(impl.Get()->AsClusterGroup()); - } - } - } +namespace ignite { +namespace odbc { +namespace cluster { +IgniteCluster::IgniteCluster(SharedPointer< IgniteClusterImpl > impl) + : impl(impl) { + // No-op. } + +bool IgniteCluster::IsActive() { + return impl.Get()->IsActive(); +} + +void IgniteCluster::SetActive(bool active) { + impl.Get()->SetActive(active); +} + +void IgniteCluster::DisableWal(std::string cacheName) { + impl.Get()->DisableWal(cacheName); +} + +void IgniteCluster::EnableWal(std::string cacheName) { + impl.Get()->EnableWal(cacheName); +} + +bool IgniteCluster::IsWalEnabled(std::string cacheName) { + return impl.Get()->IsWalEnabled(cacheName); +} + +ClusterGroup IgniteCluster::ForLocal() { + return impl.Get()->ForLocal(); +} + +ClusterNode IgniteCluster::GetLocalNode() { + return impl.Get()->GetLocalNode(); +} + +void IgniteCluster::SetBaselineTopologyVersion(int64_t topVer) { + impl.Get()->SetBaselineTopologyVersion(topVer); +} + +void IgniteCluster::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) { + impl.Get()->SetTxTimeoutOnPartitionMapExchange(timeout); +} + +bool IgniteCluster::PingNode(Guid nid) { + return impl.Get()->PingNode(nid); +} + +std::vector< ClusterNode > IgniteCluster::GetTopology(int64_t version) { + return impl.Get()->GetTopology(version); +} + +int64_t IgniteCluster::GetTopologyVersion() { + return impl.Get()->GetTopologyVersion(); +} + +ClusterGroup IgniteCluster::AsClusterGroup() { + return ClusterGroup(impl.Get()->AsClusterGroup()); +} +} // namespace cluster +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/config/connection_info.cpp b/src/odbc/src/config/connection_info.cpp index efdd2dedd..f864eb1ad 100644 --- a/src/odbc/src/config/connection_info.cpp +++ b/src/odbc/src/config/connection_info.cpp @@ -2874,7 +2874,7 @@ SqlResult::Type ConnectionInfo::GetInfo(InfoType type, void* buf, short buflen, if (!buflen) return SqlResult::AI_ERROR; - // Length is given in bytes, + // Length is given in bytes, unsigned short strlen = static_cast< short >(utility::CopyStringToBuffer( itStr->second, reinterpret_cast< SQLWCHAR* >(buf), buflen, true)); diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 0bf53a839..d1970b16c 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -257,15 +257,16 @@ SharedPointer< DocumentDbDatabaseMetadata > Connection::GetDatabaseMetadata( connection_.Get()->GetDatabaseMetadata(errInfo); if (!documentDbDatabaseMetaData.IsValid()) { std::string message = errInfo.errMsg; - err = IgniteError(IgniteError::IGNITE_ERR_JNI_GET_DOCUMENTDB_DATABASE_METADATA, - message.c_str()); + err = IgniteError( + IgniteError::IGNITE_ERR_JNI_GET_DOCUMENTDB_DATABASE_METADATA, + message.c_str()); return nullptr; } return documentDbDatabaseMetaData; } -SharedPointer< DocumentDbConnectionProperties > Connection::GetConnectionProperties( - IgniteError& err) { +SharedPointer< DocumentDbConnectionProperties > +Connection::GetConnectionProperties(IgniteError& err) { if (!connection_.IsValid()) { err = IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_STATE, "Must be connected."); @@ -276,8 +277,9 @@ SharedPointer< DocumentDbConnectionProperties > Connection::GetConnectionPropert connection_.Get()->GetConnectionProperties(errInfo); if (!connectionProperties.IsValid()) { std::string message = errInfo.errMsg; - err = IgniteError(IgniteError::IGNITE_ERR_JNI_GET_DOCUMENTDB_CONNECTION_PROPERTIES, - message.c_str()); + err = IgniteError( + IgniteError::IGNITE_ERR_JNI_GET_DOCUMENTDB_CONNECTION_PROPERTIES, + message.c_str()); return nullptr; } return connectionProperties; @@ -580,11 +582,12 @@ bool Connection::TryRestoreConnection(IgniteError& err) { JniErrorInfo errInfo; auto ctx = GetJniContext(errInfo); if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { - err = IgniteError( - static_cast< int32_t >(errInfo.code), - std::string(errInfo.errCls).append(": ").append(errInfo.errMsg).c_str()); + err = IgniteError(static_cast< int32_t >(errInfo.code), + std::string(errInfo.errCls) + .append(": ") + .append(errInfo.errMsg) + .c_str()); return false; - } SharedPointer< DocumentDbConnection > conn = new DocumentDbConnection(ctx); if (!conn.IsValid() @@ -667,7 +670,7 @@ std::string Connection::FormatMongoCppConnectionString( return mongoConnectionString; } -SharedPointer< JniContext > Connection::GetJniContext(JniErrorInfo &errInfo) { +SharedPointer< JniContext > Connection::GetJniContext(JniErrorInfo& errInfo) { if (!jniContext_.IsValid()) { // Resolve DOCUMENTDB_HOME. std::string home = jni::ResolveDocumentDbHome(); @@ -745,7 +748,7 @@ bool Connection::ConnectCPPDocumentDB(int32_t localSSHTunnelPort, tls_options.allow_invalid_certificates(true); client_options.tls_opts(tls_options); } - + mongoClient_ = std::make_shared< mongocxx::client >( mongocxx::uri(mongoCPPConnectionString), client_options); std::string database = config_.GetDatabase(); @@ -764,9 +767,9 @@ bool Connection::ConnectCPPDocumentDB(int32_t localSSHTunnelPort, } catch (const mongocxx::exception& xcp) { std::stringstream message; message << "Unable to establish connection with DocumentDB." - << " code: " << xcp.code().value() - << " messagge: " << xcp.code().message() - << " cause: " << xcp.what(); + << " code: " << xcp.code().value() + << " messagge: " << xcp.code().message() + << " cause: " << xcp.what(); err = odbc::IgniteError( odbc::IgniteError::IGNITE_ERR_SECURE_CONNECTION_FAILURE, message.str().c_str()); diff --git a/src/odbc/src/date.cpp b/src/odbc/src/date.cpp index adc47e423..23101583e 100644 --- a/src/odbc/src/date.cpp +++ b/src/odbc/src/date.cpp @@ -70,4 +70,3 @@ bool operator>=(const Date& val1, const Date& val2) { } } // namespace odbc } // namespace ignite - diff --git a/src/odbc/src/documentdb_column.cpp b/src/odbc/src/documentdb_column.cpp index ae2183181..7747ff925 100644 --- a/src/odbc/src/documentdb_column.cpp +++ b/src/odbc/src/documentdb_column.cpp @@ -31,7 +31,8 @@ void DocumentDbColumn::Update(bsoncxx::document::view const& document) { } DocumentDbColumn::DocumentDbColumn(bsoncxx::document::view& document, - JdbcColumnMetadata& columnMetadata, std::string& path) + JdbcColumnMetadata& columnMetadata, + std::string& path) : type_(columnMetadata.GetColumnType()), document_(document), columnMetadata_(columnMetadata), @@ -52,7 +53,7 @@ int64_t ToValidLong(int64_t value, ConversionResult::Type& convRes, int64_t max, } int64_t ToValidLong(std::string const& value, ConversionResult::Type& convRes, - int64_t max, int64_t min) { + int64_t max, int64_t min) { int64_t intValue = 0; try { intValue = @@ -90,11 +91,11 @@ ConversionResult::Type DocumentDbColumn::PutInt8( break; case bsoncxx::type::k_decimal128: value = ToValidLong(element.get_decimal128().value.to_string(), convRes, - INT8_MAX, INT8_MIN); + INT8_MAX, INT8_MIN); break; case bsoncxx::type::k_utf8: value = ToValidLong(element.get_utf8().value.to_string(), convRes, - INT8_MAX, INT8_MIN); + INT8_MAX, INT8_MIN); break; case bsoncxx::type::k_bool: value = element.get_bool().value ? 1 : 0; @@ -135,12 +136,12 @@ ConversionResult::Type DocumentDbColumn::PutInt16( } break; case bsoncxx::type::k_decimal128: - value = ToValidLong(element.get_decimal128().value.to_string(), convRes, INT16_MAX, - INT16_MIN); + value = ToValidLong(element.get_decimal128().value.to_string(), convRes, + INT16_MAX, INT16_MIN); break; case bsoncxx::type::k_utf8: value = ToValidLong(element.get_utf8().value.to_string(), convRes, - INT16_MAX, INT16_MIN); + INT16_MAX, INT16_MIN); break; case bsoncxx::type::k_bool: value = element.get_bool().value ? 1 : 0; @@ -187,11 +188,11 @@ ConversionResult::Type DocumentDbColumn::PutInt32( break; case bsoncxx::type::k_decimal128: value = ToValidLong(element.get_decimal128().value.to_string(), convRes, - INT32_MAX, INT32_MIN); + INT32_MAX, INT32_MIN); break; case bsoncxx::type::k_utf8: value = ToValidLong(element.get_utf8().value.to_string(), convRes, - INT32_MAX, INT32_MIN); + INT32_MAX, INT32_MIN); break; case bsoncxx::type::k_bool: value = element.get_bool().value ? 1 : 0; @@ -237,11 +238,11 @@ ConversionResult::Type DocumentDbColumn::PutInt64( break; case bsoncxx::type::k_decimal128: value = ToValidLong(element.get_decimal128().value.to_string(), convRes, - INT64_MAX, INT64_MIN); + INT64_MAX, INT64_MIN); break; case bsoncxx::type::k_utf8: value = ToValidLong(element.get_utf8().value.to_string(), convRes, - INT64_MAX, INT64_MIN); + INT64_MAX, INT64_MIN); break; case bsoncxx::type::k_bool: value = element.get_bool().value ? 1 : 0; @@ -350,11 +351,10 @@ ConversionResult::Type DocumentDbColumn::PutDouble( return convRes; } -ConversionResult::Type - DocumentDbColumn::PutString( +ConversionResult::Type DocumentDbColumn::PutString( ApplicationDataBuffer& dataBuf, bsoncxx::document::element const& element) const { - ConversionResult::Type convRes = ConversionResult::Type::AI_SUCCESS; + ConversionResult::Type convRes = ConversionResult::Type::AI_SUCCESS; bsoncxx::type docType = element.type(); boost::optional< std::string > value{}; switch (docType) { @@ -520,7 +520,6 @@ ConversionResult::Type DocumentDbColumn::PutDate( } if (convRes == ConversionResult::Type::AI_SUCCESS) { dataBuf.PutDate(value); - } return convRes; } @@ -597,18 +596,16 @@ ConversionResult::Type DocumentDbColumn::PutBinaryData( ConversionResult::Type DocumentDbColumn::ReadToBuffer( ApplicationDataBuffer& dataBuf) const { - auto element = document_[path_]; // Invalid (or missing) element is null if (!element) { dataBuf.PutNull(); return ConversionResult::Type::AI_SUCCESS; } - + ConversionResult::Type convRes = ConversionResult::Type::AI_SUCCESS; switch (type_) { - case JDBC_TYPE_BOOLEAN: case JDBC_TYPE_SMALLINT: convRes = PutInt8(dataBuf, element); @@ -667,7 +664,7 @@ ConversionResult::Type DocumentDbColumn::ReadToBuffer( case JDBC_TYPE_TIME: convRes = PutTime(dataBuf, element); break; - + default: return ConversionResult::Type::AI_UNSUPPORTED_CONVERSION; } diff --git a/src/odbc/src/documentdb_cursor.cpp b/src/odbc/src/documentdb_cursor.cpp index 78f499532..425c9abd3 100644 --- a/src/odbc/src/documentdb_cursor.cpp +++ b/src/odbc/src/documentdb_cursor.cpp @@ -20,8 +20,8 @@ namespace ignite { namespace odbc { -DocumentDbCursor::DocumentDbCursor(mongocxx::cursor& cursor, - std::vector< JdbcColumnMetadata >& columnMetadata, +DocumentDbCursor::DocumentDbCursor( + mongocxx::cursor& cursor, std::vector< JdbcColumnMetadata >& columnMetadata, std::vector< std::string >& paths) : cursor_(std::move(cursor)), iterator_(cursor_.begin()), diff --git a/src/odbc/src/documentdb_row.cpp b/src/odbc/src/documentdb_row.cpp index 4a2d166ae..822137a6a 100644 --- a/src/odbc/src/documentdb_row.cpp +++ b/src/odbc/src/documentdb_row.cpp @@ -27,8 +27,8 @@ namespace ignite { namespace odbc { // ASSUMPTION: iterator is not at the end. DocumentDbRow::DocumentDbRow(bsoncxx::document::view const& document, - std::vector< JdbcColumnMetadata >& columnMetadata, - std::vector< std::string >& paths) + std::vector< JdbcColumnMetadata >& columnMetadata, + std::vector< std::string >& paths) : pos(0), size(columnMetadata.size()), columns_(), @@ -63,7 +63,8 @@ bool DocumentDbRow::EnsureColumnDiscovered(uint32_t columnIdx) { int64_t index = columns_.size(); while (columns_.size() < columnIdx) { - DocumentDbColumn newColumn(document_, columnMetadata_[index], paths_[index]); + DocumentDbColumn newColumn(document_, columnMetadata_[index], + paths_[index]); columns_.push_back(newColumn); index++; diff --git a/src/odbc/src/driver_instance.cpp b/src/odbc/src/driver_instance.cpp index 6646c850e..cef31dbf1 100644 --- a/src/odbc/src/driver_instance.cpp +++ b/src/odbc/src/driver_instance.cpp @@ -1,31 +1,31 @@ -/* - * 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/driver_instance.h" - -#include - -DriverInstance& DriverInstance::getInstance() { - static DriverInstance driverInstance; - return driverInstance; -} - -void DriverInstance::initialize() { - // Using current, current will get an existing instance or will create a new - // one. Maybe in future we will need to change this to use a custom logger. - mongocxx::instance::current(); -} +/* + * 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/driver_instance.h" + +#include + +DriverInstance& DriverInstance::getInstance() { + static DriverInstance driverInstance; + return driverInstance; +} + +void DriverInstance::initialize() { + // Using current, current will get an existing instance or will create a new + // one. Maybe in future we will need to change this to use a custom logger. + mongocxx::instance::current(); +} diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index a27c0c898..00d76cda5 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -35,12 +35,13 @@ void ThrowLastSetupError() { DWORD code; common::FixedSizeArray< SQLWCHAR > msg(BUFFER_SIZE); - SQLInstallerError(1, &code, msg.GetData(), - msg.GetSize(), NULL); + SQLInstallerError(1, &code, msg.GetData(), msg.GetSize(), NULL); std::stringstream buf; - buf << "Message: \"" << utility::SqlStringToString(msg.GetData(), msg.GetSize()) << "\", Code: " << code; + buf << "Message: \"" + << utility::SqlStringToString(msg.GetData(), msg.GetSize()) + << "\", Code: " << code; throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, buf.str().c_str()); } @@ -61,21 +62,18 @@ SettableValue< std::string > ReadDsnString(const char* dsn, SettableValue< std::string > val(dflt); common::FixedSizeArray< SQLWCHAR > buf(BUFFER_SIZE); - + int ret = SQLGetPrivateProfileString( utility::ToWCHARVector(dsn).data(), utility::ToWCHARVector(key).data(), - utility::ToWCHARVector(unique).data(), - buf.GetData(), buf.GetSize(), + utility::ToWCHARVector(unique).data(), buf.GetData(), buf.GetSize(), utility::ToWCHARVector(CONFIG_FILE).data()); if (ret > BUFFER_SIZE) { buf.Reset(ret + 1); ret = SQLGetPrivateProfileString( - utility::ToWCHARVector(dsn).data(), - utility::ToWCHARVector(key).data(), - utility::ToWCHARVector(unique).data(), - buf.GetData(), buf.GetSize(), + utility::ToWCHARVector(dsn).data(), utility::ToWCHARVector(key).data(), + utility::ToWCHARVector(unique).data(), buf.GetData(), buf.GetSize(), utility::ToWCHARVector(CONFIG_FILE).data()); } diff --git a/src/odbc/src/entry_points.cpp b/src/odbc/src/entry_points.cpp index d1c0afa56..9d4f95d54 100644 --- a/src/odbc/src/entry_points.cpp +++ b/src/odbc/src/entry_points.cpp @@ -234,8 +234,9 @@ SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT stmt, SQLINTEGER attr, SQLRETURN SQL_API SQLPrimaryKeys(SQLHSTMT stmt, SQLWCHAR* catalogName, SQLSMALLINT catalogNameLen, - SQLWCHAR* schemaName, SQLSMALLINT schemaNameLen, - SQLWCHAR* tableName, SQLSMALLINT tableNameLen) { + SQLWCHAR* schemaName, + SQLSMALLINT schemaNameLen, SQLWCHAR* tableName, + SQLSMALLINT tableNameLen) { return ignite::SQLPrimaryKeys(stmt, catalogName, catalogNameLen, schemaName, schemaNameLen, tableName, tableNameLen); } @@ -425,10 +426,10 @@ SQLRETURN SQL_API SQLSetStmtOption(SQLHSTMT stmt, SQLUSMALLINT option, } SQLRETURN SQL_API SQLStatistics(SQLHSTMT stmt, SQLWCHAR* catalogName, - SQLSMALLINT catalogNameLen, SQLWCHAR* schemaName, - SQLSMALLINT schemaNameLen, SQLWCHAR* tableName, - SQLSMALLINT tableNameLen, SQLUSMALLINT unique, - SQLUSMALLINT reserved) { + SQLSMALLINT catalogNameLen, + SQLWCHAR* schemaName, SQLSMALLINT schemaNameLen, + SQLWCHAR* tableName, SQLSMALLINT tableNameLen, + SQLUSMALLINT unique, SQLUSMALLINT reserved) { IGNITE_UNUSED(stmt); IGNITE_UNUSED(catalogName); IGNITE_UNUSED(catalogNameLen); @@ -632,9 +633,9 @@ SQLRETURN SQL_API SQLParamOptions(SQLHSTMT stmt, SQLULEN paramSetSize, } SQLRETURN SQL_API SQLProcedures(SQLHSTMT stmt, SQLWCHAR* catalogName, - SQLSMALLINT catalogNameLen, SQLWCHAR* schemaName, - SQLSMALLINT schemaNameLen, SQLWCHAR* tableName, - SQLSMALLINT tableNameLen) { + SQLSMALLINT catalogNameLen, + SQLWCHAR* schemaName, SQLSMALLINT schemaNameLen, + SQLWCHAR* tableName, SQLSMALLINT tableNameLen) { IGNITE_UNUSED(stmt); IGNITE_UNUSED(catalogName); IGNITE_UNUSED(catalogNameLen); diff --git a/src/odbc/src/ignite.cpp b/src/odbc/src/ignite.cpp index 7c9dbcf89..dea7b8661 100644 --- a/src/odbc/src/ignite.cpp +++ b/src/odbc/src/ignite.cpp @@ -23,59 +23,46 @@ using namespace ignite::odbc::common::concurrent; using namespace ignite::odbc::impl; -namespace ignite -{ - namespace odbc - { - Ignite::Ignite() : impl(SharedPointer()) - { - // No-op. - } - - Ignite::Ignite(IgniteImpl* impl) : impl(SharedPointer(impl)) - { - // No-op. - } - - const char* Ignite::GetName() const - { - return impl.Get()->GetName(); - } - - const IgniteConfiguration& Ignite::GetConfiguration() const - { - return impl.Get()->GetConfiguration(); - } - - bool Ignite::IsActive() - { - return impl.Get()->IsActive(); - } - - void Ignite::SetActive(bool active) - { - impl.Get()->SetActive(active); - } - - cluster::IgniteCluster Ignite::GetCluster() - { - return cluster::IgniteCluster(impl.Get()->GetCluster()); - } - - compute::Compute Ignite::GetCompute() - { - return compute::Compute(impl.Get()->GetCompute()); - } - - compute::Compute Ignite::GetCompute(cluster::ClusterGroup grp) - { - return compute::Compute(impl.Get()->GetCompute(grp)); - } - - IgniteBinding Ignite::GetBinding() - { - return impl.Get()->GetBinding(); - } - } +namespace ignite { +namespace odbc { +Ignite::Ignite() : impl(SharedPointer< IgniteImpl >()) { + // No-op. } +Ignite::Ignite(IgniteImpl* impl) : impl(SharedPointer< IgniteImpl >(impl)) { + // No-op. +} + +const char* Ignite::GetName() const { + return impl.Get()->GetName(); +} + +const IgniteConfiguration& Ignite::GetConfiguration() const { + return impl.Get()->GetConfiguration(); +} + +bool Ignite::IsActive() { + return impl.Get()->IsActive(); +} + +void Ignite::SetActive(bool active) { + impl.Get()->SetActive(active); +} + +cluster::IgniteCluster Ignite::GetCluster() { + return cluster::IgniteCluster(impl.Get()->GetCluster()); +} + +compute::Compute Ignite::GetCompute() { + return compute::Compute(impl.Get()->GetCompute()); +} + +compute::Compute Ignite::GetCompute(cluster::ClusterGroup grp) { + return compute::Compute(impl.Get()->GetCompute(grp)); +} + +IgniteBinding Ignite::GetBinding() { + return impl.Get()->GetBinding(); +} +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/binary/binary_field_meta.cpp b/src/odbc/src/impl/binary/binary_field_meta.cpp index ab3ad8d96..9e13e8273 100644 --- a/src/odbc/src/impl/binary/binary_field_meta.cpp +++ b/src/odbc/src/impl/binary/binary_field_meta.cpp @@ -29,8 +29,7 @@ IGNITE_IMPORT_EXPORT void BinaryFieldMeta::Write( writer.WriteInt32(fieldId); } -IGNITE_IMPORT_EXPORT void BinaryFieldMeta::Read( - BinaryRawReader& reader) { +IGNITE_IMPORT_EXPORT void BinaryFieldMeta::Read(BinaryRawReader& reader) { typeId = reader.ReadInt32(); fieldId = reader.ReadInt32(); } diff --git a/src/odbc/src/impl/binary/binary_object_header.cpp b/src/odbc/src/impl/binary/binary_object_header.cpp index b9ad5c781..171cb05ba 100644 --- a/src/odbc/src/impl/binary/binary_object_header.cpp +++ b/src/odbc/src/impl/binary/binary_object_header.cpp @@ -58,4 +58,4 @@ int8_t* BinaryObjectHeader::GetMem() { } // namespace binary } // namespace impl } // namespace odbc -} // namespace ignite \ No newline at end of file +} // namespace ignite diff --git a/src/odbc/src/impl/binary/binary_reader_impl.cpp b/src/odbc/src/impl/binary/binary_reader_impl.cpp index 84c79e408..09627b46b 100644 --- a/src/odbc/src/impl/binary/binary_reader_impl.cpp +++ b/src/odbc/src/impl/binary/binary_reader_impl.cpp @@ -971,62 +971,52 @@ void BinaryReaderImpl::SetRawMode() { } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, int8_t >( - int8_t& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, int8_t >(int8_t& res) { res = ReadTopObject0< int8_t >(IGNITE_TYPE_BYTE, BinaryUtils::ReadInt8); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, bool >( - bool& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, bool >(bool& res) { res = ReadTopObject0< bool >(IGNITE_TYPE_BOOL, BinaryUtils::ReadBool); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, int16_t >( - int16_t& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, int16_t >(int16_t& res) { res = ReadTopObject0< int16_t >(IGNITE_TYPE_SHORT, BinaryUtils::ReadInt16); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, uint16_t >( - uint16_t& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, uint16_t >(uint16_t& res) { res = ReadTopObject0< uint16_t >(IGNITE_TYPE_CHAR, BinaryUtils::ReadUInt16); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, int32_t >( - int32_t& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, int32_t >(int32_t& res) { res = ReadTopObject0< int32_t >(IGNITE_TYPE_INT, BinaryUtils::ReadInt32); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, int64_t >( - int64_t& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, int64_t >(int64_t& res) { res = ReadTopObject0< int64_t >(IGNITE_TYPE_LONG, BinaryUtils::ReadInt64); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, float >( - float& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, float >(float& res) { res = ReadTopObject0< float >(IGNITE_TYPE_FLOAT, BinaryUtils::ReadFloat); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, double >( - double& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, double >(double& res) { res = ReadTopObject0< double >(IGNITE_TYPE_DOUBLE, BinaryUtils::ReadDouble); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, Guid >( - Guid& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, Guid >(Guid& res) { res = ReadTopObject0< Guid >(IGNITE_TYPE_UUID, BinaryUtils::ReadGuid); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, Date >( - Date& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, Date >(Date& res) { int8_t typeId = stream->ReadInt8(); if (typeId == IGNITE_TYPE_DATE) @@ -1045,21 +1035,20 @@ void BinaryReaderImpl::ReadTopObject0< BinaryReader, Date >( } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - Timestamp >(Timestamp& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, Timestamp >( + Timestamp& res) { res = ReadTopObject0< Timestamp >(IGNITE_TYPE_TIMESTAMP, BinaryUtils::ReadTimestamp); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, Time >( - Time& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, Time >(Time& res) { res = ReadTopObject0< Time >(IGNITE_TYPE_TIME, BinaryUtils::ReadTime); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - std::string >(std::string& res) { +void BinaryReaderImpl::ReadTopObject0< BinaryReader, std::string >( + std::string& res) { int8_t typeId = stream->ReadInt8(); if (typeId == IGNITE_TYPE_STRING) { @@ -1083,32 +1072,28 @@ void BinaryReaderImpl::ReadTopObject0< BinaryReader, } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - std::vector< int8_t > >( +void BinaryReaderImpl::ReadTopObject0< BinaryReader, std::vector< int8_t > >( std::vector< int8_t >& res) { ReadArrayToVectorInternal< int8_t >(res, stream, BinaryUtils::ReadInt8Array, IGNITE_TYPE_ARRAY_BYTE); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - std::vector< int16_t > >( +void BinaryReaderImpl::ReadTopObject0< BinaryReader, std::vector< int16_t > >( std::vector< int16_t >& res) { ReadArrayToVectorInternal< int16_t >(res, stream, BinaryUtils::ReadInt16Array, IGNITE_TYPE_ARRAY_SHORT); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - std::vector< int32_t > >( +void BinaryReaderImpl::ReadTopObject0< BinaryReader, std::vector< int32_t > >( std::vector< int32_t >& res) { ReadArrayToVectorInternal< int32_t >(res, stream, BinaryUtils::ReadInt32Array, IGNITE_TYPE_ARRAY_INT); } template <> -void BinaryReaderImpl::ReadTopObject0< BinaryReader, - std::vector< int64_t > >( +void BinaryReaderImpl::ReadTopObject0< BinaryReader, std::vector< int64_t > >( std::vector< int64_t >& res) { ReadArrayToVectorInternal< int64_t >(res, stream, BinaryUtils::ReadInt64Array, IGNITE_TYPE_ARRAY_LONG); diff --git a/src/odbc/src/impl/binary/binary_type_impl.cpp b/src/odbc/src/impl/binary/binary_type_impl.cpp index 2904ffd97..dcbeffa23 100644 --- a/src/odbc/src/impl/binary/binary_type_impl.cpp +++ b/src/odbc/src/impl/binary/binary_type_impl.cpp @@ -55,4 +55,3 @@ void BinaryType< IgniteError >::Read(BinaryReader& reader, IgniteError& dst) { } // namespace binary } // namespace odbc } // namespace ignite - diff --git a/src/odbc/src/impl/binary/binary_type_updater_impl.cpp b/src/odbc/src/impl/binary/binary_type_updater_impl.cpp index a0cf0c244..7eb5e833f 100644 --- a/src/odbc/src/impl/binary/binary_type_updater_impl.cpp +++ b/src/odbc/src/impl/binary/binary_type_updater_impl.cpp @@ -29,148 +29,142 @@ using namespace ignite::odbc::impl; using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace binary - { - struct Operation - { - enum Type - { - /** Operation: metadata get. */ - GET_META = 1, - - /** Operation: metadata update. */ - PUT_META = 3 - }; - }; - - BinaryTypeUpdaterImpl::BinaryTypeUpdaterImpl(IgniteEnvironment& env, jobject javaRef) : - env(env), - javaRef(javaRef) - { - // No-op. - } - - BinaryTypeUpdaterImpl::~BinaryTypeUpdaterImpl() - { - JniContext::Release(javaRef); - } - - bool BinaryTypeUpdaterImpl::Update(const Snap& snap, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = env.AllocateMemory(); - - InteropOutputStream out(mem.Get()); - BinaryWriterImpl writer(&out, 0); - BinaryRawWriter rawWriter(&writer); - - // We always pass only one meta at a time in current implementation for simplicity. - rawWriter.WriteInt32(1); - - rawWriter.WriteInt32(snap.GetTypeId()); - rawWriter.WriteString(snap.GetTypeName()); - - const std::string& affFieldName = snap.GetAffinityFieldName(); - - if (affFieldName.empty()) - rawWriter.WriteNull(); - else - rawWriter.WriteString(affFieldName); - - if (snap.HasFields()) - { - const Snap::FieldMap& fields = snap.GetFieldMap(); - - rawWriter.WriteInt32(static_cast(fields.size())); - - for (Snap::FieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it) - { - const BinaryFieldMeta& fieldMeta = it->second; - - rawWriter.WriteString(it->first); - fieldMeta.Write(rawWriter); - } - } - else - rawWriter.WriteInt32(0); - - rawWriter.WriteBool(false); // Enums are not supported for now. - - rawWriter.WriteInt32(0); // Schema size. Compact schema footer is not yet supported. - - out.Synchronize(); - - int64_t res = env.Context()->TargetInStreamOutLong(javaRef, Operation::PUT_META, mem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - return jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS && res == 1; - } - - SPSnap BinaryTypeUpdaterImpl::GetMeta(int32_t typeId, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer outMem = env.AllocateMemory(); - SharedPointer inMem = env.AllocateMemory(); - - InteropOutputStream out(outMem.Get()); - BinaryWriterImpl writer(&out, 0); - - writer.WriteInt32(typeId); - - out.Synchronize(); - - env.Context()->TargetInStreamOutStream(javaRef, Operation::GET_META, - outMem.Get()->PointerLong(), inMem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (err.GetCode() != IgniteError::IGNITE_SUCCESS) - return SPSnap(); - - InteropInputStream in(inMem.Get()); - BinaryReaderImpl reader(&in); - BinaryRawReader rawReader(&reader); - - bool found = rawReader.ReadBool(); - - if (!found) - return SPSnap(); - - int32_t readTypeId = rawReader.ReadInt32(); - - assert(typeId == readTypeId); - - std::string typeName = rawReader.ReadString(); - std::string affFieldName = rawReader.ReadString(); - - SPSnap res(new Snap(typeName, affFieldName, readTypeId)); - - int32_t fieldsNum = rawReader.ReadInt32(); - - for (int32_t i = 0; i < fieldsNum; ++i) - { - std::string fieldName = rawReader.ReadString(); - BinaryFieldMeta fieldMeta; - fieldMeta.Read(rawReader); - - res.Get()->AddField(fieldMeta.GetFieldId(), fieldName, fieldMeta.GetTypeId()); - } - - // Skipping isEnum info. - rawReader.ReadBool(); - - return res; - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace binary { +struct Operation { + enum Type { + /** Operation: metadata get. */ + GET_META = 1, + + /** Operation: metadata update. */ + PUT_META = 3 + }; +}; + +BinaryTypeUpdaterImpl::BinaryTypeUpdaterImpl(IgniteEnvironment& env, + jobject javaRef) + : env(env), javaRef(javaRef) { + // No-op. +} + +BinaryTypeUpdaterImpl::~BinaryTypeUpdaterImpl() { + JniContext::Release(javaRef); +} + +bool BinaryTypeUpdaterImpl::Update(const Snap& snap, IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = env.AllocateMemory(); + + InteropOutputStream out(mem.Get()); + BinaryWriterImpl writer(&out, 0); + BinaryRawWriter rawWriter(&writer); + + // We always pass only one meta at a time in current implementation for + // simplicity. + rawWriter.WriteInt32(1); + + rawWriter.WriteInt32(snap.GetTypeId()); + rawWriter.WriteString(snap.GetTypeName()); + + const std::string& affFieldName = snap.GetAffinityFieldName(); + + if (affFieldName.empty()) + rawWriter.WriteNull(); + else + rawWriter.WriteString(affFieldName); + + if (snap.HasFields()) { + const Snap::FieldMap& fields = snap.GetFieldMap(); + + rawWriter.WriteInt32(static_cast< int32_t >(fields.size())); + + for (Snap::FieldMap::const_iterator it = fields.begin(); it != fields.end(); + ++it) { + const BinaryFieldMeta& fieldMeta = it->second; + + rawWriter.WriteString(it->first); + fieldMeta.Write(rawWriter); } + } else + rawWriter.WriteInt32(0); + + rawWriter.WriteBool(false); // Enums are not supported for now. + + rawWriter.WriteInt32( + 0); // Schema size. Compact schema footer is not yet supported. + + out.Synchronize(); + + int64_t res = env.Context()->TargetInStreamOutLong( + javaRef, Operation::PUT_META, mem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + return jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS && res == 1; +} + +SPSnap BinaryTypeUpdaterImpl::GetMeta(int32_t typeId, IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > outMem = env.AllocateMemory(); + SharedPointer< InteropMemory > inMem = env.AllocateMemory(); + + InteropOutputStream out(outMem.Get()); + BinaryWriterImpl writer(&out, 0); + + writer.WriteInt32(typeId); + + out.Synchronize(); + + env.Context()->TargetInStreamOutStream(javaRef, Operation::GET_META, + outMem.Get()->PointerLong(), + inMem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (err.GetCode() != IgniteError::IGNITE_SUCCESS) + return SPSnap(); + + InteropInputStream in(inMem.Get()); + BinaryReaderImpl reader(&in); + BinaryRawReader rawReader(&reader); + + bool found = rawReader.ReadBool(); + + if (!found) + return SPSnap(); + + int32_t readTypeId = rawReader.ReadInt32(); + + assert(typeId == readTypeId); + + std::string typeName = rawReader.ReadString(); + std::string affFieldName = rawReader.ReadString(); + + SPSnap res(new Snap(typeName, affFieldName, readTypeId)); + + int32_t fieldsNum = rawReader.ReadInt32(); + + for (int32_t i = 0; i < fieldsNum; ++i) { + std::string fieldName = rawReader.ReadString(); + BinaryFieldMeta fieldMeta; + fieldMeta.Read(rawReader); + + res.Get()->AddField(fieldMeta.GetFieldId(), fieldName, + fieldMeta.GetTypeId()); + } + + // Skipping isEnum info. + rawReader.ReadBool(); + + return res; } +} // namespace binary +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/binary/binary_writer_impl.cpp b/src/odbc/src/impl/binary/binary_writer_impl.cpp index d1bf477c4..1d6859676 100644 --- a/src/odbc/src/impl/binary/binary_writer_impl.cpp +++ b/src/odbc/src/impl/binary/binary_writer_impl.cpp @@ -746,20 +746,20 @@ void BinaryWriterImpl::WriteFieldId(const char* fieldName, } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int8_t >( - const int8_t& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + int8_t >(const int8_t& obj) { WriteTopObject0< int8_t >(obj, BinaryUtils::WriteInt8, IGNITE_TYPE_BYTE); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, bool >( - const bool& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + bool >(const bool& obj) { WriteTopObject0< bool >(obj, BinaryUtils::WriteBool, IGNITE_TYPE_BOOL); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int16_t >( - const int16_t& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + int16_t >(const int16_t& obj) { WriteTopObject0< int16_t >(obj, BinaryUtils::WriteInt16, IGNITE_TYPE_SHORT); } @@ -770,38 +770,38 @@ void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int32_t >( - const int32_t& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + int32_t >(const int32_t& obj) { WriteTopObject0< int32_t >(obj, BinaryUtils::WriteInt32, IGNITE_TYPE_INT); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, int64_t >( - const int64_t& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + int64_t >(const int64_t& obj) { WriteTopObject0< int64_t >(obj, BinaryUtils::WriteInt64, IGNITE_TYPE_LONG); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, float >( - const float& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + float >(const float& obj) { WriteTopObject0< float >(obj, BinaryUtils::WriteFloat, IGNITE_TYPE_FLOAT); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, double >( - const double& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + double >(const double& obj) { WriteTopObject0< double >(obj, BinaryUtils::WriteDouble, IGNITE_TYPE_DOUBLE); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Guid >( - const Guid& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + Guid >(const Guid& obj) { WriteTopObject0< Guid >(obj, BinaryUtils::WriteGuid, IGNITE_TYPE_UUID); } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Date >( - const Date& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + Date >(const Date& obj) { WriteTopObject0< Date >(obj, BinaryUtils::WriteDate, IGNITE_TYPE_DATE); } @@ -813,8 +813,8 @@ void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, } template <> -void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, Time >( - const Time& obj) { +void BinaryWriterImpl::WriteTopObject0< ignite::odbc::binary::BinaryWriter, + Time >(const Time& obj) { WriteTopObject0< Time >(obj, BinaryUtils::WriteTime, IGNITE_TYPE_TIME); } diff --git a/src/odbc/src/impl/cache/cache_affinity_impl.cpp b/src/odbc/src/impl/cache/cache_affinity_impl.cpp index 589d87efb..fca4b0d14 100644 --- a/src/odbc/src/impl/cache/cache_affinity_impl.cpp +++ b/src/odbc/src/impl/cache/cache_affinity_impl.cpp @@ -23,148 +23,148 @@ using namespace ignite::odbc::cluster; using namespace ignite::odbc::jni::java; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - CacheAffinityImpl::CacheAffinityImpl(SP_IgniteEnvironment env, jobject javaRef) - : InteropTarget(env, javaRef) - { - // No-op. - } - - int32_t CacheAffinityImpl::GetPartitions() - { - IgniteError err; - - int32_t ret = static_cast(OutInOpLong(Command::PARTITIONS, 0, err)); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - std::vector CacheAffinityImpl::GetPrimaryPartitions(ClusterNode node) - { - return GetPartitions(Command::PRIMARY_PARTITIONS, node); - } - - std::vector CacheAffinityImpl::GetBackupPartitions(ClusterNode node) - { - return GetPartitions(Command::BACKUP_PARTITIONS, node); - } - - std::vector CacheAffinityImpl::GetAllPartitions(ClusterNode node) - { - return GetPartitions(Command::ALL_PARTITIONS, node); - } - - ClusterNode CacheAffinityImpl::MapPartitionToNode(int32_t part) - { - Guid nodeId; - In1Operation inOp(part); - Out1Operation outOp(nodeId); - - IgniteError err; - InteropTarget::OutInOp(Command::MAP_PARTITION_TO_NODE, inOp, outOp, err); - IgniteError::ThrowIfNeeded(err); - - return GetEnvironment().GetNode(nodeId); - } - - std::map CacheAffinityImpl::MapPartitionsToNodes(const std::vector& parts) - { - SharedPointer memIn = GetEnvironment().AllocateMemory(); - SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteInt32(static_cast(parts.size())); - for (size_t i = 0; i < parts.size(); i++) - writer.WriteObject(parts.at(i)); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::MAP_PARTITIONS_TO_NODES, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - std::map ret; - - int32_t cnt = reader.ReadInt32(); - for (int32_t i = 0; i < cnt; i++) - { - int32_t key = reader.ReadInt32(); - ClusterNode val(GetEnvironment().GetNode(reader.ReadGuid())); - - ret.insert(std::pair(key, val)); - } - - return ret; - } - - std::vector CacheAffinityImpl::MapPartitionToPrimaryAndBackups(int32_t part) - { - SharedPointer memIn = GetEnvironment().AllocateMemory(); - SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteObject(part); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::MAP_PARTITION_TO_PRIMARY_AND_BACKUPS, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - int32_t cnt = reader.ReadInt32(); - std::vector ret; - ret.reserve(cnt); - for (int32_t i = 0; i < cnt; i++) - ret.push_back(GetEnvironment().GetNode(reader.ReadGuid())); - - return ret; - } - - std::vector CacheAffinityImpl::GetPartitions(int32_t opType, ClusterNode node) - { - SharedPointer memIn = GetEnvironment().AllocateMemory(); - SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteGuid(node.GetId()); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(opType, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - reader.ReadInt8(); - int32_t cnt = reader.ReadInt32(); - std::vector ret; - ret.reserve(cnt); - for (int32_t i = 0; i < cnt; i++) - ret.push_back(reader.ReadInt32()); - - return ret; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +CacheAffinityImpl::CacheAffinityImpl(SP_IgniteEnvironment env, jobject javaRef) + : InteropTarget(env, javaRef) { + // No-op. } + +int32_t CacheAffinityImpl::GetPartitions() { + IgniteError err; + + int32_t ret = + static_cast< int32_t >(OutInOpLong(Command::PARTITIONS, 0, err)); + + IgniteError::ThrowIfNeeded(err); + + return ret; +} + +std::vector< int32_t > CacheAffinityImpl::GetPrimaryPartitions( + ClusterNode node) { + return GetPartitions(Command::PRIMARY_PARTITIONS, node); +} + +std::vector< int32_t > CacheAffinityImpl::GetBackupPartitions( + ClusterNode node) { + return GetPartitions(Command::BACKUP_PARTITIONS, node); +} + +std::vector< int32_t > CacheAffinityImpl::GetAllPartitions(ClusterNode node) { + return GetPartitions(Command::ALL_PARTITIONS, node); +} + +ClusterNode CacheAffinityImpl::MapPartitionToNode(int32_t part) { + Guid nodeId; + In1Operation< int32_t > inOp(part); + Out1Operation< Guid > outOp(nodeId); + + IgniteError err; + InteropTarget::OutInOp(Command::MAP_PARTITION_TO_NODE, inOp, outOp, err); + IgniteError::ThrowIfNeeded(err); + + return GetEnvironment().GetNode(nodeId); +} + +std::map< int32_t, ClusterNode > CacheAffinityImpl::MapPartitionsToNodes( + const std::vector< int32_t >& parts) { + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteInt32(static_cast< int32_t >(parts.size())); + for (size_t i = 0; i < parts.size(); i++) + writer.WriteObject< int32_t >(parts.at(i)); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::MAP_PARTITIONS_TO_NODES, *memIn.Get(), + *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + std::map< int32_t, ClusterNode > ret; + + int32_t cnt = reader.ReadInt32(); + for (int32_t i = 0; i < cnt; i++) { + int32_t key = reader.ReadInt32(); + ClusterNode val(GetEnvironment().GetNode(reader.ReadGuid())); + + ret.insert(std::pair< int32_t, ClusterNode >(key, val)); + } + + return ret; +} + +std::vector< ClusterNode > CacheAffinityImpl::MapPartitionToPrimaryAndBackups( + int32_t part) { + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteObject(part); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::MAP_PARTITION_TO_PRIMARY_AND_BACKUPS, *memIn.Get(), + *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + int32_t cnt = reader.ReadInt32(); + std::vector< ClusterNode > ret; + ret.reserve(cnt); + for (int32_t i = 0; i < cnt; i++) + ret.push_back(GetEnvironment().GetNode(reader.ReadGuid())); + + return ret; +} + +std::vector< int32_t > CacheAffinityImpl::GetPartitions(int32_t opType, + ClusterNode node) { + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteGuid(node.GetId()); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(opType, *memIn.Get(), *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + reader.ReadInt8(); + int32_t cnt = reader.ReadInt32(); + std::vector< int32_t > ret; + ret.reserve(cnt); + for (int32_t i = 0; i < cnt; i++) + ret.push_back(reader.ReadInt32()); + + return ret; +} +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cache/cache_impl.cpp b/src/odbc/src/impl/cache/cache_impl.cpp index 0b6a70260..5e5f4ee18 100644 --- a/src/odbc/src/impl/cache/cache_impl.cpp +++ b/src/odbc/src/impl/cache/cache_impl.cpp @@ -36,459 +36,435 @@ using namespace ignite::odbc::impl::cache::query::continuous; using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::binary; -struct Operation -{ - enum Type - { - /** Operation: Clear. */ - CLEAR = 1, +struct Operation { + enum Type { + /** Operation: Clear. */ + CLEAR = 1, - /** Operation: ClearAll. */ - CLEAR_ALL = 2, + /** Operation: ClearAll. */ + CLEAR_ALL = 2, - /** Operation: ContainsKey. */ - CONTAINS_KEY = 3, + /** Operation: ContainsKey. */ + CONTAINS_KEY = 3, - /** Operation: ContainsKeys. */ - CONTAINS_KEYS = 4, + /** Operation: ContainsKeys. */ + CONTAINS_KEYS = 4, - /** Operation: Get. */ - GET = 5, + /** Operation: Get. */ + GET = 5, - /** Operation: GetAll. */ - GET_ALL = 6, + /** Operation: GetAll. */ + GET_ALL = 6, - /** Operation: GetAndPut. */ - GET_AND_PUT = 7, + /** Operation: GetAndPut. */ + GET_AND_PUT = 7, - /** Operation: GetAndPutIfAbsent. */ - GET_AND_PUT_IF_ABSENT = 8, + /** Operation: GetAndPutIfAbsent. */ + GET_AND_PUT_IF_ABSENT = 8, - /** Operation: GetAndRemove. */ - GET_AND_REMOVE = 9, + /** Operation: GetAndRemove. */ + GET_AND_REMOVE = 9, - /** Operation: GetAndReplace. */ - GET_AND_REPLACE = 10, + /** Operation: GetAndReplace. */ + GET_AND_REPLACE = 10, - /** Operation: Invoke. */ - INVOKE = 12, + /** Operation: Invoke. */ + INVOKE = 12, - /** Operation: LoadCache */ - LOAD_CACHE = 15, + /** Operation: LoadCache */ + LOAD_CACHE = 15, - /** Operation: LocalEvict. */ - LOCAL_EVICT = 16, + /** Operation: LocalEvict. */ + LOCAL_EVICT = 16, - /** Operation: LocalLoadCache */ - LOC_LOAD_CACHE = 17, + /** Operation: LocalLoadCache */ + LOC_LOAD_CACHE = 17, - /** Operation: LocalClear. */ - LOCAL_CLEAR = 20, + /** Operation: LocalClear. */ + LOCAL_CLEAR = 20, - /** Operation: LocalClearAll. */ - LOCAL_CLEAR_ALL = 21, + /** Operation: LocalClearAll. */ + LOCAL_CLEAR_ALL = 21, - /** Operation: LocalPeek. */ - LOCAL_PEEK = 25, + /** Operation: LocalPeek. */ + LOCAL_PEEK = 25, - /** Operation: Put. */ - PUT = 26, + /** Operation: Put. */ + PUT = 26, - /** Operation: PutAll. */ - PUT_ALL = 27, + /** Operation: PutAll. */ + PUT_ALL = 27, - /** Operation: PutIfAbsent. */ - PUT_IF_ABSENT = 28, + /** Operation: PutIfAbsent. */ + PUT_IF_ABSENT = 28, - /** Operation: CONTINUOUS query. */ - QRY_CONTINUOUS = 29, + /** Operation: CONTINUOUS query. */ + QRY_CONTINUOUS = 29, - /** Operation: SCAN query. */ - QRY_SCAN = 30, + /** Operation: SCAN query. */ + QRY_SCAN = 30, - /** Operation: SQL query. */ - QRY_SQL = 31, + /** Operation: SQL query. */ + QRY_SQL = 31, - /** Operation: SQL fields query. */ - QRY_SQL_FIELDS = 32, + /** Operation: SQL fields query. */ + QRY_SQL_FIELDS = 32, - /** Operation: TEXT query. */ - QRY_TEXT = 33, + /** Operation: TEXT query. */ + QRY_TEXT = 33, - /** Operation: RemoveAll. */ - REMOVE_ALL = 34, + /** Operation: RemoveAll. */ + REMOVE_ALL = 34, - /** Operation: Remove(K, V). */ - REMOVE_2 = 35, + /** Operation: Remove(K, V). */ + REMOVE_2 = 35, - /** Operation: Remove(K). */ - REMOVE_1 = 36, + /** Operation: Remove(K). */ + REMOVE_1 = 36, - /** Operation: Replace(K, V). */ - REPLACE_2 = 37, + /** Operation: Replace(K, V). */ + REPLACE_2 = 37, - /** Operation: Replace(K, V, V). */ - REPLACE_3 = 38, + /** Operation: Replace(K, V, V). */ + REPLACE_3 = 38, - /** Operation: Clear(). */ - CLEAR_CACHE = 41, + /** Operation: Clear(). */ + CLEAR_CACHE = 41, - /** Operation: RemoveAll(). */ - REMOVE_ALL2 = 43, + /** Operation: RemoveAll(). */ + REMOVE_ALL2 = 43, - /** Operation: Size(peekModes). */ - SIZE = 48, + /** Operation: Size(peekModes). */ + SIZE = 48, - /** Operation: SizeLoc(peekModes). */ - SIZE_LOC = 56, + /** Operation: SizeLoc(peekModes). */ + SIZE_LOC = 56, - /** Operation: Invoke. */ - INVOKE_JAVA = 98, - }; + /** Operation: Invoke. */ + INVOKE_JAVA = 98, + }; }; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - - CacheImpl::CacheImpl(char* name, SharedPointer env, jobject javaRef) : - InteropTarget(env, javaRef), - name(name) - { - // No-op. - } - - CacheImpl::~CacheImpl() - { - ReleaseChars(name); - - JniContext::Release(GetTarget()); - } - - const char* CacheImpl::GetName() const - { - return name; - } - - bool CacheImpl::ContainsKey(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::CONTAINS_KEY, inOp, err); - } - - bool CacheImpl::ContainsKeys(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::CONTAINS_KEYS, inOp, err); - } - - void CacheImpl::LocalPeek(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::LOCAL_PEEK, inOp, outOp, err); - } - - void CacheImpl::Get(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET, inOp, outOp, err); - } - - void CacheImpl::GetAll(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET_ALL, inOp, outOp, err); - } - - void CacheImpl::Put(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::PUT, inOp, err); - } - - void CacheImpl::PutAll(ignite::odbc::impl::InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::PUT_ALL, inOp, err); - } - - void CacheImpl::GetAndPut(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET_AND_PUT, inOp, outOp, err); - } - - void CacheImpl::GetAndReplace(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET_AND_REPLACE, inOp, outOp, err); - } - - void CacheImpl::GetAndRemove(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET_AND_REMOVE, inOp, outOp, err); - } - - bool CacheImpl::PutIfAbsent(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::PUT_IF_ABSENT, inOp, err); - } - - void CacheImpl::GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::GET_AND_PUT_IF_ABSENT, inOp, outOp, err); - } - - bool CacheImpl::Replace(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::REPLACE_2, inOp, err); - } - - bool CacheImpl::ReplaceIfEqual(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::REPLACE_3, inOp, err); - } - - void CacheImpl::LocalEvict(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::LOCAL_EVICT, inOp, err); - } - - void CacheImpl::Clear(IgniteError& err) - { - JniErrorInfo jniErr; - - OutOp(Operation::CLEAR_CACHE, err); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - } - - void CacheImpl::Clear(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::CLEAR, inOp, err); - } - - void CacheImpl::ClearAll(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::CLEAR_ALL, inOp, err); - } - - void CacheImpl::LocalClear(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::LOCAL_CLEAR, inOp, err); - } - - void CacheImpl::LocalClearAll(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::LOCAL_CLEAR_ALL, inOp, err); - } - - bool CacheImpl::Remove(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::REMOVE_1, inOp, err); - } - - bool CacheImpl::RemoveIfEqual(InputOperation& inOp, IgniteError& err) - { - return OutOp(Operation::REMOVE_2, inOp, err); - } - - void CacheImpl::RemoveAll(InputOperation& inOp, IgniteError& err) - { - OutOp(Operation::REMOVE_ALL, inOp, err); - } - - void CacheImpl::RemoveAll(IgniteError& err) - { - JniErrorInfo jniErr; - - OutOp(Operation::REMOVE_ALL2, err); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - } - - int32_t CacheImpl::Size(int32_t peekModes, bool local, IgniteError& err) - { - int32_t op = local ? Operation::SIZE_LOC : Operation::SIZE; - - return static_cast(OutInOpLong(op, peekModes, err)); - } - - QueryCursorImpl* CacheImpl::QuerySql(const SqlQuery& qry, IgniteError& err) - { - return QueryInternal(qry, Operation::QRY_SQL, err); - } - - QueryCursorImpl* CacheImpl::QueryText(const TextQuery& qry, IgniteError& err) - { - return QueryInternal(qry, Operation::QRY_TEXT, err); - } - - QueryCursorImpl* CacheImpl::QueryScan(const ScanQuery& qry, IgniteError& err) - { - return QueryInternal(qry, Operation::QRY_SCAN, err); - } - - void CacheImpl::Invoke(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::INVOKE, inOp, outOp, err); - } - - void CacheImpl::InvokeJava(InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - OutInOpX(Operation::INVOKE_JAVA, inOp, outOp, err); - } - - QueryCursorImpl* CacheImpl::QuerySqlFields(const SqlFieldsQuery& qry, IgniteError& err) - { - return QueryInternal(qry, Operation::QRY_SQL_FIELDS, err); - } - - ContinuousQueryHandleImpl* CacheImpl::QueryContinuous(const SharedPointer qry, - const SqlQuery& initialQry, IgniteError& err) - { - return QueryContinuous(qry, initialQry, Operation::QRY_SQL, Operation::QRY_CONTINUOUS, err); - } - - ContinuousQueryHandleImpl* CacheImpl::QueryContinuous(const SharedPointer qry, - const TextQuery& initialQry, IgniteError& err) - { - return QueryContinuous(qry, initialQry, Operation::QRY_TEXT, Operation::QRY_CONTINUOUS, err); - } - - ContinuousQueryHandleImpl* CacheImpl::QueryContinuous(const SharedPointer qry, - const ScanQuery& initialQry, IgniteError& err) - { - return QueryContinuous(qry, initialQry, Operation::QRY_SCAN, Operation::QRY_CONTINUOUS, err); - } - - void CacheImpl::LoadCache(IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = GetEnvironment().AllocateMemory(); - InteropOutputStream out(mem.Get()); - BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - // Predicate. Always null for now. - writer.WriteNull(); - - // Arguments. No arguments supported for now. - writer.WriteInt32(0); - - out.Synchronize(); - - InStreamOutLong(Operation::LOAD_CACHE, *mem.Get(), err); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - } - - void CacheImpl::LocalLoadCache(IgniteError & err) - { - JniErrorInfo jniErr; - - SharedPointer mem = GetEnvironment().AllocateMemory(); - InteropOutputStream out(mem.Get()); - BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - // Predicate. Always null for now. - writer.WriteNull(); - - // Arguments. No arguments supported for now. - writer.WriteInt32(0); - - out.Synchronize(); - - InStreamOutLong(Operation::LOC_LOAD_CACHE, *mem.Get(), err); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - } - - struct Dummy - { - void Write(BinaryRawWriter&) const - { - // No-op. - } - }; - - ContinuousQueryHandleImpl* CacheImpl::QueryContinuous(const SharedPointer qry, - IgniteError& err) - { - Dummy dummy; - return QueryContinuous(qry, dummy, -1, Operation::QRY_CONTINUOUS, err); - } - - template - QueryCursorImpl* CacheImpl::QueryInternal(const T& qry, int32_t typ, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = GetEnvironment().AllocateMemory(); - InteropMemory* mem0 = mem.Get(); - InteropOutputStream out(mem0); - BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - BinaryRawWriter rawWriter(&writer); - - qry.Write(rawWriter); - - out.Synchronize(); - - jobject qryJavaRef = GetEnvironment().Context()->CacheOutOpQueryCursor(GetTarget(), - typ, mem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return new QueryCursorImpl(GetEnvironmentPointer(), qryJavaRef); - - return 0; - } - - template - ContinuousQueryHandleImpl* CacheImpl::QueryContinuous(const SharedPointer qry, - const T& initialQry, int32_t typ, int32_t cmd, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = GetEnvironment().AllocateMemory(); - InteropMemory* mem0 = mem.Get(); - InteropOutputStream out(mem0); - BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - BinaryRawWriter rawWriter(&writer); - - const ContinuousQueryImplBase& qry0 = *qry.Get(); - - int64_t handle = GetEnvironment().GetHandleRegistry().Allocate(qry); - - rawWriter.WriteInt64(handle); - rawWriter.WriteBool(qry0.GetLocal()); - rawWriter.WriteBool(false); // IncludeExpired - - event::CacheEntryEventFilterHolderBase& filterOp = qry0.GetFilterHolder(); - - filterOp.Write(writer); - - rawWriter.WriteInt32(qry0.GetBufferSize()); - rawWriter.WriteInt64(qry0.GetTimeInterval()); - - // Autounsubscribe is a filter feature. - rawWriter.WriteBool(false); - - // Writing initial query. When there is not initial query writing -1. - rawWriter.WriteInt32(typ); - if (typ != -1) - initialQry.Write(rawWriter); - - out.Synchronize(); - - jobject qryJavaRef = GetEnvironment().Context()->CacheOutOpContinuousQuery(GetTarget(), - cmd, mem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return new ContinuousQueryHandleImpl(GetEnvironmentPointer(), handle, qryJavaRef); - - return 0; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { + +CacheImpl::CacheImpl(char* name, SharedPointer< IgniteEnvironment > env, + jobject javaRef) + : InteropTarget(env, javaRef), name(name) { + // No-op. +} + +CacheImpl::~CacheImpl() { + ReleaseChars(name); + + JniContext::Release(GetTarget()); +} + +const char* CacheImpl::GetName() const { + return name; +} + +bool CacheImpl::ContainsKey(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::CONTAINS_KEY, inOp, err); +} + +bool CacheImpl::ContainsKeys(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::CONTAINS_KEYS, inOp, err); +} + +void CacheImpl::LocalPeek(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::LOCAL_PEEK, inOp, outOp, err); +} + +void CacheImpl::Get(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET, inOp, outOp, err); +} + +void CacheImpl::GetAll(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET_ALL, inOp, outOp, err); +} + +void CacheImpl::Put(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::PUT, inOp, err); +} + +void CacheImpl::PutAll(ignite::odbc::impl::InputOperation& inOp, + IgniteError& err) { + OutOp(Operation::PUT_ALL, inOp, err); +} + +void CacheImpl::GetAndPut(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET_AND_PUT, inOp, outOp, err); +} + +void CacheImpl::GetAndReplace(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET_AND_REPLACE, inOp, outOp, err); +} + +void CacheImpl::GetAndRemove(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET_AND_REMOVE, inOp, outOp, err); +} + +bool CacheImpl::PutIfAbsent(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::PUT_IF_ABSENT, inOp, err); +} + +void CacheImpl::GetAndPutIfAbsent(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::GET_AND_PUT_IF_ABSENT, inOp, outOp, err); +} + +bool CacheImpl::Replace(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::REPLACE_2, inOp, err); +} + +bool CacheImpl::ReplaceIfEqual(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::REPLACE_3, inOp, err); +} + +void CacheImpl::LocalEvict(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::LOCAL_EVICT, inOp, err); +} + +void CacheImpl::Clear(IgniteError& err) { + JniErrorInfo jniErr; + + OutOp(Operation::CLEAR_CACHE, err); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); +} + +void CacheImpl::Clear(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::CLEAR, inOp, err); +} + +void CacheImpl::ClearAll(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::CLEAR_ALL, inOp, err); +} + +void CacheImpl::LocalClear(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::LOCAL_CLEAR, inOp, err); +} + +void CacheImpl::LocalClearAll(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::LOCAL_CLEAR_ALL, inOp, err); +} + +bool CacheImpl::Remove(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::REMOVE_1, inOp, err); +} + +bool CacheImpl::RemoveIfEqual(InputOperation& inOp, IgniteError& err) { + return OutOp(Operation::REMOVE_2, inOp, err); +} + +void CacheImpl::RemoveAll(InputOperation& inOp, IgniteError& err) { + OutOp(Operation::REMOVE_ALL, inOp, err); +} + +void CacheImpl::RemoveAll(IgniteError& err) { + JniErrorInfo jniErr; + + OutOp(Operation::REMOVE_ALL2, err); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); +} + +int32_t CacheImpl::Size(int32_t peekModes, bool local, IgniteError& err) { + int32_t op = local ? Operation::SIZE_LOC : Operation::SIZE; + + return static_cast< int32_t >(OutInOpLong(op, peekModes, err)); +} + +QueryCursorImpl* CacheImpl::QuerySql(const SqlQuery& qry, IgniteError& err) { + return QueryInternal(qry, Operation::QRY_SQL, err); +} + +QueryCursorImpl* CacheImpl::QueryText(const TextQuery& qry, IgniteError& err) { + return QueryInternal(qry, Operation::QRY_TEXT, err); +} + +QueryCursorImpl* CacheImpl::QueryScan(const ScanQuery& qry, IgniteError& err) { + return QueryInternal(qry, Operation::QRY_SCAN, err); +} + +void CacheImpl::Invoke(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::INVOKE, inOp, outOp, err); +} + +void CacheImpl::InvokeJava(InputOperation& inOp, OutputOperation& outOp, + IgniteError& err) { + OutInOpX(Operation::INVOKE_JAVA, inOp, outOp, err); +} + +QueryCursorImpl* CacheImpl::QuerySqlFields(const SqlFieldsQuery& qry, + IgniteError& err) { + return QueryInternal(qry, Operation::QRY_SQL_FIELDS, err); +} + +ContinuousQueryHandleImpl* CacheImpl::QueryContinuous( + const SharedPointer< ContinuousQueryImplBase > qry, + const SqlQuery& initialQry, IgniteError& err) { + return QueryContinuous(qry, initialQry, Operation::QRY_SQL, + Operation::QRY_CONTINUOUS, err); +} + +ContinuousQueryHandleImpl* CacheImpl::QueryContinuous( + const SharedPointer< ContinuousQueryImplBase > qry, + const TextQuery& initialQry, IgniteError& err) { + return QueryContinuous(qry, initialQry, Operation::QRY_TEXT, + Operation::QRY_CONTINUOUS, err); +} + +ContinuousQueryHandleImpl* CacheImpl::QueryContinuous( + const SharedPointer< ContinuousQueryImplBase > qry, + const ScanQuery& initialQry, IgniteError& err) { + return QueryContinuous(qry, initialQry, Operation::QRY_SCAN, + Operation::QRY_CONTINUOUS, err); +} + +void CacheImpl::LoadCache(IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = GetEnvironment().AllocateMemory(); + InteropOutputStream out(mem.Get()); + BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + // Predicate. Always null for now. + writer.WriteNull(); + + // Arguments. No arguments supported for now. + writer.WriteInt32(0); + + out.Synchronize(); + + InStreamOutLong(Operation::LOAD_CACHE, *mem.Get(), err); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); +} + +void CacheImpl::LocalLoadCache(IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = GetEnvironment().AllocateMemory(); + InteropOutputStream out(mem.Get()); + BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + // Predicate. Always null for now. + writer.WriteNull(); + + // Arguments. No arguments supported for now. + writer.WriteInt32(0); + + out.Synchronize(); + + InStreamOutLong(Operation::LOC_LOAD_CACHE, *mem.Get(), err); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); +} + +struct Dummy { + void Write(BinaryRawWriter&) const { + // No-op. + } +}; + +ContinuousQueryHandleImpl* CacheImpl::QueryContinuous( + const SharedPointer< ContinuousQueryImplBase > qry, IgniteError& err) { + Dummy dummy; + return QueryContinuous(qry, dummy, -1, Operation::QRY_CONTINUOUS, err); +} + +template < typename T > +QueryCursorImpl* CacheImpl::QueryInternal(const T& qry, int32_t typ, + IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = GetEnvironment().AllocateMemory(); + InteropMemory* mem0 = mem.Get(); + InteropOutputStream out(mem0); + BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + BinaryRawWriter rawWriter(&writer); + + qry.Write(rawWriter); + + out.Synchronize(); + + jobject qryJavaRef = GetEnvironment().Context()->CacheOutOpQueryCursor( + GetTarget(), typ, mem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return new QueryCursorImpl(GetEnvironmentPointer(), qryJavaRef); + + return 0; +} + +template < typename T > +ContinuousQueryHandleImpl* CacheImpl::QueryContinuous( + const SharedPointer< ContinuousQueryImplBase > qry, const T& initialQry, + int32_t typ, int32_t cmd, IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = GetEnvironment().AllocateMemory(); + InteropMemory* mem0 = mem.Get(); + InteropOutputStream out(mem0); + BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + BinaryRawWriter rawWriter(&writer); + + const ContinuousQueryImplBase& qry0 = *qry.Get(); + + int64_t handle = GetEnvironment().GetHandleRegistry().Allocate(qry); + + rawWriter.WriteInt64(handle); + rawWriter.WriteBool(qry0.GetLocal()); + rawWriter.WriteBool(false); // IncludeExpired + + event::CacheEntryEventFilterHolderBase& filterOp = qry0.GetFilterHolder(); + + filterOp.Write(writer); + + rawWriter.WriteInt32(qry0.GetBufferSize()); + rawWriter.WriteInt64(qry0.GetTimeInterval()); + + // Autounsubscribe is a filter feature. + rawWriter.WriteBool(false); + + // Writing initial query. When there is not initial query writing -1. + rawWriter.WriteInt32(typ); + if (typ != -1) + initialQry.Write(rawWriter); + + out.Synchronize(); + + jobject qryJavaRef = GetEnvironment().Context()->CacheOutOpContinuousQuery( + GetTarget(), cmd, mem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return new ContinuousQueryHandleImpl(GetEnvironmentPointer(), handle, + qryJavaRef); + + return 0; } +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp b/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp index 0c99141c9..d01a8ab32 100644 --- a/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp +++ b/src/odbc/src/impl/cache/query/continuous/continuous_query_handle_impl.cpp @@ -22,76 +22,65 @@ using namespace ignite::odbc::jni::java; using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::impl::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - namespace continuous - { - struct Command - { - enum Type - { - GET_INITIAL_QUERY = 0, - - CLOSE = 1 - }; - }; - - ContinuousQueryHandleImpl::ContinuousQueryHandleImpl(SP_IgniteEnvironment env, int64_t handle, jobject javaRef) : - env(env), - handle(handle), - javaRef(javaRef), - mutex(), - extracted(false) - { - // No-op. - } - - ContinuousQueryHandleImpl::~ContinuousQueryHandleImpl() - { - JniErrorInfo err; - env.Get()->Context()->TargetInLongOutLong(javaRef, Command::CLOSE, 0, &err); - - JniContext::Release(javaRef); - - env.Get()->GetHandleRegistry().Release(handle); - } - - QueryCursorImpl* ContinuousQueryHandleImpl::GetInitialQueryCursor(IgniteError& err) - { - CsLockGuard guard(mutex); - - if (extracted) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "GetInitialQueryCursor() can be called only once."); - - return 0; - } - - JniErrorInfo jniErr; - - jobject res = env.Get()->Context()->TargetOutObject(javaRef, Command::GET_INITIAL_QUERY, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return 0; - - extracted = true; - - return new QueryCursorImpl(env, res); - } - } - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +namespace continuous { +struct Command { + enum Type { + GET_INITIAL_QUERY = 0, + + CLOSE = 1 + }; +}; + +ContinuousQueryHandleImpl::ContinuousQueryHandleImpl(SP_IgniteEnvironment env, + int64_t handle, + jobject javaRef) + : env(env), handle(handle), javaRef(javaRef), mutex(), extracted(false) { + // No-op. +} + +ContinuousQueryHandleImpl::~ContinuousQueryHandleImpl() { + JniErrorInfo err; + env.Get()->Context()->TargetInLongOutLong(javaRef, Command::CLOSE, 0, &err); + + JniContext::Release(javaRef); + + env.Get()->GetHandleRegistry().Release(handle); +} + +QueryCursorImpl* ContinuousQueryHandleImpl::GetInitialQueryCursor( + IgniteError& err) { + CsLockGuard guard(mutex); + + if (extracted) { + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "GetInitialQueryCursor() can be called only once."); + + return 0; + } + + JniErrorInfo jniErr; + + jobject res = env.Get()->Context()->TargetOutObject( + javaRef, Command::GET_INITIAL_QUERY, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return 0; + + extracted = true; + + return new QueryCursorImpl(env, res); } +} // namespace continuous +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cache/query/query_batch.cpp b/src/odbc/src/impl/cache/query/query_batch.cpp index f10097f39..8cbdffb20 100644 --- a/src/odbc/src/impl/cache/query/query_batch.cpp +++ b/src/odbc/src/impl/cache/query/query_batch.cpp @@ -18,38 +18,32 @@ #include "ignite/odbc/impl/cache/query/query_batch.h" #include "ignite/odbc/impl/cache/query/query_fields_row_impl.h" -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - QueryFieldsRowImpl* QueryBatch::GetNextRow() - { - assert(Left() > 0); - - int32_t rowBegin = stream.Position(); - - int32_t rowLen = reader.ReadInt32(); - int32_t columnNum = reader.ReadInt32(); - - int32_t dataPos = stream.Position(); - - assert(rowLen >= 4); - - ++pos; - - stream.Position(rowBegin + rowLen); - - return new QueryFieldsRowImpl(mem, dataPos, columnNum); - } - - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +QueryFieldsRowImpl* QueryBatch::GetNextRow() { + assert(Left() > 0); + + int32_t rowBegin = stream.Position(); + + int32_t rowLen = reader.ReadInt32(); + int32_t columnNum = reader.ReadInt32(); + + int32_t dataPos = stream.Position(); + + assert(rowLen >= 4); + + ++pos; + + stream.Position(rowBegin + rowLen); + + return new QueryFieldsRowImpl(mem, dataPos, columnNum); } + +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cache/query/query_impl.cpp b/src/odbc/src/impl/cache/query/query_impl.cpp index ee1f8665a..8b4ffff9a 100644 --- a/src/odbc/src/impl/cache/query/query_impl.cpp +++ b/src/odbc/src/impl/cache/query/query_impl.cpp @@ -23,287 +23,274 @@ using namespace ignite::odbc::jni::java; using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::impl::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cache - { - namespace query - { - /** Operation: get all entries. */ - const int32_t OP_GET_ALL = 1; - - /** Operation: get multiple entries. */ - const int32_t OP_GET_BATCH = 2; - - /** Operation: start iterator. */ - const int32_t OP_ITERATOR = 4; - - /** Operation: close iterator. */ - const int32_t OP_ITERATOR_CLOSE = 5; - - /** Operation: close iterator. */ - const int32_t OP_ITERATOR_HAS_NEXT = 6; - - QueryCursorImpl::QueryCursorImpl(SharedPointer env, jobject javaRef) : - env(env), - javaRef(javaRef), - batch(0), - endReached(false), - iterCalled(false), - getAllCalled(false) - { - // No-op. - } - - QueryCursorImpl::~QueryCursorImpl() - { - // 1. Releasing memory. - delete batch; - - // 2. Close the cursor. - JniErrorInfo err; - env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_CLOSE, 0, &err); - - // 3. Release Java reference. - JniContext::Release(javaRef); - } - - bool QueryCursorImpl::HasNext(IgniteError& err) - { - // Check whether GetAll() was called earlier. - if (getAllCalled) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use HasNext() method because GetAll() was called."); - - return false; - } - - // Create iterator in Java if needed. - if (!CreateIteratorIfNeeded(err)) - return false; - - // Get next results batch if the end in the current batch - // has been reached. - if (!GetNextBatchIfNeeded(err)) - return false; - - return !endReached; - } - - void QueryCursorImpl::GetNext(OutputOperation& op, IgniteError& err) - { - // Check whether GetAll() was called earlier. - if (getAllCalled) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use GetNext() method because GetAll() was called."); - - return; - } - - // Create iterator in Java if needed. - if (!CreateIteratorIfNeeded(err)) - return; - - // Get next results batch if the end in the current batch - // has been reached. - if (!GetNextBatchIfNeeded(err)) - return; - - if (endReached) - { - // Ensure we do not overwrite possible previous error. - if (err.GetCode() == IgniteError::IGNITE_SUCCESS) - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available."); - - return; - } - - batch->GetNext(op); - } - - QueryFieldsRowImpl* QueryCursorImpl::GetNextRow(IgniteError& err) - { - // Create iterator in Java if needed. - if (!CreateIteratorIfNeeded(err)) - return 0; - - // Get next results batch if the end in the current batch - // has been reached. - if (!GetNextBatchIfNeeded(err)) - return 0; - - if (endReached) - { - // Ensure we do not overwrite possible previous error. - if (err.GetCode() == IgniteError::IGNITE_SUCCESS) - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available."); - - return 0; - } - - return batch->GetNextRow(); - } - - void QueryCursorImpl::GetAll(OutputOperation& op, IgniteError& err) - { - // Check whether any of iterator methods were called. - if (iterCalled) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use GetAll() method because an iteration method was called."); - - return; - } - - // Check whether GetAll was called before. - if (getAllCalled) - { - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use GetNext() method because GetAll() was called."); - - return; - } - - // Get data. - JniErrorInfo jniErr; - - SharedPointer inMem = env.Get()->AllocateMemory(); - - env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, inMem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - { - getAllCalled = true; - - InteropInputStream in(inMem.Get()); - - BinaryReaderImpl reader(&in); - - op.ProcessOutput(reader); - } - } - - void QueryCursorImpl::GetAll(OutputOperation& op) - { - // Check whether any of iterator methods were called. - if (iterCalled) - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use GetAll() method because an iteration method was called."); - } - - // Check whether GetAll was called before. - if (getAllCalled) - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - "Cannot use GetNext() method because GetAll() was called."); - } - - // Get data. - JniErrorInfo jniErr; - - SharedPointer inMem = env.Get()->AllocateMemory(); - - env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, inMem.Get()->PointerLong(), &jniErr); - - IgniteError err; - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - IgniteError::ThrowIfNeeded(err); - - getAllCalled = true; - - InteropInputStream in(inMem.Get()); - - BinaryReaderImpl reader(&in); - - op.ProcessOutput(reader); - } - - bool QueryCursorImpl::CreateIteratorIfNeeded(IgniteError& err) - { - if (iterCalled) - return true; - - JniErrorInfo jniErr; - - env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR, 0, &jniErr); - - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - iterCalled = true; - - return iterCalled; - } - - bool QueryCursorImpl::GetNextBatchIfNeeded(IgniteError& err) - { - assert(iterCalled); - - if (endReached || (batch && batch->Left() > 0)) - return true; - - endReached = !IteratorHasNext(err); - - if (endReached) - return true; - - JniErrorInfo jniErr; - - SharedPointer inMem = env.Get()->AllocateMemory(); - - env.Get()->Context()->TargetOutStream( - javaRef, OP_GET_BATCH, inMem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return false; - - delete batch; - - // Needed for exception safety. - batch = 0; - - batch = new QueryBatch(*env.Get(), inMem); - - endReached = batch->IsEmpty(); - - return true; - } - - bool QueryCursorImpl::IteratorHasNext(IgniteError& err) - { - JniErrorInfo jniErr; - - bool res = env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_HAS_NEXT, 0, &jniErr) == 1; - - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return res; - - return false; - } - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cache { +namespace query { +/** Operation: get all entries. */ +const int32_t OP_GET_ALL = 1; + +/** Operation: get multiple entries. */ +const int32_t OP_GET_BATCH = 2; + +/** Operation: start iterator. */ +const int32_t OP_ITERATOR = 4; + +/** Operation: close iterator. */ +const int32_t OP_ITERATOR_CLOSE = 5; + +/** Operation: close iterator. */ +const int32_t OP_ITERATOR_HAS_NEXT = 6; + +QueryCursorImpl::QueryCursorImpl(SharedPointer< IgniteEnvironment > env, + jobject javaRef) + : env(env), + javaRef(javaRef), + batch(0), + endReached(false), + iterCalled(false), + getAllCalled(false) { + // No-op. +} + +QueryCursorImpl::~QueryCursorImpl() { + // 1. Releasing memory. + delete batch; + + // 2. Close the cursor. + JniErrorInfo err; + env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR_CLOSE, 0, + &err); + + // 3. Release Java reference. + JniContext::Release(javaRef); +} + +bool QueryCursorImpl::HasNext(IgniteError& err) { + // Check whether GetAll() was called earlier. + if (getAllCalled) { + err = + IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Cannot use HasNext() method because GetAll() was called."); + + return false; + } + + // Create iterator in Java if needed. + if (!CreateIteratorIfNeeded(err)) + return false; + + // Get next results batch if the end in the current batch + // has been reached. + if (!GetNextBatchIfNeeded(err)) + return false; + + return !endReached; +} + +void QueryCursorImpl::GetNext(OutputOperation& op, IgniteError& err) { + // Check whether GetAll() was called earlier. + if (getAllCalled) { + err = + IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Cannot use GetNext() method because GetAll() was called."); + + return; + } + + // Create iterator in Java if needed. + if (!CreateIteratorIfNeeded(err)) + return; + + // Get next results batch if the end in the current batch + // has been reached. + if (!GetNextBatchIfNeeded(err)) + return; + + if (endReached) { + // Ensure we do not overwrite possible previous error. + if (err.GetCode() == IgniteError::IGNITE_SUCCESS) + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "No more elements available."); + + return; + } + + batch->GetNext(op); +} + +QueryFieldsRowImpl* QueryCursorImpl::GetNextRow(IgniteError& err) { + // Create iterator in Java if needed. + if (!CreateIteratorIfNeeded(err)) + return 0; + + // Get next results batch if the end in the current batch + // has been reached. + if (!GetNextBatchIfNeeded(err)) + return 0; + + if (endReached) { + // Ensure we do not overwrite possible previous error. + if (err.GetCode() == IgniteError::IGNITE_SUCCESS) + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "No more elements available."); + + return 0; + } + + return batch->GetNextRow(); +} + +void QueryCursorImpl::GetAll(OutputOperation& op, IgniteError& err) { + // Check whether any of iterator methods were called. + if (iterCalled) { + err = IgniteError( + IgniteError::IGNITE_ERR_GENERIC, + "Cannot use GetAll() method because an iteration method was called."); + + return; + } + + // Check whether GetAll was called before. + if (getAllCalled) { + err = + IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Cannot use GetNext() method because GetAll() was called."); + + return; + } + + // Get data. + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > inMem = env.Get()->AllocateMemory(); + + env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, + inMem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + getAllCalled = true; + + InteropInputStream in(inMem.Get()); + + BinaryReaderImpl reader(&in); + + op.ProcessOutput(reader); + } +} + +void QueryCursorImpl::GetAll(OutputOperation& op) { + // Check whether any of iterator methods were called. + if (iterCalled) { + throw IgniteError( + IgniteError::IGNITE_ERR_GENERIC, + "Cannot use GetAll() method because an iteration method was called."); + } + + // Check whether GetAll was called before. + if (getAllCalled) { + throw IgniteError( + IgniteError::IGNITE_ERR_GENERIC, + "Cannot use GetNext() method because GetAll() was called."); + } + + // Get data. + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > inMem = env.Get()->AllocateMemory(); + + env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, + inMem.Get()->PointerLong(), &jniErr); + + IgniteError err; + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + IgniteError::ThrowIfNeeded(err); + + getAllCalled = true; + + InteropInputStream in(inMem.Get()); + + BinaryReaderImpl reader(&in); + + op.ProcessOutput(reader); +} + +bool QueryCursorImpl::CreateIteratorIfNeeded(IgniteError& err) { + if (iterCalled) + return true; + + JniErrorInfo jniErr; + + env.Get()->Context()->TargetInLongOutLong(javaRef, OP_ITERATOR, 0, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + iterCalled = true; + + return iterCalled; +} + +bool QueryCursorImpl::GetNextBatchIfNeeded(IgniteError& err) { + assert(iterCalled); + + if (endReached || (batch && batch->Left() > 0)) + return true; + + endReached = !IteratorHasNext(err); + + if (endReached) + return true; + + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > inMem = env.Get()->AllocateMemory(); + + env.Get()->Context()->TargetOutStream(javaRef, OP_GET_BATCH, + inMem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return false; + + delete batch; + + // Needed for exception safety. + batch = 0; + + batch = new QueryBatch(*env.Get(), inMem); + + endReached = batch->IsEmpty(); + + return true; +} + +bool QueryCursorImpl::IteratorHasNext(IgniteError& err) { + JniErrorInfo jniErr; + + bool res = env.Get()->Context()->TargetInLongOutLong( + javaRef, OP_ITERATOR_HAS_NEXT, 0, &jniErr) + == 1; + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return res; + + return false; } +} // namespace query +} // namespace cache +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cluster/cluster_group_impl.cpp b/src/odbc/src/impl/cluster/cluster_group_impl.cpp index 62728130c..77589b4d7 100644 --- a/src/odbc/src/impl/cluster/cluster_group_impl.cpp +++ b/src/odbc/src/impl/cluster/cluster_group_impl.cpp @@ -29,655 +29,601 @@ using namespace ignite::odbc::cluster; using namespace ignite::odbc::jni::java; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cluster - { - - /** Attribute: platform. */ - const std::string attrPlatform = "org.apache.ignite.platform"; - - /** Platform. */ - const std::string platform = "cpp"; - - struct Command - { - enum Type - { - FOR_ATTRIBUTE = 2, - - FOR_CACHE = 3, - - FOR_CLIENT = 4, - - FOR_DATA = 5, - - FOR_HOST = 6, - - FOR_NODE_IDS = 7, - - NODES = 12, - - PING_NODE = 13, - - TOPOLOGY = 14, - - FOR_REMOTES = 17, - - FOR_DAEMONS = 18, - - FOR_RANDOM = 19, - - FOR_OLDEST = 20, - - FOR_YOUNGEST = 21, - - RESET_METRICS = 22, - - FOR_SERVERS = 23, - - SET_ACTIVE = 28, - - IS_ACTIVE = 29 - }; - }; - - /** - * Cluster node predicates holder. - */ - class ClusterNodePredicateHolder : public IgnitePredicate - { - typedef common::concurrent::SharedPointer > SP_Pred; - public: - /* - * Constructor. - */ - ClusterNodePredicateHolder() - { - // No-op. - } - - /** - * Check cluster node predicate. - * - * @param node Cluster node to check. - * @return True in case of positive result. - */ - bool operator()(ClusterNode& node) - { - for (size_t i = 0; i < preds.size(); i++) - if (!preds.at(i).Get()->operator()(node)) - return false; - - return true; - } - - /** - * Insert pointer to new predicate. - * - * @param pred Pointer to predicate object. - */ - void Insert(IgnitePredicate* pred) - { - preds.push_back(SP_Pred(pred)); - } - - /** - * Insert predicates from another predicate holder. - * - * @param h Predicate holder object. - */ - void Insert(ClusterNodePredicateHolder& h) - { - preds.insert(preds.end(), h.preds.begin(), h.preds.end()); - } - - /** - * Check if predicate holder is empty - * - * @return True if empty. - */ - bool IsEmpty() - { - return preds.empty(); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ClusterNodePredicateHolder); - - /* Predicates container. */ - std::vector preds; - }; - - ClusterGroupImpl::ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef) : - InteropTarget(env, javaRef), - predHolder(new ClusterNodePredicateHolder), - nodes(), - nodesLock(), - topVer(0) - { - // No-op. - } - - ClusterGroupImpl::~ClusterGroupImpl() - { - // No-op. - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForAttribute(std::string name, std::string val) - { - SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteString(name); - writer.WriteString(val); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(Command::FOR_ATTRIBUTE, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), target)); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForCacheNodes(std::string cacheName) - { - return ForCacheNodes(cacheName, Command::FOR_CACHE); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForClientNodes(std::string cacheName) - { - return ForCacheNodes(cacheName, Command::FOR_CLIENT); - } - - class IsClientPredicate : public IgnitePredicate - { - public: - bool operator()(ClusterNode& node) - { - return node.IsClient(); - } - }; - - SP_ClusterGroupImpl ClusterGroupImpl::ForClients() - { - return ForPredicate(new IsClientPredicate); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForDaemons() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_DAEMONS, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForDataNodes(std::string cacheName) - { - return ForCacheNodes(cacheName, Command::FOR_DATA); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForHost(ClusterNode node) - { - SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteGuid(node.GetId()); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(Command::FOR_HOST, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), target)); - } - - class HostPredicate : public IgnitePredicate - { - public: - bool operator()(ClusterNode& node) - { - const std::vector& hostNames = node.GetHostNames(); - for (size_t i = 0; i < hostNames.size(); i++) - if (std::find(names.begin(), names.end(), hostNames.at(i)) != names.end()) - return true; - - return false; - } - - HostPredicate(const std::string& hostName) - { - names.push_back(hostName); - } - - HostPredicate(std::vector hostNames) : - names(hostNames) - { - // No-op. - } - - private: - std::vector names; - }; - - SP_ClusterGroupImpl ClusterGroupImpl::ForHost(std::string hostName) - { - return ForPredicate(new HostPredicate(hostName)); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForHosts(std::vector hostNames) - { - return ForPredicate(new HostPredicate(hostNames)); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForNode(ClusterNode node) - { - return ForNodeId(node.GetId()); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForNodeId(Guid id) - { - std::vector ids; - - ids.push_back(id); - - return ForNodeIds(ids); - } - - struct WriteGuid - { - WriteGuid(binary::BinaryWriterImpl& writer) : - writer(writer) - { - // No-op. - } - - void operator()(Guid id) - { - writer.WriteGuid(id); - } - - binary::BinaryWriterImpl& writer; - }; - - SP_ClusterGroupImpl ClusterGroupImpl::ForNodeIds(std::vector ids) - { - SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteInt32(static_cast(ids.size())); - - std::for_each(ids.begin(), ids.end(), WriteGuid(writer)); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(Command::FOR_NODE_IDS, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), target)); - } - - struct GetGuid - { - Guid operator()(ClusterNode& node) - { - return node.GetId(); - } - }; - - SP_ClusterGroupImpl ClusterGroupImpl::ForNodes(std::vector nodes) - { - std::vector ids; - - std::transform(nodes.begin(), nodes.end(), std::back_inserter(ids), GetGuid()); - - return ForNodeIds(ids); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForOldest() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_OLDEST, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForPredicate(IgnitePredicate* pred) - { - SP_PredicateHolder newPredHolder(new ClusterNodePredicateHolder()); - - newPredHolder.Get()->Insert(pred); - newPredHolder.Get()->Insert(*predHolder.Get()); - - std::vector nodeIds; - std::vector allNodes = GetNodes(); - for (size_t i = 0; i < allNodes.size(); i++) - if (newPredHolder.Get()->operator()(allNodes.at(i))) - nodeIds.push_back(allNodes.at(i).GetId()); - - SP_ClusterGroupImpl ret; - if (nodeIds.empty()) - ret = GetEmptyClusterGroup(); - else - ret = ForNodeIds(nodeIds); - - ret.Get()->SetPredicate(newPredHolder); - - return ret; - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForRandom() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_RANDOM, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForRemotes() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_REMOTES, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForYoungest() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_YOUNGEST, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForServers() - { - IgniteError err; - - jobject res = InOpObject(Command::FOR_SERVERS, err); - - IgniteError::ThrowIfNeeded(err); - - return FromTarget(res); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForCpp() - { - return ForAttribute(attrPlatform, platform); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForLocal() - { - return ForNodeId(GetLocalNode().GetId()); - } - - ClusterNode ClusterGroupImpl::GetLocalNode() - { - RefreshNodes(); - - return ClusterNode(GetEnvironment().GetLocalNode()); - } - - ClusterNode ClusterGroupImpl::GetNode() - { - std::vector nodes = GetNodes(); - if (nodes.size()) - return nodes.at(0); - - const char* msg = "There are no available cluster nodes"; - throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); - } - - struct FindGuid - { - FindGuid(Guid id) - : id(id) - { - // No-op. - } - - bool operator()(ClusterNode& node) - { - return node.GetId() == id; - } - - Guid id; - }; - - ClusterNode ClusterGroupImpl::GetNode(Guid nid) - { - std::vector nodes = GetNodes(); - std::vector::iterator it = find_if(nodes.begin(), nodes.end(), FindGuid(nid)); - if (it != nodes.end()) - return *it; - - const char* msg = "There is no cluster node with requested ID"; - throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); - } - - std::vector ClusterGroupImpl::GetNodes() - { - return RefreshNodes(); - } - - bool ClusterGroupImpl::IsActive() - { - IgniteError err; - - int64_t res = OutInOpLong(Command::IS_ACTIVE, 0, err); - - IgniteError::ThrowIfNeeded(err); - - return res == 1; - } - - void ClusterGroupImpl::SetActive(bool active) - { - IgniteError err; - - OutInOpLong(Command::SET_ACTIVE, active ? 1 : 0, err); - - IgniteError::ThrowIfNeeded(err); - } - - void ClusterGroupImpl::DisableWal(std::string cacheName) - { - IgniteImpl proc(GetEnvironmentPointer()); - - proc.DisableWal(cacheName); - } - - void ClusterGroupImpl::EnableWal(std::string cacheName) - { - IgniteImpl proc(GetEnvironmentPointer()); - - proc.EnableWal(cacheName); - } - - bool ClusterGroupImpl::IsWalEnabled(std::string cacheName) - { - IgniteImpl proc(GetEnvironmentPointer()); - - return proc.IsWalEnabled(cacheName); - } - - void ClusterGroupImpl::SetBaselineTopologyVersion(int64_t topVer) - { - IgniteImpl proc(GetEnvironmentPointer()); - - proc.SetBaselineTopologyVersion(topVer); - } - - void ClusterGroupImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) - { - IgniteImpl proc(GetEnvironmentPointer()); - - proc.SetTxTimeoutOnPartitionMapExchange(timeout); - } - - bool ClusterGroupImpl::PingNode(Guid nid) - { - IgniteError err; - In1Operation inOp(nid); - - return OutOp(Command::PING_NODE, inOp, err); - } - - IgnitePredicate* ClusterGroupImpl::GetPredicate() - { - return predHolder.Get(); - } - - const IgnitePredicate* ClusterGroupImpl::GetPredicate() const - { - return predHolder.Get(); - } - - std::vector ClusterGroupImpl::GetTopology(int64_t version) - { - SharedPointer memIn = GetEnvironment().AllocateMemory(); - SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteInt64(version); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::TOPOLOGY, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - return *ReadNodes(reader).Get(); - } - - int64_t ClusterGroupImpl::GetTopologyVersion() - { - RefreshNodes(); - - return topVer; - } - - SP_ClusterGroupImpl ClusterGroupImpl::GetEmptyClusterGroup() - { - // The empty cluster group could be created using ForNodeId() - // method with not exist (Guid(0, 0)) Cluster Node Id. - // It is required for ForPredicate() implementation - // to avoid situation when two ClusterGroupImpl's uses same jobject. - - return ForNodeId(Guid(0, 0)); - } - - SP_ClusterGroupImpl ClusterGroupImpl::ForCacheNodes(std::string name, int32_t op) - { - SharedPointer mem = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(mem.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - writer.WriteString(name); - - out.Synchronize(); - - IgniteError err; - jobject target = InStreamOutObject(op, *mem.Get(), err); - IgniteError::ThrowIfNeeded(err); - - return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), target)); - } - - SP_ClusterGroupImpl ClusterGroupImpl::FromTarget(jobject javaRef) - { - return SP_ClusterGroupImpl(new ClusterGroupImpl(GetEnvironmentPointer(), javaRef)); - } - - jobject ClusterGroupImpl::GetComputeProcessor() - { - return GetEnvironment().GetProcessorCompute(GetTarget()); - } - - ClusterGroupImpl::SP_ClusterNodes ClusterGroupImpl::ReadNodes(binary::BinaryReaderImpl& reader) - { - SP_ClusterNodes newNodes(new std::vector()); - - int cnt = reader.ReadInt32(); - if (cnt < 0) - return newNodes; - - newNodes.Get()->reserve(cnt); - for (int i = 0; i < cnt; i++) - { - SP_ClusterNodeImpl impl = GetEnvironment().GetNode(reader.ReadGuid()); - ClusterNode node(impl); - if (impl.IsValid() && predHolder.Get()->operator()(node)) - newNodes.Get()->push_back(node); - } - - return newNodes; - } - - std::vector ClusterGroupImpl::RefreshNodes() - { - SharedPointer memIn = GetEnvironment().AllocateMemory(); - SharedPointer memOut = GetEnvironment().AllocateMemory(); - interop::InteropOutputStream out(memIn.Get()); - binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); - - CsLockGuard mtx(nodesLock); - - writer.WriteInt64(topVer); - - out.Synchronize(); - - IgniteError err; - InStreamOutStream(Command::NODES, *memIn.Get(), *memOut.Get(), err); - IgniteError::ThrowIfNeeded(err); - - interop::InteropInputStream inStream(memOut.Get()); - binary::BinaryReaderImpl reader(&inStream); - - bool wasUpdated = reader.ReadBool(); - if (wasUpdated) - { - topVer = reader.ReadInt64(); - nodes = ReadNodes(reader); - } - - return *nodes.Get(); - } - - void ClusterGroupImpl::SetPredicate(SP_PredicateHolder predHolder) - { - this->predHolder = predHolder; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cluster { + +/** Attribute: platform. */ +const std::string attrPlatform = "org.apache.ignite.platform"; + +/** Platform. */ +const std::string platform = "cpp"; + +struct Command { + enum Type { + FOR_ATTRIBUTE = 2, + + FOR_CACHE = 3, + + FOR_CLIENT = 4, + + FOR_DATA = 5, + + FOR_HOST = 6, + + FOR_NODE_IDS = 7, + + NODES = 12, + + PING_NODE = 13, + + TOPOLOGY = 14, + + FOR_REMOTES = 17, + + FOR_DAEMONS = 18, + + FOR_RANDOM = 19, + + FOR_OLDEST = 20, + + FOR_YOUNGEST = 21, + + RESET_METRICS = 22, + + FOR_SERVERS = 23, + + SET_ACTIVE = 28, + + IS_ACTIVE = 29 + }; +}; + +/** + * Cluster node predicates holder. + */ +class ClusterNodePredicateHolder : public IgnitePredicate< ClusterNode > { + typedef common::concurrent::SharedPointer< IgnitePredicate< ClusterNode > > + SP_Pred; + + public: + /* + * Constructor. + */ + ClusterNodePredicateHolder() { + // No-op. + } + + /** + * Check cluster node predicate. + * + * @param node Cluster node to check. + * @return True in case of positive result. + */ + bool operator()(ClusterNode& node) { + for (size_t i = 0; i < preds.size(); i++) + if (!preds.at(i).Get()->operator()(node)) + return false; + + return true; + } + + /** + * Insert pointer to new predicate. + * + * @param pred Pointer to predicate object. + */ + void Insert(IgnitePredicate< ClusterNode >* pred) { + preds.push_back(SP_Pred(pred)); + } + + /** + * Insert predicates from another predicate holder. + * + * @param h Predicate holder object. + */ + void Insert(ClusterNodePredicateHolder& h) { + preds.insert(preds.end(), h.preds.begin(), h.preds.end()); + } + + /** + * Check if predicate holder is empty + * + * @return True if empty. + */ + bool IsEmpty() { + return preds.empty(); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ClusterNodePredicateHolder); + + /* Predicates container. */ + std::vector< SP_Pred > preds; +}; + +ClusterGroupImpl::ClusterGroupImpl(SP_IgniteEnvironment env, jobject javaRef) + : InteropTarget(env, javaRef), + predHolder(new ClusterNodePredicateHolder), + nodes(), + nodesLock(), + topVer(0) { + // No-op. +} + +ClusterGroupImpl::~ClusterGroupImpl() { + // No-op. +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForAttribute(std::string name, + std::string val) { + SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteString(name); + writer.WriteString(val); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(Command::FOR_ATTRIBUTE, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + return SP_ClusterGroupImpl( + new ClusterGroupImpl(GetEnvironmentPointer(), target)); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForCacheNodes(std::string cacheName) { + return ForCacheNodes(cacheName, Command::FOR_CACHE); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForClientNodes(std::string cacheName) { + return ForCacheNodes(cacheName, Command::FOR_CLIENT); +} + +class IsClientPredicate : public IgnitePredicate< ClusterNode > { + public: + bool operator()(ClusterNode& node) { + return node.IsClient(); + } +}; + +SP_ClusterGroupImpl ClusterGroupImpl::ForClients() { + return ForPredicate(new IsClientPredicate); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForDaemons() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_DAEMONS, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForDataNodes(std::string cacheName) { + return ForCacheNodes(cacheName, Command::FOR_DATA); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForHost(ClusterNode node) { + SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteGuid(node.GetId()); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(Command::FOR_HOST, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + return SP_ClusterGroupImpl( + new ClusterGroupImpl(GetEnvironmentPointer(), target)); +} + +class HostPredicate : public IgnitePredicate< ClusterNode > { + public: + bool operator()(ClusterNode& node) { + const std::vector< std::string >& hostNames = node.GetHostNames(); + for (size_t i = 0; i < hostNames.size(); i++) + if (std::find(names.begin(), names.end(), hostNames.at(i)) != names.end()) + return true; + + return false; + } + + HostPredicate(const std::string& hostName) { + names.push_back(hostName); + } + + HostPredicate(std::vector< std::string > hostNames) : names(hostNames) { + // No-op. + } + + private: + std::vector< std::string > names; +}; + +SP_ClusterGroupImpl ClusterGroupImpl::ForHost(std::string hostName) { + return ForPredicate(new HostPredicate(hostName)); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForHosts( + std::vector< std::string > hostNames) { + return ForPredicate(new HostPredicate(hostNames)); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForNode(ClusterNode node) { + return ForNodeId(node.GetId()); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForNodeId(Guid id) { + std::vector< Guid > ids; + + ids.push_back(id); + + return ForNodeIds(ids); +} + +struct WriteGuid { + WriteGuid(binary::BinaryWriterImpl& writer) : writer(writer) { + // No-op. + } + + void operator()(Guid id) { + writer.WriteGuid(id); + } + + binary::BinaryWriterImpl& writer; +}; + +SP_ClusterGroupImpl ClusterGroupImpl::ForNodeIds(std::vector< Guid > ids) { + SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteInt32(static_cast< int >(ids.size())); + + std::for_each(ids.begin(), ids.end(), WriteGuid(writer)); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(Command::FOR_NODE_IDS, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + return SP_ClusterGroupImpl( + new ClusterGroupImpl(GetEnvironmentPointer(), target)); +} + +struct GetGuid { + Guid operator()(ClusterNode& node) { + return node.GetId(); + } +}; + +SP_ClusterGroupImpl ClusterGroupImpl::ForNodes( + std::vector< ClusterNode > nodes) { + std::vector< Guid > ids; + + std::transform(nodes.begin(), nodes.end(), std::back_inserter(ids), + GetGuid()); + + return ForNodeIds(ids); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForOldest() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_OLDEST, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForPredicate( + IgnitePredicate< ClusterNode >* pred) { + SP_PredicateHolder newPredHolder(new ClusterNodePredicateHolder()); + + newPredHolder.Get()->Insert(pred); + newPredHolder.Get()->Insert(*predHolder.Get()); + + std::vector< Guid > nodeIds; + std::vector< ClusterNode > allNodes = GetNodes(); + for (size_t i = 0; i < allNodes.size(); i++) + if (newPredHolder.Get()->operator()(allNodes.at(i))) + nodeIds.push_back(allNodes.at(i).GetId()); + + SP_ClusterGroupImpl ret; + if (nodeIds.empty()) + ret = GetEmptyClusterGroup(); + else + ret = ForNodeIds(nodeIds); + + ret.Get()->SetPredicate(newPredHolder); + + return ret; +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForRandom() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_RANDOM, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForRemotes() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_REMOTES, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForYoungest() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_YOUNGEST, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForServers() { + IgniteError err; + + jobject res = InOpObject(Command::FOR_SERVERS, err); + + IgniteError::ThrowIfNeeded(err); + + return FromTarget(res); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForCpp() { + return ForAttribute(attrPlatform, platform); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForLocal() { + return ForNodeId(GetLocalNode().GetId()); +} + +ClusterNode ClusterGroupImpl::GetLocalNode() { + RefreshNodes(); + + return ClusterNode(GetEnvironment().GetLocalNode()); +} + +ClusterNode ClusterGroupImpl::GetNode() { + std::vector< ClusterNode > nodes = GetNodes(); + if (nodes.size()) + return nodes.at(0); + + const char* msg = "There are no available cluster nodes"; + throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); +} + +struct FindGuid { + FindGuid(Guid id) : id(id) { + // No-op. + } + + bool operator()(ClusterNode& node) { + return node.GetId() == id; + } + + Guid id; +}; + +ClusterNode ClusterGroupImpl::GetNode(Guid nid) { + std::vector< ClusterNode > nodes = GetNodes(); + std::vector< ClusterNode >::iterator it = + find_if(nodes.begin(), nodes.end(), FindGuid(nid)); + if (it != nodes.end()) + return *it; + + const char* msg = "There is no cluster node with requested ID"; + throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); +} + +std::vector< ClusterNode > ClusterGroupImpl::GetNodes() { + return RefreshNodes(); +} + +bool ClusterGroupImpl::IsActive() { + IgniteError err; + + int64_t res = OutInOpLong(Command::IS_ACTIVE, 0, err); + + IgniteError::ThrowIfNeeded(err); + + return res == 1; +} + +void ClusterGroupImpl::SetActive(bool active) { + IgniteError err; + + OutInOpLong(Command::SET_ACTIVE, active ? 1 : 0, err); + + IgniteError::ThrowIfNeeded(err); +} + +void ClusterGroupImpl::DisableWal(std::string cacheName) { + IgniteImpl proc(GetEnvironmentPointer()); + + proc.DisableWal(cacheName); +} + +void ClusterGroupImpl::EnableWal(std::string cacheName) { + IgniteImpl proc(GetEnvironmentPointer()); + + proc.EnableWal(cacheName); +} + +bool ClusterGroupImpl::IsWalEnabled(std::string cacheName) { + IgniteImpl proc(GetEnvironmentPointer()); + + return proc.IsWalEnabled(cacheName); +} + +void ClusterGroupImpl::SetBaselineTopologyVersion(int64_t topVer) { + IgniteImpl proc(GetEnvironmentPointer()); + + proc.SetBaselineTopologyVersion(topVer); +} + +void ClusterGroupImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) { + IgniteImpl proc(GetEnvironmentPointer()); + + proc.SetTxTimeoutOnPartitionMapExchange(timeout); +} + +bool ClusterGroupImpl::PingNode(Guid nid) { + IgniteError err; + In1Operation< Guid > inOp(nid); + + return OutOp(Command::PING_NODE, inOp, err); +} + +IgnitePredicate< ClusterNode >* ClusterGroupImpl::GetPredicate() { + return predHolder.Get(); +} + +const IgnitePredicate< ClusterNode >* ClusterGroupImpl::GetPredicate() const { + return predHolder.Get(); +} + +std::vector< ClusterNode > ClusterGroupImpl::GetTopology(int64_t version) { + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteInt64(version); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::TOPOLOGY, *memIn.Get(), *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + return *ReadNodes(reader).Get(); +} + +int64_t ClusterGroupImpl::GetTopologyVersion() { + RefreshNodes(); + + return topVer; +} + +SP_ClusterGroupImpl ClusterGroupImpl::GetEmptyClusterGroup() { + // The empty cluster group could be created using ForNodeId() + // method with not exist (Guid(0, 0)) Cluster Node Id. + // It is required for ForPredicate() implementation + // to avoid situation when two ClusterGroupImpl's uses same jobject. + + return ForNodeId(Guid(0, 0)); +} + +SP_ClusterGroupImpl ClusterGroupImpl::ForCacheNodes(std::string name, + int32_t op) { + SharedPointer< interop::InteropMemory > mem = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(mem.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + writer.WriteString(name); + + out.Synchronize(); + + IgniteError err; + jobject target = InStreamOutObject(op, *mem.Get(), err); + IgniteError::ThrowIfNeeded(err); + + return SP_ClusterGroupImpl( + new ClusterGroupImpl(GetEnvironmentPointer(), target)); +} + +SP_ClusterGroupImpl ClusterGroupImpl::FromTarget(jobject javaRef) { + return SP_ClusterGroupImpl( + new ClusterGroupImpl(GetEnvironmentPointer(), javaRef)); +} + +jobject ClusterGroupImpl::GetComputeProcessor() { + return GetEnvironment().GetProcessorCompute(GetTarget()); +} + +ClusterGroupImpl::SP_ClusterNodes ClusterGroupImpl::ReadNodes( + binary::BinaryReaderImpl& reader) { + SP_ClusterNodes newNodes(new std::vector< ClusterNode >()); + + int cnt = reader.ReadInt32(); + if (cnt < 0) + return newNodes; + + newNodes.Get()->reserve(cnt); + for (int i = 0; i < cnt; i++) { + SP_ClusterNodeImpl impl = GetEnvironment().GetNode(reader.ReadGuid()); + ClusterNode node(impl); + if (impl.IsValid() && predHolder.Get()->operator()(node)) + newNodes.Get()->push_back(node); + } + + return newNodes; +} + +std::vector< ClusterNode > ClusterGroupImpl::RefreshNodes() { + SharedPointer< interop::InteropMemory > memIn = + GetEnvironment().AllocateMemory(); + SharedPointer< interop::InteropMemory > memOut = + GetEnvironment().AllocateMemory(); + interop::InteropOutputStream out(memIn.Get()); + binary::BinaryWriterImpl writer(&out, GetEnvironment().GetTypeManager()); + + CsLockGuard mtx(nodesLock); + + writer.WriteInt64(topVer); + + out.Synchronize(); + + IgniteError err; + InStreamOutStream(Command::NODES, *memIn.Get(), *memOut.Get(), err); + IgniteError::ThrowIfNeeded(err); + + interop::InteropInputStream inStream(memOut.Get()); + binary::BinaryReaderImpl reader(&inStream); + + bool wasUpdated = reader.ReadBool(); + if (wasUpdated) { + topVer = reader.ReadInt64(); + nodes = ReadNodes(reader); + } + + return *nodes.Get(); +} + +void ClusterGroupImpl::SetPredicate(SP_PredicateHolder predHolder) { + this->predHolder = predHolder; } +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cluster/cluster_node_impl.cpp b/src/odbc/src/impl/cluster/cluster_node_impl.cpp index 21f13db76..231089157 100644 --- a/src/odbc/src/impl/cluster/cluster_node_impl.cpp +++ b/src/odbc/src/impl/cluster/cluster_node_impl.cpp @@ -25,161 +25,144 @@ using namespace ignite::odbc::impl::cluster; using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::impl::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cluster - { - ClusterNodeImpl::ClusterNodeImpl(SharedPointer mem) : - mem(mem), addrs(new std::vector), attrs(new std::map), hosts(new std::vector), - isClient(false), isDaemon(false), isLocal(false), consistentId(new std::string) - { - InteropInputStream stream(mem.Get()); - BinaryReaderImpl reader(&stream); - - id = reader.ReadGuid(); - - ReadAttributes(reader); - ReadAddresses(reader); - ReadHosts(reader); - - order = reader.ReadInt64(); - isLocal = reader.ReadBool(); - isDaemon = reader.ReadBool(); - isClient = reader.ReadBool(); - - ReadConsistentId(reader); - ReadProductVersion(reader); - } - - ClusterNodeImpl::~ClusterNodeImpl() - { - // No-op. - } - - const std::vector& ClusterNodeImpl::GetAddresses() const - { - return *addrs.Get(); - } - - bool ClusterNodeImpl::IsAttributeSet(std::string name) const - { - return attrs.Get()->find(name) != attrs.Get()->end() ? true : false; - } - - std::vector ClusterNodeImpl::GetAttributes() const - { - std::vector ret; - - for (std::map::const_iterator it = attrs.Get()->begin(); - it != attrs.Get()->end(); ++it) - ret.push_back(it->first); - - return ret; - } - - std::string ClusterNodeImpl::GetConsistentId() const - { - return *consistentId.Get(); - } - - const std::vector& ClusterNodeImpl::GetHostNames() const - { - return *hosts.Get(); - } - - Guid ClusterNodeImpl::GetId() const - { - return id; - } - - bool ClusterNodeImpl::IsClient() const - { - return isClient; - } - - bool ClusterNodeImpl::IsDaemon() const - { - return isDaemon; - } - - bool ClusterNodeImpl::IsLocal() const - { - return isLocal; - } - - int64_t ClusterNodeImpl::GetOrder() const - { - return order; - } - - const IgniteProductVersion& ClusterNodeImpl::GetVersion() const - { - return *ver.Get(); - } - - void ClusterNodeImpl::ReadAddresses(BinaryReaderImpl& reader) - { - std::back_insert_iterator > iter(*addrs.Get()); - - reader.ReadCollection(iter); - } - - void ClusterNodeImpl::ReadAttributes(BinaryReaderImpl& reader) - { - int32_t cnt = reader.ReadInt32(); - for (int32_t i = 0; i < cnt; i++) - { - std::string name = reader.ReadObject(); - int32_t pos = reader.GetStream()->Position(); - attrs.Get()->insert(std::pair(name, pos)); - reader.Skip(); - } - } - - void ClusterNodeImpl::ReadHosts(BinaryReaderImpl& reader) - { - std::back_insert_iterator > iter(*hosts.Get()); - - reader.ReadCollection(iter); - } - - void ClusterNodeImpl::ReadConsistentId(BinaryReaderImpl& reader) - { - int8_t typeId = reader.ReadInt8(); - reader.GetStream()->Position(reader.GetStream()->Position() - 1); - if (typeId == IGNITE_TYPE_STRING) - { - reader.ReadString(*consistentId.Get()); - return; - } - - std::stringstream ss; - ss << reader.ReadGuid(); - *consistentId.Get() = ss.str(); - } - - void ClusterNodeImpl::ReadProductVersion(BinaryReaderImpl& reader) - { - int8_t major = reader.ReadInt8(); - int8_t minor = reader.ReadInt8(); - int8_t maintenance = reader.ReadInt8(); - - std::string stage; - reader.ReadString(stage); - - int64_t releaseDate = reader.ReadInt64(); - - std::vector revHash(IgniteProductVersion::SHA1_LENGTH); - reader.ReadInt8Array(&revHash[0], IgniteProductVersion::SHA1_LENGTH); - - ver = SharedPointer(new IgniteProductVersion(major, minor, - maintenance, stage, releaseDate, revHash)); - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cluster { +ClusterNodeImpl::ClusterNodeImpl(SharedPointer< InteropMemory > mem) + : mem(mem), + addrs(new std::vector< std::string >), + attrs(new std::map< std::string, int32_t >), + hosts(new std::vector< std::string >), + isClient(false), + isDaemon(false), + isLocal(false), + consistentId(new std::string) { + InteropInputStream stream(mem.Get()); + BinaryReaderImpl reader(&stream); + + id = reader.ReadGuid(); + + ReadAttributes(reader); + ReadAddresses(reader); + ReadHosts(reader); + + order = reader.ReadInt64(); + isLocal = reader.ReadBool(); + isDaemon = reader.ReadBool(); + isClient = reader.ReadBool(); + + ReadConsistentId(reader); + ReadProductVersion(reader); +} + +ClusterNodeImpl::~ClusterNodeImpl() { + // No-op. +} + +const std::vector< std::string >& ClusterNodeImpl::GetAddresses() const { + return *addrs.Get(); +} + +bool ClusterNodeImpl::IsAttributeSet(std::string name) const { + return attrs.Get()->find(name) != attrs.Get()->end() ? true : false; +} + +std::vector< std::string > ClusterNodeImpl::GetAttributes() const { + std::vector< std::string > ret; + + for (std::map< std::string, int32_t >::const_iterator it = + attrs.Get()->begin(); + it != attrs.Get()->end(); ++it) + ret.push_back(it->first); + + return ret; +} + +std::string ClusterNodeImpl::GetConsistentId() const { + return *consistentId.Get(); +} + +const std::vector< std::string >& ClusterNodeImpl::GetHostNames() const { + return *hosts.Get(); +} + +Guid ClusterNodeImpl::GetId() const { + return id; +} + +bool ClusterNodeImpl::IsClient() const { + return isClient; +} + +bool ClusterNodeImpl::IsDaemon() const { + return isDaemon; +} + +bool ClusterNodeImpl::IsLocal() const { + return isLocal; +} + +int64_t ClusterNodeImpl::GetOrder() const { + return order; +} + +const IgniteProductVersion& ClusterNodeImpl::GetVersion() const { + return *ver.Get(); +} + +void ClusterNodeImpl::ReadAddresses(BinaryReaderImpl& reader) { + std::back_insert_iterator< std::vector< std::string > > iter(*addrs.Get()); + + reader.ReadCollection< std::string >(iter); +} + +void ClusterNodeImpl::ReadAttributes(BinaryReaderImpl& reader) { + int32_t cnt = reader.ReadInt32(); + for (int32_t i = 0; i < cnt; i++) { + std::string name = reader.ReadObject< std::string >(); + int32_t pos = reader.GetStream()->Position(); + attrs.Get()->insert(std::pair< std::string, int32_t >(name, pos)); + reader.Skip(); + } +} + +void ClusterNodeImpl::ReadHosts(BinaryReaderImpl& reader) { + std::back_insert_iterator< std::vector< std::string > > iter(*hosts.Get()); + + reader.ReadCollection< std::string >(iter); +} + +void ClusterNodeImpl::ReadConsistentId(BinaryReaderImpl& reader) { + int8_t typeId = reader.ReadInt8(); + reader.GetStream()->Position(reader.GetStream()->Position() - 1); + if (typeId == IGNITE_TYPE_STRING) { + reader.ReadString(*consistentId.Get()); + return; + } + + std::stringstream ss; + ss << reader.ReadGuid(); + *consistentId.Get() = ss.str(); +} + +void ClusterNodeImpl::ReadProductVersion(BinaryReaderImpl& reader) { + int8_t major = reader.ReadInt8(); + int8_t minor = reader.ReadInt8(); + int8_t maintenance = reader.ReadInt8(); + + std::string stage; + reader.ReadString(stage); + + int64_t releaseDate = reader.ReadInt64(); + + std::vector< int8_t > revHash(IgniteProductVersion::SHA1_LENGTH); + reader.ReadInt8Array(&revHash[0], IgniteProductVersion::SHA1_LENGTH); + + ver = SharedPointer< IgniteProductVersion >(new IgniteProductVersion( + major, minor, maintenance, stage, releaseDate, revHash)); } +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/cluster/ignite_cluster_impl.cpp b/src/odbc/src/impl/cluster/ignite_cluster_impl.cpp index 726227882..cb6a66077 100644 --- a/src/odbc/src/impl/cluster/ignite_cluster_impl.cpp +++ b/src/odbc/src/impl/cluster/ignite_cluster_impl.cpp @@ -23,90 +23,70 @@ using namespace ignite::odbc::jni::java; using namespace ignite::odbc::cluster; using namespace ignite::odbc::impl::cluster; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace cluster - { - IgniteClusterImpl::IgniteClusterImpl(SP_ClusterGroupImpl impl) : - impl(impl) - { - // No-op. - } - - IgniteClusterImpl::~IgniteClusterImpl() - { - // No-op. - } - - bool IgniteClusterImpl::IsActive() - { - return impl.Get()->IsActive(); - } - - void IgniteClusterImpl::SetActive(bool active) - { - impl.Get()->SetActive(active); - } - - void IgniteClusterImpl::DisableWal(std::string cacheName) - { - impl.Get()->DisableWal(cacheName); - } - - void IgniteClusterImpl::EnableWal(std::string cacheName) - { - impl.Get()->EnableWal(cacheName); - } - - bool IgniteClusterImpl::IsWalEnabled(std::string cacheName) - { - return impl.Get()->IsWalEnabled(cacheName); - } - - ClusterGroup IgniteClusterImpl::ForLocal() - { - return impl.Get()->ForLocal(); - } - - ClusterNode IgniteClusterImpl::GetLocalNode() - { - return impl.Get()->GetLocalNode(); - } - - void IgniteClusterImpl::SetBaselineTopologyVersion(int64_t topVer) - { - impl.Get()->SetBaselineTopologyVersion(topVer); - } - - void IgniteClusterImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) - { - impl.Get()->SetTxTimeoutOnPartitionMapExchange(timeout); - } - - bool IgniteClusterImpl::PingNode(Guid nid) - { - return impl.Get()->PingNode(nid); - } - - std::vector IgniteClusterImpl::GetTopology(int64_t version) - { - return impl.Get()->GetTopology(version); - } - - int64_t IgniteClusterImpl::GetTopologyVersion() - { - return impl.Get()->GetTopologyVersion(); - } - - SP_ClusterGroupImpl IgniteClusterImpl::AsClusterGroup() - { - return impl; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace cluster { +IgniteClusterImpl::IgniteClusterImpl(SP_ClusterGroupImpl impl) : impl(impl) { + // No-op. } + +IgniteClusterImpl::~IgniteClusterImpl() { + // No-op. +} + +bool IgniteClusterImpl::IsActive() { + return impl.Get()->IsActive(); +} + +void IgniteClusterImpl::SetActive(bool active) { + impl.Get()->SetActive(active); +} + +void IgniteClusterImpl::DisableWal(std::string cacheName) { + impl.Get()->DisableWal(cacheName); +} + +void IgniteClusterImpl::EnableWal(std::string cacheName) { + impl.Get()->EnableWal(cacheName); +} + +bool IgniteClusterImpl::IsWalEnabled(std::string cacheName) { + return impl.Get()->IsWalEnabled(cacheName); +} + +ClusterGroup IgniteClusterImpl::ForLocal() { + return impl.Get()->ForLocal(); +} + +ClusterNode IgniteClusterImpl::GetLocalNode() { + return impl.Get()->GetLocalNode(); +} + +void IgniteClusterImpl::SetBaselineTopologyVersion(int64_t topVer) { + impl.Get()->SetBaselineTopologyVersion(topVer); +} + +void IgniteClusterImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) { + impl.Get()->SetTxTimeoutOnPartitionMapExchange(timeout); +} + +bool IgniteClusterImpl::PingNode(Guid nid) { + return impl.Get()->PingNode(nid); +} + +std::vector< ClusterNode > IgniteClusterImpl::GetTopology(int64_t version) { + return impl.Get()->GetTopology(version); +} + +int64_t IgniteClusterImpl::GetTopologyVersion() { + return impl.Get()->GetTopologyVersion(); +} + +SP_ClusterGroupImpl IgniteClusterImpl::AsClusterGroup() { + return impl; +} +} // namespace cluster +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/compute/cancelable_impl.cpp b/src/odbc/src/impl/compute/cancelable_impl.cpp index 815e4b02e..c2e65594f 100644 --- a/src/odbc/src/impl/compute/cancelable_impl.cpp +++ b/src/odbc/src/impl/compute/cancelable_impl.cpp @@ -19,44 +19,33 @@ using namespace ignite::odbc::common::concurrent; -namespace -{ - /** - * Operation type. - */ - struct Operation - { - enum Type - { - Cancel = 1 - }; - }; +namespace { +/** + * Operation type. + */ +struct Operation { + enum Type { Cancel = 1 }; +}; +} // namespace + +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +CancelableImpl::CancelableImpl(SharedPointer< IgniteEnvironment > env, + jobject javaRef) + : InteropTarget(env, javaRef), Cancelable() { + // No-op. } -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - CancelableImpl::CancelableImpl(SharedPointer env, jobject javaRef) : - InteropTarget(env, javaRef), - Cancelable() - { - // No-op. - } - - void CancelableImpl::Cancel() - { - IgniteError err; - - OutInOpLong(Operation::Cancel, 0, err); - - IgniteError::ThrowIfNeeded(err); - } - } - } - } +void CancelableImpl::Cancel() { + IgniteError err; + + OutInOpLong(Operation::Cancel, 0, err); + + IgniteError::ThrowIfNeeded(err); } +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/compute/compute_impl.cpp b/src/odbc/src/impl/compute/compute_impl.cpp index 240a04b98..1c850215b 100644 --- a/src/odbc/src/impl/compute/compute_impl.cpp +++ b/src/odbc/src/impl/compute/compute_impl.cpp @@ -19,31 +19,25 @@ using namespace ignite::odbc::common::concurrent; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace compute - { - ComputeImpl::ComputeImpl(SharedPointer env, cluster::SP_ClusterGroupImpl clusterGroup) : - InteropTarget(env, clusterGroup.Get()->GetComputeProcessor()), - clusterGroup(clusterGroup) - { - // No-op. - } - - bool ComputeImpl::ProjectionContainsPredicate() const - { - return clusterGroup.IsValid() && clusterGroup.Get()->GetPredicate() != 0; - } - - std::vector ComputeImpl::GetNodes() - { - return clusterGroup.Get()->GetNodes(); - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace compute { +ComputeImpl::ComputeImpl(SharedPointer< IgniteEnvironment > env, + cluster::SP_ClusterGroupImpl clusterGroup) + : InteropTarget(env, clusterGroup.Get()->GetComputeProcessor()), + clusterGroup(clusterGroup) { + // No-op. } + +bool ComputeImpl::ProjectionContainsPredicate() const { + return clusterGroup.IsValid() && clusterGroup.Get()->GetPredicate() != 0; +} + +std::vector< ignite::odbc::cluster::ClusterNode > ComputeImpl::GetNodes() { + return clusterGroup.Get()->GetNodes(); +} +} // namespace compute +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/handle_registry.cpp b/src/odbc/src/impl/handle_registry.cpp index 238d5e885..3bcac88af 100644 --- a/src/odbc/src/impl/handle_registry.cpp +++ b/src/odbc/src/impl/handle_registry.cpp @@ -19,205 +19,179 @@ using namespace ignite::odbc::common::concurrent; -namespace ignite -{ - namespace odbc - { - namespace impl - { - HandleRegistrySegment::HandleRegistrySegment() : - map(), - mux() - { - // No-op. - } - - HandleRegistrySegment::~HandleRegistrySegment() - { - // No-op. - } - - SharedPointer HandleRegistrySegment::Get(int64_t hnd) - { - typedef std::map > Map; - - CsLockGuard guard(mux); - - Map::const_iterator it = map.find(hnd); - if (it == map.end()) - return SharedPointer(); - - return it->second; - } - - void HandleRegistrySegment::Put(int64_t hnd, const SharedPointer& entry) - { - CsLockGuard guard(mux); - - map[hnd] = entry; - } - - void HandleRegistrySegment::Remove(int64_t hnd) - { - CsLockGuard guard(mux); - - map.erase(hnd); - } - - void HandleRegistrySegment::Clear() - { - CsLockGuard guard(mux); - - map.clear(); - } - - HandleRegistry::HandleRegistry(int32_t fastCap, int32_t slowSegmentCnt) : - fastCap(fastCap), - fastCtr(0), - fast(new SharedPointer[fastCap]), - slowSegmentCnt(slowSegmentCnt), - slowCtr(fastCap), - slow(new HandleRegistrySegment*[slowSegmentCnt]), - closed(0) - { - for (int32_t i = 0; i < fastCap; i++) - fast[i] = SharedPointer(); - - for (int32_t i = 0; i < slowSegmentCnt; i++) - slow[i] = new HandleRegistrySegment(); - - Memory::Fence(); - } - - HandleRegistry::~HandleRegistry() - { - Close(); - - delete[] fast; - - for (int i = 0; i < slowSegmentCnt; i++) - delete slow[i]; - - delete[] slow; - } - - int64_t HandleRegistry::Allocate(const SharedPointer& target) - { - return Allocate0(target, false, false); - } - - int64_t HandleRegistry::AllocateCritical(const SharedPointer& target) - { - return Allocate0(target, true, false); - } - - int64_t HandleRegistry::AllocateSafe(const SharedPointer& target) - { - return Allocate0(target, false, true); - } - - int64_t HandleRegistry::AllocateCriticalSafe(const SharedPointer& target) - { - return Allocate0(target, true, true); - } - - void HandleRegistry::Release(int64_t hnd) - { - if (hnd < 0) - return; - else if (hnd < fastCap) - fast[static_cast(hnd)] = SharedPointer(); - else - { - HandleRegistrySegment* segment = slow[hnd % slowSegmentCnt]; - - segment->Remove(hnd); - } - - Memory::Fence(); - } - - SharedPointer HandleRegistry::Get(int64_t hnd) - { - Memory::Fence(); - - if (hnd < fastCap) - return fast[static_cast(hnd)]; - else - { - HandleRegistrySegment* segment = slow[hnd % slowSegmentCnt]; - - return segment->Get(hnd); - } - } - - void HandleRegistry::Close() - { - if (Atomics::CompareAndSet32(&closed, 0, 1)) - { - // Cleanup fast-path handles. - for (int32_t i = 0; i < fastCap; i++) - fast[i] = SharedPointer(); - - // Cleanup slow-path handles. - for (int32_t i = 0; i < slowSegmentCnt; i++) - slow[i]->Clear(); - } - } - - int64_t HandleRegistry::Allocate0(const SharedPointer& target, bool critical, bool safe) - { - // Check closed state. - Memory::Fence(); - - if (closed == 1) - return -1; - - // Try allocating entry on critical path. - if (critical) - { - if (fastCtr < fastCap) - { - int32_t fastIdx = Atomics::IncrementAndGet32(&fastCtr) - 1; - - if (fastIdx < fastCap) - { - fast[fastIdx] = target; - - // Double-check for closed state if safe mode is on. - Memory::Fence(); - - if (safe && closed == 1) - { - fast[fastIdx] = SharedPointer(); - - return -1; - } - else - return fastIdx; - } - } - } - - // Either allocating on slow-path, or fast-path can no longer accomodate more entries. - int64_t slowIdx = Atomics::IncrementAndGet64(&slowCtr) - 1; - - HandleRegistrySegment* segment = slow[slowIdx % slowSegmentCnt]; - - segment->Put(slowIdx, target); - - // Double-check for closed state if safe mode is on. - Memory::Fence(); - - if (safe && closed == 1) - { - segment->Remove(slowIdx); - - return -1; - } - - return slowIdx; - } - } +namespace ignite { +namespace odbc { +namespace impl { +HandleRegistrySegment::HandleRegistrySegment() : map(), mux() { + // No-op. +} + +HandleRegistrySegment::~HandleRegistrySegment() { + // No-op. +} + +SharedPointer< void > HandleRegistrySegment::Get(int64_t hnd) { + typedef std::map< int64_t, SharedPointer< void > > Map; + + CsLockGuard guard(mux); + + Map::const_iterator it = map.find(hnd); + if (it == map.end()) + return SharedPointer< void >(); + + return it->second; +} + +void HandleRegistrySegment::Put(int64_t hnd, + const SharedPointer< void >& entry) { + CsLockGuard guard(mux); + + map[hnd] = entry; +} + +void HandleRegistrySegment::Remove(int64_t hnd) { + CsLockGuard guard(mux); + + map.erase(hnd); +} + +void HandleRegistrySegment::Clear() { + CsLockGuard guard(mux); + + map.clear(); +} + +HandleRegistry::HandleRegistry(int32_t fastCap, int32_t slowSegmentCnt) + : fastCap(fastCap), + fastCtr(0), + fast(new SharedPointer< void >[fastCap]), + slowSegmentCnt(slowSegmentCnt), + slowCtr(fastCap), + slow(new HandleRegistrySegment*[slowSegmentCnt]), + closed(0) { + for (int32_t i = 0; i < fastCap; i++) + fast[i] = SharedPointer< void >(); + + for (int32_t i = 0; i < slowSegmentCnt; i++) + slow[i] = new HandleRegistrySegment(); + + Memory::Fence(); +} + +HandleRegistry::~HandleRegistry() { + Close(); + + delete[] fast; + + for (int i = 0; i < slowSegmentCnt; i++) + delete slow[i]; + + delete[] slow; +} + +int64_t HandleRegistry::Allocate(const SharedPointer< void >& target) { + return Allocate0(target, false, false); +} + +int64_t HandleRegistry::AllocateCritical(const SharedPointer< void >& target) { + return Allocate0(target, true, false); +} + +int64_t HandleRegistry::AllocateSafe(const SharedPointer< void >& target) { + return Allocate0(target, false, true); +} + +int64_t HandleRegistry::AllocateCriticalSafe( + const SharedPointer< void >& target) { + return Allocate0(target, true, true); +} + +void HandleRegistry::Release(int64_t hnd) { + if (hnd < 0) + return; + else if (hnd < fastCap) + fast[static_cast< int32_t >(hnd)] = SharedPointer< void >(); + else { + HandleRegistrySegment* segment = slow[hnd % slowSegmentCnt]; + + segment->Remove(hnd); + } + + Memory::Fence(); +} + +SharedPointer< void > HandleRegistry::Get(int64_t hnd) { + Memory::Fence(); + + if (hnd < fastCap) + return fast[static_cast< int32_t >(hnd)]; + else { + HandleRegistrySegment* segment = slow[hnd % slowSegmentCnt]; + + return segment->Get(hnd); + } +} + +void HandleRegistry::Close() { + if (Atomics::CompareAndSet32(&closed, 0, 1)) { + // Cleanup fast-path handles. + for (int32_t i = 0; i < fastCap; i++) + fast[i] = SharedPointer< void >(); + + // Cleanup slow-path handles. + for (int32_t i = 0; i < slowSegmentCnt; i++) + slow[i]->Clear(); + } +} + +int64_t HandleRegistry::Allocate0(const SharedPointer< void >& target, + bool critical, bool safe) { + // Check closed state. + Memory::Fence(); + + if (closed == 1) + return -1; + + // Try allocating entry on critical path. + if (critical) { + if (fastCtr < fastCap) { + int32_t fastIdx = Atomics::IncrementAndGet32(&fastCtr) - 1; + + if (fastIdx < fastCap) { + fast[fastIdx] = target; + + // Double-check for closed state if safe mode is on. + Memory::Fence(); + + if (safe && closed == 1) { + fast[fastIdx] = SharedPointer< void >(); + + return -1; + } else + return fastIdx; + } } + } + + // Either allocating on slow-path, or fast-path can no longer accomodate more + // entries. + int64_t slowIdx = Atomics::IncrementAndGet64(&slowCtr) - 1; + + HandleRegistrySegment* segment = slow[slowIdx % slowSegmentCnt]; + + segment->Put(slowIdx, target); + + // Double-check for closed state if safe mode is on. + Memory::Fence(); + + if (safe && closed == 1) { + segment->Remove(slowIdx); + + return -1; + } + + return slowIdx; } +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/ignite_binding_impl.cpp b/src/odbc/src/impl/ignite_binding_impl.cpp index 8807b7056..7a2ca416d 100644 --- a/src/odbc/src/impl/ignite_binding_impl.cpp +++ b/src/odbc/src/impl/ignite_binding_impl.cpp @@ -20,72 +20,67 @@ using namespace ignite::odbc::common::concurrent; -namespace ignite -{ - namespace odbc - { - namespace impl - { - IgniteBindingImpl::IgniteBindingImpl(IgniteEnvironment &env) : - env(env), - callbacks() - { - // No-op. - } - - int64_t IgniteBindingImpl::InvokeCallback(bool& found, int32_t type, int32_t id, - binary::BinaryReaderImpl& reader, binary::BinaryWriterImpl& writer) - { - int64_t key = makeKey(type, id); - - CsLockGuard guard(lock); - - std::map::iterator it = callbacks.find(key); - - found = it != callbacks.end(); - - if (found) - { - Callback* callback = it->second; - - // We have found callback and does not need lock here anymore. - guard.Reset(); - - return callback(reader, writer, env); - } - - return 0; - } - - void IgniteBindingImpl::RegisterCallback(int32_t type, int32_t id, Callback* proc, IgniteError& err) - { - int64_t key = makeKey(type, id); - - CsLockGuard guard(lock); - - bool inserted = callbacks.insert(std::make_pair(key, proc)).second; - - guard.Reset(); - - if (!inserted) - { - std::stringstream builder; - - builder << "Trying to register multiple PRC callbacks with the same ID. [type=" - << type << ", id=" << id << ']'; - - err = IgniteError(IgniteError::IGNITE_ERR_ENTRY_PROCESSOR, builder.str().c_str()); - } - } - - void IgniteBindingImpl::RegisterCallback(int32_t type, int32_t id, Callback* callback) - { - IgniteError err; - - RegisterCallback(type, id, callback, err); - - IgniteError::ThrowIfNeeded(err); - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +IgniteBindingImpl::IgniteBindingImpl(IgniteEnvironment& env) + : env(env), callbacks() { + // No-op. } + +int64_t IgniteBindingImpl::InvokeCallback(bool& found, int32_t type, int32_t id, + binary::BinaryReaderImpl& reader, + binary::BinaryWriterImpl& writer) { + int64_t key = makeKey(type, id); + + CsLockGuard guard(lock); + + std::map< int64_t, Callback* >::iterator it = callbacks.find(key); + + found = it != callbacks.end(); + + if (found) { + Callback* callback = it->second; + + // We have found callback and does not need lock here anymore. + guard.Reset(); + + return callback(reader, writer, env); + } + + return 0; +} + +void IgniteBindingImpl::RegisterCallback(int32_t type, int32_t id, + Callback* proc, IgniteError& err) { + int64_t key = makeKey(type, id); + + CsLockGuard guard(lock); + + bool inserted = callbacks.insert(std::make_pair(key, proc)).second; + + guard.Reset(); + + if (!inserted) { + std::stringstream builder; + + builder + << "Trying to register multiple PRC callbacks with the same ID. [type=" + << type << ", id=" << id << ']'; + + err = IgniteError(IgniteError::IGNITE_ERR_ENTRY_PROCESSOR, + builder.str().c_str()); + } +} + +void IgniteBindingImpl::RegisterCallback(int32_t type, int32_t id, + Callback* callback) { + IgniteError err; + + RegisterCallback(type, id, callback, err); + + IgniteError::ThrowIfNeeded(err); +} +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/ignite_environment.cpp b/src/odbc/src/impl/ignite_environment.cpp index 25876af01..165cefc2e 100644 --- a/src/odbc/src/impl/ignite_environment.cpp +++ b/src/odbc/src/impl/ignite_environment.cpp @@ -37,967 +37,913 @@ using namespace ignite::odbc::impl::binary; using namespace ignite::odbc::binary; using namespace ignite::odbc::impl::cache::query::continuous; -namespace ignite -{ - namespace odbc - { - namespace impl - { - /** - * Callback codes. - */ - struct OperationCallback - { - enum Type - { - CACHE_INVOKE = 8, - COMPUTE_TASK_JOB_RESULT = 10, - COMPUTE_TASK_REDUCE = 11, - COMPUTE_TASK_COMPLETE = 12, - COMPUTE_JOB_CREATE = 14, - COMPUTE_JOB_EXECUTE = 15, - COMPUTE_JOB_DESTROY = 17, - CONTINUOUS_QUERY_LISTENER_APPLY = 18, - CONTINUOUS_QUERY_FILTER_CREATE = 19, - CONTINUOUS_QUERY_FILTER_APPLY = 20, - CONTINUOUS_QUERY_FILTER_RELEASE = 21, - FUTURE_BYTE_RESULT = 24, - FUTURE_BOOL_RESULT = 25, - FUTURE_SHORT_RESULT = 26, - FUTURE_CHAR_RESULT = 27, - FUTURE_INT_RESULT = 28, - FUTURE_FLOAT_RESULT = 29, - FUTURE_LONG_RESULT = 30, - FUTURE_DOUBLE_RESULT = 31, - FUTURE_OBJECT_RESULT = 32, - FUTURE_NULL_RESULT = 33, - FUTURE_ERROR = 34, - REALLOC = 36, - NODE_INFO = 48, - ON_START = 49, - ON_STOP = 50, - COMPUTE_TASK_LOCAL_JOB_RESULT = 60, - COMPUTE_JOB_EXECUTE_LOCAL = 61, - COMPUTE_OUT_FUNC_EXECUTE = 74, - COMPUTE_ACTION_EXECUTE = 75 - }; - }; - - /* - * PlatformProcessor op codes. - */ - struct ProcessorOp - { - enum Type - { - GET_BINARY_PROCESSOR = 21, - RELEASE_START = 22 - }; - }; - - /* - * PlatformClusterGroup op codes. - */ - struct ClusterGroupOp - { - enum Type - { - GET_COMPUTE = 31 - }; - }; - - typedef SharedPointer SP_ClusterNodeImpl; - - /* - * Stores cluster nodes in thread-safe manner. - */ - class ClusterNodesHolder - { - CriticalSection nodesLock; - std::map nodes; - - public: - ClusterNodesHolder() : - nodesLock() - { - // No-op. - } - - void AddNode(SP_ClusterNodeImpl node) - { - CsLockGuard mtx(nodesLock); - - nodes.insert(std::pair(node.Get()->GetId(), node)); - } - - SP_ClusterNodeImpl GetLocalNode() - { - CsLockGuard mtx(nodesLock); - - std::map::iterator it; - for (it = nodes.begin(); it != nodes.end(); ++it) - if (it->second.Get()->IsLocal()) - return it->second; - - return NULL; - } - - SP_ClusterNodeImpl GetNode(Guid Id) - { - CsLockGuard mtx(nodesLock); - - if (nodes.find(Id) != nodes.end()) - return nodes.at(Id); - - return NULL; - } - }; - - /** - * InLongOutLong callback. - * - * @param target Target environment. - * @param type Operation type. - * @param val Value. - */ - int64_t IGNITE_CALL InLongOutLong(void* target, int type, int64_t val) - { - int64_t res = 0; - SharedPointer* env = static_cast*>(target); - - if (!env) - return res; - - switch (type) - { - case OperationCallback::NODE_INFO: - { - SharedPointer mem = env->Get()->GetMemory(val); - SharedPointer memCopy(new InteropUnpooledMemory(mem.Get()->Capacity())); - - memCopy.Get()->Length(mem.Get()->Length()); - memcpy(memCopy.Get()->Data(), mem.Get()->Data(), mem.Get()->Capacity()); - - SP_ClusterNodeImpl node = (new impl::cluster::ClusterNodeImpl(memCopy)); - env->Get()->nodes.Get()->AddNode(node); - - break; - } - - case OperationCallback::ON_STOP: - { - delete env; - - break; - } - - case OperationCallback::COMPUTE_JOB_CREATE: - { - SharedPointer mem = env->Get()->GetMemory(val); - - res = env->Get()->ComputeJobCreate(mem); - - break; - } - - case OperationCallback::COMPUTE_JOB_EXECUTE: - { - SharedPointer mem = env->Get()->GetMemory(val); - - env->Get()->ComputeJobExecute(mem); - - break; - } - - case OperationCallback::COMPUTE_JOB_DESTROY: - { - env->Get()->ComputeJobDestroy(val); - - break; - } - - case OperationCallback::COMPUTE_TASK_JOB_RESULT: - { - SharedPointer mem = env->Get()->GetMemory(val); - - res = env->Get()->ComputeTaskJobResult(mem); - - break; - } - - case OperationCallback::COMPUTE_TASK_REDUCE: - { - env->Get()->ComputeTaskReduce(val); - - break; - } - - case OperationCallback::CONTINUOUS_QUERY_LISTENER_APPLY: - { - SharedPointer mem = env->Get()->GetMemory(val); - - env->Get()->OnContinuousQueryListenerApply(mem); - - break; - } - - case OperationCallback::CONTINUOUS_QUERY_FILTER_CREATE: - { - SharedPointer mem = env->Get()->GetMemory(val); - - res = env->Get()->OnContinuousQueryFilterCreate(mem); - - break; - } - - case OperationCallback::CONTINUOUS_QUERY_FILTER_APPLY: - { - SharedPointer mem = env->Get()->GetMemory(val); - - res = env->Get()->OnContinuousQueryFilterApply(mem); - - break; - } - - case OperationCallback::CONTINUOUS_QUERY_FILTER_RELEASE: - { - // No-op. - - break; - } - - case OperationCallback::COMPUTE_ACTION_EXECUTE: - case OperationCallback::COMPUTE_OUT_FUNC_EXECUTE: - { - SharedPointer mem = env->Get()->GetMemory(val); - - res = env->Get()->OnComputeFuncExecute(mem); - - break; - } - - case OperationCallback::FUTURE_NULL_RESULT: - { - env->Get()->OnFutureNullResult(val); - - break; - } - - case OperationCallback::CACHE_INVOKE: - { - SharedPointer mem = env->Get()->GetMemory(val); - - env->Get()->CacheInvokeCallback(mem); - - break; - } - - default: - { - break; - } - } - - return res; - } - - /** - * InLongOutLong callback. - * - * @param target Target environment. - * @param type Operation type. - * @param val1 Value1. - * @param val2 Value2. - * @param val3 Value3. - * @param arg Object arg. - */ - int64_t IGNITE_CALL InLongLongLongObjectOutLong(void* target, int type, int64_t val1, int64_t val2, - int64_t val3, void* arg) - { - IGNITE_UNUSED(val3); - - int64_t res = 0; - SharedPointer* env = static_cast*>(target); - - switch (type) - { - case OperationCallback::COMPUTE_JOB_EXECUTE_LOCAL: - { - env->Get()->ComputeJobExecuteLocal(val1); - - break; - } - - case OperationCallback::COMPUTE_TASK_LOCAL_JOB_RESULT: - { - res = env->Get()->ComputeTaskLocalJobResult(val1, val2); - - break; - } - - case OperationCallback::COMPUTE_TASK_COMPLETE: - { - env->Get()->ComputeTaskComplete(val1); - - break; - } - - case OperationCallback::ON_START: - { - env->Get()->OnStartCallback(val1, reinterpret_cast(arg)); - - break; - } - - case OperationCallback::REALLOC: - { - SharedPointer mem = env->Get()->GetMemory(val1); - - mem.Get()->Reallocate(static_cast(val2)); - - break; - } - - case OperationCallback::FUTURE_BYTE_RESULT: - case OperationCallback::FUTURE_BOOL_RESULT: - case OperationCallback::FUTURE_SHORT_RESULT: - case OperationCallback::FUTURE_CHAR_RESULT: - case OperationCallback::FUTURE_INT_RESULT: - case OperationCallback::FUTURE_LONG_RESULT: - case OperationCallback::FUTURE_FLOAT_RESULT: - case OperationCallback::FUTURE_DOUBLE_RESULT: - { - env->Get()->OnFuturePrimitiveResult(val1, val2); - - break; - } - - case OperationCallback::FUTURE_OBJECT_RESULT: - { - SharedPointer mem = env->Get()->GetMemory(val2); - - env->Get()->OnFutureObjectResult(val1, mem); - - break; - } - - case OperationCallback::FUTURE_ERROR: - { - SharedPointer mem = env->Get()->GetMemory(val2); - - env->Get()->OnFutureError(val1, mem); - - break; - } - - default: - { - break; - } - } - - return res; - } - - IgniteEnvironment::IgniteEnvironment(const IgniteConfiguration& cfg) : - cfg(new IgniteConfiguration(cfg)), - ctx(SharedPointer()), - latch(), - name(0), - proc(), - registry(DEFAULT_FAST_PATH_CONTAINERS_CAP, DEFAULT_SLOW_PATH_CONTAINERS_CAP), - metaMgr(new BinaryTypeManager()), - metaUpdater(0), - binding(), - moduleMgr(), - nodes(new ClusterNodesHolder()), - ignite(0) - { - binding = SharedPointer(new IgniteBindingImpl(*this)); - - IgniteBindingContext bindingContext(cfg, GetBinding()); - - moduleMgr = SharedPointer(new ModuleManager(bindingContext)); - } - - IgniteEnvironment::~IgniteEnvironment() - { - delete[] name; - - delete ignite; - delete metaUpdater; - delete metaMgr; - delete cfg; - } - - const IgniteConfiguration& IgniteEnvironment::GetConfiguration() const - { - return *cfg; - } - - JniHandlers IgniteEnvironment::GetJniHandlers(SharedPointer* target) - { - JniHandlers hnds; - - memset(&hnds, 0, sizeof(hnds)); - - hnds.target = target; - - hnds.inLongOutLong = InLongOutLong; - hnds.inLongLongLongObjectOutLong = InLongLongLongObjectOutLong; - - hnds.error = 0; - - return hnds; - } - - void IgniteEnvironment::SetContext(SharedPointer ctx) - { - this->ctx = ctx; - } - - void IgniteEnvironment::Initialize() - { - latch.CountDown(); - - JniErrorInfo jniErr; - - jobject binaryProc = Context()->TargetOutObject(proc.Get(), ProcessorOp::GET_BINARY_PROCESSOR, &jniErr); - - metaUpdater = new BinaryTypeUpdaterImpl(*this, binaryProc); - - metaMgr->SetUpdater(metaUpdater); - - common::dynamic::Module currentModule = common::dynamic::GetCurrent(); - moduleMgr.Get()->RegisterModule(currentModule); - - ignite = new Ignite(new IgniteImpl(SharedPointer(this, SharedPointerEmptyDeleter))); - } - - const char* IgniteEnvironment::InstanceName() const - { - return name; - } - - void* IgniteEnvironment::GetProcessor() - { - return (void*)proc.Get(); - } - - JniContext* IgniteEnvironment::Context() - { - return ctx.Get(); - } - - SharedPointer IgniteEnvironment::AllocateMemory() - { - SharedPointer ptr(new InteropUnpooledMemory(DEFAULT_ALLOCATION_SIZE)); - - return ptr; - } - - SharedPointer IgniteEnvironment::AllocateMemory(int32_t cap) - { - SharedPointer ptr(new InteropUnpooledMemory(cap)); - - return ptr; - } - - SharedPointer IgniteEnvironment::GetMemory(int64_t memPtr) - { - int8_t* memPtr0 = reinterpret_cast(memPtr); - - int32_t flags = InteropMemory::Flags(memPtr0); - - if (InteropMemory::IsExternal(flags)) - { - SharedPointer ptr(new InteropExternalMemory(memPtr0)); - - return ptr; - } - else - { - SharedPointer ptr(new InteropUnpooledMemory(memPtr0)); - - return ptr; - } - } - - BinaryTypeManager* IgniteEnvironment::GetTypeManager() - { - return metaMgr; - } - - BinaryTypeUpdater* IgniteEnvironment::GetTypeUpdater() - { - return metaUpdater; - } - - IgniteEnvironment::SP_ClusterNodeImpl IgniteEnvironment::GetLocalNode() - { - return nodes.Get()->GetLocalNode(); - } - - IgniteEnvironment::SP_ClusterNodeImpl IgniteEnvironment::GetNode(Guid Id) - { - return nodes.Get()->GetNode(Id); - } - - SharedPointer IgniteEnvironment::GetBinding() const - { - return binding; - } - - jobject IgniteEnvironment::GetProcessorCompute(jobject proj) - { - JniErrorInfo jniErr; - - jobject res = ctx.Get()->TargetOutObject(proj, ClusterGroupOp::GET_COMPUTE, &jniErr); - - IgniteError err; - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - IgniteError::ThrowIfNeeded(err); - - return res; - } - - void IgniteEnvironment::ComputeJobExecuteLocal(int64_t jobHandle) - { - SharedPointer job0 = - StaticPointerCast(registry.Get(jobHandle)); - - compute::ComputeJobHolder* job = job0.Get(); - - if (job) - job->ExecuteLocal(this); - else - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Job is not registred for handle", "jobHandle", jobHandle); - } - } - - int32_t IgniteEnvironment::ComputeTaskLocalJobResult(int64_t taskHandle, int64_t jobHandle) - { - SharedPointer job0 = - StaticPointerCast(registry.Get(jobHandle)); - - compute::ComputeJobHolder* job = job0.Get(); - - SharedPointer task0 = - StaticPointerCast(registry.Get(taskHandle)); - - compute::ComputeTaskHolder* task = task0.Get(); - - if (task && job) - return task->JobResultLocal(*job); - - if (!task) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Task is not registred for handle", "taskHandle", taskHandle); - } - - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Job is not registred for handle", "jobHandle", jobHandle); - } - - ignite::odbc::Ignite* IgniteEnvironment::GetIgnite() - { - return ignite; - } - - void IgniteEnvironment::ComputeTaskReduce(int64_t taskHandle) - { - SharedPointer task0 = - StaticPointerCast(registry.Get(taskHandle)); - - compute::ComputeTaskHolder* task = task0.Get(); - - if (task) - task->Reduce(); - else - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Task is not registred for handle", "taskHandle", taskHandle); - } - } - - void IgniteEnvironment::ComputeTaskComplete(int64_t taskHandle) - { - SharedPointer task0 = - StaticPointerCast(registry.Get(taskHandle)); - - compute::ComputeTaskHolder* task = task0.Get(); - - if (task) - { - registry.Release(task->GetJobHandle()); - registry.Release(taskHandle); - } - } - - int64_t IgniteEnvironment::ComputeJobCreate(SharedPointer& mem) - { - if (!binding.Get()) - throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, "IgniteBinding is not initialized."); - - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - InteropOutputStream outStream(mem.Get()); - BinaryWriterImpl writer(&outStream, GetTypeManager()); - - BinaryObjectImpl binJob = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), 0); - - int32_t jobTypeId = binJob.GetTypeId(); - - bool invoked = false; - - int64_t handle = binding.Get()->InvokeCallback(invoked, - IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, jobTypeId, reader, writer); - - if (!invoked) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "C++ compute job is not registered on the node (did you compile your program without -rdynamic?).", - "jobTypeId", jobTypeId); - } - - return handle; - } - - void IgniteEnvironment::ComputeJobExecute(SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - - InteropOutputStream outStream(mem.Get()); - BinaryWriterImpl writer(&outStream, GetTypeManager()); - - int64_t jobHandle = inStream.ReadInt64(); - - SharedPointer job0 = - StaticPointerCast(registry.Get(jobHandle)); - - compute::ComputeJobHolder* job = job0.Get(); - - if (job) - job->ExecuteRemote(this, writer); - else - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Job is not registred for handle", "jobHandle", jobHandle); - } - - outStream.Synchronize(); - } - - void IgniteEnvironment::ComputeJobDestroy(int64_t jobHandle) - { - registry.Release(jobHandle); - } - - int32_t IgniteEnvironment::ComputeTaskJobResult(SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - int64_t taskHandle = reader.ReadInt64(); - - // Job Handle. - reader.ReadInt64(); - - // Node GUID - reader.ReadGuid(); - - // Cancel flag - reader.ReadBool(); - - SharedPointer task0 = - StaticPointerCast(registry.Get(taskHandle)); - - compute::ComputeTaskHolder* task = task0.Get(); - - if (!task) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Task is not registred for handle", "taskHandle", taskHandle); - } - - return task->JobResultRemote(reader); - } - - void IgniteEnvironment::ProcessorReleaseStart() - { - if (proc.Get()) - { - JniErrorInfo jniErr; - ctx.Get()->TargetInLongOutLong(proc.Get(), ProcessorOp::RELEASE_START, 0, &jniErr); - } - } - - HandleRegistry& IgniteEnvironment::GetHandleRegistry() - { - return registry; - } - - void IgniteEnvironment::OnStartCallback(int64_t memPtr, jobject proc) - { - this->proc = jni::JavaGlobalRef(ctx, proc); - - InteropExternalMemory mem(reinterpret_cast(memPtr)); - InteropInputStream stream(&mem); - - BinaryReaderImpl reader(&stream); - - int32_t nameLen = reader.ReadString(0, 0); - - if (nameLen >= 0) - { - name = new char[nameLen + 1]; - reader.ReadString(name, nameLen + 1); - } - else - name = 0; - } - - void IgniteEnvironment::OnContinuousQueryListenerApply(SharedPointer& mem) - { - InteropInputStream stream(mem.Get()); - BinaryReaderImpl reader(&stream); - - int64_t qryHandle = reader.ReadInt64(); - - ContinuousQueryImplBase* contQry = reinterpret_cast(registry.Get(qryHandle).Get()); - - if (contQry) - { - BinaryRawReader rawReader(&reader); - - contQry->ReadAndProcessEvents(rawReader); - } - } - - int64_t IgniteEnvironment::OnContinuousQueryFilterCreate(SharedPointer& mem) - { - if (!binding.Get()) - throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, "IgniteBinding is not initialized."); - - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - InteropOutputStream outStream(mem.Get()); - BinaryWriterImpl writer(&outStream, GetTypeManager()); - - BinaryObjectImpl binFilter = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), metaMgr); - - int32_t filterId = binFilter.GetTypeId(); - - bool invoked = false; - - int64_t res = binding.Get()->InvokeCallback(invoked, - IgniteBindingImpl::CallbackType::CACHE_ENTRY_FILTER_CREATE, filterId, reader, writer); - - if (!invoked) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "C++ remote filter is not registered on the node (did you compile your program without -rdynamic?).", - "filterId", filterId); - } - - outStream.Synchronize(); - - return res; - } - - int64_t IgniteEnvironment::OnContinuousQueryFilterApply(SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - BinaryRawReader rawReader(&reader); - - int64_t handle = rawReader.ReadInt64(); - - SharedPointer qry = - StaticPointerCast(registry.Get(handle)); - - if (!qry.Get()) - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, "Null query for handle.", "handle", handle); - - cache::event::CacheEntryEventFilterBase* filter = qry.Get()->GetFilterHolder().GetFilter(); - - if (!filter) - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, "Null filter for handle.", "handle", handle); - - bool res = filter->ReadAndProcessEvent(rawReader); - - return res ? 1 : 0; - } - - int64_t IgniteEnvironment::OnFuturePrimitiveResult(int64_t handle, int64_t value) - { - SharedPointer task0 = - StaticPointerCast(registry.Get(handle)); - - registry.Release(handle); - - compute::ComputeTaskHolder* task = task0.Get(); - - task->JobResultSuccess(value); - task->Reduce(); - - return 1; - } - - int64_t IgniteEnvironment::OnFutureObjectResult(int64_t handle, SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - SharedPointer task0 = - StaticPointerCast(registry.Get(handle)); - - registry.Release(handle); - - compute::ComputeTaskHolder* task = task0.Get(); - - task->JobResultSuccess(reader); - task->Reduce(); - - return 1; - } - - int64_t IgniteEnvironment::OnFutureNullResult(int64_t handle) - { - SharedPointer task0 = - StaticPointerCast(registry.Get(handle)); - - registry.Release(handle); - - compute::ComputeTaskHolder* task = task0.Get(); - - task->JobNullResultSuccess(); - task->Reduce(); - - return 1; - } - - int64_t IgniteEnvironment::OnFutureError(int64_t handle, SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - BinaryRawReader rawReader(&reader); - - rawReader.ReadString(); - rawReader.ReadString(); - - std::string errStr = rawReader.ReadString(); - - IgniteError err(IgniteError::IGNITE_ERR_GENERIC, errStr.c_str()); - - SharedPointer task0 = - StaticPointerCast(registry.Get(handle)); - - registry.Release(handle); - - compute::ComputeTaskHolder* task = task0.Get(); - - task->JobResultError(err); - task->Reduce(); - - return 1; - } - - int64_t IgniteEnvironment::OnComputeFuncExecute(SharedPointer& mem) - { - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - InteropOutputStream outStream(mem.Get()); - BinaryWriterImpl writer(&outStream, GetTypeManager()); - - bool local = reader.ReadBool(); - - int64_t handle = -1; - - if (local) - { - handle = reader.ReadInt64(); - } - else - { - bool invoked = false; - - BinaryObjectImpl func(*mem.Get(), inStream.Position(), 0, 0); - int32_t jobTypeId = func.GetTypeId(); - - handle = binding.Get()->InvokeCallback(invoked, - IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, jobTypeId, reader, writer); - - if (!invoked) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Compute function is not registred", "jobTypeId", jobTypeId); - } - } - - SharedPointer job0 = - StaticPointerCast(registry.Get(handle)); - - registry.Release(handle); - - compute::ComputeJobHolder* job = job0.Get(); - - if (!job) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "Job is not registred for handle", "handle", handle); - } - - job->ExecuteRemote(this, writer); - - outStream.Synchronize(); - - return 1; - } - - void IgniteEnvironment::CacheInvokeCallback(SharedPointer& mem) - { - if (!binding.Get()) - throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, "IgniteBinding is not initialized."); - - InteropInputStream inStream(mem.Get()); - BinaryReaderImpl reader(&inStream); - - InteropOutputStream outStream(mem.Get()); - BinaryWriterImpl writer(&outStream, GetTypeManager()); - - bool local = reader.ReadBool(); - - if (local) - throw IgniteError(IgniteError::IGNITE_ERR_UNSUPPORTED_OPERATION, "Local invokation is not supported."); - - BinaryObjectImpl binProcHolder = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), 0); - BinaryObjectImpl binProc = binProcHolder.GetField(0); - - int32_t procId = binProc.GetTypeId(); - - bool invoked = false; - - binding.Get()->InvokeCallback(invoked, - IgniteBindingImpl::CallbackType::CACHE_ENTRY_PROCESSOR_APPLY, procId, reader, writer); - - if (!invoked) - { - IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, - "C++ entry processor is not registered on the node (did you compile your program without -rdynamic?).", - "procId", procId); - } - - outStream.Synchronize(); - } - } +namespace ignite { +namespace odbc { +namespace impl { +/** + * Callback codes. + */ +struct OperationCallback { + enum Type { + CACHE_INVOKE = 8, + COMPUTE_TASK_JOB_RESULT = 10, + COMPUTE_TASK_REDUCE = 11, + COMPUTE_TASK_COMPLETE = 12, + COMPUTE_JOB_CREATE = 14, + COMPUTE_JOB_EXECUTE = 15, + COMPUTE_JOB_DESTROY = 17, + CONTINUOUS_QUERY_LISTENER_APPLY = 18, + CONTINUOUS_QUERY_FILTER_CREATE = 19, + CONTINUOUS_QUERY_FILTER_APPLY = 20, + CONTINUOUS_QUERY_FILTER_RELEASE = 21, + FUTURE_BYTE_RESULT = 24, + FUTURE_BOOL_RESULT = 25, + FUTURE_SHORT_RESULT = 26, + FUTURE_CHAR_RESULT = 27, + FUTURE_INT_RESULT = 28, + FUTURE_FLOAT_RESULT = 29, + FUTURE_LONG_RESULT = 30, + FUTURE_DOUBLE_RESULT = 31, + FUTURE_OBJECT_RESULT = 32, + FUTURE_NULL_RESULT = 33, + FUTURE_ERROR = 34, + REALLOC = 36, + NODE_INFO = 48, + ON_START = 49, + ON_STOP = 50, + COMPUTE_TASK_LOCAL_JOB_RESULT = 60, + COMPUTE_JOB_EXECUTE_LOCAL = 61, + COMPUTE_OUT_FUNC_EXECUTE = 74, + COMPUTE_ACTION_EXECUTE = 75 + }; +}; + +/* + * PlatformProcessor op codes. + */ +struct ProcessorOp { + enum Type { GET_BINARY_PROCESSOR = 21, RELEASE_START = 22 }; +}; + +/* + * PlatformClusterGroup op codes. + */ +struct ClusterGroupOp { + enum Type { GET_COMPUTE = 31 }; +}; + +typedef SharedPointer< impl::cluster::ClusterNodeImpl > SP_ClusterNodeImpl; + +/* + * Stores cluster nodes in thread-safe manner. + */ +class ClusterNodesHolder { + CriticalSection nodesLock; + std::map< Guid, SP_ClusterNodeImpl > nodes; + + public: + ClusterNodesHolder() : nodesLock() { + // No-op. + } + + void AddNode(SP_ClusterNodeImpl node) { + CsLockGuard mtx(nodesLock); + + nodes.insert( + std::pair< Guid, SP_ClusterNodeImpl >(node.Get()->GetId(), node)); + } + + SP_ClusterNodeImpl GetLocalNode() { + CsLockGuard mtx(nodesLock); + + std::map< Guid, SP_ClusterNodeImpl >::iterator it; + for (it = nodes.begin(); it != nodes.end(); ++it) + if (it->second.Get()->IsLocal()) + return it->second; + + return NULL; + } + + SP_ClusterNodeImpl GetNode(Guid Id) { + CsLockGuard mtx(nodesLock); + + if (nodes.find(Id) != nodes.end()) + return nodes.at(Id); + + return NULL; + } +}; + +/** + * InLongOutLong callback. + * + * @param target Target environment. + * @param type Operation type. + * @param val Value. + */ +int64_t IGNITE_CALL InLongOutLong(void* target, int type, int64_t val) { + int64_t res = 0; + SharedPointer< IgniteEnvironment >* env = + static_cast< SharedPointer< IgniteEnvironment >* >(target); + + if (!env) + return res; + + switch (type) { + case OperationCallback::NODE_INFO: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + SharedPointer< InteropMemory > memCopy( + new InteropUnpooledMemory(mem.Get()->Capacity())); + + memCopy.Get()->Length(mem.Get()->Length()); + memcpy(memCopy.Get()->Data(), mem.Get()->Data(), mem.Get()->Capacity()); + + SP_ClusterNodeImpl node = (new impl::cluster::ClusterNodeImpl(memCopy)); + env->Get()->nodes.Get()->AddNode(node); + + break; + } + + case OperationCallback::ON_STOP: { + delete env; + + break; + } + + case OperationCallback::COMPUTE_JOB_CREATE: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + res = env->Get()->ComputeJobCreate(mem); + + break; + } + + case OperationCallback::COMPUTE_JOB_EXECUTE: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + env->Get()->ComputeJobExecute(mem); + + break; + } + + case OperationCallback::COMPUTE_JOB_DESTROY: { + env->Get()->ComputeJobDestroy(val); + + break; + } + + case OperationCallback::COMPUTE_TASK_JOB_RESULT: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + res = env->Get()->ComputeTaskJobResult(mem); + + break; + } + + case OperationCallback::COMPUTE_TASK_REDUCE: { + env->Get()->ComputeTaskReduce(val); + + break; + } + + case OperationCallback::CONTINUOUS_QUERY_LISTENER_APPLY: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + env->Get()->OnContinuousQueryListenerApply(mem); + + break; + } + + case OperationCallback::CONTINUOUS_QUERY_FILTER_CREATE: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + res = env->Get()->OnContinuousQueryFilterCreate(mem); + + break; + } + + case OperationCallback::CONTINUOUS_QUERY_FILTER_APPLY: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + res = env->Get()->OnContinuousQueryFilterApply(mem); + + break; + } + + case OperationCallback::CONTINUOUS_QUERY_FILTER_RELEASE: { + // No-op. + + break; + } + + case OperationCallback::COMPUTE_ACTION_EXECUTE: + case OperationCallback::COMPUTE_OUT_FUNC_EXECUTE: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + res = env->Get()->OnComputeFuncExecute(mem); + + break; + } + + case OperationCallback::FUTURE_NULL_RESULT: { + env->Get()->OnFutureNullResult(val); + + break; + } + + case OperationCallback::CACHE_INVOKE: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val); + + env->Get()->CacheInvokeCallback(mem); + + break; + } + + default: { + break; + } + } + + return res; +} + +/** + * InLongOutLong callback. + * + * @param target Target environment. + * @param type Operation type. + * @param val1 Value1. + * @param val2 Value2. + * @param val3 Value3. + * @param arg Object arg. + */ +int64_t IGNITE_CALL InLongLongLongObjectOutLong(void* target, int type, + int64_t val1, int64_t val2, + int64_t val3, void* arg) { + IGNITE_UNUSED(val3); + + int64_t res = 0; + SharedPointer< IgniteEnvironment >* env = + static_cast< SharedPointer< IgniteEnvironment >* >(target); + + switch (type) { + case OperationCallback::COMPUTE_JOB_EXECUTE_LOCAL: { + env->Get()->ComputeJobExecuteLocal(val1); + + break; + } + + case OperationCallback::COMPUTE_TASK_LOCAL_JOB_RESULT: { + res = env->Get()->ComputeTaskLocalJobResult(val1, val2); + + break; + } + + case OperationCallback::COMPUTE_TASK_COMPLETE: { + env->Get()->ComputeTaskComplete(val1); + + break; + } + + case OperationCallback::ON_START: { + env->Get()->OnStartCallback(val1, reinterpret_cast< jobject >(arg)); + + break; + } + + case OperationCallback::REALLOC: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val1); + + mem.Get()->Reallocate(static_cast< int32_t >(val2)); + + break; + } + + case OperationCallback::FUTURE_BYTE_RESULT: + case OperationCallback::FUTURE_BOOL_RESULT: + case OperationCallback::FUTURE_SHORT_RESULT: + case OperationCallback::FUTURE_CHAR_RESULT: + case OperationCallback::FUTURE_INT_RESULT: + case OperationCallback::FUTURE_LONG_RESULT: + case OperationCallback::FUTURE_FLOAT_RESULT: + case OperationCallback::FUTURE_DOUBLE_RESULT: { + env->Get()->OnFuturePrimitiveResult(val1, val2); + + break; + } + + case OperationCallback::FUTURE_OBJECT_RESULT: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val2); + + env->Get()->OnFutureObjectResult(val1, mem); + + break; + } + + case OperationCallback::FUTURE_ERROR: { + SharedPointer< InteropMemory > mem = env->Get()->GetMemory(val2); + + env->Get()->OnFutureError(val1, mem); + + break; + } + + default: { + break; + } + } + + return res; +} + +IgniteEnvironment::IgniteEnvironment(const IgniteConfiguration& cfg) + : cfg(new IgniteConfiguration(cfg)), + ctx(SharedPointer< JniContext >()), + latch(), + name(0), + proc(), + registry(DEFAULT_FAST_PATH_CONTAINERS_CAP, + DEFAULT_SLOW_PATH_CONTAINERS_CAP), + metaMgr(new BinaryTypeManager()), + metaUpdater(0), + binding(), + moduleMgr(), + nodes(new ClusterNodesHolder()), + ignite(0) { + binding = SharedPointer< IgniteBindingImpl >(new IgniteBindingImpl(*this)); + + IgniteBindingContext bindingContext(cfg, GetBinding()); + + moduleMgr = SharedPointer< ModuleManager >(new ModuleManager(bindingContext)); +} + +IgniteEnvironment::~IgniteEnvironment() { + delete[] name; + + delete ignite; + delete metaUpdater; + delete metaMgr; + delete cfg; +} + +const IgniteConfiguration& IgniteEnvironment::GetConfiguration() const { + return *cfg; +} + +JniHandlers IgniteEnvironment::GetJniHandlers( + SharedPointer< IgniteEnvironment >* target) { + JniHandlers hnds; + + memset(&hnds, 0, sizeof(hnds)); + + hnds.target = target; + + hnds.inLongOutLong = InLongOutLong; + hnds.inLongLongLongObjectOutLong = InLongLongLongObjectOutLong; + + hnds.error = 0; + + return hnds; +} + +void IgniteEnvironment::SetContext(SharedPointer< JniContext > ctx) { + this->ctx = ctx; +} + +void IgniteEnvironment::Initialize() { + latch.CountDown(); + + JniErrorInfo jniErr; + + jobject binaryProc = Context()->TargetOutObject( + proc.Get(), ProcessorOp::GET_BINARY_PROCESSOR, &jniErr); + + metaUpdater = new BinaryTypeUpdaterImpl(*this, binaryProc); + + metaMgr->SetUpdater(metaUpdater); + + common::dynamic::Module currentModule = common::dynamic::GetCurrent(); + moduleMgr.Get()->RegisterModule(currentModule); + + ignite = new Ignite(new IgniteImpl( + SharedPointer< IgniteEnvironment >(this, SharedPointerEmptyDeleter))); +} + +const char* IgniteEnvironment::InstanceName() const { + return name; +} + +void* IgniteEnvironment::GetProcessor() { + return (void*)proc.Get(); +} + +JniContext* IgniteEnvironment::Context() { + return ctx.Get(); +} + +SharedPointer< InteropMemory > IgniteEnvironment::AllocateMemory() { + SharedPointer< InteropMemory > ptr( + new InteropUnpooledMemory(DEFAULT_ALLOCATION_SIZE)); + + return ptr; +} + +SharedPointer< InteropMemory > IgniteEnvironment::AllocateMemory(int32_t cap) { + SharedPointer< InteropMemory > ptr(new InteropUnpooledMemory(cap)); + + return ptr; +} + +SharedPointer< InteropMemory > IgniteEnvironment::GetMemory(int64_t memPtr) { + int8_t* memPtr0 = reinterpret_cast< int8_t* >(memPtr); + + int32_t flags = InteropMemory::Flags(memPtr0); + + if (InteropMemory::IsExternal(flags)) { + SharedPointer< InteropMemory > ptr(new InteropExternalMemory(memPtr0)); + + return ptr; + } else { + SharedPointer< InteropMemory > ptr(new InteropUnpooledMemory(memPtr0)); + + return ptr; + } +} + +BinaryTypeManager* IgniteEnvironment::GetTypeManager() { + return metaMgr; +} + +BinaryTypeUpdater* IgniteEnvironment::GetTypeUpdater() { + return metaUpdater; +} + +IgniteEnvironment::SP_ClusterNodeImpl IgniteEnvironment::GetLocalNode() { + return nodes.Get()->GetLocalNode(); +} + +IgniteEnvironment::SP_ClusterNodeImpl IgniteEnvironment::GetNode(Guid Id) { + return nodes.Get()->GetNode(Id); +} + +SharedPointer< IgniteBindingImpl > IgniteEnvironment::GetBinding() const { + return binding; +} + +jobject IgniteEnvironment::GetProcessorCompute(jobject proj) { + JniErrorInfo jniErr; + + jobject res = + ctx.Get()->TargetOutObject(proj, ClusterGroupOp::GET_COMPUTE, &jniErr); + + IgniteError err; + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + IgniteError::ThrowIfNeeded(err); + + return res; +} + +void IgniteEnvironment::ComputeJobExecuteLocal(int64_t jobHandle) { + SharedPointer< compute::ComputeJobHolder > job0 = + StaticPointerCast< compute::ComputeJobHolder >(registry.Get(jobHandle)); + + compute::ComputeJobHolder* job = job0.Get(); + + if (job) + job->ExecuteLocal(this); + else { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Job is not registred for handle", "jobHandle", jobHandle); + } +} + +int32_t IgniteEnvironment::ComputeTaskLocalJobResult(int64_t taskHandle, + int64_t jobHandle) { + SharedPointer< compute::ComputeJobHolder > job0 = + StaticPointerCast< compute::ComputeJobHolder >(registry.Get(jobHandle)); + + compute::ComputeJobHolder* job = job0.Get(); + + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(taskHandle)); + + compute::ComputeTaskHolder* task = task0.Get(); + + if (task && job) + return task->JobResultLocal(*job); + + if (!task) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Task is not registred for handle", "taskHandle", taskHandle); + } + + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Job is not registred for handle", "jobHandle", jobHandle); +} + +ignite::odbc::Ignite* IgniteEnvironment::GetIgnite() { + return ignite; +} + +void IgniteEnvironment::ComputeTaskReduce(int64_t taskHandle) { + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(taskHandle)); + + compute::ComputeTaskHolder* task = task0.Get(); + + if (task) + task->Reduce(); + else { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Task is not registred for handle", "taskHandle", taskHandle); + } +} + +void IgniteEnvironment::ComputeTaskComplete(int64_t taskHandle) { + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(taskHandle)); + + compute::ComputeTaskHolder* task = task0.Get(); + + if (task) { + registry.Release(task->GetJobHandle()); + registry.Release(taskHandle); + } +} + +int64_t IgniteEnvironment::ComputeJobCreate( + SharedPointer< InteropMemory >& mem) { + if (!binding.Get()) + throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, + "IgniteBinding is not initialized."); + + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + InteropOutputStream outStream(mem.Get()); + BinaryWriterImpl writer(&outStream, GetTypeManager()); + + BinaryObjectImpl binJob = + BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), 0); + + int32_t jobTypeId = binJob.GetTypeId(); + + bool invoked = false; + + int64_t handle = binding.Get()->InvokeCallback( + invoked, IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, jobTypeId, + reader, writer); + + if (!invoked) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "C++ compute job is not registered on the node (did you compile your " + "program without -rdynamic?).", + "jobTypeId", jobTypeId); + } + + return handle; +} + +void IgniteEnvironment::ComputeJobExecute(SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + + InteropOutputStream outStream(mem.Get()); + BinaryWriterImpl writer(&outStream, GetTypeManager()); + + int64_t jobHandle = inStream.ReadInt64(); + + SharedPointer< compute::ComputeJobHolder > job0 = + StaticPointerCast< compute::ComputeJobHolder >(registry.Get(jobHandle)); + + compute::ComputeJobHolder* job = job0.Get(); + + if (job) + job->ExecuteRemote(this, writer); + else { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Job is not registred for handle", "jobHandle", jobHandle); + } + + outStream.Synchronize(); +} + +void IgniteEnvironment::ComputeJobDestroy(int64_t jobHandle) { + registry.Release(jobHandle); +} + +int32_t IgniteEnvironment::ComputeTaskJobResult( + SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + int64_t taskHandle = reader.ReadInt64(); + + // Job Handle. + reader.ReadInt64(); + + // Node GUID + reader.ReadGuid(); + + // Cancel flag + reader.ReadBool(); + + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(taskHandle)); + + compute::ComputeTaskHolder* task = task0.Get(); + + if (!task) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Task is not registred for handle", "taskHandle", taskHandle); + } + + return task->JobResultRemote(reader); +} + +void IgniteEnvironment::ProcessorReleaseStart() { + if (proc.Get()) { + JniErrorInfo jniErr; + ctx.Get()->TargetInLongOutLong(proc.Get(), ProcessorOp::RELEASE_START, 0, + &jniErr); + } +} + +HandleRegistry& IgniteEnvironment::GetHandleRegistry() { + return registry; +} + +void IgniteEnvironment::OnStartCallback(int64_t memPtr, jobject proc) { + this->proc = jni::JavaGlobalRef(ctx, proc); + + InteropExternalMemory mem(reinterpret_cast< int8_t* >(memPtr)); + InteropInputStream stream(&mem); + + BinaryReaderImpl reader(&stream); + + int32_t nameLen = reader.ReadString(0, 0); + + if (nameLen >= 0) { + name = new char[nameLen + 1]; + reader.ReadString(name, nameLen + 1); + } else + name = 0; +} + +void IgniteEnvironment::OnContinuousQueryListenerApply( + SharedPointer< InteropMemory >& mem) { + InteropInputStream stream(mem.Get()); + BinaryReaderImpl reader(&stream); + + int64_t qryHandle = reader.ReadInt64(); + + ContinuousQueryImplBase* contQry = + reinterpret_cast< ContinuousQueryImplBase* >( + registry.Get(qryHandle).Get()); + + if (contQry) { + BinaryRawReader rawReader(&reader); + + contQry->ReadAndProcessEvents(rawReader); + } +} + +int64_t IgniteEnvironment::OnContinuousQueryFilterCreate( + SharedPointer< InteropMemory >& mem) { + if (!binding.Get()) + throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, + "IgniteBinding is not initialized."); + + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + InteropOutputStream outStream(mem.Get()); + BinaryWriterImpl writer(&outStream, GetTypeManager()); + + BinaryObjectImpl binFilter = + BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), metaMgr); + + int32_t filterId = binFilter.GetTypeId(); + + bool invoked = false; + + int64_t res = binding.Get()->InvokeCallback( + invoked, IgniteBindingImpl::CallbackType::CACHE_ENTRY_FILTER_CREATE, + filterId, reader, writer); + + if (!invoked) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "C++ remote filter is not registered on the node (did you compile your " + "program without -rdynamic?).", + "filterId", filterId); + } + + outStream.Synchronize(); + + return res; +} + +int64_t IgniteEnvironment::OnContinuousQueryFilterApply( + SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + BinaryRawReader rawReader(&reader); + + int64_t handle = rawReader.ReadInt64(); + + SharedPointer< ContinuousQueryImplBase > qry = + StaticPointerCast< ContinuousQueryImplBase >(registry.Get(handle)); + + if (!qry.Get()) + IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, + "Null query for handle.", "handle", handle); + + cache::event::CacheEntryEventFilterBase* filter = + qry.Get()->GetFilterHolder().GetFilter(); + + if (!filter) + IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC, + "Null filter for handle.", "handle", handle); + + bool res = filter->ReadAndProcessEvent(rawReader); + + return res ? 1 : 0; +} + +int64_t IgniteEnvironment::OnFuturePrimitiveResult(int64_t handle, + int64_t value) { + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(handle)); + + registry.Release(handle); + + compute::ComputeTaskHolder* task = task0.Get(); + + task->JobResultSuccess(value); + task->Reduce(); + + return 1; +} + +int64_t IgniteEnvironment::OnFutureObjectResult( + int64_t handle, SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(handle)); + + registry.Release(handle); + + compute::ComputeTaskHolder* task = task0.Get(); + + task->JobResultSuccess(reader); + task->Reduce(); + + return 1; +} + +int64_t IgniteEnvironment::OnFutureNullResult(int64_t handle) { + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(handle)); + + registry.Release(handle); + + compute::ComputeTaskHolder* task = task0.Get(); + + task->JobNullResultSuccess(); + task->Reduce(); + + return 1; +} + +int64_t IgniteEnvironment::OnFutureError(int64_t handle, + SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + BinaryRawReader rawReader(&reader); + + rawReader.ReadString(); + rawReader.ReadString(); + + std::string errStr = rawReader.ReadString(); + + IgniteError err(IgniteError::IGNITE_ERR_GENERIC, errStr.c_str()); + + SharedPointer< compute::ComputeTaskHolder > task0 = + StaticPointerCast< compute::ComputeTaskHolder >(registry.Get(handle)); + + registry.Release(handle); + + compute::ComputeTaskHolder* task = task0.Get(); + + task->JobResultError(err); + task->Reduce(); + + return 1; +} + +int64_t IgniteEnvironment::OnComputeFuncExecute( + SharedPointer< InteropMemory >& mem) { + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + InteropOutputStream outStream(mem.Get()); + BinaryWriterImpl writer(&outStream, GetTypeManager()); + + bool local = reader.ReadBool(); + + int64_t handle = -1; + + if (local) { + handle = reader.ReadInt64(); + } else { + bool invoked = false; + + BinaryObjectImpl func(*mem.Get(), inStream.Position(), 0, 0); + int32_t jobTypeId = func.GetTypeId(); + + handle = binding.Get()->InvokeCallback( + invoked, IgniteBindingImpl::CallbackType::COMPUTE_JOB_CREATE, jobTypeId, + reader, writer); + + if (!invoked) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Compute function is not registred", "jobTypeId", jobTypeId); } + } + + SharedPointer< compute::ComputeJobHolder > job0 = + StaticPointerCast< compute::ComputeJobHolder >(registry.Get(handle)); + + registry.Release(handle); + + compute::ComputeJobHolder* job = job0.Get(); + + if (!job) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "Job is not registred for handle", "handle", handle); + } + + job->ExecuteRemote(this, writer); + + outStream.Synchronize(); + + return 1; +} + +void IgniteEnvironment::CacheInvokeCallback( + SharedPointer< InteropMemory >& mem) { + if (!binding.Get()) + throw IgniteError(IgniteError::IGNITE_ERR_UNKNOWN, + "IgniteBinding is not initialized."); + + InteropInputStream inStream(mem.Get()); + BinaryReaderImpl reader(&inStream); + + InteropOutputStream outStream(mem.Get()); + BinaryWriterImpl writer(&outStream, GetTypeManager()); + + bool local = reader.ReadBool(); + + if (local) + throw IgniteError(IgniteError::IGNITE_ERR_UNSUPPORTED_OPERATION, + "Local invokation is not supported."); + + BinaryObjectImpl binProcHolder = + BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), 0); + BinaryObjectImpl binProc = binProcHolder.GetField(0); + + int32_t procId = binProc.GetTypeId(); + + bool invoked = false; + + binding.Get()->InvokeCallback( + invoked, IgniteBindingImpl::CallbackType::CACHE_ENTRY_PROCESSOR_APPLY, + procId, reader, writer); + + if (!invoked) { + IGNITE_ERROR_FORMATTED_1( + IgniteError::IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, + "C++ entry processor is not registered on the node (did you compile " + "your program without -rdynamic?).", + "procId", procId); + } + + outStream.Synchronize(); } +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/ignite_impl.cpp b/src/odbc/src/impl/ignite_impl.cpp index f45abd1b1..e1fd5b372 100644 --- a/src/odbc/src/impl/ignite_impl.cpp +++ b/src/odbc/src/impl/ignite_impl.cpp @@ -29,211 +29,192 @@ using namespace ignite::odbc::impl::cluster; using namespace ignite::odbc::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - /* - * PlatformProcessor op codes. - */ - struct ProcessorOp - { - enum Type - { - GET_CACHE = 1, - CREATE_CACHE = 2, - GET_OR_CREATE_CACHE = 3, - GET_AFFINITY = 7, - GET_TRANSACTIONS = 9, - GET_CLUSTER_GROUP = 10, - SET_BASELINE_TOPOLOGY_VERSION = 24, - WAL_DISABLE = 27, - WAL_ENABLE = 28, - WAL_IS_ENABLED = 29, - SET_TX_TIMEOUT_ON_PARTITION_MAP_EXCHANGE = 30, - }; - }; - - IgniteImpl::IgniteImpl(SharedPointer env) : - InteropTarget(env, static_cast(env.Get()->GetProcessor()), true), - env(env), - prjImpl() - { - prjImpl.Init(common::Bind(this, &IgniteImpl::InternalGetProjection)); - } - - IgniteImpl::SP_CacheAffinityImpl IgniteImpl::GetAffinity(const std::string& cacheName, IgniteError& err) - { - SharedPointer mem = env.Get()->AllocateMemory(); - InteropMemory* mem0 = mem.Get(); - InteropOutputStream out(mem0); - BinaryWriterImpl writer(&out, env.Get()->GetTypeManager()); - BinaryRawWriter rawWriter(&writer); - - rawWriter.WriteString(cacheName); - - out.Synchronize(); - - jobject affinityJavaRef = InStreamOutObject(ProcessorOp::GET_AFFINITY, *mem0, err); - - if (!affinityJavaRef) - { - return NULL; - } - - return new CacheAffinityImpl(env, affinityJavaRef); - } - - const char* IgniteImpl::GetName() const - { - return env.Get()->InstanceName(); - } - - const IgniteConfiguration& IgniteImpl::GetConfiguration() const - { - return env.Get()->GetConfiguration(); - } - - JniContext* IgniteImpl::GetContext() - { - return env.Get()->Context(); - } - - CacheImpl* IgniteImpl::GetCache(const char* name, IgniteError& err) - { - return GetOrCreateCache(name, err, ProcessorOp::GET_CACHE); - } - - CacheImpl* IgniteImpl::GetOrCreateCache(const char* name, IgniteError& err) - { - return GetOrCreateCache(name, err, ProcessorOp::GET_OR_CREATE_CACHE); - } - - CacheImpl* IgniteImpl::CreateCache(const char* name, IgniteError& err) - { - return GetOrCreateCache(name, err, ProcessorOp::CREATE_CACHE); - } - - IgniteImpl::SP_IgniteBindingImpl IgniteImpl::GetBinding() - { - return env.Get()->GetBinding(); - } - - IgniteImpl::SP_IgniteClusterImpl IgniteImpl::GetCluster() - { - return IgniteImpl::SP_IgniteClusterImpl(new IgniteClusterImpl(this->GetProjection())); - } - - IgniteImpl::SP_ComputeImpl IgniteImpl::GetCompute() - { - SP_ClusterGroupImpl serversCluster = prjImpl.Get().Get()->ForServers(); - - return GetCompute(serversCluster); - } - - IgniteImpl::SP_ComputeImpl IgniteImpl::GetCompute(ClusterGroup grp) - { - SP_ClusterGroupImpl grpImpl = grp.GetImpl(); - - return SP_ComputeImpl(new compute::ComputeImpl(GetEnvironmentPointer(), grpImpl)); - } - - void IgniteImpl::DisableWal(std::string cacheName) - { - IgniteError err; - In1Operation inOp(cacheName); - - InteropTarget::OutOp(ProcessorOp::WAL_DISABLE, inOp, err); - - IgniteError::ThrowIfNeeded(err); - } - - void IgniteImpl::EnableWal(std::string cacheName) - { - IgniteError err; - In1Operation inOp(cacheName); - - InteropTarget::OutOp(ProcessorOp::WAL_ENABLE, inOp, err); - - IgniteError::ThrowIfNeeded(err); - } - - bool IgniteImpl::IsWalEnabled(std::string cacheName) - { - IgniteError err; - In1Operation inOp(cacheName); - - bool ret = InteropTarget::OutOp(ProcessorOp::WAL_IS_ENABLED, inOp, err); - - IgniteError::ThrowIfNeeded(err); - - return ret; - } - - void IgniteImpl::SetBaselineTopologyVersion(int64_t topVer) - { - IgniteError err; - - OutInOpLong(ProcessorOp::SET_BASELINE_TOPOLOGY_VERSION, topVer, err); - - IgniteError::ThrowIfNeeded(err); - } - - void IgniteImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) - { - IgniteError err; - - if (timeout < 0) { - const char* msg = "Impossible to set negative timeout"; - throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); - } - - In1Operation inOp(timeout); - - OutOp(ProcessorOp::SET_TX_TIMEOUT_ON_PARTITION_MAP_EXCHANGE, inOp, err); - - IgniteError::ThrowIfNeeded(err); - } - - ClusterGroupImpl* IgniteImpl::InternalGetProjection() - { - IgniteError err; - - jobject clusterGroupJavaRef = InOpObject(ProcessorOp::GET_CLUSTER_GROUP, err); - - IgniteError::ThrowIfNeeded(err); - - if (!clusterGroupJavaRef) - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Can not get ClusterGroup instance."); - - return new ClusterGroupImpl(env, clusterGroupJavaRef); - } - - CacheImpl* IgniteImpl::GetOrCreateCache(const char* name, IgniteError& err, int32_t op) - { - SharedPointer mem = env.Get()->AllocateMemory(); - InteropMemory* mem0 = mem.Get(); - InteropOutputStream out(mem0); - BinaryWriterImpl writer(&out, env.Get()->GetTypeManager()); - BinaryRawWriter rawWriter(&writer); - - rawWriter.WriteString(name); - - out.Synchronize(); - - jobject cacheJavaRef = InStreamOutObject(op, *mem0, err); - - if (!cacheJavaRef) - { - return NULL; - } - - char* name0 = common::CopyChars(name); - - return new CacheImpl(name0, env, cacheJavaRef); - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +/* + * PlatformProcessor op codes. + */ +struct ProcessorOp { + enum Type { + GET_CACHE = 1, + CREATE_CACHE = 2, + GET_OR_CREATE_CACHE = 3, + GET_AFFINITY = 7, + GET_TRANSACTIONS = 9, + GET_CLUSTER_GROUP = 10, + SET_BASELINE_TOPOLOGY_VERSION = 24, + WAL_DISABLE = 27, + WAL_ENABLE = 28, + WAL_IS_ENABLED = 29, + SET_TX_TIMEOUT_ON_PARTITION_MAP_EXCHANGE = 30, + }; +}; + +IgniteImpl::IgniteImpl(SharedPointer< IgniteEnvironment > env) + : InteropTarget(env, static_cast< jobject >(env.Get()->GetProcessor()), + true), + env(env), + prjImpl() { + prjImpl.Init(common::Bind(this, &IgniteImpl::InternalGetProjection)); +} + +IgniteImpl::SP_CacheAffinityImpl IgniteImpl::GetAffinity( + const std::string& cacheName, IgniteError& err) { + SharedPointer< InteropMemory > mem = env.Get()->AllocateMemory(); + InteropMemory* mem0 = mem.Get(); + InteropOutputStream out(mem0); + BinaryWriterImpl writer(&out, env.Get()->GetTypeManager()); + BinaryRawWriter rawWriter(&writer); + + rawWriter.WriteString(cacheName); + + out.Synchronize(); + + jobject affinityJavaRef = + InStreamOutObject(ProcessorOp::GET_AFFINITY, *mem0, err); + + if (!affinityJavaRef) { + return NULL; + } + + return new CacheAffinityImpl(env, affinityJavaRef); +} + +const char* IgniteImpl::GetName() const { + return env.Get()->InstanceName(); +} + +const IgniteConfiguration& IgniteImpl::GetConfiguration() const { + return env.Get()->GetConfiguration(); +} + +JniContext* IgniteImpl::GetContext() { + return env.Get()->Context(); +} + +CacheImpl* IgniteImpl::GetCache(const char* name, IgniteError& err) { + return GetOrCreateCache(name, err, ProcessorOp::GET_CACHE); +} + +CacheImpl* IgniteImpl::GetOrCreateCache(const char* name, IgniteError& err) { + return GetOrCreateCache(name, err, ProcessorOp::GET_OR_CREATE_CACHE); +} + +CacheImpl* IgniteImpl::CreateCache(const char* name, IgniteError& err) { + return GetOrCreateCache(name, err, ProcessorOp::CREATE_CACHE); +} + +IgniteImpl::SP_IgniteBindingImpl IgniteImpl::GetBinding() { + return env.Get()->GetBinding(); +} + +IgniteImpl::SP_IgniteClusterImpl IgniteImpl::GetCluster() { + return IgniteImpl::SP_IgniteClusterImpl( + new IgniteClusterImpl(this->GetProjection())); +} + +IgniteImpl::SP_ComputeImpl IgniteImpl::GetCompute() { + SP_ClusterGroupImpl serversCluster = prjImpl.Get().Get()->ForServers(); + + return GetCompute(serversCluster); +} + +IgniteImpl::SP_ComputeImpl IgniteImpl::GetCompute(ClusterGroup grp) { + SP_ClusterGroupImpl grpImpl = grp.GetImpl(); + + return SP_ComputeImpl( + new compute::ComputeImpl(GetEnvironmentPointer(), grpImpl)); +} + +void IgniteImpl::DisableWal(std::string cacheName) { + IgniteError err; + In1Operation< std::string > inOp(cacheName); + + InteropTarget::OutOp(ProcessorOp::WAL_DISABLE, inOp, err); + + IgniteError::ThrowIfNeeded(err); +} + +void IgniteImpl::EnableWal(std::string cacheName) { + IgniteError err; + In1Operation< std::string > inOp(cacheName); + + InteropTarget::OutOp(ProcessorOp::WAL_ENABLE, inOp, err); + + IgniteError::ThrowIfNeeded(err); +} + +bool IgniteImpl::IsWalEnabled(std::string cacheName) { + IgniteError err; + In1Operation< std::string > inOp(cacheName); + + bool ret = InteropTarget::OutOp(ProcessorOp::WAL_IS_ENABLED, inOp, err); + + IgniteError::ThrowIfNeeded(err); + + return ret; +} + +void IgniteImpl::SetBaselineTopologyVersion(int64_t topVer) { + IgniteError err; + + OutInOpLong(ProcessorOp::SET_BASELINE_TOPOLOGY_VERSION, topVer, err); + + IgniteError::ThrowIfNeeded(err); +} + +void IgniteImpl::SetTxTimeoutOnPartitionMapExchange(int64_t timeout) { + IgniteError err; + + if (timeout < 0) { + const char* msg = "Impossible to set negative timeout"; + throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, msg); + } + + In1Operation< int64_t > inOp(timeout); + + OutOp(ProcessorOp::SET_TX_TIMEOUT_ON_PARTITION_MAP_EXCHANGE, inOp, err); + + IgniteError::ThrowIfNeeded(err); +} + +ClusterGroupImpl* IgniteImpl::InternalGetProjection() { + IgniteError err; + + jobject clusterGroupJavaRef = InOpObject(ProcessorOp::GET_CLUSTER_GROUP, err); + + IgniteError::ThrowIfNeeded(err); + + if (!clusterGroupJavaRef) + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, + "Can not get ClusterGroup instance."); + + return new ClusterGroupImpl(env, clusterGroupJavaRef); +} + +CacheImpl* IgniteImpl::GetOrCreateCache(const char* name, IgniteError& err, + int32_t op) { + SharedPointer< InteropMemory > mem = env.Get()->AllocateMemory(); + InteropMemory* mem0 = mem.Get(); + InteropOutputStream out(mem0); + BinaryWriterImpl writer(&out, env.Get()->GetTypeManager()); + BinaryRawWriter rawWriter(&writer); + + rawWriter.WriteString(name); + + out.Synchronize(); + + jobject cacheJavaRef = InStreamOutObject(op, *mem0, err); + + if (!cacheJavaRef) { + return NULL; + } + + char* name0 = common::CopyChars(name); + + return new CacheImpl(name0, env, cacheJavaRef); } +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/interop/interop_external_memory.cpp b/src/odbc/src/impl/interop/interop_external_memory.cpp index 844124840..5f5bebd14 100644 --- a/src/odbc/src/impl/interop/interop_external_memory.cpp +++ b/src/odbc/src/impl/interop/interop_external_memory.cpp @@ -22,27 +22,22 @@ using namespace ignite::odbc::jni::java; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace interop - { - InteropExternalMemory::InteropExternalMemory(int8_t* memPtr) - { - this->memPtr = memPtr; - } - - void InteropExternalMemory::Reallocate(int32_t cap) - { - if (JniContext::Reallocate(reinterpret_cast(memPtr), cap) == -1) { - IGNITE_ERROR_FORMATTED_2(IgniteError::IGNITE_ERR_MEMORY, "Failed to reallocate external memory", - "memPtr", PointerLong(), "requestedCapacity", cap) - } - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace interop { +InteropExternalMemory::InteropExternalMemory(int8_t* memPtr) { + this->memPtr = memPtr; } + +void InteropExternalMemory::Reallocate(int32_t cap) { + if (JniContext::Reallocate(reinterpret_cast< int64_t >(memPtr), cap) == -1) { + IGNITE_ERROR_FORMATTED_2(IgniteError::IGNITE_ERR_MEMORY, + "Failed to reallocate external memory", "memPtr", + PointerLong(), "requestedCapacity", cap) + } +} +} // namespace interop +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/impl/interop/interop_target.cpp b/src/odbc/src/impl/interop/interop_target.cpp index c558aee8f..4481ff527 100644 --- a/src/odbc/src/impl/interop/interop_target.cpp +++ b/src/odbc/src/impl/interop/interop_target.cpp @@ -24,301 +24,296 @@ using namespace ignite::odbc::impl::interop; using namespace ignite::odbc::impl::binary; using namespace ignite::odbc::binary; -namespace ignite -{ - namespace odbc - { - namespace impl - { - namespace interop - { - InteropTarget::InteropTarget(SharedPointer env, jobject javaRef) : - env(env), javaRef(javaRef), skipJavaRefRelease(false) - { - // No-op. - } - - InteropTarget::InteropTarget(SharedPointer env, jobject javaRef, - bool skipJavaRefRelease) : - env(env), javaRef(javaRef), skipJavaRefRelease(skipJavaRefRelease) - { - // No-op. - } - - InteropTarget::~InteropTarget() - { - if (!skipJavaRefRelease) - { - JniContext::Release(javaRef); - } - } - - int64_t InteropTarget::WriteTo(InteropMemory* mem, InputOperation& inOp, IgniteError& err) - { - BinaryTypeManager* metaMgr = env.Get()->GetTypeManager(); - - int32_t metaVer = metaMgr->GetVersion(); - - InteropOutputStream out(mem); - BinaryWriterImpl writer(&out, metaMgr); - - inOp.ProcessInput(writer); - - out.Synchronize(); - - if (metaMgr->IsUpdatedSince(metaVer)) - { - if (!metaMgr->ProcessPendingUpdates(err)) - return 0; - } - - return mem->PointerLong(); - } - - void InteropTarget::ReadFrom(InteropMemory* mem, OutputOperation& outOp) - { - InteropInputStream in(mem); - BinaryReaderImpl reader(&in); - - outOp.ProcessOutput(reader); - } - - void InteropTarget::ReadError(InteropMemory* mem, IgniteError& err) - { - InteropInputStream in(mem); - BinaryReaderImpl reader(&in); - - // Reading and skipping error class name. - reader.ReadObject(); - - std::string msg = reader.ReadObject(); - - err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); - } - - bool InteropTarget::OutOp(int32_t opType, InteropMemory& inMem, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = env.Get()->AllocateMemory(); - - int64_t outPtr = inMem.PointerLong(); - - if (outPtr) - { - int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, outPtr, &jniErr); - - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return res == 1; - } - - return false; - } - - bool InteropTarget::OutOp(int32_t opType, InputOperation& inOp, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = env.Get()->AllocateMemory(); - - int64_t outPtr = WriteTo(mem.Get(), inOp, err); - - if (outPtr) - { - int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, outPtr, &jniErr); - - IgniteError::SetError(jniErr.code, - jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return res == 1; - } - - return false; - } - - bool InteropTarget::OutOp(int32_t opType, IgniteError& err) - { - JniErrorInfo jniErr; - - int64_t res = env.Get()->Context()->TargetInLongOutLong(javaRef, opType, 0, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return res == 1; - - return false; - } - - bool InteropTarget::InOp(int32_t opType, OutputOperation& outOp, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer mem = env.Get()->AllocateMemory(); - - env.Get()->Context()->TargetOutStream(javaRef, opType, mem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), - jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - { - ReadFrom(mem.Get(), outOp); - - return true; - } - - return false; - } - - jobject InteropTarget::InOpObject(int32_t opType, IgniteError& err) - { - JniErrorInfo jniErr; - - jobject res = env.Get()->Context()->TargetOutObject(javaRef, opType, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - return res; - } - - void InteropTarget::OutInOp(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer outMem = env.Get()->AllocateMemory(); - SharedPointer inMem = env.Get()->AllocateMemory(); - - int64_t outPtr = WriteTo(outMem.Get(), inOp, err); - - if (outPtr) - { - env.Get()->Context()->TargetInStreamOutStream(javaRef, opType, outPtr, - inMem.Get()->PointerLong(), &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - ReadFrom(inMem.Get(), outOp); - } - } - - void InteropTarget::OutInOpX(int32_t opType, InputOperation& inOp, OutputOperation& outOp, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer outInMem = env.Get()->AllocateMemory(); - - int64_t outInPtr = WriteTo(outInMem.Get(), inOp, err); - - if (outInPtr) - { - int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, outInPtr, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS && res == OperationResult::AI_SUCCESS) - ReadFrom(outInMem.Get(), outOp); - else if (res == OperationResult::AI_NULL) - outOp.SetNull(); - else if (res == OperationResult::AI_ERROR) - ReadError(outInMem.Get(), err); - else - assert(false); - } - } - - InteropTarget::OperationResult::Type InteropTarget::InStreamOutLong(int32_t opType, - InteropMemory& outInMem, IgniteError& err) - { - JniErrorInfo jniErr; - - int64_t outInPtr = outInMem.PointerLong(); - - if (outInPtr) - { - int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, outInPtr, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - return static_cast(res); - } - - return OperationResult::AI_ERROR; - } - - int64_t InteropTarget::InStreamOutLong(int32_t opType, InputOperation& inOp, IgniteError& err) - { - JniErrorInfo jniErr; - - SharedPointer outMem = env.Get()->AllocateMemory(); - int64_t outPtr = WriteTo(outMem.Get(), inOp, err); - - if (outPtr) - { - int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, outPtr, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) - return res; - } - - return OperationResult::AI_ERROR; - } - - jobject InteropTarget::InStreamOutObject(int32_t opType, InteropMemory& outInMem, IgniteError& err) - { - JniErrorInfo jniErr; - - int64_t outInPtr = outInMem.PointerLong(); - - if (outInPtr) - { - jobject res = env.Get()->Context()->TargetInStreamOutObject(javaRef, opType, outInPtr, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - return res; - } - - return 0; - } - - void InteropTarget::InStreamOutStream(int32_t opType, - InteropMemory& inMem, InteropMemory& outMem, IgniteError& err) - { - JniErrorInfo jniErr; - - int64_t inPtr = inMem.PointerLong(); - int64_t outPtr = outMem.PointerLong(); - - if (inPtr && outPtr) - { - env.Get()->Context()->TargetInStreamOutStream(javaRef, opType, inPtr, outPtr, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - } - } - - int64_t InteropTarget::OutInOpLong(int32_t opType, int64_t val, IgniteError& err) - { - JniErrorInfo jniErr; - - int64_t res = env.Get()->Context()->TargetInLongOutLong(javaRef, opType, val, &jniErr); - - IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), jniErr.errMsg.c_str(), err); - - return res; - } - } - } - } +namespace ignite { +namespace odbc { +namespace impl { +namespace interop { +InteropTarget::InteropTarget(SharedPointer< IgniteEnvironment > env, + jobject javaRef) + : env(env), javaRef(javaRef), skipJavaRefRelease(false) { + // No-op. } + +InteropTarget::InteropTarget(SharedPointer< IgniteEnvironment > env, + jobject javaRef, bool skipJavaRefRelease) + : env(env), javaRef(javaRef), skipJavaRefRelease(skipJavaRefRelease) { + // No-op. +} + +InteropTarget::~InteropTarget() { + if (!skipJavaRefRelease) { + JniContext::Release(javaRef); + } +} + +int64_t InteropTarget::WriteTo(InteropMemory* mem, InputOperation& inOp, + IgniteError& err) { + BinaryTypeManager* metaMgr = env.Get()->GetTypeManager(); + + int32_t metaVer = metaMgr->GetVersion(); + + InteropOutputStream out(mem); + BinaryWriterImpl writer(&out, metaMgr); + + inOp.ProcessInput(writer); + + out.Synchronize(); + + if (metaMgr->IsUpdatedSince(metaVer)) { + if (!metaMgr->ProcessPendingUpdates(err)) + return 0; + } + + return mem->PointerLong(); +} + +void InteropTarget::ReadFrom(InteropMemory* mem, OutputOperation& outOp) { + InteropInputStream in(mem); + BinaryReaderImpl reader(&in); + + outOp.ProcessOutput(reader); +} + +void InteropTarget::ReadError(InteropMemory* mem, IgniteError& err) { + InteropInputStream in(mem); + BinaryReaderImpl reader(&in); + + // Reading and skipping error class name. + reader.ReadObject< std::string >(); + + std::string msg = reader.ReadObject< std::string >(); + + err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, msg.c_str()); +} + +bool InteropTarget::OutOp(int32_t opType, InteropMemory& inMem, + IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = env.Get()->AllocateMemory(); + + int64_t outPtr = inMem.PointerLong(); + + if (outPtr) { + int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, + outPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return res == 1; + } + + return false; +} + +bool InteropTarget::OutOp(int32_t opType, InputOperation& inOp, + IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = env.Get()->AllocateMemory(); + + int64_t outPtr = WriteTo(mem.Get(), inOp, err); + + if (outPtr) { + int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, + outPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return res == 1; + } + + return false; +} + +bool InteropTarget::OutOp(int32_t opType, IgniteError& err) { + JniErrorInfo jniErr; + + int64_t res = + env.Get()->Context()->TargetInLongOutLong(javaRef, opType, 0, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return res == 1; + + return false; +} + +bool InteropTarget::InOp(int32_t opType, OutputOperation& outOp, + IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > mem = env.Get()->AllocateMemory(); + + env.Get()->Context()->TargetOutStream(javaRef, opType, + mem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { + ReadFrom(mem.Get(), outOp); + + return true; + } + + return false; +} + +jobject InteropTarget::InOpObject(int32_t opType, IgniteError& err) { + JniErrorInfo jniErr; + + jobject res = env.Get()->Context()->TargetOutObject(javaRef, opType, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + return res; +} + +void InteropTarget::OutInOp(int32_t opType, InputOperation& inOp, + OutputOperation& outOp, IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > outMem = env.Get()->AllocateMemory(); + SharedPointer< InteropMemory > inMem = env.Get()->AllocateMemory(); + + int64_t outPtr = WriteTo(outMem.Get(), inOp, err); + + if (outPtr) { + env.Get()->Context()->TargetInStreamOutStream( + javaRef, opType, outPtr, inMem.Get()->PointerLong(), &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + ReadFrom(inMem.Get(), outOp); + } +} + +void InteropTarget::OutInOpX(int32_t opType, InputOperation& inOp, + OutputOperation& outOp, IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > outInMem = env.Get()->AllocateMemory(); + + int64_t outInPtr = WriteTo(outInMem.Get(), inOp, err); + + if (outInPtr) { + int64_t res = env.Get()->Context()->TargetInStreamOutLong( + javaRef, opType, outInPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS + && res == OperationResult::AI_SUCCESS) + ReadFrom(outInMem.Get(), outOp); + else if (res == OperationResult::AI_NULL) + outOp.SetNull(); + else if (res == OperationResult::AI_ERROR) + ReadError(outInMem.Get(), err); + else + assert(false); + } +} + +InteropTarget::OperationResult::Type InteropTarget::InStreamOutLong( + int32_t opType, InteropMemory& outInMem, IgniteError& err) { + JniErrorInfo jniErr; + + int64_t outInPtr = outInMem.PointerLong(); + + if (outInPtr) { + int64_t res = env.Get()->Context()->TargetInStreamOutLong( + javaRef, opType, outInPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + return static_cast< OperationResult::Type >(res); + } + + return OperationResult::AI_ERROR; +} + +int64_t InteropTarget::InStreamOutLong(int32_t opType, InputOperation& inOp, + IgniteError& err) { + JniErrorInfo jniErr; + + SharedPointer< InteropMemory > outMem = env.Get()->AllocateMemory(); + int64_t outPtr = WriteTo(outMem.Get(), inOp, err); + + if (outPtr) { + int64_t res = env.Get()->Context()->TargetInStreamOutLong(javaRef, opType, + outPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + if (jniErr.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) + return res; + } + + return OperationResult::AI_ERROR; +} + +jobject InteropTarget::InStreamOutObject(int32_t opType, + InteropMemory& outInMem, + IgniteError& err) { + JniErrorInfo jniErr; + + int64_t outInPtr = outInMem.PointerLong(); + + if (outInPtr) { + jobject res = env.Get()->Context()->TargetInStreamOutObject( + javaRef, opType, outInPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + return res; + } + + return 0; +} + +void InteropTarget::InStreamOutStream(int32_t opType, InteropMemory& inMem, + InteropMemory& outMem, IgniteError& err) { + JniErrorInfo jniErr; + + int64_t inPtr = inMem.PointerLong(); + int64_t outPtr = outMem.PointerLong(); + + if (inPtr && outPtr) { + env.Get()->Context()->TargetInStreamOutStream(javaRef, opType, inPtr, + outPtr, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + } +} + +int64_t InteropTarget::OutInOpLong(int32_t opType, int64_t val, + IgniteError& err) { + JniErrorInfo jniErr; + + int64_t res = + env.Get()->Context()->TargetInLongOutLong(javaRef, opType, val, &jniErr); + + IgniteError::SetError(jniErr.code, jniErr.errCls.c_str(), + jniErr.errMsg.c_str(), err); + + return res; +} +} // namespace interop +} // namespace impl +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/jni/database_metadata.cpp b/src/odbc/src/jni/database_metadata.cpp index 86e848a05..1d31b089d 100644 --- a/src/odbc/src/jni/database_metadata.cpp +++ b/src/odbc/src/jni/database_metadata.cpp @@ -34,7 +34,7 @@ SharedPointer< ResultSet > DatabaseMetaData::GetTables( const boost::optional< std::string >& catalog, const boost::optional< std::string >& schemaPattern, const std::string& tableNamePattern, - const boost::optional < std::vector< std::string > >& types, + const boost::optional< std::vector< std::string > >& types, JniErrorInfo& errInfo) { SharedPointer< GlobalJObject > resultSet; JniErrorCode success = _jniContext.Get()->DatabaseMetaDataGetTables( @@ -78,8 +78,8 @@ SharedPointer< ResultSet > DatabaseMetaData::GetPrimaryKeys( SharedPointer< ResultSet > DatabaseMetaData::GetImportedKeys( const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, JniErrorInfo& errInfo) { + const boost::optional< std::string >& schema, const std::string& table, + JniErrorInfo& errInfo) { SharedPointer< GlobalJObject > resultSet; const std::vector< std::string > types; JniErrorCode success = _jniContext.Get()->DatabaseMetaDataGetImportedKeys( diff --git a/src/odbc/src/jni/documentdb_connection.cpp b/src/odbc/src/jni/documentdb_connection.cpp index da0c89503..5b3abf727 100644 --- a/src/odbc/src/jni/documentdb_connection.cpp +++ b/src/odbc/src/jni/documentdb_connection.cpp @@ -113,7 +113,8 @@ DocumentDbConnection::GetConnectionProperties(JniErrorInfo& errInfo) { return nullptr; } SharedPointer< GlobalJObject > connectionProperties; - JniErrorCode success = _jniContext.Get()->DocumentDbConnectionGetConnectionProperties( + JniErrorCode success = + _jniContext.Get()->DocumentDbConnectionGetConnectionProperties( _connection, connectionProperties, errInfo); if (success != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { return nullptr; @@ -122,8 +123,7 @@ DocumentDbConnection::GetConnectionProperties(JniErrorInfo& errInfo) { } SharedPointer< DocumentDbDatabaseMetadata > -DocumentDbConnection::GetDatabaseMetadata( - JniErrorInfo& errInfo) { +DocumentDbConnection::GetDatabaseMetadata(JniErrorInfo& errInfo) { if (!_connection.IsValid()) { errInfo = JniErrorInfo(JniErrorCode::IGNITE_JNI_ERR_GENERIC, "", "Connection must be set."); diff --git a/src/odbc/src/jni/documentdb_connection_properties.cpp b/src/odbc/src/jni/documentdb_connection_properties.cpp index fe714f73b..7429f7746 100644 --- a/src/odbc/src/jni/documentdb_connection_properties.cpp +++ b/src/odbc/src/jni/documentdb_connection_properties.cpp @@ -17,8 +17,6 @@ namespace ignite { namespace odbc { -namespace jni { - -} // namespace jni +namespace jni {} // namespace jni } // namespace odbc } // namespace ignite diff --git a/src/odbc/src/jni/documentdb_database_metadata.cpp b/src/odbc/src/jni/documentdb_database_metadata.cpp index fe714f73b..7429f7746 100644 --- a/src/odbc/src/jni/documentdb_database_metadata.cpp +++ b/src/odbc/src/jni/documentdb_database_metadata.cpp @@ -17,8 +17,6 @@ namespace ignite { namespace odbc { -namespace jni { - -} // namespace jni +namespace jni {} // namespace jni } // namespace odbc } // namespace ignite diff --git a/src/odbc/src/jni/documentdb_mql_query_context.cpp b/src/odbc/src/jni/documentdb_mql_query_context.cpp index ec489259c..7429f7746 100644 --- a/src/odbc/src/jni/documentdb_mql_query_context.cpp +++ b/src/odbc/src/jni/documentdb_mql_query_context.cpp @@ -15,10 +15,8 @@ * limitations under the License. */ - namespace ignite { - namespace odbc { - namespace jni { - - } // namespace jni - } // namespace odbc - } // namespace ignite +namespace ignite { +namespace odbc { +namespace jni {} // namespace jni +} // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/jni/documentdb_query_mapping_service.cpp b/src/odbc/src/jni/documentdb_query_mapping_service.cpp index d60df69d9..744af3434 100644 --- a/src/odbc/src/jni/documentdb_query_mapping_service.cpp +++ b/src/odbc/src/jni/documentdb_query_mapping_service.cpp @@ -72,7 +72,8 @@ bool ReadListOfString(SharedPointer< JniContext >& _jniContext, if (success != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { return false; } - std::string value = _jniContext.Get()->JavaStringToCppString(operation, errInfo); + std::string value = + _jniContext.Get()->JavaStringToCppString(operation, errInfo); if (errInfo.code != JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { return false; } diff --git a/src/odbc/src/jni/java.cpp b/src/odbc/src/jni/java.cpp index 06a6bdb8b..72a91c68b 100644 --- a/src/odbc/src/jni/java.cpp +++ b/src/odbc/src/jni/java.cpp @@ -118,7 +118,6 @@ void BuildJvmOptions(const std::string& cp, std::vector< char* >& opts, int xms, opts.reserve(REQ_OPTS_CNT + JAVA9_OPTS_CNT); - // 1. Set calcite default charset to utf8. opts.push_back(CopyChars("-Dcalcite.default.charset=utf8")); @@ -266,9 +265,10 @@ JniMethod const M_DATABASE_META_DATA_GET_PRIMARY_KEYS = "String;)Ljava/sql/ResultSet;", false); JniMethod const M_DATABASE_META_DATA_GET_IMPORTED_KEYS = - JniMethod("getImportedKeys", + JniMethod("getImportedKeys", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" - "String;)Ljava/sql/ResultSet;", false); + "String;)Ljava/sql/ResultSet;", + false); const char* const C_DOCUMENTDB_CONNECTION = "software/amazon/documentdb/jdbc/DocumentDbConnection"; @@ -672,10 +672,10 @@ void JniMembers::Initialize(JNIEnv* env) { FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_TABLES); m_DatabaseMetaDataGetColumns = FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_COLUMNS); - m_DatabaseMetaDataGetPrimaryKeys = - FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_PRIMARY_KEYS); - m_DatabaseMetaDataGetImportedKeys = - FindMethod(env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_IMPORTED_KEYS); + m_DatabaseMetaDataGetPrimaryKeys = FindMethod( + env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_PRIMARY_KEYS); + m_DatabaseMetaDataGetImportedKeys = FindMethod( + env, c_DatabaseMetaData, M_DATABASE_META_DATA_GET_IMPORTED_KEYS); c_Connection = FindClass(env, C_JAVA_SQL_CONNECTION); m_ConnectionClose = @@ -1094,7 +1094,7 @@ JniErrorCode JniContext::DriverManagerGetConnection( // TODO enable string logging and hide the user password. // https://bitquill.atlassian.net/browse/AD-702 - //LOG_INFO_MSG("Connection String: [" << connectionString << "]"); + // LOG_INFO_MSG("Connection String: [" << connectionString << "]"); jstring jConnectionString = env->NewStringUTF(connectionString); jobject result = env->CallStaticObjectMethod( @@ -1108,7 +1108,7 @@ JniErrorCode JniContext::DriverManagerGetConnection( } env->DeleteLocalRef(jConnectionString); - + LOG_DEBUG_MSG("DriverManagerGetConnection exiting"); return errInfo.code; @@ -1366,7 +1366,7 @@ JniErrorCode JniContext::DatabaseMetaDataGetTables( const boost::optional< std::string >& catalog, const boost::optional< std::string >& schemaPattern, const std::string& tableNamePattern, - const boost::optional < std::vector< std::string > >& types, + const boost::optional< std::vector< std::string > >& types, SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo) { LOG_DEBUG_MSG("DatabaseMetaDataGetTables is called"); @@ -1398,8 +1398,7 @@ JniErrorCode JniContext::DatabaseMetaDataGetTables( env->SetObjectArrayElement(jTypes, i, env->NewStringUTF((*types)[i].c_str())); } - } - else { + } else { jTypes = nullptr; } @@ -1489,8 +1488,7 @@ JniErrorCode JniContext::DatabaseMetaDataGetPrimaryKeys( const boost::optional< std::string >& catalog, const boost::optional< std::string >& schema, const boost::optional< std::string >& table, - SharedPointer< GlobalJObject >& resultSet, - JniErrorInfo& errInfo) { + SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo) { LOG_DEBUG_MSG("DatabaseMetaDataGetPrimaryKeys is called"); if (databaseMetaData.Get() == nullptr) { @@ -1540,9 +1538,8 @@ JniErrorCode JniContext::DatabaseMetaDataGetPrimaryKeys( JniErrorCode JniContext::DatabaseMetaDataGetImportedKeys( const SharedPointer< GlobalJObject >& databaseMetaData, const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, SharedPointer< GlobalJObject >& resultSet, - JniErrorInfo& errInfo) { + const boost::optional< std::string >& schema, const std::string& table, + SharedPointer< GlobalJObject >& resultSet, JniErrorInfo& errInfo) { LOG_DEBUG_MSG("DatabaseMetaDataGetImportedKeys is called"); if (databaseMetaData.Get() == nullptr) { @@ -1564,10 +1561,10 @@ JniErrorCode JniContext::DatabaseMetaDataGetImportedKeys( jstring jSchema = schema ? env->NewStringUTF(schema->c_str()) : nullptr; jstring jTable = env->NewStringUTF(table.c_str()); - jobject result = env->CallObjectMethod( - databaseMetaData.Get()->GetRef(), - jvm->GetMembers().m_DatabaseMetaDataGetImportedKeys, jCatalog, jSchema, - jTable); + jobject result = + env->CallObjectMethod(databaseMetaData.Get()->GetRef(), + jvm->GetMembers().m_DatabaseMetaDataGetImportedKeys, + jCatalog, jSchema, jTable); ExceptionCheck(env, &errInfo); env->DeleteLocalRef(jCatalog); @@ -1713,7 +1710,7 @@ JniErrorCode JniContext::ResultSetGetString( resultSet.Get()->GetRef(), jvm->GetMembers().m_ResultSetGetStringByName, jColumnName); ExceptionCheck(env, &errInfo); - + env->DeleteLocalRef(jColumnName); if (errInfo.code == JniErrorCode::IGNITE_JNI_ERR_SUCCESS) { @@ -2703,7 +2700,6 @@ jobject JniContext::Acquire(jobject obj) { return nullptr; } - if (env) { jobject obj0 = env->NewGlobalRef(obj); @@ -2756,15 +2752,14 @@ JNIEnv* JniContext::Attach(JniErrorInfo& errInfo) { if (attachRes == JNI_OK) { AttachHelper::OnThreadAttach(); errInfo.code = JniErrorCode::IGNITE_JNI_ERR_SUCCESS; - } - else { + } else { errInfo.code = JniErrorCode::IGNITE_JNI_ERR_JVM_ATTACH; errInfo.errMsg = "Failed to connect to JVM"; LOG_ERROR_MSG(errInfo.errMsg); if (hnds.error) - hnds.error(hnds.target, errInfo.code, nullptr, - 0, nullptr, 0, nullptr, 0, nullptr, 0); + hnds.error(hnds.target, errInfo.code, nullptr, 0, nullptr, 0, nullptr, 0, + nullptr, 0); } LOG_DEBUG_MSG("Attach exiting"); diff --git a/src/odbc/src/jni/jdbc_column_metadata.cpp b/src/odbc/src/jni/jdbc_column_metadata.cpp index 43c406d9c..7429f7746 100644 --- a/src/odbc/src/jni/jdbc_column_metadata.cpp +++ b/src/odbc/src/jni/jdbc_column_metadata.cpp @@ -17,7 +17,6 @@ namespace ignite { namespace odbc { -namespace jni { -} // namespace jni +namespace jni {} // namespace jni } // namespace odbc } // namespace ignite diff --git a/src/odbc/src/jni/os/win/utils.cpp b/src/odbc/src/jni/os/win/utils.cpp index f028369cb..4a86b682f 100644 --- a/src/odbc/src/jni/os/win/utils.cpp +++ b/src/odbc/src/jni/os/win/utils.cpp @@ -389,4 +389,4 @@ BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, } return TRUE; -} \ No newline at end of file +} diff --git a/src/odbc/src/log.cpp b/src/odbc/src/log.cpp index 8cbd8fc9f..084c7aeff 100644 --- a/src/odbc/src/log.cpp +++ b/src/odbc/src/log.cpp @@ -14,9 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#if defined(__unix__) || defined(__unix) || \ - (defined(__APPLE__) && defined(__MACH__)) -# define PREDEF_PLATFORM_UNIX_OR_APPLE 1 +#if defined(__unix__) || defined(__unix) \ + || (defined(__APPLE__) && defined(__MACH__)) +#define PREDEF_PLATFORM_UNIX_OR_APPLE 1 #endif #ifdef PREDEF_PLATFORM_UNIX_OR_APPLE @@ -105,8 +105,7 @@ void Logger::SetLogPath(const std::string& path) { if (!common::IsValidDirectory(path)) { // if path is not a valid directory, ignore passed path. std::cerr << "Error during setting log path: \"" << path - << "\" is not a valid directory. Log path is not updated" - << '\n'; + << "\" is not a valid directory. Log path is not updated" << '\n'; std::cout << "Current Log Path: \"" << logPath << "\" \n"; return; } @@ -142,7 +141,8 @@ bool Logger::EnableLog() { if (stream == nullptr) SetLogStream(&fileStream); - if (!IsEnabled() && logLevel != LogLevel::Type::OFF && stream == &fileStream) { + if (!IsEnabled() && logLevel != LogLevel::Type::OFF + && stream == &fileStream) { if (logFileName.empty()) { logFileName = CreateFileName(); std::stringstream tmpStream; @@ -150,7 +150,8 @@ bool Logger::EnableLog() { logFilePath = tmpStream.str(); if (common::FileExists(logFilePath)) { std::cout << "log file at \"" << logFilePath - << "\" already exists. Appending logs to the log file." << '\n'; + << "\" already exists. Appending logs to the log file." + << '\n'; } std::cout << "logFilePath: " << logFilePath << '\n'; } diff --git a/src/odbc/src/log_level.cpp b/src/odbc/src/log_level.cpp index 57d24c448..8ec0f6b6b 100644 --- a/src/odbc/src/log_level.cpp +++ b/src/odbc/src/log_level.cpp @@ -20,8 +20,7 @@ namespace ignite { namespace odbc { -LogLevel::Type LogLevel::FromString(const std::string& val, - Type dflt) { +LogLevel::Type LogLevel::FromString(const std::string& val, Type dflt) { std::string lowerVal = common::ToLower(val); common::StripSurroundingWhitespaces(lowerVal); diff --git a/src/odbc/src/meta/column_meta.cpp b/src/odbc/src/meta/column_meta.cpp index c960dce7e..d80c25a5c 100644 --- a/src/odbc/src/meta/column_meta.cpp +++ b/src/odbc/src/meta/column_meta.cpp @@ -275,8 +275,7 @@ bool ColumnMeta::GetAttribute(uint16_t fieldId, SqlLen& value) const { } case SQL_DESC_CASE_SENSITIVE: { - if (dataType - && isCharType(*dataType)) + if (dataType && isCharType(*dataType)) value = SQL_TRUE; else value = SQL_FALSE; diff --git a/src/odbc/src/meta/foreign_key_meta.cpp b/src/odbc/src/meta/foreign_key_meta.cpp index b2d71a376..b0ff913aa 100644 --- a/src/odbc/src/meta/foreign_key_meta.cpp +++ b/src/odbc/src/meta/foreign_key_meta.cpp @@ -43,7 +43,8 @@ const std::string FK_NAME = "FK_NAME"; const std::string PK_NAME = "PK_NAME"; const std::string DEFERRABILITY = "DEFERRABILITY"; -void ForeignKeyMeta::Read(SharedPointer< ResultSet >& resultSet, JniErrorInfo& errInfo) { +void ForeignKeyMeta::Read(SharedPointer< ResultSet >& resultSet, + JniErrorInfo& errInfo) { boost::optional< int > intDataType; resultSet.Get()->GetString(PKTABLE_CAT, PKCatalogName, errInfo); resultSet.Get()->GetString(PKTABLE_SCHEM, PKSchemaName, errInfo); @@ -62,7 +63,7 @@ void ForeignKeyMeta::Read(SharedPointer< ResultSet >& resultSet, JniErrorInfo& e } void ReadForeignKeysColumnMetaVector(SharedPointer< ResultSet >& resultSet, - ForeignKeyMetaVector& meta) { + ForeignKeyMetaVector& meta) { meta.clear(); if (!resultSet.IsValid()) { diff --git a/src/odbc/src/meta/primary_key_meta.cpp b/src/odbc/src/meta/primary_key_meta.cpp index 28a44e880..53621d100 100644 --- a/src/odbc/src/meta/primary_key_meta.cpp +++ b/src/odbc/src/meta/primary_key_meta.cpp @@ -35,7 +35,6 @@ const std::string COLUMN_NAME = "COLUMN_NAME"; const std::string KEY_SEQ = "KEY_SEQ"; const std::string PK_NAME = "PK_NAME"; - void PrimaryKeyMeta::Read(SharedPointer< ResultSet >& resultSet, JniErrorInfo& errInfo) { resultSet.Get()->GetString(TABLE_CAT, catalog, errInfo); diff --git a/src/odbc/src/odbc.cpp b/src/odbc/src/odbc.cpp index 806f8810a..da07a05f6 100644 --- a/src/odbc/src/odbc.cpp +++ b/src/odbc/src/odbc.cpp @@ -813,8 +813,8 @@ SQLRETURN SQLColAttribute(SQLHSTMT stmt, SQLUSMALLINT columnNum, } statement->GetColumnAttribute(columnNum, fieldId, - reinterpret_cast< SQLWCHAR* >(strAttr), bufferLen, - strAttrLen, numericAttr); + reinterpret_cast< SQLWCHAR* >(strAttr), + bufferLen, strAttrLen, numericAttr); LOG_DEBUG_MSG("SQLColAttribute exiting"); @@ -920,8 +920,8 @@ SQLRETURN SQLForeignKeys( SQLSMALLINT foreignSchemaNameLen, SQLWCHAR* foreignTableName, SQLSMALLINT foreignTableNameLen) { using odbc::Statement; - using odbc::utility::SqlStringToString; using odbc::utility::SqlStringToOptString; + using odbc::utility::SqlStringToString; LOG_DEBUG_MSG("SQLForeignKeys called"); @@ -1201,7 +1201,8 @@ SQLRETURN SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, if (!msgBuffer || msgBufferLen < static_cast< SQLSMALLINT >(errMsg.size() + 1)) { if (!msgLen) { - LOG_ERROR_MSG("SQLGetDiagRec exiting with SQL_ERROR. msgLen must not be NULL."); + LOG_ERROR_MSG( + "SQLGetDiagRec exiting with SQL_ERROR. msgLen must not be NULL."); return SQL_ERROR; } diff --git a/src/odbc/src/query/column_metadata_query.cpp b/src/odbc/src/query/column_metadata_query.cpp index 2aee5ebc0..472db293b 100644 --- a/src/odbc/src/query/column_metadata_query.cpp +++ b/src/odbc/src/query/column_metadata_query.cpp @@ -101,12 +101,11 @@ struct ResultColumn { namespace ignite { namespace odbc { namespace query { -ColumnMetadataQuery::ColumnMetadataQuery(diagnostic::DiagnosableAdapter& diag, - Connection& connection, - const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const std::string& column) +ColumnMetadataQuery::ColumnMetadataQuery( + diagnostic::DiagnosableAdapter& diag, Connection& connection, + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const std::string& column) : Query(diag, QueryType::COLUMN_METADATA), connection(connection), catalog(catalog), @@ -401,8 +400,7 @@ SqlResult::Type ColumnMetadataQuery::MakeRequestGetColumnsMeta() { << meta[i].GetColumnName().get_value_or("") << "\n[" << i << "] ColumnType: " << static_cast< int32_t >(*meta[i].GetDataType())); - } - else { + } else { LOG_MSG("\n[" << i << "] SchemaName: " << meta[i].GetSchemaName().get_value_or("") << "\n[" << i << "] TableName: " diff --git a/src/odbc/src/query/foreign_keys_query.cpp b/src/odbc/src/query/foreign_keys_query.cpp index 2ca7bbf8c..0874bafb4 100644 --- a/src/odbc/src/query/foreign_keys_query.cpp +++ b/src/odbc/src/query/foreign_keys_query.cpp @@ -80,11 +80,10 @@ struct ResultColumn { namespace ignite { namespace odbc { namespace query { -ForeignKeysQuery::ForeignKeysQuery(diagnostic::DiagnosableAdapter& diag, - Connection& connection, - const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table) +ForeignKeysQuery::ForeignKeysQuery( + diagnostic::DiagnosableAdapter& diag, Connection& connection, + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table) : Query(diag, QueryType::FOREIGN_KEYS), connection(connection), catalog(catalog), @@ -322,8 +321,7 @@ SqlResult::Type ForeignKeysQuery::MakeRequestGetForeignKeysMeta() { << meta[i].GetPKTableName().get_value_or("") << "\n[" << i << "] PKColumnName: " << meta[i].GetPKColumnName().get_value_or("") << "\n[" - << i << "] KeySeq: " - << meta[i].GetKeySeq()); + << i << "] KeySeq: " << meta[i].GetKeySeq()); } return SqlResult::AI_SUCCESS; diff --git a/src/odbc/src/query/primary_keys_query.cpp b/src/odbc/src/query/primary_keys_query.cpp index e54d8fbba..e00e5fa7d 100644 --- a/src/odbc/src/query/primary_keys_query.cpp +++ b/src/odbc/src/query/primary_keys_query.cpp @@ -49,11 +49,11 @@ struct ResultColumn { namespace ignite { namespace odbc { namespace query { -PrimaryKeysQuery::PrimaryKeysQuery(diagnostic::DiagnosableAdapter& diag, - Connection& connection, - const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const boost::optional< std::string >& table) +PrimaryKeysQuery::PrimaryKeysQuery( + diagnostic::DiagnosableAdapter& diag, Connection& connection, + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, + const boost::optional< std::string >& table) : Query(diag, QueryType::PRIMARY_KEYS), connection(connection), catalog(catalog), @@ -231,12 +231,12 @@ SqlResult::Type PrimaryKeysQuery::MakeRequestGetPrimaryKeysMeta() { for (size_t i = 0; i < meta.size(); ++i) { LOG_DEBUG_MSG("\n[" << i << "] SchemaName: " - << meta[i].GetSchemaName().get_value_or("") << "\n[" << i - << "] TableName: " - << meta[i].GetTableName().get_value_or("") << "\n[" << i - << "] ColumnName: " - << meta[i].GetColumnName().get_value_or("") << "\n[" << i - << "] ColumnType: not available"); + << meta[i].GetSchemaName().get_value_or("") << "\n[" + << i << "] TableName: " + << meta[i].GetTableName().get_value_or("") << "\n[" << i + << "] ColumnName: " + << meta[i].GetColumnName().get_value_or("") << "\n[" + << i << "] ColumnType: not available"); } return SqlResult::AI_SUCCESS; } diff --git a/src/odbc/src/query/table_metadata_query.cpp b/src/odbc/src/query/table_metadata_query.cpp index 66365fbad..c3beb36e1 100644 --- a/src/odbc/src/query/table_metadata_query.cpp +++ b/src/odbc/src/query/table_metadata_query.cpp @@ -60,12 +60,11 @@ struct ResultColumn { namespace ignite { namespace odbc { namespace query { -TableMetadataQuery::TableMetadataQuery(diagnostic::DiagnosableAdapter& diag, - Connection& connection, - const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const boost::optional< std::string >& tableType) +TableMetadataQuery::TableMetadataQuery( + diagnostic::DiagnosableAdapter& diag, Connection& connection, + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const boost::optional< std::string >& tableType) : Query(diag, QueryType::TABLE_METADATA), connection(connection), catalog(catalog), diff --git a/src/odbc/src/statement.cpp b/src/odbc/src/statement.cpp index 23aac36af..4bba11c58 100644 --- a/src/odbc/src/statement.cpp +++ b/src/odbc/src/statement.cpp @@ -390,7 +390,7 @@ SqlResult::Type Statement::InternalGetAttribute(int attr, void* buf, SQLINTEGER, case SQL_ATTR_ROW_ARRAY_SIZE: { SQLINTEGER* val = reinterpret_cast< SQLINTEGER* >(buf); - *val = static_cast< SQLINTEGER >(rowArraySize); + *val = static_cast< SQLINTEGER >(rowArraySize); if (valueLen) *valueLen = SQL_IS_INTEGER; @@ -657,18 +657,18 @@ SqlResult::Type Statement::InternalExecuteSqlQuery() { return currentQuery->Execute(); } -void Statement::ExecuteGetColumnsMetaQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const std::string& column) { +void Statement::ExecuteGetColumnsMetaQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const std::string& column) { IGNITE_ODBC_API_CALL( InternalExecuteGetColumnsMetaQuery(catalog, schema, table, column)); } SqlResult::Type Statement::InternalExecuteGetColumnsMetaQuery( const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, const std::string& column) { + const boost::optional< std::string >& schema, const std::string& table, + const std::string& column) { if (currentQuery.get()) currentQuery->Close(); @@ -683,10 +683,10 @@ SqlResult::Type Statement::InternalExecuteGetColumnsMetaQuery( return currentQuery->Execute(); } -void Statement::ExecuteGetTablesMetaQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const std::string& table, - const boost::optional< std::string >& tableType) { +void Statement::ExecuteGetTablesMetaQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, const std::string& table, + const boost::optional< std::string >& tableType) { IGNITE_ODBC_API_CALL( InternalExecuteGetTablesMetaQuery(catalog, schema, table, tableType)); } @@ -704,18 +704,19 @@ SqlResult::Type Statement::InternalExecuteGetTablesMetaQuery( return currentQuery->Execute(); } -void Statement::ExecuteGetForeignKeysQuery(const std::string& primaryCatalog, - const std::string& primarySchema, - const std::string& primaryTable, - const boost::optional< std::string >& foreignCatalog, - const boost::optional< std::string >& foreignSchema, - const std::string& foreignTable) { +void Statement::ExecuteGetForeignKeysQuery( + const std::string& primaryCatalog, const std::string& primarySchema, + const std::string& primaryTable, + const boost::optional< std::string >& foreignCatalog, + const boost::optional< std::string >& foreignSchema, + const std::string& foreignTable) { IGNITE_ODBC_API_CALL(InternalExecuteGetForeignKeysQuery( primaryCatalog, primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable)); } -SqlResult::Type Statement::InternalExecuteGetForeignKeysQuery(const std::string& primaryCatalog, const std::string& primarySchema, +SqlResult::Type Statement::InternalExecuteGetForeignKeysQuery( + const std::string& primaryCatalog, const std::string& primarySchema, const std::string& primaryTable, const boost::optional< std::string >& foreignCatalog, const boost::optional< std::string >& foreignSchema, @@ -729,9 +730,10 @@ SqlResult::Type Statement::InternalExecuteGetForeignKeysQuery(const std::string& return currentQuery->Execute(); } -void Statement::ExecuteGetPrimaryKeysQuery(const boost::optional< std::string >& catalog, - const boost::optional< std::string >& schema, - const boost::optional< std::string >& table) { +void Statement::ExecuteGetPrimaryKeysQuery( + const boost::optional< std::string >& catalog, + const boost::optional< std::string >& schema, + const boost::optional< std::string >& table) { IGNITE_ODBC_API_CALL( InternalExecuteGetPrimaryKeysQuery(catalog, schema, table)); } @@ -1169,17 +1171,16 @@ SqlResult::Type Statement::InternalDescribeParam(int16_t paramNum, boost::optional< int16_t > sqlType = type_traits::BinaryToSqlType(type); if (dataType && sqlType) - *dataType = *sqlType; + *dataType = *sqlType; - boost::optional< int32_t > colSize = - type_traits::BinaryTypeColumnSize(type); + boost::optional< int32_t > colSize = type_traits::BinaryTypeColumnSize(type); if (paramSize && colSize) - *paramSize = *colSize; + *paramSize = *colSize; boost::optional< int16_t > decDigits = - type_traits::BinaryTypeDecimalDigits(type); + type_traits::BinaryTypeDecimalDigits(type); if (decimalDigits && decDigits) - *decimalDigits = *decDigits; + *decimalDigits = *decDigits; if (nullable) *nullable = type_traits::BinaryTypeNullability(type); diff --git a/src/odbc/src/time.cpp b/src/odbc/src/time.cpp index 0d646dc03..200c89155 100644 --- a/src/odbc/src/time.cpp +++ b/src/odbc/src/time.cpp @@ -69,4 +69,4 @@ bool operator>=(const Time& val1, const Time& val2) { return val1.milliseconds >= val2.milliseconds; } } // namespace odbc -} // namespace ignite \ No newline at end of file +} // namespace ignite diff --git a/src/odbc/src/timestamp.cpp b/src/odbc/src/timestamp.cpp index 2fbe8128a..1d3e26547 100644 --- a/src/odbc/src/timestamp.cpp +++ b/src/odbc/src/timestamp.cpp @@ -91,4 +91,4 @@ bool operator>=(const Timestamp& val1, const Timestamp& val2) { && val1.fractionNs >= val2.fractionNs); } } // namespace odbc -} // namespace ignite \ No newline at end of file +} // namespace ignite diff --git a/src/odbc/src/type_traits.cpp b/src/odbc/src/type_traits.cpp index 6e865bdb1..bea2e9e9c 100644 --- a/src/odbc/src/type_traits.cpp +++ b/src/odbc/src/type_traits.cpp @@ -196,7 +196,7 @@ const boost::optional< std::string > BinaryTypeToSqlTypeName( } } -bool IsApplicationTypeSupported(boost::optional type) { +bool IsApplicationTypeSupported(boost::optional< int16_t > type) { if (type) return ToDriverType(*type) != OdbcNativeType::AI_UNSUPPORTED; else @@ -256,7 +256,7 @@ bool IsSqlTypeSupported(boost::optional< int16_t > type) { * JDBC side, the change should be reflected under this function as * well. */ -boost::optional SqlTypeToBinary(boost::optional< int16_t > sqlType) { +boost::optional< int16_t > SqlTypeToBinary(boost::optional< int16_t > sqlType) { if (!sqlType) return boost::none; switch (*sqlType) { @@ -406,7 +406,8 @@ OdbcNativeType::Type ToDriverType(int16_t type) { * JDBC side, the change should be reflected under this function as * well. */ -boost::optional BinaryToSqlType(boost::optional binaryType) { +boost::optional< int16_t > BinaryToSqlType( + boost::optional< int16_t > binaryType) { if (!binaryType) return boost::none; switch (*binaryType) { @@ -506,7 +507,7 @@ boost::optional< std::string > NullabilityToIsNullable( } } -boost::optional SqlTypeDisplaySize(boost::optional type) { +boost::optional< int32_t > SqlTypeDisplaySize(boost::optional< int16_t > type) { if (!type) return boost::none; switch (*type) { @@ -563,7 +564,8 @@ boost::optional SqlTypeDisplaySize(boost::optional type) { } } -boost::optional BinaryTypeDisplaySize(boost::optional type) { +boost::optional< int32_t > BinaryTypeDisplaySize( + boost::optional< int16_t > type) { boost::optional< int16_t > sqlType = BinaryToSqlType(type); return SqlTypeDisplaySize(sqlType); @@ -626,13 +628,15 @@ boost::optional< int32_t > SqlTypeColumnSize(boost::optional< int16_t > type) { } } -boost::optional BinaryTypeColumnSize(boost::optional type) { +boost::optional< int32_t > BinaryTypeColumnSize( + boost::optional< int16_t > type) { boost::optional< int16_t > sqlType = BinaryToSqlType(type); return SqlTypeColumnSize(sqlType); } -boost::optional< int32_t > SqlTypeTransferLength(boost::optional< int16_t > type) { +boost::optional< int32_t > SqlTypeTransferLength( + boost::optional< int16_t > type) { if (!type) return boost::none; switch (*type) { @@ -721,9 +725,11 @@ boost::optional< int32_t > BinaryTypeNumPrecRadix( return SqlTypeNumPrecRadix(sqlType); } -boost::optional< int16_t > SqlTypeDecimalDigits(boost::optional< int16_t > type) { +boost::optional< int16_t > SqlTypeDecimalDigits( + boost::optional< int16_t > type) { // Not implemented for the NUMERIC and DECIMAL data types. - // All exact numeric types other than SQL_DECIMAL and SQL_NUMERIC should return 0 + // All exact numeric types other than SQL_DECIMAL and SQL_NUMERIC should + // return 0 if (!type) return boost::none; switch (*type) { @@ -772,7 +778,7 @@ boost::optional< int32_t > BinaryTypeCharOctetLength( return SqlTypeCharOctetLength(sqlType); } -bool SqlTypeUnsigned(boost::optional type) { +bool SqlTypeUnsigned(boost::optional< int16_t > type) { if (!type) return false; switch (*type) { @@ -791,7 +797,7 @@ bool SqlTypeUnsigned(boost::optional type) { } } -bool BinaryTypeUnsigned(boost::optional type) { +bool BinaryTypeUnsigned(boost::optional< int16_t > type) { boost::optional< int16_t > sqlType = BinaryToSqlType(type); return SqlTypeUnsigned(sqlType); diff --git a/src/odbc/src/utility.cpp b/src/odbc/src/utility.cpp index 458cadc71..b629729ab 100644 --- a/src/odbc/src/utility.cpp +++ b/src/odbc/src/utility.cpp @@ -66,7 +66,7 @@ size_t CopyUtf8StringToSqlCharString(const char* inBuffer, SQLCHAR* outBuffer, return outBufferLenActual; } -template< typename OutCharT > +template < typename OutCharT > size_t CopyUtf8StringToWcharString(const char* inBuffer, OutCharT* outBuffer, size_t outBufferLenBytes, bool& isTruncated) { @@ -202,13 +202,11 @@ void ReadString(BinaryReaderImpl& reader, std::string& str) { } } -void WriteString(BinaryWriterImpl& writer, - const std::string& str) { +void WriteString(BinaryWriterImpl& writer, const std::string& str) { writer.WriteString(str.data(), static_cast< int32_t >(str.size())); } -void ReadDecimal(BinaryReaderImpl& reader, - Decimal& decimal) { +void ReadDecimal(BinaryReaderImpl& reader, Decimal& decimal) { int8_t hdr = reader.ReadInt8(); assert(hdr == IGNITE_TYPE_DECIMAL); @@ -223,8 +221,8 @@ void ReadDecimal(BinaryReaderImpl& reader, mag.resize(len); - BinaryUtils::ReadInt8Array( - reader.GetStream(), mag.data(), static_cast< int32_t >(mag.size())); + BinaryUtils::ReadInt8Array(reader.GetStream(), mag.data(), + static_cast< int32_t >(mag.size())); int32_t sign = 1; @@ -234,14 +232,12 @@ void ReadDecimal(BinaryReaderImpl& reader, sign = -1; } - Decimal res(mag.data(), static_cast< int32_t >(mag.size()), - scale, sign); + Decimal res(mag.data(), static_cast< int32_t >(mag.size()), scale, sign); decimal.Swap(res); } -void WriteDecimal(BinaryWriterImpl& writer, - const Decimal& decimal) { +void WriteDecimal(BinaryWriterImpl& writer, const Decimal& decimal) { writer.WriteInt8(IGNITE_TYPE_DECIMAL); const BigInteger& unscaled = decimal.GetUnscaledValue(); @@ -262,8 +258,8 @@ void WriteDecimal(BinaryWriterImpl& writer, magnitude[0] |= addBit; } - BinaryUtils::WriteInt8Array( - writer.GetStream(), magnitude.GetData(), magnitude.GetSize()); + BinaryUtils::WriteInt8Array(writer.GetStream(), magnitude.GetData(), + magnitude.GetSize()); } std::string SqlStringToString(const SQLWCHAR* sqlStr, int32_t sqlStrLen, @@ -321,29 +317,7 @@ std::wstring FromUtf8(const char* value) { return converter.from_bytes(value); } -boost::optional< std::string > SqlStringToOptString(const unsigned char* sqlStr, - int32_t sqlStrLen) { - boost::optional< std::string > res = boost::none; - std::string tmp; - - const char* sqlStrC = reinterpret_cast< const char* >(sqlStr); - - if (!sqlStr) - return res; - - if (sqlStrLen == SQL_NTS) { - tmp.assign(sqlStrC); - res = tmp; - } else if (sqlStrLen > 0) { - tmp.assign(sqlStrC, sqlStrLen); - res = tmp; - } - - return res; -} - -void ReadByteArray(BinaryReaderImpl& reader, - std::vector< int8_t >& res) { +void ReadByteArray(BinaryReaderImpl& reader, std::vector< int8_t >& res) { int32_t len = reader.ReadInt8Array(0, 0); if (len > 0) { diff --git a/src/tests/performance/include/performance_odbc_helper.h b/src/tests/performance/include/performance_odbc_helper.h index 3365ee87f..15279697a 100644 --- a/src/tests/performance/include/performance_odbc_helper.h +++ b/src/tests/performance/include/performance_odbc_helper.h @@ -26,7 +26,6 @@ #pragma comment(lib, "odbc32.lib") #endif - #ifndef ODBCVER #define ODBCVER 0x0351 #endif @@ -35,7 +34,6 @@ #include #include - #include #include #include @@ -54,7 +52,7 @@ typedef std::wstring test_string; #endif #define AS_SQLTCHAR(str) \ - const_cast(reinterpret_cast(str)) + const_cast< SQLTCHAR* >(reinterpret_cast< const SQLTCHAR* >(str)) #define convert_to_test_string(t) to_test_string(std::to_string(t)) test_string to_test_string(const std::string& src); @@ -91,4 +89,4 @@ std::u16string string_to_u16string(const std::string& src); std::string tchar_to_string(const SQLTCHAR* tchar); std::string wchar_to_string(const SQLWCHAR* tchar); -#endif // PERFORMANCE_ODBC_HELPER_H +#endif // PERFORMANCE_ODBC_HELPER_H diff --git a/src/tests/performance/include/performance_test_runner.h b/src/tests/performance/include/performance_test_runner.h index 7b674859b..86d7aafe1 100644 --- a/src/tests/performance/include/performance_test_runner.h +++ b/src/tests/performance/include/performance_test_runner.h @@ -31,7 +31,7 @@ typedef SQLLEN SQLROWOFFSET; * GLOBAL CONSTANTS *******************************************************/ -#define BIND_SIZE 512 // used for SQLBindCol function +#define BIND_SIZE 512 // used for SQLBindCol function // CSV header definitions (input csv file must match) #define QUERY_HEADER "query" @@ -42,8 +42,7 @@ typedef SQLLEN SQLROWOFFSET; const std::string kInputFile = "..\\..\\cmake\\tests\\performance\\Performance_Test_Plan.csv"; -const std::string kOutputFile = - "Performance_Test_Results.csv"; +const std::string kOutputFile = "Performance_Test_Results.csv"; // Ensure DSN is setup on machine before running test // DSN name should be "documentdb-perf-test" @@ -60,41 +59,41 @@ const std::string kTestQuery = enum testCaseStatus { success, error, skip }; typedef struct Col { - SQLLEN data_len; - SQLCHAR data_dat[BIND_SIZE]; + SQLLEN data_len; + SQLCHAR data_dat[BIND_SIZE]; } Col; struct CsvHeaders { - int idx_query = -1; - int idx_limit = -1; - int idx_skip_test = -1; - int idx_test_name = -1; - int idx_iteration_count = -1; + int idx_query = -1; + int idx_limit = -1; + int idx_skip_test = -1; + int idx_test_name = -1; + int idx_iteration_count = -1; }; struct StatisticalInfo { - long long avg = 0; - long long min = 0; - long long max = 0; - long long median = 0; - long long stdev = 0; - long long percentile_95 = 0; + long long avg = 0; + long long min = 0; + long long max = 0; + long long median = 0; + long long stdev = 0; + long long percentile_95 = 0; }; struct TestCase { - testCaseStatus status; // success/error/skip - std::string err_msg = ""; // value is set if status = error - int test_case_num = 0; - std::string test_name = ""; - std::string query = ""; - int limit = 0; - int num_iterations = 0; - std::vector< long long > time_ms; // time for exec->bind->fetch combined - std::vector< long long > time_exec_ms; - std::vector< long long > time_bind_fetch_ms; - StatisticalInfo stat_info; - StatisticalInfo stat_info_exec; - StatisticalInfo stat_info_bind_fetch; + testCaseStatus status; // success/error/skip + std::string err_msg = ""; // value is set if status = error + int test_case_num = 0; + std::string test_name = ""; + std::string query = ""; + int limit = 0; + int num_iterations = 0; + std::vector< long long > time_ms; // time for exec->bind->fetch combined + std::vector< long long > time_exec_ms; + std::vector< long long > time_bind_fetch_ms; + StatisticalInfo stat_info; + StatisticalInfo stat_info_exec; + StatisticalInfo stat_info_bind_fetch; }; /******************************************************** @@ -104,173 +103,172 @@ struct TestCase { namespace performance { class PerformanceTestRunner { - private: - std::string _dsn = kDsnDefault; - std::vector< TestCase > _results; + private: + std::string _dsn = kDsnDefault; + std::vector< TestCase > _results; - // SQL Handles - SQLHENV _env = SQL_NULL_HENV; - SQLHDBC _conn = SQL_NULL_HDBC; - SQLHSTMT _hstmt = SQL_NULL_HSTMT; + // SQL Handles + SQLHENV _env = SQL_NULL_HENV; + SQLHDBC _conn = SQL_NULL_HDBC; + SQLHSTMT _hstmt = SQL_NULL_HSTMT; - // CSV data - std::vector< std::vector< Csv::CellReference > > - _cell_refs; // references _csv_data - std::string _input_file = kInputFile; // input test plan csv file - std::string _output_file = kOutputFile; // output test results csv file - std::string _csv_data = ""; - CsvHeaders _headers; // col index of headers - + // CSV data + std::vector< std::vector< Csv::CellReference > > + _cell_refs; // references _csv_data + std::string _input_file = kInputFile; // input test plan csv file + std::string _output_file = kOutputFile; // output test results csv file + std::string _csv_data = ""; + CsvHeaders _headers; // col index of headers - // _output_mode = 0 - output time for exec/bind/fetch combined - // _output_mode = 1 - output time for exec only - // _output_mode = 2 - output time for bind and fetch only - // _output_mode = 3 - output all above (combined and separate) - int _output_mode = 0; + // _output_mode = 0 - output time for exec/bind/fetch combined + // _output_mode = 1 - output time for exec only + // _output_mode = 2 - output time for bind and fetch only + // _output_mode = 3 - output all above (combined and separate) + int _output_mode = 0; - // HELPER FUNCTIONS + // HELPER FUNCTIONS - // return true if filename has extension = ".xxx" - void CheckFileExtension(const std::string filename, - const std::string extension); + // return true if filename has extension = ".xxx" + void CheckFileExtension(const std::string filename, + const std::string extension); - // return true if DSN matches any data sources installed - void CheckDSN(const std::string dsn); - - // return true if output mode = 0, 1, 2 or 3 - void CheckOutputMode(const int output_mode); - - // get csv input file header col index - void CheckCsvHeaders(); + // return true if DSN matches any data sources installed + void CheckDSN(const std::string dsn); + + // return true if output mode = 0, 1, 2 or 3 + void CheckOutputMode(const int output_mode); - // Output headers to output file - // col 1 = test # - // col 2 = test name - // col 3 = status - // col 4 = query - // col 5 = limit - // col 6 = iteration count - // col 7 = avg time - // col 8 = max time - // col 9 = min time - // col 10 = median time - void OutputHeaders(std::ofstream& ofs) const; + // get csv input file header col index + void CheckCsvHeaders(); - // Returns true if test should be skipped, otherwise false - bool SkipTest(const Csv::CellReference& cell_skip_test) const; + // Output headers to output file + // col 1 = test # + // col 2 = test name + // col 3 = status + // col 4 = query + // col 5 = limit + // col 6 = iteration count + // col 7 = avg time + // col 8 = max time + // col 9 = min time + // col 10 = median time + void OutputHeaders(std::ofstream& ofs) const; - // Returns query string from current test case csv data - std::string GetQueryString(const Csv::CellReference& cell_query) const; - - // Return limit from current test case csv data - int GetLimit(const Csv::CellReference& cell_limit) const; - - // Returns test name string from current test case csv data - std::string GetTestName(const Csv::CellReference& cell_test_name) const; - - // Returns iteration/loop count from current test case csv data - int GetIterationCount(const Csv::CellReference& cell_iteration_count) const; - - // Returns true if string has comma or newline - bool HasCommaOrNewLine(const std::string str) const; - - // Calculate statistical info from current test case - void CalcStats(TestCase& test_case); - - // Output test case to output file - void OutputTestCase(std::ofstream& ofs, const TestCase& test_case) const; - - // Record time_ms for current test case: exec->bind->fetch - void RecordExecBindFetch(SQLHSTMT* hstmt, TestCase& test_case); - - // ReportTime for current test case - void ReportTime(const TestCase& test_case); - - public: - // STATIC METHODS - - static void ListDriversInstalled(); - static void ListDataSourcesInstalled(); - - // Test if connection to test database DSN=documentdb-perf-test can be - // established and if query "SELECT * from performance.employer_employees - // LIMIT 10000" can be executed - static SQLRETURN TestDefaultDSN(); - - // CONSTRUCTORS AND DESTRUCTOR - - // Default constructor - PerformanceTestRunner(); - - // Specify input (test plan) csv file, output (results) csv file and dsn - // connection string to test database - PerformanceTestRunner(const std::string test_plan_csv, - const std::string output_file_csv, - const std::string dsn, const int output_mode = 0); - - // Destructor - virtual ~PerformanceTestRunner(); - - // SETTERS AND GETTERS + // Returns true if test should be skipped, otherwise false + bool SkipTest(const Csv::CellReference& cell_skip_test) const; - // get input test plan csv file - inline std::string GetInputTestPlanCsvFile() const { - return _input_file; - } + // Returns query string from current test case csv data + std::string GetQueryString(const Csv::CellReference& cell_query) const; + + // Return limit from current test case csv data + int GetLimit(const Csv::CellReference& cell_limit) const; + + // Returns test name string from current test case csv data + std::string GetTestName(const Csv::CellReference& cell_test_name) const; + + // Returns iteration/loop count from current test case csv data + int GetIterationCount(const Csv::CellReference& cell_iteration_count) const; + + // Returns true if string has comma or newline + bool HasCommaOrNewLine(const std::string str) const; + + // Calculate statistical info from current test case + void CalcStats(TestCase& test_case); + + // Output test case to output file + void OutputTestCase(std::ofstream& ofs, const TestCase& test_case) const; + + // Record time_ms for current test case: exec->bind->fetch + void RecordExecBindFetch(SQLHSTMT* hstmt, TestCase& test_case); + + // ReportTime for current test case + void ReportTime(const TestCase& test_case); + + public: + // STATIC METHODS + + static void ListDriversInstalled(); + static void ListDataSourcesInstalled(); + + // Test if connection to test database DSN=documentdb-perf-test can be + // established and if query "SELECT * from performance.employer_employees + // LIMIT 10000" can be executed + static SQLRETURN TestDefaultDSN(); + + // CONSTRUCTORS AND DESTRUCTOR + + // Default constructor + PerformanceTestRunner(); + + // Specify input (test plan) csv file, output (results) csv file and dsn + // connection string to test database + PerformanceTestRunner(const std::string test_plan_csv, + const std::string output_file_csv, + const std::string dsn, const int output_mode = 0); + + // Destructor + virtual ~PerformanceTestRunner(); + + // SETTERS AND GETTERS - // set input test plan csv file - inline void SetInputTestPlanCsvFile(const std::string filename) { - _input_file = filename; - } + // get input test plan csv file + inline std::string GetInputTestPlanCsvFile() const { + return _input_file; + } - // get output results csv file - inline std::string GetOutputResultsCsvFile() const { - return _output_file; - } + // set input test plan csv file + inline void SetInputTestPlanCsvFile(const std::string filename) { + _input_file = filename; + } - // set output results csv file - inline void SetOutputResultsCsvFile(const std::string filename) { - _output_file = filename; - } + // get output results csv file + inline std::string GetOutputResultsCsvFile() const { + return _output_file; + } - // get data source name - inline std::string GetDSN() const { - return _dsn; - } + // set output results csv file + inline void SetOutputResultsCsvFile(const std::string filename) { + _output_file = filename; + } - // set data source name - void SetDSN(const std::string dsn); + // get data source name + inline std::string GetDSN() const { + return _dsn; + } - // get results - inline std::vector< TestCase > GetTestResults() const { - return _results; - } + // set data source name + void SetDSN(const std::string dsn); - // get output mode - inline int GetOutputMode() const { - return _output_mode; - } + // get results + inline std::vector< TestCase > GetTestResults() const { + return _results; + } - // set output mode (must = 0, 1, 2 or 3) - void SetOutputMode(const int output_mode); + // get output mode + inline int GetOutputMode() const { + return _output_mode; + } - // METHODS TO RUN PEFORMANCE TEST PLAN + // set output mode (must = 0, 1, 2 or 3) + void SetOutputMode(const int output_mode); - // read input test plan csv file - // assumptions: - // 1. csv file contains following headers (order does not matter): - // "query" : string (can contain new lines and commas) - // "limit" : integer (limit number of rows returned in query) - // "test_name" : string (can contain new lines and commas) - // "loop_count" : integer (number of times to execute query) - // "skip_test" : string (must be "TRUE" or "FALSE") - void ReadPerformanceTestPlan(); + // METHODS TO RUN PEFORMANCE TEST PLAN - // allocate env, conn and stmt - void SetupConnection(); + // read input test plan csv file + // assumptions: + // 1. csv file contains following headers (order does not matter): + // "query" : string (can contain new lines and commas) + // "limit" : integer (limit number of rows returned in query) + // "test_name" : string (can contain new lines and commas) + // "loop_count" : integer (number of times to execute query) + // "skip_test" : string (must be "TRUE" or "FALSE") + void ReadPerformanceTestPlan(); - // run performance test plan and record results to output file - void RunPerformanceTestPlan(); + // allocate env, conn and stmt + void SetupConnection(); + + // run performance test plan and record results to output file + void RunPerformanceTestPlan(); }; } // namespace performance diff --git a/src/tests/performance/lib/csv_cell.h b/src/tests/performance/lib/csv_cell.h index 11b47ace0..7cde2ec62 100644 --- a/src/tests/performance/lib/csv_cell.h +++ b/src/tests/performance/lib/csv_cell.h @@ -15,622 +15,514 @@ License: Zlib #include #include - - namespace Csv { - - /// Type hint associated with the cell to determine the type of the cell value enum class CellTypeHint { - Empty, ///< Empty data (no quotes, no whitespace) - StringWithEscapedQuotes, ///< Quoted or unquoted string with escaped quotes inside. - StringWithoutEscapedQuotes, ///< Quoted or unquoted string without any escaped quotes inside - UnquotedData, ///< Unquoted data, no escaped quotes inside. + Empty, ///< Empty data (no quotes, no whitespace) + StringWithEscapedQuotes, ///< Quoted or unquoted string with escaped quotes + ///< inside. + StringWithoutEscapedQuotes, ///< Quoted or unquoted string without any + ///< escaped quotes inside + UnquotedData, ///< Unquoted data, no escaped quotes inside. }; - /// Type of the cell value enum class CellType { - Empty, - Double, - String, + Empty, + Double, + String, }; - - /// A helper class for compile-time buffer construction and string unescaping -template +template < std::size_t Size > class CellStringBuffer { - public: - - /// Constructor. Cleans up the data in cell, creating a buffer with. - constexpr inline explicit CellStringBuffer(std::string_view cell, bool has_escaped_quotes); - - /// Check if the buffer was successfully created and contains a cleaned up string - [[nodiscard]] constexpr bool isValid() const noexcept; - - /// Return string view to stored buffer. - /// The returned view has collapsed consecutive double-quotes inside. - /// \throw std::out_of_range if buffer is invalid (of insufficient size) - [[nodiscard]] constexpr std::string_view getStringView() const; - - /// Return string view to stored buffer. - /// The returned view has collapsed consecutive double-quotes inside. - /// \return std::nullopt if buffer is invalid (of insufficient size) - [[nodiscard]] constexpr std::optional getOptionalStringView() const noexcept; - - - private: - - struct Buffer { - std::array buffer = { }; - std::size_t size = 0; - bool valid = false; - }; - - /// Create a buffer object, with cleaned-up input in it - constexpr static Buffer prepareBuffer(std::string_view input, bool has_escaped_quotes); - - /// Unescape a string view to newly created buffer - constexpr static Buffer cleanString(std::string_view input); - - Buffer buffer_; + public: + /// Constructor. Cleans up the data in cell, creating a buffer with. + constexpr inline explicit CellStringBuffer(std::string_view cell, + bool has_escaped_quotes); + + /// Check if the buffer was successfully created and contains a cleaned up + /// string + [[nodiscard]] constexpr bool isValid() const noexcept; + + /// Return string view to stored buffer. + /// The returned view has collapsed consecutive double-quotes inside. + /// \throw std::out_of_range if buffer is invalid (of insufficient size) + [[nodiscard]] constexpr std::string_view getStringView() const; + + /// Return string view to stored buffer. + /// The returned view has collapsed consecutive double-quotes inside. + /// \return std::nullopt if buffer is invalid (of insufficient size) + [[nodiscard]] constexpr std::optional< std::string_view > + getOptionalStringView() const noexcept; + + private: + struct Buffer { + std::array< char, Size > buffer = {}; + std::size_t size = 0; + bool valid = false; + }; + + /// Create a buffer object, with cleaned-up input in it + constexpr static Buffer prepareBuffer(std::string_view input, + bool has_escaped_quotes); + + /// Unescape a string view to newly created buffer + constexpr static Buffer cleanString(std::string_view input); + + Buffer buffer_; }; - - -/// A value of a cell, referencing the data in original CSV text (if the data is of string type). +/// A value of a cell, referencing the data in original CSV text (if the data is +/// of string type). class CellReference { - public: - - /// Constructor - CellReference() = default; - - /// Constructor - inline CellReference(std::string_view cell, CellTypeHint hint); - - /// Get cell type - [[nodiscard]] inline CellType getType() const; - - /// Check whether the cell is of Empty type - [[nodiscard]] inline bool isEmpty() const; - - /// Get the cell value if cell type is Double. - /// \return std::nullopt on type mismatch - [[nodiscard]] inline std::optional getDouble() const; - - /// Get stored cell reference as string_view. - /// This cell may contain escaped consecutive double-quotes inside; if has_escaped_quotes is not nullptr, - /// *has_escaped_quotes will reflect that. - /// \return std::nullopt on type mismatch - [[nodiscard]] inline std::optional getOriginalStringView( - bool* has_escaped_quotes = nullptr) const; - - /// Get stored cell reference as string. - /// The string has collapsed consecutive double-quotes inside. - /// \return std::nullopt on type mismatch - [[nodiscard]] inline std::optional getCleanString() const; - - private: - - /// Empty value (empty unquoted cell) - struct Empty { }; - - /// String value - struct String { - std::string_view view; - bool has_escaped_quotes = false; - }; - - /// Stored data - std::variant< - Empty, - double, - String - > value_ = Empty(); + public: + /// Constructor + CellReference() = default; + + /// Constructor + inline CellReference(std::string_view cell, CellTypeHint hint); + + /// Get cell type + [[nodiscard]] inline CellType getType() const; + + /// Check whether the cell is of Empty type + [[nodiscard]] inline bool isEmpty() const; + + /// Get the cell value if cell type is Double. + /// \return std::nullopt on type mismatch + [[nodiscard]] inline std::optional< double > getDouble() const; + + /// Get stored cell reference as string_view. + /// This cell may contain escaped consecutive double-quotes inside; if + /// has_escaped_quotes is not nullptr, *has_escaped_quotes will reflect that. + /// \return std::nullopt on type mismatch + [[nodiscard]] inline std::optional< std::string_view > getOriginalStringView( + bool* has_escaped_quotes = nullptr) const; + + /// Get stored cell reference as string. + /// The string has collapsed consecutive double-quotes inside. + /// \return std::nullopt on type mismatch + [[nodiscard]] inline std::optional< std::string > getCleanString() const; + + private: + /// Empty value (empty unquoted cell) + struct Empty {}; + + /// String value + struct String { + std::string_view view; + bool has_escaped_quotes = false; + }; + + /// Stored data + std::variant< Empty, double, String > value_ = Empty(); }; - - -/// A value of a cell. The object owns its data and does not reference the original CSV text. +/// A value of a cell. The object owns its data and does not reference the +/// original CSV text. class CellValue { - public: + public: + /// Constructor + CellValue() = default; - /// Constructor - CellValue() = default; + /// Constructor + inline CellValue(std::string_view cell, CellTypeHint hint); - /// Constructor - inline CellValue(std::string_view cell, CellTypeHint hint); + /// Get cell type + [[nodiscard]] inline CellType getType() const; - /// Get cell type - [[nodiscard]] inline CellType getType() const; + /// Check whether the cell is of Empty type + [[nodiscard]] inline bool isEmpty() const; - /// Check whether the cell is of Empty type - [[nodiscard]] inline bool isEmpty() const; + /// Get the cell value if cell type is Double. + /// \return std::nullopt on type mismatch + [[nodiscard]] inline std::optional< double > getDouble() const; - /// Get the cell value if cell type is Double. - /// \return std::nullopt on type mismatch - [[nodiscard]] inline std::optional getDouble() const; + /// Get stored cell reference as string. + /// The string has collapsed consecutive double-quotes inside. + /// \return std::nullopt on type mismatch + [[nodiscard]] inline std::optional< std::string > getString() const; - /// Get stored cell reference as string. - /// The string has collapsed consecutive double-quotes inside. - /// \return std::nullopt on type mismatch - [[nodiscard]] inline std::optional getString() const; + private: + /// Empty value (empty unquoted cell) + struct Empty {}; - private: - - /// Empty value (empty unquoted cell) - struct Empty { }; - - /// Stored data - std::variant< - Empty, - double, - std::string - > value_ = Empty(); + /// Stored data + std::variant< Empty, double, std::string > value_ = Empty(); }; - - -/// A value of a cell. All cell contents are treated as doubles. The data is owned by this object. +/// A value of a cell. All cell contents are treated as doubles. The data is +/// owned by this object. class CellDoubleValue { - public: - - /// Constructor - CellDoubleValue() = default; - - /// Constructor - inline explicit CellDoubleValue(std::string_view cell, - CellTypeHint hint_ignored = CellTypeHint::UnquotedData); - - /// Get the cell value if cell type is Double. - /// \return std::numeric_limits::quiet_NaN() on error. - [[nodiscard]] inline double getValue() const; - - private: - /// Stored data - double value_ = std::numeric_limits::quiet_NaN(); + public: + /// Constructor + CellDoubleValue() = default; + + /// Constructor + inline explicit CellDoubleValue( + std::string_view cell, + CellTypeHint hint_ignored = CellTypeHint::UnquotedData); + + /// Get the cell value if cell type is Double. + /// \return std::numeric_limits::quiet_NaN() on error. + [[nodiscard]] inline double getValue() const; + + private: + /// Stored data + double value_ = std::numeric_limits< double >::quiet_NaN(); }; - - - /// A value of a cell, referencing the data in original CSV text. /// All cell contents are treated as strings. class CellStringReference { - public: - - /// Constructor - constexpr CellStringReference() = default; - - /// Constructor - inline constexpr CellStringReference(std::string_view cell, CellTypeHint hint) noexcept; - - /// Get stored cell reference as string_view. - /// Cell type is assumed to be String, regardless of autodetected type. - /// This cell may contain escaped consecutive double-quotes inside; if has_escaped_quotes is not nullptr, - /// *has_escaped_quotes will reflect that. - [[nodiscard]] inline constexpr std::string_view getOriginalStringView( - bool* has_escaped_quotes = nullptr) const noexcept; - - /// Get stored cell reference as string. - /// Cell type is assumed to be String, regardless of autodetected type. - /// The string has collapsed consecutive double-quotes inside. - [[nodiscard]] inline std::string getCleanString(); - - /// Get a string buffer with collapsed consecutive double-quotes. - /// This function is useful in constexpr context to retrieve unescaped cell data. - /// \tparam BufferSize buffer size has to be at least strlen(getOriginalStringView()). Note - /// that buffer size is always checked, regardless of whether quotes had to be escaped or not. - /// Reserving additional character for terminating null is not required. - /// \return invalid buffer if BufferSize is too small. - template - [[nodiscard]] constexpr CellStringBuffer getCleanStringBuffer() const - { - return CellStringBuffer(value_, has_escaped_quotes_); - } - - - private: - - /// Stored data - std::string_view value_; - - /// If the stored data may contain unescaped double-quotes, this is set to true. - bool has_escaped_quotes_ = false; - + public: + /// Constructor + constexpr CellStringReference() = default; + + /// Constructor + inline constexpr CellStringReference(std::string_view cell, + CellTypeHint hint) noexcept; + + /// Get stored cell reference as string_view. + /// Cell type is assumed to be String, regardless of autodetected type. + /// This cell may contain escaped consecutive double-quotes inside; if + /// has_escaped_quotes is not nullptr, *has_escaped_quotes will reflect that. + [[nodiscard]] inline constexpr std::string_view getOriginalStringView( + bool* has_escaped_quotes = nullptr) const noexcept; + + /// Get stored cell reference as string. + /// Cell type is assumed to be String, regardless of autodetected type. + /// The string has collapsed consecutive double-quotes inside. + [[nodiscard]] inline std::string getCleanString(); + + /// Get a string buffer with collapsed consecutive double-quotes. + /// This function is useful in constexpr context to retrieve unescaped cell + /// data. \tparam BufferSize buffer size has to be at least + /// strlen(getOriginalStringView()). Note that buffer size is always checked, + /// regardless of whether quotes had to be escaped or not. Reserving + /// additional character for terminating null is not required. \return invalid + /// buffer if BufferSize is too small. + template < std::size_t BufferSize > + [[nodiscard]] constexpr CellStringBuffer< BufferSize > getCleanStringBuffer() + const { + return CellStringBuffer< BufferSize >(value_, has_escaped_quotes_); + } + + private: + /// Stored data + std::string_view value_; + + /// If the stored data may contain unescaped double-quotes, this is set to + /// true. + bool has_escaped_quotes_ = false; }; - - -/// A value of a cell. The object owns its data and does not reference the original CSV text. -/// All cell contents are treated as strings. +/// A value of a cell. The object owns its data and does not reference the +/// original CSV text. All cell contents are treated as strings. class CellStringValue { - public: - - /// Constructor - CellStringValue() = default; + public: + /// Constructor + CellStringValue() = default; - /// Constructor - inline CellStringValue(std::string_view cell, CellTypeHint hint); + /// Constructor + inline CellStringValue(std::string_view cell, CellTypeHint hint); - /// Get stored cell reference as string. - /// Cell type is assumed to be String, regardless of autodetected type. - /// The string has collapsed consecutive double-quotes inside. - [[nodiscard]] inline const std::string& getString() const; + /// Get stored cell reference as string. + /// Cell type is assumed to be String, regardless of autodetected type. + /// The string has collapsed consecutive double-quotes inside. + [[nodiscard]] inline const std::string& getString() const; - private: - /// Stored data - std::string value_; + private: + /// Stored data + std::string value_; }; - - - -/// Unescape a string - collapse every occurrence of 2 consecutive double-quotes to one. +/// Unescape a string - collapse every occurrence of 2 consecutive double-quotes +/// to one. inline std::string cleanString(std::string_view view); - /// Try to read a double value from string data. -/// Unless the string data (with optional whitespace on either or both sides) completely represents a serialized -/// double, std::nullopt is returned. -inline std::optional readDouble(std::string_view cell); - - - +/// Unless the string data (with optional whitespace on either or both sides) +/// completely represents a serialized double, std::nullopt is returned. +inline std::optional< double > readDouble(std::string_view cell); // ----- Implementation - - -template -constexpr CellStringBuffer::CellStringBuffer(std::string_view cell, bool has_escaped_quotes) - : buffer_(prepareBuffer(cell, has_escaped_quotes)) -{ } - - - -template -[[nodiscard]] constexpr bool CellStringBuffer::isValid() const noexcept -{ - return buffer_.valid; +template < std::size_t Size > +constexpr CellStringBuffer< Size >::CellStringBuffer(std::string_view cell, + bool has_escaped_quotes) + : buffer_(prepareBuffer(cell, has_escaped_quotes)) { } - - -template -[[nodiscard]] constexpr std::string_view CellStringBuffer::getStringView() const -{ - if (!buffer_.valid) { - throw std::out_of_range("Insufficient buffer size"); - } - return {buffer_.buffer.data(), buffer_.size}; +template < std::size_t Size > +[[nodiscard]] constexpr bool CellStringBuffer< Size >::isValid() + const noexcept { + return buffer_.valid; } - - -template -[[nodiscard]] constexpr std::optional CellStringBuffer::getOptionalStringView() const noexcept -{ - if (!buffer_.valid) { - return std::nullopt; - } - return std::string_view{buffer_.buffer.data(), buffer_.size}; +template < std::size_t Size > +[[nodiscard]] constexpr std::string_view +CellStringBuffer< Size >::getStringView() const { + if (!buffer_.valid) { + throw std::out_of_range("Insufficient buffer size"); + } + return {buffer_.buffer.data(), buffer_.size}; } - - -template -constexpr typename CellStringBuffer::Buffer CellStringBuffer::prepareBuffer(std::string_view input, bool -has_escaped_quotes) -{ - if (Size < input.size()) { - return Buffer{}; - } - if (has_escaped_quotes) { - return cleanString(input); - } - std::array buffer = { }; - for (std::size_t pos = 0; pos < std::min(Size, input.size()); ++pos) { - buffer[pos] = input[pos]; - } - return Buffer{buffer, input.size(), true}; +template < std::size_t Size > +[[nodiscard]] constexpr std::optional< std::string_view > +CellStringBuffer< Size >::getOptionalStringView() const noexcept { + if (!buffer_.valid) { + return std::nullopt; + } + return std::string_view{buffer_.buffer.data(), buffer_.size}; } - - -template -constexpr typename CellStringBuffer::Buffer CellStringBuffer::cleanString(std::string_view input) -{ - std::array buffer = { }; - std::size_t output_pos = 0; - for (std::size_t input_pos = 0; input_pos < std::min(Size, input.size()); ++input_pos) { - char c = input[input_pos]; - buffer[output_pos] = c; - ++output_pos; - if (c == '\"' && (input_pos + 1) < input.size() && input[input_pos + 1] == '\"') { - ++input_pos; - } - } - return {buffer, output_pos, true}; +template < std::size_t Size > +constexpr typename CellStringBuffer< Size >::Buffer +CellStringBuffer< Size >::prepareBuffer(std::string_view input, + bool has_escaped_quotes) { + if (Size < input.size()) { + return Buffer{}; + } + if (has_escaped_quotes) { + return cleanString(input); + } + std::array< char, Size > buffer = {}; + for (std::size_t pos = 0; pos < std::min(Size, input.size()); ++pos) { + buffer[pos] = input[pos]; + } + return Buffer{buffer, input.size(), true}; } - - - - -CellReference::CellReference(std::string_view cell, CellTypeHint hint) -{ - switch (hint) { - case CellTypeHint::Empty: - // Nothing, value is empty - break; - - case CellTypeHint::StringWithEscapedQuotes: - value_ = String{cell, true}; - break; - - case CellTypeHint::StringWithoutEscapedQuotes: - value_ = String{cell, false}; - break; - - case CellTypeHint::UnquotedData: - if (auto double_value = readDouble(cell); double_value.has_value()) { - value_ = double_value.value(); - } else { - value_ = String{cell, false}; - } - break; - } +template < std::size_t Size > +constexpr typename CellStringBuffer< Size >::Buffer +CellStringBuffer< Size >::cleanString(std::string_view input) { + std::array< char, Size > buffer = {}; + std::size_t output_pos = 0; + for (std::size_t input_pos = 0; input_pos < std::min(Size, input.size()); + ++input_pos) { + char c = input[input_pos]; + buffer[output_pos] = c; + ++output_pos; + if (c == '\"' && (input_pos + 1) < input.size() + && input[input_pos + 1] == '\"') { + ++input_pos; + } + } + return {buffer, output_pos, true}; } - - -CellType CellReference::getType() const -{ - if (std::holds_alternative(value_)) { - return CellType::Empty; - } - if (std::holds_alternative(value_)) { - return CellType::Double; - } - if (std::holds_alternative(value_)) { - return CellType::String; - } - throw std::bad_variant_access(); +CellReference::CellReference(std::string_view cell, CellTypeHint hint) { + switch (hint) { + case CellTypeHint::Empty: + // Nothing, value is empty + break; + + case CellTypeHint::StringWithEscapedQuotes: + value_ = String{cell, true}; + break; + + case CellTypeHint::StringWithoutEscapedQuotes: + value_ = String{cell, false}; + break; + + case CellTypeHint::UnquotedData: + if (auto double_value = readDouble(cell); double_value.has_value()) { + value_ = double_value.value(); + } else { + value_ = String{cell, false}; + } + break; + } } - - -bool CellReference::isEmpty() const -{ - return std::holds_alternative(value_); +CellType CellReference::getType() const { + if (std::holds_alternative< Empty >(value_)) { + return CellType::Empty; + } + if (std::holds_alternative< double >(value_)) { + return CellType::Double; + } + if (std::holds_alternative< String >(value_)) { + return CellType::String; + } + throw std::bad_variant_access(); } - - -std::optional CellReference::getDouble() const -{ - if (std::holds_alternative(value_)) { - return std::get(value_); - } - return {}; +bool CellReference::isEmpty() const { + return std::holds_alternative< Empty >(value_); } - - -std::optional CellReference::getOriginalStringView(bool* has_escaped_quotes) const -{ - if (std::holds_alternative(value_)) { - const auto& s = std::get(value_); - if (has_escaped_quotes) { - *has_escaped_quotes = s.has_escaped_quotes; - } - return s.view; - } - return {}; +std::optional< double > CellReference::getDouble() const { + if (std::holds_alternative< double >(value_)) { + return std::get< double >(value_); + } + return {}; } - - -std::optional CellReference::getCleanString() const -{ - if (std::holds_alternative(value_)) { - const auto& s = std::get(value_); - return s.has_escaped_quotes ? cleanString(s.view) : std::string(s.view); - } - return {}; +std::optional< std::string_view > CellReference::getOriginalStringView( + bool* has_escaped_quotes) const { + if (std::holds_alternative< String >(value_)) { + const auto& s = std::get< String >(value_); + if (has_escaped_quotes) { + *has_escaped_quotes = s.has_escaped_quotes; + } + return s.view; + } + return {}; } - - - - -CellValue::CellValue(std::string_view cell, CellTypeHint hint) -{ - switch (hint) { - case CellTypeHint::Empty: - // Nothing, value is empty - break; - - case CellTypeHint::StringWithEscapedQuotes: - value_ = cleanString(cell); - break; - - case CellTypeHint::StringWithoutEscapedQuotes: - value_ = std::string(cell); - break; - - case CellTypeHint::UnquotedData: - if (auto double_value = readDouble(cell); double_value.has_value()) { - value_ = double_value.value(); - } else { - value_ = std::string(cell); - } - break; - } +std::optional< std::string > CellReference::getCleanString() const { + if (std::holds_alternative< String >(value_)) { + const auto& s = std::get< String >(value_); + return s.has_escaped_quotes ? cleanString(s.view) : std::string(s.view); + } + return {}; } - - -CellType CellValue::getType() const -{ - if (std::holds_alternative(value_)) { - return CellType::Empty; - } - if (std::holds_alternative(value_)) { - return CellType::Double; - } - if (std::holds_alternative(value_)) { - return CellType::String; - } - throw std::bad_variant_access(); +CellValue::CellValue(std::string_view cell, CellTypeHint hint) { + switch (hint) { + case CellTypeHint::Empty: + // Nothing, value is empty + break; + + case CellTypeHint::StringWithEscapedQuotes: + value_ = cleanString(cell); + break; + + case CellTypeHint::StringWithoutEscapedQuotes: + value_ = std::string(cell); + break; + + case CellTypeHint::UnquotedData: + if (auto double_value = readDouble(cell); double_value.has_value()) { + value_ = double_value.value(); + } else { + value_ = std::string(cell); + } + break; + } } - - -bool CellValue::isEmpty() const -{ - return std::holds_alternative(value_); +CellType CellValue::getType() const { + if (std::holds_alternative< Empty >(value_)) { + return CellType::Empty; + } + if (std::holds_alternative< double >(value_)) { + return CellType::Double; + } + if (std::holds_alternative< std::string >(value_)) { + return CellType::String; + } + throw std::bad_variant_access(); } - - -std::optional CellValue::getDouble() const -{ - if (std::holds_alternative(value_)) { - return std::get(value_); - } - return {}; +bool CellValue::isEmpty() const { + return std::holds_alternative< Empty >(value_); } - - -std::optional CellValue::getString() const -{ - if (std::holds_alternative(value_)) { - return std::get(value_); - } - return {}; +std::optional< double > CellValue::getDouble() const { + if (std::holds_alternative< double >(value_)) { + return std::get< double >(value_); + } + return {}; } - - - +std::optional< std::string > CellValue::getString() const { + if (std::holds_alternative< std::string >(value_)) { + return std::get< std::string >(value_); + } + return {}; +} CellDoubleValue::CellDoubleValue(std::string_view cell, - [[maybe_unused]] CellTypeHint hint_ignored) -{ - if (auto double_value = readDouble(cell); double_value.has_value()) { - value_ = double_value.value(); - } + [[maybe_unused]] CellTypeHint hint_ignored) { + if (auto double_value = readDouble(cell); double_value.has_value()) { + value_ = double_value.value(); + } } - - -double CellDoubleValue::getValue() const -{ - return value_; +double CellDoubleValue::getValue() const { + return value_; } - - - - -constexpr CellStringReference::CellStringReference(std::string_view cell, CellTypeHint hint) noexcept - : value_(cell), - has_escaped_quotes_(hint == CellTypeHint::StringWithEscapedQuotes) -{ } - - - -constexpr std::string_view CellStringReference::getOriginalStringView(bool* has_escaped_quotes) const noexcept -{ - if (has_escaped_quotes) { - *has_escaped_quotes = has_escaped_quotes_; - } - return value_; +constexpr CellStringReference::CellStringReference(std::string_view cell, + CellTypeHint hint) noexcept + : value_(cell), + has_escaped_quotes_(hint == CellTypeHint::StringWithEscapedQuotes) { } - - -std::string CellStringReference::getCleanString() -{ - return has_escaped_quotes_ ? cleanString(value_) : std::string(value_); +constexpr std::string_view CellStringReference::getOriginalStringView( + bool* has_escaped_quotes) const noexcept { + if (has_escaped_quotes) { + *has_escaped_quotes = has_escaped_quotes_; + } + return value_; } - - - +std::string CellStringReference::getCleanString() { + return has_escaped_quotes_ ? cleanString(value_) : std::string(value_); +} CellStringValue::CellStringValue(std::string_view cell, CellTypeHint hint) - : value_(hint == CellTypeHint::StringWithEscapedQuotes ? cleanString(cell) : std::string(cell)) -{ } - - - -const std::string& CellStringValue::getString() const -{ - return value_; + : value_(hint == CellTypeHint::StringWithEscapedQuotes + ? cleanString(cell) + : std::string(cell)) { } - - - - -std::string cleanString(std::string_view view) -{ - std::string s; - s.reserve(view.size()); - for (std::size_t pos = 0; pos < view.size(); ++pos) { - char c = view[pos]; - s += c; - if (c == '\"' && (pos + 1) < view.size() && view[pos + 1] == '\"') { - ++pos; - } - } - return s; +const std::string& CellStringValue::getString() const { + return value_; } - - -std::optional readDouble(std::string_view cell) -{ - // Trim right whitespace (left whitespace is ignored by stod()). - std::size_t size = cell.size(); - if (auto end_pos = cell.find_last_not_of(" \t"); end_pos != std::string_view::npos) { - size = end_pos + 1; - } - std::string s(cell.data(), size); - - // Convert to lowercase (needed for Matlab-produced CSV files) - std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { - return static_cast(std::tolower(c)); - }); - - std::optional double_value; - // As of 2020, from_chars() is broken for floats/doubles in most compilers, so we'll have to do with stod() for - // now, even if it means using current locale instead of C locale. - // While calling std::strtod() could be potentially faster, it also means we have to deal with some - // platform-specific errno and other peculiarities. std::stod() wraps that nicely. - try { - std::size_t num_processed = 0; - // We have to use a 0-terminated string in stod(). - double parsed_double = std::stod(s, &num_processed); - if (num_processed == s.size()) { - double_value = parsed_double; - } - } catch (...) { - // nothing - } - return double_value; +std::string cleanString(std::string_view view) { + std::string s; + s.reserve(view.size()); + for (std::size_t pos = 0; pos < view.size(); ++pos) { + char c = view[pos]; + s += c; + if (c == '\"' && (pos + 1) < view.size() && view[pos + 1] == '\"') { + ++pos; + } + } + return s; } +std::optional< double > readDouble(std::string_view cell) { + // Trim right whitespace (left whitespace is ignored by stod()). + std::size_t size = cell.size(); + if (auto end_pos = cell.find_last_not_of(" \t"); + end_pos != std::string_view::npos) { + size = end_pos + 1; + } + std::string s(cell.data(), size); + + // Convert to lowercase (needed for Matlab-produced CSV files) + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) { + return static_cast< char >(std::tolower(c)); + }); + + std::optional< double > double_value; + // As of 2020, from_chars() is broken for floats/doubles in most compilers, so + // we'll have to do with stod() for now, even if it means using current locale + // instead of C locale. While calling std::strtod() could be potentially + // faster, it also means we have to deal with some platform-specific errno and + // other peculiarities. std::stod() wraps that nicely. + try { + std::size_t num_processed = 0; + // We have to use a 0-terminated string in stod(). + double parsed_double = std::stod(s, &num_processed); + if (num_processed == s.size()) { + double_value = parsed_double; + } + } catch (...) { + // nothing + } + return double_value; +} - -} // end ns - - +} // namespace Csv #endif diff --git a/src/tests/performance/lib/csv_error.h b/src/tests/performance/lib/csv_error.h index edefaf951..2e3669cb3 100644 --- a/src/tests/performance/lib/csv_error.h +++ b/src/tests/performance/lib/csv_error.h @@ -9,56 +9,38 @@ License: Zlib #include #include - - namespace Csv { - - /// Exception thrown on CSV parse error. class ParseError : public std::runtime_error { - - public: - ParseError(std::size_t row, std::size_t column) - : runtime_error(createWhatString(row, column)), - row_(row), column_(column) - { } - - - /// Return a 0-based row number where error occurred - [[nodiscard]] std::size_t row() const - { - return row_; - } - - - /// Return a 0-based column number where error occurred - [[nodiscard]] std::size_t column() const - { - return column_; - } - - - private: - - /// Create a string for \ref what() to return - static std::string createWhatString(std::size_t row, std::size_t column) - { - return std::string("CSV parse error at row ") + std::to_string(row + 1) - + ", column " + std::to_string(column + 1); - } - - - std::size_t row_ = 0; ///< 0-based - std::size_t column_ = 0; ///< 0-based - + public: + ParseError(std::size_t row, std::size_t column) + : runtime_error(createWhatString(row, column)), + row_(row), + column_(column) { + } + + /// Return a 0-based row number where error occurred + [[nodiscard]] std::size_t row() const { + return row_; + } + + /// Return a 0-based column number where error occurred + [[nodiscard]] std::size_t column() const { + return column_; + } + + private: + /// Create a string for \ref what() to return + static std::string createWhatString(std::size_t row, std::size_t column) { + return std::string("CSV parse error at row ") + std::to_string(row + 1) + + ", column " + std::to_string(column + 1); + } + + std::size_t row_ = 0; ///< 0-based + std::size_t column_ = 0; ///< 0-based }; - - - -} // end ns - - +} // namespace Csv #endif diff --git a/src/tests/performance/lib/csv_parser.h b/src/tests/performance/lib/csv_parser.h index d8315ca83..c1c83bd95 100644 --- a/src/tests/performance/lib/csv_parser.h +++ b/src/tests/performance/lib/csv_parser.h @@ -13,12 +13,8 @@ License: Zlib #include #include - - namespace Csv { - - /* * The main CSV parser class. * @@ -28,12 +24,14 @@ namespace Csv { * RFC 4180 CSV format summary: * - Each line ends with CRLF. * - CRLF is optional for the last line. - * - There is an optional header line (in the same format as the rest of the data). - * - Each line must have the same number of fields. Spaces are part of the cells. There is no trailing comma on the - * line. - * - A field _may_ be enclosed in double-quotes. If the field is not enclosed in double-quotes, there may not be a - * double quote inside. - * - Fields containing double-quotes, commas, and newlines _must_ be enclosed in double-quotes. + * - There is an optional header line (in the same format as the rest of the + * data). + * - Each line must have the same number of fields. Spaces are part of the + * cells. There is no trailing comma on the line. + * - A field _may_ be enclosed in double-quotes. If the field is not enclosed in + * double-quotes, there may not be a double quote inside. + * - Fields containing double-quotes, commas, and newlines _must_ be enclosed in + * double-quotes. * - Double-quotes are escaped by repeating them, like "". * * Considerations: @@ -41,428 +39,414 @@ namespace Csv { * - A parser should be liberal in accepting variations of CSV format. * * Our parser implementation details: - * - Cell types are determined automatically. There is a String, Double, and Empty cell type. + * - Cell types are determined automatically. There is a String, Double, and + * Empty cell type. * - Numeric cell must be unquoted to be treated as Double. - * - Numeric cells may be preceded and/or followed by a whitespace (space or tab) (for easy loading of hand-typed - * numeric data). - * - Standard C++, Matlab, and a few implementation-specific floating point formats are accepted as doubles. - * - A cell is treated as Empty type only if it's completely empty and unquoted; calling - * parser.useEmptyCellType(false) disables the Empty type completely. - * - If a quoted cell is preceded and/or followed by whitespace (space or tab), this whitespace is ignored. - * - A cell is treated as Double only if it's unquoted and can be completely parsed as a string representation of a - * double. - * - Escaped quotes inside unquoted strings are supported, but only if they are not at the beginning of a cell - * (ignoring the whitespace). - * - DOS, UNIX, Mac line endings are supported; Excel on Mac uses/used Mac endings for CSV. + * - Numeric cells may be preceded and/or followed by a whitespace (space or + * tab) (for easy loading of hand-typed numeric data). + * - Standard C++, Matlab, and a few implementation-specific floating point + * formats are accepted as doubles. + * - A cell is treated as Empty type only if it's completely empty and unquoted; + * calling parser.useEmptyCellType(false) disables the Empty type completely. + * - If a quoted cell is preceded and/or followed by whitespace (space or tab), + * this whitespace is ignored. + * - A cell is treated as Double only if it's unquoted and can be completely + * parsed as a string representation of a double. + * - Escaped quotes inside unquoted strings are supported, but only if they are + * not at the beginning of a cell (ignoring the whitespace). + * - DOS, UNIX, Mac line endings are supported; Excel on Mac uses/used Mac + * endings for CSV. * - Line ending format inside strings is preserved. - * - getOriginalStringView() methods may return escaped double-quotes; string_views are read-only and we - * cannot touch the original CSV data; use getCleanString() methods if you need unescaped data. + * - getOriginalStringView() methods may return escaped double-quotes; + * string_views are read-only and we cannot touch the original CSV data; use + * getCleanString() methods if you need unescaped data. */ class Parser { - public: - - /// If set to true, empty cell type is a separate type from (empty) string. - /// Default: true. - inline constexpr void useEmptyCellType(bool use_empty_cell_type); - - /// Check whether an empty cell type is a separate type from (empty) string. - [[nodiscard]] inline constexpr bool useEmptyCellType() const; - - - /// Parse CSV string data and store the results using a callback function. - /// Callback function signature: - /// void func(std::size_t row, std::size_t column, std::string_view cell_data, CellTypeHint hint). - /// \throws ParseError - template - constexpr void parse(std::string_view data, StoreCellFunction storeCellFunc) const; - - - /// Parse CSV string data into a vector of columns. - /// Accepts types like std::vector>. - /// \throws ParseError - template - constexpr void parseTo(std::string_view data, Vector2D& values) const; - - - /// Parse CSV string to std::array>, an array of columns. - /// This method conveniently wraps parseTo() to simplify compile-time parsing. - /// \return std::array, columns> - /// \throws ParseError - template - constexpr auto parseTo2DArray(std::string_view data) const; - - - private: - - /// Parser state machine state - enum class MachineState { - AtCellStart, - InLeadingWhiteSpace, - InsideUnquotedValue, - InsideQuotedValue, - AfterQuotedValue, - }; - - - /// Internal state maintained during parsing - struct ParserState { - MachineState machine_state = MachineState::AtCellStart; - std::size_t current_row = 0, current_column = 0; - std::string_view current_value; - bool escaped_quotes_encountered = false; - - - /// Switch to next column - constexpr void switchToNextColumn() - { - current_value = std::string_view(); - escaped_quotes_encountered = false; - ++current_column; - } - - - /// Switch to next line. - /// \return new current position - [[nodiscard]] constexpr std::size_t switchToNextLine(const std::string_view& data, std::size_t current_pos) - { - current_value = std::string_view(); - escaped_quotes_encountered = false; - current_column = 0; - ++current_row; - // If it's CR, and the next character is LF, skip LF as well. - if (auto next_char = peek(data, current_pos); data[current_pos] == '\r' && next_char == '\n') { - ++current_pos; - } - return current_pos; - } - - - /// Advance current value's end point by \ref by_chars - constexpr void increaseCurrentValueSize(std::size_t by_chars) - { - current_value = std::string_view(current_value.data(), current_value.size() + by_chars); - } - - - /// Reset current value to specific start point and size - constexpr void restartCurrentValue(const std::string_view& data, std::size_t current_pos, std::size_t size) - { - current_value = data.substr(current_pos, size); - escaped_quotes_encountered = false; - } - - }; - - - /// Read a character from \ref data at position (current_pos + advance_chars). - /// \return std::char_traits::eof() if position is past the data's contents. - [[nodiscard]] static constexpr std::char_traits::int_type peek(const std::string_view& data, - std::size_t current_pos, std::size_t advance_chars = 1) - { - if ((current_pos + advance_chars) < data.size()) { - return std::char_traits::to_int_type(data[current_pos + advance_chars]); - } - return std::char_traits::eof(); - } - - - /// Read a character from \ref data at position \ref pos. - /// \return std::char_traits::eof() if position is past the data's contents. - [[nodiscard]] static constexpr std::char_traits::int_type readChar( - const std::string_view& data, std::size_t pos) - { - return peek(data, pos, 0); - } - - - /// Store current value using a callback function. - /// StoreCellFunction is of the same type as in parse(). - template - constexpr void store(StoreCellFunction storeCellFunc, - const ParserState& state, CellTypeHint type_hint) const - { - if (type_hint == CellTypeHint::Empty && !use_empty_cell_type_) { - type_hint = CellTypeHint::StringWithoutEscapedQuotes; - } - storeCellFunc(state.current_row, state.current_column, state.current_value, type_hint); - } - - - /// If set to true, empty cell type is a separate type from (empty) string. - bool use_empty_cell_type_ = true; - + public: + /// If set to true, empty cell type is a separate type from (empty) string. + /// Default: true. + inline constexpr void useEmptyCellType(bool use_empty_cell_type); + + /// Check whether an empty cell type is a separate type from (empty) string. + [[nodiscard]] inline constexpr bool useEmptyCellType() const; + + /// Parse CSV string data and store the results using a callback function. + /// Callback function signature: + /// void func(std::size_t row, std::size_t column, std::string_view cell_data, + /// CellTypeHint hint). \throws ParseError + template < typename StoreCellFunction > + constexpr void parse(std::string_view data, + StoreCellFunction storeCellFunc) const; + + /// Parse CSV string data into a vector of columns. + /// Accepts types like std::vector>. + /// \throws ParseError + template < typename Vector2D > + constexpr void parseTo(std::string_view data, Vector2D& values) const; + + /// Parse CSV string to std::array>, an array + /// of columns. This method conveniently wraps parseTo() to simplify + /// compile-time parsing. \return std::array, columns> + /// \throws ParseError + template < std::size_t columns, std::size_t rows, + typename Cell = CellStringReference > + constexpr auto parseTo2DArray(std::string_view data) const; + + private: + /// Parser state machine state + enum class MachineState { + AtCellStart, + InLeadingWhiteSpace, + InsideUnquotedValue, + InsideQuotedValue, + AfterQuotedValue, + }; + + /// Internal state maintained during parsing + struct ParserState { + MachineState machine_state = MachineState::AtCellStart; + std::size_t current_row = 0, current_column = 0; + std::string_view current_value; + bool escaped_quotes_encountered = false; + + /// Switch to next column + constexpr void switchToNextColumn() { + current_value = std::string_view(); + escaped_quotes_encountered = false; + ++current_column; + } + + /// Switch to next line. + /// \return new current position + [[nodiscard]] constexpr std::size_t switchToNextLine( + const std::string_view& data, std::size_t current_pos) { + current_value = std::string_view(); + escaped_quotes_encountered = false; + current_column = 0; + ++current_row; + // If it's CR, and the next character is LF, skip LF as well. + if (auto next_char = peek(data, current_pos); + data[current_pos] == '\r' && next_char == '\n') { + ++current_pos; + } + return current_pos; + } + + /// Advance current value's end point by \ref by_chars + constexpr void increaseCurrentValueSize(std::size_t by_chars) { + current_value = std::string_view(current_value.data(), + current_value.size() + by_chars); + } + + /// Reset current value to specific start point and size + constexpr void restartCurrentValue(const std::string_view& data, + std::size_t current_pos, + std::size_t size) { + current_value = data.substr(current_pos, size); + escaped_quotes_encountered = false; + } + }; + + /// Read a character from \ref data at position (current_pos + advance_chars). + /// \return std::char_traits::eof() if position is past the data's + /// contents. + [[nodiscard]] static constexpr std::char_traits< char >::int_type peek( + const std::string_view& data, std::size_t current_pos, + std::size_t advance_chars = 1) { + if ((current_pos + advance_chars) < data.size()) { + return std::char_traits< char >::to_int_type( + data[current_pos + advance_chars]); + } + return std::char_traits< char >::eof(); + } + + /// Read a character from \ref data at position \ref pos. + /// \return std::char_traits::eof() if position is past the data's + /// contents. + [[nodiscard]] static constexpr std::char_traits< char >::int_type readChar( + const std::string_view& data, std::size_t pos) { + return peek(data, pos, 0); + } + + /// Store current value using a callback function. + /// StoreCellFunction is of the same type as in parse(). + template < typename StoreCellFunction > + constexpr void store(StoreCellFunction storeCellFunc, + const ParserState& state, CellTypeHint type_hint) const { + if (type_hint == CellTypeHint::Empty && !use_empty_cell_type_) { + type_hint = CellTypeHint::StringWithoutEscapedQuotes; + } + storeCellFunc(state.current_row, state.current_column, state.current_value, + type_hint); + } + + /// If set to true, empty cell type is a separate type from (empty) string. + bool use_empty_cell_type_ = true; }; - - - // ---- Implementation - - -constexpr void Parser::useEmptyCellType(bool use_empty_cell_type) -{ - use_empty_cell_type_ = use_empty_cell_type; +constexpr void Parser::useEmptyCellType(bool use_empty_cell_type) { + use_empty_cell_type_ = use_empty_cell_type; } - - -constexpr bool Parser::useEmptyCellType() const -{ - return use_empty_cell_type_; +constexpr bool Parser::useEmptyCellType() const { + return use_empty_cell_type_; } - - -template -constexpr void Parser::parse(std::string_view data, StoreCellFunction storeCellFunc) const -{ - ParserState state; - - for (std::size_t pos = 0; pos <= data.size(); ++pos) { - auto current_char = readChar(data, pos); - - switch (state.machine_state) { - // Starting the cell - case MachineState::AtCellStart: - { - switch(current_char) { - case ' ': - case '\t': - // Store the whitespace - state.machine_state = MachineState::InLeadingWhiteSpace; - state.restartCurrentValue(data, pos, 1); - break; - case '\"': - // Start a quoted cell. - // Discard the starting quote as well, but provide a "Quoted" hint when the quoted cell - // is stored. - state.machine_state = MachineState::InsideQuotedValue; - state.restartCurrentValue(data, pos + 1, 0); - break; - case ',': - // Empty cell. Store the value. - store(storeCellFunc, state, CellTypeHint::Empty); - state.switchToNextColumn(); - break; - case '\r': - case '\n': - // Empty cell (trailing comma; last value on the line). Store the value. - store(storeCellFunc, state, CellTypeHint::Empty); - state.machine_state = MachineState::AtCellStart; - // Handle CRLF if needed and set the state to the next line, cell start. - pos = state.switchToNextLine(data, pos); - break; - case std::char_traits::eof(): - // If it's in the first column, it's a trailing newline, nothing else to do. - // Otherwise, it's a last empty cell on the line after comma (aka trailing comma). - if (state.current_column != 0) { - store(storeCellFunc, state, CellTypeHint::Empty); - } - return; - default: - // Start an unquoted cell - state.machine_state = MachineState::InsideUnquotedValue; - state.restartCurrentValue(data, pos, 1); - break; - } - break; - } - - // Only whitespace encountered in the cell so far - case MachineState::InLeadingWhiteSpace: - { - switch(current_char) { - case ' ': - case '\t': - // More whitespace. Append to existing leading whitespace. - state.increaseCurrentValueSize(1); - break; - case '\"': - // Quote encountered. Discard the leading whitespace, start a quoted cell. - // Discard the starting quote as well, but provide a "Quoted" hint when the quoted cell - // is stored. - state.machine_state = MachineState::InsideQuotedValue; - state.restartCurrentValue(data, pos + 1, 0); - break; - case ',': - // Whitespace-only string cell. Store the value. - store(storeCellFunc, state, CellTypeHint::StringWithoutEscapedQuotes); - state.machine_state = MachineState::AtCellStart; - state.switchToNextColumn(); - break; - case '\r': - case '\n': - // Whitespace-only string cell (last value on the line). Store the value. - store(storeCellFunc, state, CellTypeHint::StringWithoutEscapedQuotes); - state.machine_state = MachineState::AtCellStart; - // Handle CRLF if needed and set the state to the next line, cell start. - pos = state.switchToNextLine(data, pos); - break; - case std::char_traits::eof(): - // Store the value, exit. - store(storeCellFunc, state, CellTypeHint::StringWithoutEscapedQuotes); - return; - default: - // Continue an unquoted cell - state.machine_state = MachineState::InsideUnquotedValue; - state.increaseCurrentValueSize(1); - break; - } - break; - } - - // We encountered non-whitespace characters in a cell and it didn't start with a quote. - case MachineState::InsideUnquotedValue: - { - switch(current_char) { - case '\"': - // Make sure the next character is also a quote, otherwise it's a format error. - // We don't accept unescaped double-quotes in unquoted strings because it leads - // to ambiguity. - if (peek(data, pos) != '\"') { - throw ParseError(state.current_row, state.current_column); - } - // Continue unquoted string, consume the second quote as well. - ++pos; - state.increaseCurrentValueSize(2); - state.escaped_quotes_encountered = true; // used for hints when storing the value - break; - case ',': - // End of cell. Store the value. - store(storeCellFunc, state, state.escaped_quotes_encountered ? - CellTypeHint::StringWithEscapedQuotes : CellTypeHint::UnquotedData); - state.machine_state = MachineState::AtCellStart; - state.switchToNextColumn(); - break; - case '\r': - case '\n': - // End of line. Store the value. - store(storeCellFunc, state, state.escaped_quotes_encountered ? - CellTypeHint::StringWithEscapedQuotes : CellTypeHint::UnquotedData); - state.machine_state = MachineState::AtCellStart; - // Handle CRLF if needed and set the state to the next line, cell start. - pos = state.switchToNextLine(data, pos); - break; - case std::char_traits::eof(): - // Store the value, exit. - store(storeCellFunc, state, state.escaped_quotes_encountered ? - CellTypeHint::StringWithEscapedQuotes : CellTypeHint::UnquotedData); - return; - default: - // Continue an unquoted cell - state.increaseCurrentValueSize(1); - break; - } - break; - } - - // The cell started with an optional whitespace and a quote, we're past the first quote. - case MachineState::InsideQuotedValue: - { - switch(current_char) { - case '\"': - // If the next character is also a quote, it's an escaped quote. - if (peek(data, pos) == '\"') { - // Continue quoted string, consume the second quote as well. - ++pos; - state.increaseCurrentValueSize(2); - state.escaped_quotes_encountered = true; // used for hints when storing the value - } else { - // End of quoted value. Store the value, discard the ending quote. - store(storeCellFunc, state, state.escaped_quotes_encountered ? - CellTypeHint::StringWithEscapedQuotes : CellTypeHint::StringWithoutEscapedQuotes); - state.machine_state = MachineState::AfterQuotedValue; - } - break; - case std::char_traits::eof(): - // EOF while inside a quoted cell, throw an error. - throw ParseError(state.current_row, state.current_column); - default: - // Continue an unquoted cell - state.increaseCurrentValueSize(1); - break; - } - break; - } - - // The quoted cell just ended - case MachineState::AfterQuotedValue: - { - switch(current_char) { - case ' ': - case '\t': - // Just whitespace, ignore it. - break; - case ',': - // End of cell. The value has been stored already, switch to the next line. - state.machine_state = MachineState::AtCellStart; - state.switchToNextColumn(); - break; - case '\r': - case '\n': - // End of line. The value has been stored already, switch to the next line. - state.machine_state = MachineState::AtCellStart; - pos = state.switchToNextLine(data, pos); - break; - case std::char_traits::eof(): - // Nothing more to do, return. - return; - default: - // Anything else is an error - throw ParseError(state.current_row, state.current_column); - } - break; - } - } - } +template < typename StoreCellFunction > +constexpr void Parser::parse(std::string_view data, + StoreCellFunction storeCellFunc) const { + ParserState state; + + for (std::size_t pos = 0; pos <= data.size(); ++pos) { + auto current_char = readChar(data, pos); + + switch (state.machine_state) { + // Starting the cell + case MachineState::AtCellStart: { + switch (current_char) { + case ' ': + case '\t': + // Store the whitespace + state.machine_state = MachineState::InLeadingWhiteSpace; + state.restartCurrentValue(data, pos, 1); + break; + case '\"': + // Start a quoted cell. + // Discard the starting quote as well, but provide a "Quoted" hint + // when the quoted cell is stored. + state.machine_state = MachineState::InsideQuotedValue; + state.restartCurrentValue(data, pos + 1, 0); + break; + case ',': + // Empty cell. Store the value. + store(storeCellFunc, state, CellTypeHint::Empty); + state.switchToNextColumn(); + break; + case '\r': + case '\n': + // Empty cell (trailing comma; last value on the line). Store the + // value. + store(storeCellFunc, state, CellTypeHint::Empty); + state.machine_state = MachineState::AtCellStart; + // Handle CRLF if needed and set the state to the next line, cell + // start. + pos = state.switchToNextLine(data, pos); + break; + case std::char_traits< char >::eof(): + // If it's in the first column, it's a trailing newline, nothing + // else to do. Otherwise, it's a last empty cell on the line after + // comma (aka trailing comma). + if (state.current_column != 0) { + store(storeCellFunc, state, CellTypeHint::Empty); + } + return; + default: + // Start an unquoted cell + state.machine_state = MachineState::InsideUnquotedValue; + state.restartCurrentValue(data, pos, 1); + break; + } + break; + } + + // Only whitespace encountered in the cell so far + case MachineState::InLeadingWhiteSpace: { + switch (current_char) { + case ' ': + case '\t': + // More whitespace. Append to existing leading whitespace. + state.increaseCurrentValueSize(1); + break; + case '\"': + // Quote encountered. Discard the leading whitespace, start a quoted + // cell. Discard the starting quote as well, but provide a "Quoted" + // hint when the quoted cell is stored. + state.machine_state = MachineState::InsideQuotedValue; + state.restartCurrentValue(data, pos + 1, 0); + break; + case ',': + // Whitespace-only string cell. Store the value. + store(storeCellFunc, state, + CellTypeHint::StringWithoutEscapedQuotes); + state.machine_state = MachineState::AtCellStart; + state.switchToNextColumn(); + break; + case '\r': + case '\n': + // Whitespace-only string cell (last value on the line). Store the + // value. + store(storeCellFunc, state, + CellTypeHint::StringWithoutEscapedQuotes); + state.machine_state = MachineState::AtCellStart; + // Handle CRLF if needed and set the state to the next line, cell + // start. + pos = state.switchToNextLine(data, pos); + break; + case std::char_traits< char >::eof(): + // Store the value, exit. + store(storeCellFunc, state, + CellTypeHint::StringWithoutEscapedQuotes); + return; + default: + // Continue an unquoted cell + state.machine_state = MachineState::InsideUnquotedValue; + state.increaseCurrentValueSize(1); + break; + } + break; + } + + // We encountered non-whitespace characters in a cell and it didn't start + // with a quote. + case MachineState::InsideUnquotedValue: { + switch (current_char) { + case '\"': + // Make sure the next character is also a quote, otherwise it's a + // format error. We don't accept unescaped double-quotes in unquoted + // strings because it leads to ambiguity. + if (peek(data, pos) != '\"') { + throw ParseError(state.current_row, state.current_column); + } + // Continue unquoted string, consume the second quote as well. + ++pos; + state.increaseCurrentValueSize(2); + state.escaped_quotes_encountered = + true; // used for hints when storing the value + break; + case ',': + // End of cell. Store the value. + store(storeCellFunc, state, + state.escaped_quotes_encountered + ? CellTypeHint::StringWithEscapedQuotes + : CellTypeHint::UnquotedData); + state.machine_state = MachineState::AtCellStart; + state.switchToNextColumn(); + break; + case '\r': + case '\n': + // End of line. Store the value. + store(storeCellFunc, state, + state.escaped_quotes_encountered + ? CellTypeHint::StringWithEscapedQuotes + : CellTypeHint::UnquotedData); + state.machine_state = MachineState::AtCellStart; + // Handle CRLF if needed and set the state to the next line, cell + // start. + pos = state.switchToNextLine(data, pos); + break; + case std::char_traits< char >::eof(): + // Store the value, exit. + store(storeCellFunc, state, + state.escaped_quotes_encountered + ? CellTypeHint::StringWithEscapedQuotes + : CellTypeHint::UnquotedData); + return; + default: + // Continue an unquoted cell + state.increaseCurrentValueSize(1); + break; + } + break; + } + + // The cell started with an optional whitespace and a quote, we're past + // the first quote. + case MachineState::InsideQuotedValue: { + switch (current_char) { + case '\"': + // If the next character is also a quote, it's an escaped quote. + if (peek(data, pos) == '\"') { + // Continue quoted string, consume the second quote as well. + ++pos; + state.increaseCurrentValueSize(2); + state.escaped_quotes_encountered = + true; // used for hints when storing the value + } else { + // End of quoted value. Store the value, discard the ending quote. + store(storeCellFunc, state, + state.escaped_quotes_encountered + ? CellTypeHint::StringWithEscapedQuotes + : CellTypeHint::StringWithoutEscapedQuotes); + state.machine_state = MachineState::AfterQuotedValue; + } + break; + case std::char_traits< char >::eof(): + // EOF while inside a quoted cell, throw an error. + throw ParseError(state.current_row, state.current_column); + default: + // Continue an unquoted cell + state.increaseCurrentValueSize(1); + break; + } + break; + } + + // The quoted cell just ended + case MachineState::AfterQuotedValue: { + switch (current_char) { + case ' ': + case '\t': + // Just whitespace, ignore it. + break; + case ',': + // End of cell. The value has been stored already, switch to the + // next line. + state.machine_state = MachineState::AtCellStart; + state.switchToNextColumn(); + break; + case '\r': + case '\n': + // End of line. The value has been stored already, switch to the + // next line. + state.machine_state = MachineState::AtCellStart; + pos = state.switchToNextLine(data, pos); + break; + case std::char_traits< char >::eof(): + // Nothing more to do, return. + return; + default: + // Anything else is an error + throw ParseError(state.current_row, state.current_column); + } + break; + } + } + } } - - -template -constexpr void Parser::parseTo(std::string_view data, Vector2D& values) const -{ - Vector2D parsed_values; - parse(data, - [&parsed_values](std::size_t row, std::size_t column, std::string_view cell_data, CellTypeHint hint) - { - if (parsed_values.size() < (column + 1)) { - parsed_values.resize(column + 1); - } - if (parsed_values[column].size() < (row + 1)) { - parsed_values[column].resize(row + 1); - } - parsed_values[column][row] = typename Vector2D::value_type::value_type(cell_data, hint); - } - ); - std::swap(values, parsed_values); +template < typename Vector2D > +constexpr void Parser::parseTo(std::string_view data, Vector2D& values) const { + Vector2D parsed_values; + parse(data, [&parsed_values](std::size_t row, std::size_t column, + std::string_view cell_data, CellTypeHint hint) { + if (parsed_values.size() < (column + 1)) { + parsed_values.resize(column + 1); + } + if (parsed_values[column].size() < (row + 1)) { + parsed_values[column].resize(row + 1); + } + parsed_values[column][row] = + typename Vector2D::value_type::value_type(cell_data, hint); + }); + std::swap(values, parsed_values); } +template < std::size_t columns, std::size_t rows, typename Cell > +constexpr auto Parser::parseTo2DArray(std::string_view data) const { + std::array< std::array< Cell, rows >, columns > matrix; + parse( + data, [&matrix](std::size_t row, std::size_t column, + std::string_view cell_data, + Csv::CellTypeHint hint) constexpr { + matrix[column][row] = Cell(cell_data, hint); + }); -template -constexpr auto Parser::parseTo2DArray(std::string_view data) const -{ - std::array, columns> matrix; - - parse(data, - [&matrix](std::size_t row, std::size_t column, - std::string_view cell_data, Csv::CellTypeHint hint) - constexpr - { - matrix[column][row] = Cell(cell_data, hint); - } - ); - - return matrix; + return matrix; } - - - -} // end ns - - +} // namespace Csv #endif diff --git a/src/tests/performance/src/performance.cpp b/src/tests/performance/src/performance.cpp index fd530d77a..33ceab3d4 100644 --- a/src/tests/performance/src/performance.cpp +++ b/src/tests/performance/src/performance.cpp @@ -22,7 +22,8 @@ * 0 command line arguments * - default mode: * - dsn = documentdb-perf-test - * - test plan file = \build\odbc\cmake\tests\performance\Performance_Test_Plan.csv + * - test plan file = + *\build\odbc\cmake\tests\performance\Performance_Test_Plan.csv * - test results file = Performance_Test_Results.csv * * 1 command line argument @@ -40,68 +41,68 @@ int main(int argc, char* argv[]) { #ifdef WIN32 - // Enable CRT for detecting memory leaks - _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); - _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + // Enable CRT for detecting memory leaks + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif #ifdef __APPLE__ - // Enable malloc logging for detecting memory leaks. - system("export MallocStackLogging=1"); + // Enable malloc logging for detecting memory leaks. + system("export MallocStackLogging=1"); #endif - // Initialize variables - std::string data_source_name, test_plan_file, test_results_file; - int output_mode = 0; // output time for exec/bind/fetch combined + // Initialize variables + std::string data_source_name, test_plan_file, test_results_file; + int output_mode = 0; // output time for exec/bind/fetch combined - // Check command line arguments - if (argc == 1) { - // default mode - data_source_name = kDsnDefault; - test_plan_file = kInputFile; - test_results_file = kOutputFile; - } else { - std::cout << "You have entered " << (argc - 1) << " arguments:\n"; - for (int i = 1; i < argc; i++) { - std::cout << argv[i] << "\n"; - } + // Check command line arguments + if (argc == 1) { + // default mode + data_source_name = kDsnDefault; + test_plan_file = kInputFile; + test_results_file = kOutputFile; + } else { + std::cout << "You have entered " << (argc - 1) << " arguments:\n"; + for (int i = 1; i < argc; i++) { + std::cout << argv[i] << "\n"; + } - if (argc == 2) { - // dsn passed in - data_source_name = argv[1]; - test_plan_file = kInputFile; - test_results_file = kOutputFile; - } else if (argc == 3) { - // input and output file passed in - data_source_name = kDsnDefault; - test_plan_file = argv[1]; - test_results_file = argv[2]; - } else if (argc == 4) { - // input file, output file and dsn passed in - test_plan_file = argv[1]; - test_results_file = argv[2]; - data_source_name = argv[3]; - } else { - std::cerr << "ERROR: invalid number of command line arguments\n"; - } + if (argc == 2) { + // dsn passed in + data_source_name = argv[1]; + test_plan_file = kInputFile; + test_results_file = kOutputFile; + } else if (argc == 3) { + // input and output file passed in + data_source_name = kDsnDefault; + test_plan_file = argv[1]; + test_results_file = argv[2]; + } else if (argc == 4) { + // input file, output file and dsn passed in + test_plan_file = argv[1]; + test_results_file = argv[2]; + data_source_name = argv[3]; + } else { + std::cerr << "ERROR: invalid number of command line arguments\n"; } + } - // Run performance test - try { - // Initialize performance test runner - performance::PerformanceTestRunner performanceTest( - test_plan_file, test_results_file, data_source_name, output_mode); + // Run performance test + try { + // Initialize performance test runner + performance::PerformanceTestRunner performanceTest( + test_plan_file, test_results_file, data_source_name, output_mode); - performanceTest.SetupConnection(); - performanceTest.ReadPerformanceTestPlan(); - performanceTest.RunPerformanceTestPlan(); - } catch (const std::runtime_error& err) { - std::cerr << err.what() << std::endl; - } + performanceTest.SetupConnection(); + performanceTest.ReadPerformanceTestPlan(); + performanceTest.RunPerformanceTestPlan(); + } catch (const std::runtime_error& err) { + std::cerr << err.what() << std::endl; + } #ifdef __APPLE__ - // Disable malloc logging and report memory leaks - system("unset MallocStackLogging"); - system("leaks performance_results > leaks_performance_results"); + // Disable malloc logging and report memory leaks + system("unset MallocStackLogging"); + system("leaks performance_results > leaks_performance_results"); #endif } diff --git a/src/tests/performance/src/performance_odbc_helper.cpp b/src/tests/performance/src/performance_odbc_helper.cpp index 7e1ebc49a..1b088c418 100644 --- a/src/tests/performance/src/performance_odbc_helper.cpp +++ b/src/tests/performance/src/performance_odbc_helper.cpp @@ -16,24 +16,25 @@ #include "performance_odbc_helper.h" -#define EXECUTION_HANDLER(throw_on_error, log_diag, handle_type, handle, \ - ret_code, statement, error_msg) \ - do { \ - (ret_code) = (statement); \ - if ((log_diag)) LogAnyDiagnostics((handle_type), (handle), (ret_code)); \ - if ((throw_on_error) && !SQL_SUCCEEDED((ret_code))) \ - throw std::runtime_error((error_msg)); \ +#define EXECUTION_HANDLER(throw_on_error, log_diag, handle_type, handle, \ + ret_code, statement, error_msg) \ + do { \ + (ret_code) = (statement); \ + if ((log_diag)) \ + LogAnyDiagnostics((handle_type), (handle), (ret_code)); \ + if ((throw_on_error) && !SQL_SUCCEEDED((ret_code))) \ + throw std::runtime_error((error_msg)); \ } while (0); #ifdef __linux__ test_string to_test_string(const std::string& src) { - return std::wstring_convert, char16_t>{} + return std::wstring_convert< std::codecvt_utf8_utf16< char16_t >, char16_t >{} .from_bytes(src); } #else test_string to_test_string(const std::string& src) { - return std::wstring_convert, wchar_t>{}.from_bytes( - src); + return std::wstring_convert< std::codecvt_utf8< wchar_t >, wchar_t >{} + .from_bytes(src); } #endif @@ -92,22 +93,22 @@ void CloseCursor(SQLHSTMT* h_statement, bool throw_on_error, bool log_diag) { } std::string wstring_to_string(const std::wstring& src) { - return std::wstring_convert, wchar_t>{}.to_bytes( - src); + return std::wstring_convert< std::codecvt_utf8< wchar_t >, wchar_t >{} + .to_bytes(src); } std::string u16string_to_string(const std::u16string& src) { - return std::wstring_convert, char16_t>{} + return std::wstring_convert< std::codecvt_utf8_utf16< char16_t >, char16_t >{} .to_bytes(src); } std::string u32string_to_string(const std::u32string& src) { - return std::wstring_convert, char32_t>{}.to_bytes( - src); + return std::wstring_convert< std::codecvt_utf8< char32_t >, char32_t >{} + .to_bytes(src); } std::u16string string_to_u16string(const std::string& src) { - return std::wstring_convert, char16_t>{} + return std::wstring_convert< std::codecvt_utf8_utf16< char16_t >, char16_t >{} .from_bytes(src); } diff --git a/src/tests/performance/src/performance_test_runner.cpp b/src/tests/performance/src/performance_test_runner.cpp index 1cf5a433f..9e024f1bd 100644 --- a/src/tests/performance/src/performance_test_runner.cpp +++ b/src/tests/performance/src/performance_test_runner.cpp @@ -28,121 +28,121 @@ *******************************************************/ void performance::PerformanceTestRunner::ListDriversInstalled() { - SQLHENV env; - SQLRETURN ret; - SQLWCHAR driver[256]; - SQLWCHAR attr[256]; - SQLSMALLINT driver_ret; - SQLSMALLINT attr_ret; - SQLUSMALLINT direction; - - SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); - - direction = SQL_FETCH_FIRST; - printf("List of drivers installed:\n"); - while (SQL_SUCCEEDED(ret = SQLDrivers(env, direction, driver, - sizeof(driver), &driver_ret, attr, - sizeof(attr), &attr_ret))) { - direction = SQL_FETCH_NEXT; - printf("%s - %s\n", wchar_to_string(driver).c_str(), - wchar_to_string(attr).c_str()); - if (ret == SQL_SUCCESS_WITH_INFO) - printf("\tdata truncation\n"); - } - printf("\n"); - - if (SQL_NULL_HENV != env) { - SQLFreeHandle(SQL_HANDLE_ENV, env); - } + SQLHENV env; + SQLRETURN ret; + SQLWCHAR driver[256]; + SQLWCHAR attr[256]; + SQLSMALLINT driver_ret; + SQLSMALLINT attr_ret; + SQLUSMALLINT direction; + + SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); + SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + + direction = SQL_FETCH_FIRST; + printf("List of drivers installed:\n"); + while (SQL_SUCCEEDED(ret = SQLDrivers(env, direction, driver, sizeof(driver), + &driver_ret, attr, sizeof(attr), + &attr_ret))) { + direction = SQL_FETCH_NEXT; + printf("%s - %s\n", wchar_to_string(driver).c_str(), + wchar_to_string(attr).c_str()); + if (ret == SQL_SUCCESS_WITH_INFO) + printf("\tdata truncation\n"); + } + printf("\n"); + + if (SQL_NULL_HENV != env) { + SQLFreeHandle(SQL_HANDLE_ENV, env); + } } void performance::PerformanceTestRunner::ListDataSourcesInstalled() { - SQLHENV env; - SQLRETURN ret; - SQLWCHAR dsn[256]; - SQLWCHAR desc[256]; - SQLSMALLINT dsn_ret; - SQLSMALLINT desc_ret; - SQLUSMALLINT direction; - - SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); - - direction = SQL_FETCH_FIRST; - printf("List of data sources installed:\n"); - while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction, dsn, sizeof(dsn), - &dsn_ret, desc, sizeof(desc), - &desc_ret))) { - direction = SQL_FETCH_NEXT; - printf("%s - %s\n", wchar_to_string(dsn).c_str(), - wchar_to_string(desc).c_str()); - if (ret == SQL_SUCCESS_WITH_INFO) - printf("\tdata truncation\n"); - } - printf("\n"); - - if (SQL_NULL_HENV != env) { - SQLFreeHandle(SQL_HANDLE_ENV, env); - } + SQLHENV env; + SQLRETURN ret; + SQLWCHAR dsn[256]; + SQLWCHAR desc[256]; + SQLSMALLINT dsn_ret; + SQLSMALLINT desc_ret; + SQLUSMALLINT direction; + + SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); + SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + + direction = SQL_FETCH_FIRST; + printf("List of data sources installed:\n"); + while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction, dsn, sizeof(dsn), + &dsn_ret, desc, sizeof(desc), + &desc_ret))) { + direction = SQL_FETCH_NEXT; + printf("%s - %s\n", wchar_to_string(dsn).c_str(), + wchar_to_string(desc).c_str()); + if (ret == SQL_SUCCESS_WITH_INFO) + printf("\tdata truncation\n"); + } + printf("\n"); + + if (SQL_NULL_HENV != env) { + SQLFreeHandle(SQL_HANDLE_ENV, env); + } } SQLRETURN performance::PerformanceTestRunner::TestDefaultDSN() { - SQLRETURN ret; - SQLHENV env = SQL_NULL_HENV; - SQLHDBC conn = SQL_NULL_HDBC; - SQLHSTMT hstmt = SQL_NULL_HSTMT; + SQLRETURN ret; + SQLHENV env = SQL_NULL_HENV; + SQLHDBC conn = SQL_NULL_HDBC; + SQLHSTMT hstmt = SQL_NULL_HSTMT; - SQLTCHAR out_conn_string[1024]; - SQLSMALLINT out_conn_string_length; + SQLTCHAR out_conn_string[1024]; + SQLSMALLINT out_conn_string_length; - test_string dsn = to_test_string("DSN=" + kDsnDefault); - test_string query = to_test_string(kTestQuery); + test_string dsn = to_test_string("DSN=" + kDsnDefault); + test_string query = to_test_string(kTestQuery); - // SQLAllocHandle (env) -> SQLSetEnvAttr -> SQLAllocHandle (conn) -> - // SQLDriverConnect (conn) -> SQLAllocHandle (statement) -> SQLExecDirec - ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); - if (ret != SQL_SUCCESS) { - return ret; - } - - ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); - if (ret != SQL_SUCCESS) { - return ret; - } - - ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); - if (ret != SQL_SUCCESS) { - return ret; - } - - ret = SQLDriverConnect(conn, nullptr, (SQLTCHAR*)dsn.c_str(), SQL_NTS, - out_conn_string, IT_SIZEOF(out_conn_string), - &out_conn_string_length, SQL_DRIVER_COMPLETE); - if (ret != SQL_SUCCESS) { - return ret; - } + // SQLAllocHandle (env) -> SQLSetEnvAttr -> SQLAllocHandle (conn) -> + // SQLDriverConnect (conn) -> SQLAllocHandle (statement) -> SQLExecDirec + ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); + if (ret != SQL_SUCCESS) { + return ret; + } - ret = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); - if (ret != SQL_SUCCESS) { - return ret; - } + ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + if (ret != SQL_SUCCESS) { + return ret; + } - ret = SQLExecDirect(hstmt, AS_SQLTCHAR(query.c_str()), SQL_NTS); + ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &conn); + if (ret != SQL_SUCCESS) { + return ret; + } - if (SQL_NULL_HSTMT != hstmt) { - CloseCursor(&hstmt, true, true); - SQLFreeHandle(SQL_HANDLE_STMT, hstmt); - } - if (SQL_NULL_HDBC != conn) { - SQLDisconnect(conn); - SQLFreeHandle(SQL_HANDLE_DBC, conn); - } - if (SQL_NULL_HENV != env) { - SQLFreeHandle(SQL_HANDLE_ENV, env); - } + ret = SQLDriverConnect(conn, nullptr, (SQLTCHAR*)dsn.c_str(), SQL_NTS, + out_conn_string, IT_SIZEOF(out_conn_string), + &out_conn_string_length, SQL_DRIVER_COMPLETE); + if (ret != SQL_SUCCESS) { + return ret; + } + ret = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt); + if (ret != SQL_SUCCESS) { return ret; + } + + ret = SQLExecDirect(hstmt, AS_SQLTCHAR(query.c_str()), SQL_NTS); + + if (SQL_NULL_HSTMT != hstmt) { + CloseCursor(&hstmt, true, true); + SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + } + if (SQL_NULL_HDBC != conn) { + SQLDisconnect(conn); + SQLFreeHandle(SQL_HANDLE_DBC, conn); + } + if (SQL_NULL_HENV != env) { + SQLFreeHandle(SQL_HANDLE_ENV, env); + } + + return ret; } /******************************************************** @@ -151,631 +151,625 @@ SQLRETURN performance::PerformanceTestRunner::TestDefaultDSN() { void performance::PerformanceTestRunner::CheckFileExtension( const std::string filename, const std::string extension) { - - std::size_t input_length = filename.length(); - std::string error_msg; - - // assume extension has length = 4 (e.g. ".xxx") - if (input_length < 6 - || extension.compare(filename.substr(input_length - 4, 4)) != 0) { - error_msg = "CONSTRUCTOR ERROR: " + filename + "must be a " + extension - + " file."; - throw std::runtime_error(error_msg); - } + std::size_t input_length = filename.length(); + std::string error_msg; + + // assume extension has length = 4 (e.g. ".xxx") + if (input_length < 6 + || extension.compare(filename.substr(input_length - 4, 4)) != 0) { + error_msg = + "CONSTRUCTOR ERROR: " + filename + "must be a " + extension + " file."; + throw std::runtime_error(error_msg); + } } void performance::PerformanceTestRunner::CheckDSN(const std::string dsn) { - SQLHENV env; - SQLRETURN ret; - SQLWCHAR dsn_wchar[256]; - SQLWCHAR desc[256]; - SQLSMALLINT dsn_ret; - SQLSMALLINT desc_ret; - SQLUSMALLINT direction; - - std::string dsn_str; - std::string error_msg; - - // Allocate environment handle - SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); - SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); - - // List data sources via driver manager to see if DSN is installed - direction = SQL_FETCH_FIRST; - while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction, dsn_wchar, - sizeof(dsn_wchar), &dsn_ret, desc, - sizeof(desc), &desc_ret))) { - dsn_str = wchar_to_string(dsn_wchar); - if (dsn_str.compare(dsn) == 0) { - // Deallocate environment handle - if (SQL_NULL_HENV != env) { - SQLFreeHandle(SQL_HANDLE_ENV, env); - } - return; // DSN found - } - direction = SQL_FETCH_NEXT; - } - - // DSN not found; Deallocate environment handle - if (SQL_NULL_HENV != env) { + SQLHENV env; + SQLRETURN ret; + SQLWCHAR dsn_wchar[256]; + SQLWCHAR desc[256]; + SQLSMALLINT dsn_ret; + SQLSMALLINT desc_ret; + SQLUSMALLINT direction; + + std::string dsn_str; + std::string error_msg; + + // Allocate environment handle + SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env); + SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + + // List data sources via driver manager to see if DSN is installed + direction = SQL_FETCH_FIRST; + while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction, dsn_wchar, + sizeof(dsn_wchar), &dsn_ret, desc, + sizeof(desc), &desc_ret))) { + dsn_str = wchar_to_string(dsn_wchar); + if (dsn_str.compare(dsn) == 0) { + // Deallocate environment handle + if (SQL_NULL_HENV != env) { SQLFreeHandle(SQL_HANDLE_ENV, env); - } - error_msg = "DSN ERROR: " + dsn + " is not installed."; - throw std::runtime_error(error_msg); + } + return; // DSN found + } + direction = SQL_FETCH_NEXT; + } + + // DSN not found; Deallocate environment handle + if (SQL_NULL_HENV != env) { + SQLFreeHandle(SQL_HANDLE_ENV, env); + } + error_msg = "DSN ERROR: " + dsn + " is not installed."; + throw std::runtime_error(error_msg); } void performance::PerformanceTestRunner::CheckOutputMode( const int output_mode) { - if (output_mode < 0 || output_mode > 3) { - throw std::invalid_argument("ERROR: output_mode must be 0, 1, 2 or 3."); - } + if (output_mode < 0 || output_mode > 3) { + throw std::invalid_argument("ERROR: output_mode must be 0, 1, 2 or 3."); + } } void performance::PerformanceTestRunner::CheckCsvHeaders() { - std::string header_value, error_msg; - bool has_escaped_quotes = false; - - // set column index in CSVHeaders structure (_headers) - for (std::size_t column = 0; column < _cell_refs.size(); ++column) { - const auto& cell = _cell_refs[column][0]; - if (cell.getType() == Csv::CellType::String) { - header_value = - cell.getOriginalStringView(&has_escaped_quotes).value(); - if (header_value.compare(QUERY_HEADER) == 0) { - _headers.idx_query = static_cast< int >(column); - } else if ((header_value.compare(LIMIT_HEADER)) == 0) { - _headers.idx_limit = static_cast< int >(column); - } else if ((header_value.compare(TEST_NAME_HEADER)) == 0) { - _headers.idx_test_name = static_cast< int >(column); - } else if ((header_value.compare(ITERATION_COUNT_HEADER)) == 0) { - _headers.idx_iteration_count = static_cast< int >(column); - } else if ((header_value.compare(SKIP_TEST_HEADER)) == 0) { - _headers.idx_skip_test = static_cast< int >(column); - } - } else { - error_msg = - "INPUT FILE ERROR: header values must be of string type in " - "input " - "file " + std::string header_value, error_msg; + bool has_escaped_quotes = false; + + // set column index in CSVHeaders structure (_headers) + for (std::size_t column = 0; column < _cell_refs.size(); ++column) { + const auto& cell = _cell_refs[column][0]; + if (cell.getType() == Csv::CellType::String) { + header_value = cell.getOriginalStringView(&has_escaped_quotes).value(); + if (header_value.compare(QUERY_HEADER) == 0) { + _headers.idx_query = static_cast< int >(column); + } else if ((header_value.compare(LIMIT_HEADER)) == 0) { + _headers.idx_limit = static_cast< int >(column); + } else if ((header_value.compare(TEST_NAME_HEADER)) == 0) { + _headers.idx_test_name = static_cast< int >(column); + } else if ((header_value.compare(ITERATION_COUNT_HEADER)) == 0) { + _headers.idx_iteration_count = static_cast< int >(column); + } else if ((header_value.compare(SKIP_TEST_HEADER)) == 0) { + _headers.idx_skip_test = static_cast< int >(column); + } + } else { + error_msg = + "INPUT FILE ERROR: header values must be of string type in " + "input " + "file " + + _input_file + "."; + throw std::runtime_error(error_msg); + } + } + + // Check that all headers have been found + if (_headers.idx_query < 0 || _headers.idx_limit < 0 + || _headers.idx_test_name < 0 || _headers.idx_iteration_count < 0 + || _headers.idx_skip_test < 0) { + error_msg = "INPUT FILE ERROR: header value(s) missing in input file " + _input_file + "."; - throw std::runtime_error(error_msg); - } - } - - // Check that all headers have been found - if (_headers.idx_query < 0 || _headers.idx_limit < 0 - || _headers.idx_test_name < 0 || _headers.idx_iteration_count < 0 - || _headers.idx_skip_test < 0) { - error_msg = "INPUT FILE ERROR: header value(s) missing in input file " - + _input_file + "."; - throw std::runtime_error(error_msg); - } + throw std::runtime_error(error_msg); + } } void performance::PerformanceTestRunner::OutputHeaders( std::ofstream& ofs) const { - std::string test_name, query, limit, iter; - test_name = TEST_NAME_HEADER; - query = QUERY_HEADER; - limit = LIMIT_HEADER; - iter = ITERATION_COUNT_HEADER; - std::string header_str; - // TODO: once standard deviation and 95th percentile are calculated, - // update output headers to include columns for both - - // Output haders are different for each output mode - if (_output_mode == 0) { - header_str = + std::string test_name, query, limit, iter; + test_name = TEST_NAME_HEADER; + query = QUERY_HEADER; + limit = LIMIT_HEADER; + iter = ITERATION_COUNT_HEADER; + std::string header_str; + // TODO: once standard deviation and 95th percentile are calculated, + // update output headers to include columns for both + + // Output haders are different for each output mode + if (_output_mode == 0) { + header_str = "Test #," + test_name + "," + query + "," + limit + "," + iter + ",Status,Average Time (ms),Max Time (ms),Min Time (ms),Median Time (ms)\n"; - } else if (_output_mode == 1) { - header_str = + } else if (_output_mode == 1) { + header_str = "Test #," + test_name + "," + query + "," + limit + "," + iter + ",Status,Average Execution Time (ms),Max Execution Time (ms),Min Execution Time (ms),Median Execution Time (ms)\n"; - } else if (_output_mode == 2) { - header_str = + } else if (_output_mode == 2) { + header_str = "Test #," + test_name + "," + query + "," + limit + "," + iter + ",Status,Average Bind and Fetch Time (ms),Max Bind and Fetch Time (ms),Min Bind and Fetch Time (ms),Median Bind and Fetch Time (ms)\n"; - } else { - header_str = + } else { + header_str = "Test #," + test_name + "," + query + "," + limit + "," + iter + ",Status,Average Total Time (ms),Max Total Time (ms),Min Total Time (ms),Median Total Time (ms)" "Average Execution Time (ms),Max Execution Time (ms),Min Execution Time (ms),Median Execution Time (ms)," "Average Bind and Fetch Time (ms),Max Bind and Fetch Time (ms),Min " "Bind and Fetch Time (ms),Median Bind and Fetch Time (ms)\n"; - } + } - ofs << header_str; + ofs << header_str; } bool performance::PerformanceTestRunner::SkipTest( const Csv::CellReference& cell_skip_test) const { - bool skip_test; - std::string skip_test_str; - std::string skip_test_header = SKIP_TEST_HEADER; - - // cell value should be string = "TRUE" or "FALSE" - if (cell_skip_test.getType() == Csv::CellType::String) { - skip_test_str = cell_skip_test.getCleanString().value(); - if (skip_test_str.compare("TRUE") == 0) { - skip_test = true; - } else if (skip_test_str.compare("FALSE") == 0) { - skip_test = false; - } else { - throw std::runtime_error( - "incorrect \"" + skip_test_header - + "\" field (must be TRUE or FALSE) for test case "); - } + bool skip_test; + std::string skip_test_str; + std::string skip_test_header = SKIP_TEST_HEADER; + + // cell value should be string = "TRUE" or "FALSE" + if (cell_skip_test.getType() == Csv::CellType::String) { + skip_test_str = cell_skip_test.getCleanString().value(); + if (skip_test_str.compare("TRUE") == 0) { + skip_test = true; + } else if (skip_test_str.compare("FALSE") == 0) { + skip_test = false; } else { - throw std::runtime_error("incorrect \"" + skip_test_header - + "\" field type for test case "); - } - return skip_test; + throw std::runtime_error( + "incorrect \"" + skip_test_header + + "\" field (must be TRUE or FALSE) for test case "); + } + } else { + throw std::runtime_error("incorrect \"" + skip_test_header + + "\" field type for test case "); + } + return skip_test; } std::string performance::PerformanceTestRunner::GetQueryString( const Csv::CellReference& cell_query) const { - std::string query; - std::string query_header = QUERY_HEADER; - - // cell value for query should be String type - if (cell_query.getType() == Csv::CellType::String) { - query = cell_query.getCleanString().value(); - } else { - throw std::runtime_error("incorrect \"" + query_header - + "\" field type for test case "); - } - return query; + std::string query; + std::string query_header = QUERY_HEADER; + + // cell value for query should be String type + if (cell_query.getType() == Csv::CellType::String) { + query = cell_query.getCleanString().value(); + } else { + throw std::runtime_error("incorrect \"" + query_header + + "\" field type for test case "); + } + return query; } int performance::PerformanceTestRunner::GetLimit( const Csv::CellReference& cell_limit) const { - double limit_dbl; - int limit_int; - std::string limit_header = LIMIT_HEADER; - - // cell value for limit should be Double type - if (cell_limit.getType() == Csv::CellType::Double) { - limit_dbl = cell_limit.getDouble().value(); - limit_dbl = limit_dbl + 0.5; // convert double to int (truncation) - limit_int = (int)limit_dbl; - if (limit_int < 1) { - throw std::runtime_error("incorrect \"" + limit_header - + "\" field (must be > 0) for test case "); - } - } else { - throw std::runtime_error("incorrect \"" + limit_header - + "\" field type for test case "); - } - return limit_int; + double limit_dbl; + int limit_int; + std::string limit_header = LIMIT_HEADER; + + // cell value for limit should be Double type + if (cell_limit.getType() == Csv::CellType::Double) { + limit_dbl = cell_limit.getDouble().value(); + limit_dbl = limit_dbl + 0.5; // convert double to int (truncation) + limit_int = (int)limit_dbl; + if (limit_int < 1) { + throw std::runtime_error("incorrect \"" + limit_header + + "\" field (must be > 0) for test case "); + } + } else { + throw std::runtime_error("incorrect \"" + limit_header + + "\" field type for test case "); + } + return limit_int; } std::string performance::PerformanceTestRunner::GetTestName( const Csv::CellReference& cell_test_name) const { - std::string test_name; - std::string test_name_header = TEST_NAME_HEADER; - - // cell value for query should be String type - if (cell_test_name.getType() == Csv::CellType::String) { - test_name = cell_test_name.getCleanString().value(); - } else { - throw std::runtime_error("incorrect \"" + test_name_header - + "\" field for test case "); - } - return test_name; + std::string test_name; + std::string test_name_header = TEST_NAME_HEADER; + + // cell value for query should be String type + if (cell_test_name.getType() == Csv::CellType::String) { + test_name = cell_test_name.getCleanString().value(); + } else { + throw std::runtime_error("incorrect \"" + test_name_header + + "\" field for test case "); + } + return test_name; } int performance::PerformanceTestRunner::GetIterationCount( const Csv::CellReference& cell_iteration_count) const { - double iteration_count_dbl; - int iteration_count_int; - std::string iteration_count_header = ITERATION_COUNT_HEADER; - - // cell value for iteration count should be Double type - if (cell_iteration_count.getType() == Csv::CellType::Double) { - iteration_count_dbl = cell_iteration_count.getDouble().value(); - iteration_count_dbl = - iteration_count_dbl + 0.5; // convert double to int (truncation) - iteration_count_int = (int)iteration_count_dbl; - if (iteration_count_int < 1) { - throw std::runtime_error("incorrect \"" + iteration_count_header - + "\" field (must be > 0) for test case "); - } - } else { - throw std::runtime_error("incorrect \"" + iteration_count_header - + "\" field type for test case "); - } - return iteration_count_int; + double iteration_count_dbl; + int iteration_count_int; + std::string iteration_count_header = ITERATION_COUNT_HEADER; + + // cell value for iteration count should be Double type + if (cell_iteration_count.getType() == Csv::CellType::Double) { + iteration_count_dbl = cell_iteration_count.getDouble().value(); + iteration_count_dbl = + iteration_count_dbl + 0.5; // convert double to int (truncation) + iteration_count_int = (int)iteration_count_dbl; + if (iteration_count_int < 1) { + throw std::runtime_error("incorrect \"" + iteration_count_header + + "\" field (must be > 0) for test case "); + } + } else { + throw std::runtime_error("incorrect \"" + iteration_count_header + + "\" field type for test case "); + } + return iteration_count_int; } bool performance::PerformanceTestRunner::HasCommaOrNewLine( const std::string str) const { - std::size_t comma_pos, newline_pos; - comma_pos = str.find(','); - newline_pos = str.find('\n'); - if (comma_pos != std::string::npos || newline_pos != std::string::npos) { - return true; - } else { - return false; - } + std::size_t comma_pos, newline_pos; + comma_pos = str.find(','); + newline_pos = str.find('\n'); + if (comma_pos != std::string::npos || newline_pos != std::string::npos) { + return true; + } else { + return false; + } } void performance::PerformanceTestRunner::RecordExecBindFetch( SQLHSTMT* hstmt, TestCase& test_case) { - // Initialize variables - SQLRETURN ret; - SQLSMALLINT total_columns = 0; - SQLROWSETSIZE row_count; - long long time_exec_ms; - long long time_bind_fetch_ms; - std::vector< Col > cols; - - // Query - std::string temp_str = - test_case.query + " LIMIT " + std::to_string(test_case.limit); - test_string query = to_test_string(temp_str); - - // Iterate and execute query -> bind -> fetch and record time - for (int iter = 0; iter < test_case.num_iterations; iter++) { - row_count = 0; - - // Execute query and record time - auto time_exec_start = std::chrono::steady_clock::now(); - ret = SQLExecDirect(*hstmt, AS_SQLTCHAR(query.c_str()), SQL_NTS); - auto time_exec_end = std::chrono::steady_clock::now(); - - if (ret != SQL_SUCCESS) { - LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); - test_case.status = error; - test_case.err_msg = "SQLExecDirect failed"; - return; // continue to next test case - } - - // Store execution time - time_exec_ms = std::chrono::duration_cast< std::chrono::milliseconds >( - time_exec_end - time_exec_start) - .count(); - test_case.time_exec_ms.push_back(time_exec_ms); - - // Get column count - ret = SQLNumResultCols(*hstmt, &total_columns); - - if (ret != SQL_SUCCESS) { - LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); - test_case.status = error; - test_case.err_msg = "SQLNumResultCols failed"; - return; // continue to next test case - } - - if (static_cast< size_t >(total_columns) > cols.size()) { - cols.resize(static_cast< size_t >(total_columns)); - } - - // Bind and fetch and record time - auto time_bind_fetch_start = std::chrono::steady_clock::now(); - for (size_t i = 0; i < static_cast< size_t >(total_columns); i++) { - ret = SQLBindCol(*hstmt, static_cast< SQLUSMALLINT >(i + 1), - SQL_C_CHAR, - static_cast< SQLPOINTER >(&cols[i].data_dat[0]), - BIND_SIZE, &cols[i].data_len); - if (ret != SQL_SUCCESS) { - LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); - test_case.status = error; - test_case.err_msg = "SQLBindCol failed"; - return; // continue to next test case - } - } - - while (SQLFetch(*hstmt) == SQL_SUCCESS) { - row_count++; - } - - auto time_bind_fetch_end = std::chrono::steady_clock::now(); - - // Store bind and fetch time - time_bind_fetch_ms = - std::chrono::duration_cast< std::chrono::milliseconds >( - time_bind_fetch_end - time_bind_fetch_start) - .count(); - test_case.time_bind_fetch_ms.push_back(time_bind_fetch_ms); - - test_case.time_ms.push_back(time_exec_ms + time_bind_fetch_ms); - } - test_case.status = success; -} - -void performance::PerformanceTestRunner::CalcStats(TestCase& test_case) { - size_t size = test_case.time_ms.size(); + // Initialize variables + SQLRETURN ret; + SQLSMALLINT total_columns = 0; + SQLROWSETSIZE row_count; + long long time_exec_ms; + long long time_bind_fetch_ms; + std::vector< Col > cols; + + // Query + std::string temp_str = + test_case.query + " LIMIT " + std::to_string(test_case.limit); + test_string query = to_test_string(temp_str); + + // Iterate and execute query -> bind -> fetch and record time + for (int iter = 0; iter < test_case.num_iterations; iter++) { + row_count = 0; + + // Execute query and record time + auto time_exec_start = std::chrono::steady_clock::now(); + ret = SQLExecDirect(*hstmt, AS_SQLTCHAR(query.c_str()), SQL_NTS); + auto time_exec_end = std::chrono::steady_clock::now(); - // check if there is any time recorded data - if (test_case.status == error) { - return; + if (ret != SQL_SUCCESS) { + LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); + test_case.status = error; + test_case.err_msg = "SQLExecDirect failed"; + return; // continue to next test case } - if (size < 1) { - throw std::runtime_error( - "there are no time data points to calculate performance stats. " - "Potential errors may be incorrect iteration count or " - "SQLExecDirect " - "failed for test case "); - } + // Store execution time + time_exec_ms = std::chrono::duration_cast< std::chrono::milliseconds >( + time_exec_end - time_exec_start) + .count(); + test_case.time_exec_ms.push_back(time_exec_ms); - if (size == 1) { - test_case.stat_info.max = test_case.time_ms[0]; - test_case.stat_info.min = test_case.time_ms[0]; - test_case.stat_info.avg = test_case.time_ms[0]; - test_case.stat_info.median = test_case.time_ms[0]; - test_case.stat_info_exec.max = test_case.time_exec_ms[0]; - test_case.stat_info_exec.min = test_case.time_exec_ms[0]; - test_case.stat_info_exec.avg = test_case.time_exec_ms[0]; - test_case.stat_info_exec.median = test_case.time_exec_ms[0]; - test_case.stat_info_exec.max = test_case.time_bind_fetch_ms[0]; - test_case.stat_info_exec.min = test_case.time_bind_fetch_ms[0]; - test_case.stat_info_exec.avg = test_case.time_bind_fetch_ms[0]; - test_case.stat_info_exec.median = test_case.time_bind_fetch_ms[0]; + // Get column count + ret = SQLNumResultCols(*hstmt, &total_columns); - } else { - // calculate max and min - test_case.stat_info.max = *std::max_element( - test_case.time_ms.begin(), test_case.time_ms.end()); - test_case.stat_info.min = *std::min_element( - test_case.time_ms.begin(), test_case.time_ms.end()); - test_case.stat_info_exec.max = *std::max_element( - test_case.time_exec_ms.begin(), test_case.time_exec_ms.end()); - test_case.stat_info_exec.min = *std::min_element( - test_case.time_exec_ms.begin(), test_case.time_exec_ms.end()); - test_case.stat_info_bind_fetch.max = - *std::max_element(test_case.time_bind_fetch_ms.begin(), - test_case.time_bind_fetch_ms.end()); - test_case.stat_info_bind_fetch.min = - *std::min_element(test_case.time_bind_fetch_ms.begin(), - test_case.time_bind_fetch_ms.end()); - - // calculate average - test_case.stat_info.avg = - std::accumulate(std::begin(test_case.time_ms), - std::end(test_case.time_ms), 0LL) - / size; - - test_case.stat_info_exec.avg = - std::accumulate(std::begin(test_case.time_exec_ms), - std::end(test_case.time_exec_ms), 0LL) - / size; - - test_case.stat_info_bind_fetch.avg = - std::accumulate(std::begin(test_case.time_bind_fetch_ms), - std::end(test_case.time_bind_fetch_ms), 0LL) - / size; - - // calculate median - std::sort(test_case.time_ms.begin(), test_case.time_ms.end()); - std::sort(test_case.time_exec_ms.begin(), - test_case.time_exec_ms.end()); - std::sort(test_case.time_bind_fetch_ms.begin(), - test_case.time_bind_fetch_ms.end()); - - test_case.stat_info.median = - (size % 2) ? test_case.time_ms[size / 2] - : ((test_case.time_ms[(size / 2) - 1] - + test_case.time_ms[size / 2]) - / 2); - test_case.stat_info_exec.median = - (size % 2) ? test_case.time_exec_ms[size / 2] - : ((test_case.time_exec_ms[(size / 2) - 1] - + test_case.time_exec_ms[size / 2]) - / 2); - test_case.stat_info_bind_fetch.median = - (size % 2) ? test_case.time_bind_fetch_ms[size / 2] - : ((test_case.time_bind_fetch_ms[(size / 2) - 1] - + test_case.time_bind_fetch_ms[size / 2]) - / 2); - - // calculate standard deviation - // TODO: calculate stdev and 95th percentile from vector of data - // e.g. test_case.stat_info.stdev = stdev; - // e.g. test_case.stat_info.percentile_95 = percentile_95; + if (ret != SQL_SUCCESS) { + LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); + test_case.status = error; + test_case.err_msg = "SQLNumResultCols failed"; + return; // continue to next test case } -} -void performance::PerformanceTestRunner::ReportTime(const TestCase& test_case) { - // Constants used for ReportTime function - const std::string sync_start = "%%__PARSE__SYNC__START__%% "; - const std::string sync_query = "%%__QUERY__%% "; - const std::string sync_case = "%%__CASE__%% "; - const std::string sync_status = "%%__STATUS__%% "; - const std::string sync_min = "%%__MIN__%% "; - const std::string sync_max = "%%__MAX__%% "; - const std::string sync_mean = "%%__MEAN__%% "; - const std::string sync_stdev = "%%__STDEV__%% "; - const std::string sync_median = "%%__MEDIAN__%% "; - const std::string sync_95th_percentile = "%%__95TH PERCENTILE__%% "; - const std::string sync_end = "%%__PARSE__SYNC__END__%% "; - // TODO: calculate standard deviation and 95th percentile so it can be reported - // calculation to be done in CalcStats() function. Once calculated, output results as well. - - // Output test case information - std::cout << sync_start << std::endl; - std::cout << sync_query; - std::cout << test_case.query << " limit " << test_case.limit << std::endl; - std::cout << sync_case << test_case.test_case_num << ": " - << test_case.test_name << std::endl; - - if (test_case.status == error) { - std::cout << sync_status << "Error: " << test_case.err_msg << "\n\n"; - return; + if (static_cast< size_t >(total_columns) > cols.size()) { + cols.resize(static_cast< size_t >(total_columns)); } - if (test_case.status == skip) { - std::cout << sync_status << "Skip test\n\n"; - return; + // Bind and fetch and record time + auto time_bind_fetch_start = std::chrono::steady_clock::now(); + for (size_t i = 0; i < static_cast< size_t >(total_columns); i++) { + ret = SQLBindCol(*hstmt, static_cast< SQLUSMALLINT >(i + 1), SQL_C_CHAR, + static_cast< SQLPOINTER >(&cols[i].data_dat[0]), + BIND_SIZE, &cols[i].data_len); + if (ret != SQL_SUCCESS) { + LogAnyDiagnostics(SQL_HANDLE_STMT, *hstmt, ret); + test_case.status = error; + test_case.err_msg = "SQLBindCol failed"; + return; // continue to next test case + } } - std::cout << sync_status << "Success" << std::endl; - - // Output test case time results - if (_output_mode == 0 || _output_mode == 3) { - std::cout << sync_min << test_case.stat_info.min << " ms" << std::endl; - std::cout << sync_max << test_case.stat_info.max << " ms" << std::endl; - std::cout << sync_mean << test_case.stat_info.avg << " ms" << std::endl; - // std::cout << sync_stdev << test_case.stat_info.stdev << " ms" << - // std::endl; - std::cout << sync_median << test_case.stat_info.median << " ms" - << std::endl; - std::cout << sync_end << std::endl; - - std::cout << "SQLExecDirect->SQLBindCol->SQLFetch Time dump: "; - for (size_t i = 0; i < test_case.time_ms.size(); i++) { - std::cout << test_case.time_ms[i] << " ms"; - if (i != (test_case.time_ms.size() - 1)) - std::cout << ", "; - } - std::cout << "\n\n"; - - } else if (_output_mode == 1) { - std::cout << sync_min << test_case.stat_info_exec.min << " ms" - << std::endl; - std::cout << sync_max << test_case.stat_info_exec.max << " ms" - << std::endl; - std::cout << sync_mean << test_case.stat_info_exec.avg << " ms" - << std::endl; - // std::cout << sync_stdev << test_case.stat_info_exec.stdev << " ms" << - // std::endl; - std::cout << sync_median << test_case.stat_info_exec.median << " ms" - << std::endl; - std::cout << sync_end << std::endl; - - std::cout << "SQLExecDirect time dump: "; - for (size_t i = 0; i < test_case.time_exec_ms.size(); i++) { - std::cout << test_case.time_exec_ms[i] << " ms"; - if (i != (test_case.time_exec_ms.size() - 1)) - std::cout << ", "; - } - std::cout << "\n\n"; - - } else if (_output_mode == 2) { - std::cout << sync_min << test_case.stat_info_bind_fetch.min << " ms" - << std::endl; - std::cout << sync_max << test_case.stat_info_bind_fetch.max << " ms" - << std::endl; - std::cout << sync_mean << test_case.stat_info_bind_fetch.avg << " ms" - << std::endl; - // std::cout << sync_stdev << test_case.stat_info_bind_fetch.stdev << " - // ms" - // << std::endl; - std::cout << sync_median << test_case.stat_info_bind_fetch.median - << " ms" << std::endl; - std::cout << sync_end << std::endl; - - std::cout << "SQLBindCol and SQLFetch time dump: "; - for (size_t i = 0; i < test_case.time_ms.size(); i++) { - std::cout << test_case.time_ms[i] << " ms"; - if (i != (test_case.time_ms.size() - 1)) - std::cout << ", "; - } - std::cout << "\n\n"; + while (SQLFetch(*hstmt) == SQL_SUCCESS) { + row_count++; } -} -void performance::PerformanceTestRunner::OutputTestCase( - std::ofstream& ofs, const TestCase& test_case) const { - // TODO: once standard deviation and 95th percentile is calculated, then - // output results to csv file as well - - // col 1 = test # - ofs << test_case.test_case_num << ","; - - // col 2 = test name - if (HasCommaOrNewLine(test_case.test_name)) { - ofs << "\"" << test_case.test_name << "\"" - << ","; - } else { - ofs << test_case.test_name << ","; - } + auto time_bind_fetch_end = std::chrono::steady_clock::now(); - // col 3 = query - if (HasCommaOrNewLine(test_case.query)) { - ofs << "\"" << test_case.query << "\"" - << ","; - } else { - ofs << test_case.query << ","; - } + // Store bind and fetch time + time_bind_fetch_ms = + std::chrono::duration_cast< std::chrono::milliseconds >( + time_bind_fetch_end - time_bind_fetch_start) + .count(); + test_case.time_bind_fetch_ms.push_back(time_bind_fetch_ms); - // col 4 = limit - ofs << test_case.limit << ","; + test_case.time_ms.push_back(time_exec_ms + time_bind_fetch_ms); + } + test_case.status = success; +} - // col 5 = iterations - ofs << test_case.num_iterations << ","; +void performance::PerformanceTestRunner::CalcStats(TestCase& test_case) { + size_t size = test_case.time_ms.size(); + + // check if there is any time recorded data + if (test_case.status == error) { + return; + } + + if (size < 1) { + throw std::runtime_error( + "there are no time data points to calculate performance stats. " + "Potential errors may be incorrect iteration count or " + "SQLExecDirect " + "failed for test case "); + } + + if (size == 1) { + test_case.stat_info.max = test_case.time_ms[0]; + test_case.stat_info.min = test_case.time_ms[0]; + test_case.stat_info.avg = test_case.time_ms[0]; + test_case.stat_info.median = test_case.time_ms[0]; + test_case.stat_info_exec.max = test_case.time_exec_ms[0]; + test_case.stat_info_exec.min = test_case.time_exec_ms[0]; + test_case.stat_info_exec.avg = test_case.time_exec_ms[0]; + test_case.stat_info_exec.median = test_case.time_exec_ms[0]; + test_case.stat_info_exec.max = test_case.time_bind_fetch_ms[0]; + test_case.stat_info_exec.min = test_case.time_bind_fetch_ms[0]; + test_case.stat_info_exec.avg = test_case.time_bind_fetch_ms[0]; + test_case.stat_info_exec.median = test_case.time_bind_fetch_ms[0]; + + } else { + // calculate max and min + test_case.stat_info.max = + *std::max_element(test_case.time_ms.begin(), test_case.time_ms.end()); + test_case.stat_info.min = + *std::min_element(test_case.time_ms.begin(), test_case.time_ms.end()); + test_case.stat_info_exec.max = *std::max_element( + test_case.time_exec_ms.begin(), test_case.time_exec_ms.end()); + test_case.stat_info_exec.min = *std::min_element( + test_case.time_exec_ms.begin(), test_case.time_exec_ms.end()); + test_case.stat_info_bind_fetch.max = + *std::max_element(test_case.time_bind_fetch_ms.begin(), + test_case.time_bind_fetch_ms.end()); + test_case.stat_info_bind_fetch.min = + *std::min_element(test_case.time_bind_fetch_ms.begin(), + test_case.time_bind_fetch_ms.end()); + + // calculate average + test_case.stat_info.avg = std::accumulate(std::begin(test_case.time_ms), + std::end(test_case.time_ms), 0LL) + / size; + + test_case.stat_info_exec.avg = + std::accumulate(std::begin(test_case.time_exec_ms), + std::end(test_case.time_exec_ms), 0LL) + / size; + + test_case.stat_info_bind_fetch.avg = + std::accumulate(std::begin(test_case.time_bind_fetch_ms), + std::end(test_case.time_bind_fetch_ms), 0LL) + / size; + + // calculate median + std::sort(test_case.time_ms.begin(), test_case.time_ms.end()); + std::sort(test_case.time_exec_ms.begin(), test_case.time_exec_ms.end()); + std::sort(test_case.time_bind_fetch_ms.begin(), + test_case.time_bind_fetch_ms.end()); + + test_case.stat_info.median = + (size % 2) + ? test_case.time_ms[size / 2] + : ((test_case.time_ms[(size / 2) - 1] + test_case.time_ms[size / 2]) + / 2); + test_case.stat_info_exec.median = + (size % 2) ? test_case.time_exec_ms[size / 2] + : ((test_case.time_exec_ms[(size / 2) - 1] + + test_case.time_exec_ms[size / 2]) + / 2); + test_case.stat_info_bind_fetch.median = + (size % 2) ? test_case.time_bind_fetch_ms[size / 2] + : ((test_case.time_bind_fetch_ms[(size / 2) - 1] + + test_case.time_bind_fetch_ms[size / 2]) + / 2); + + // calculate standard deviation + // TODO: calculate stdev and 95th percentile from vector of data + // e.g. test_case.stat_info.stdev = stdev; + // e.g. test_case.stat_info.percentile_95 = percentile_95; + } +} - // col 6 = status - if (test_case.status == error) { - ofs << "ERROR: " << test_case.err_msg << ","; - } else if (test_case.status == skip) { - ofs << "SKIP TEST,"; - } else { - ofs << "SUCCESS,"; - } +void performance::PerformanceTestRunner::ReportTime(const TestCase& test_case) { + // Constants used for ReportTime function + const std::string sync_start = "%%__PARSE__SYNC__START__%% "; + const std::string sync_query = "%%__QUERY__%% "; + const std::string sync_case = "%%__CASE__%% "; + const std::string sync_status = "%%__STATUS__%% "; + const std::string sync_min = "%%__MIN__%% "; + const std::string sync_max = "%%__MAX__%% "; + const std::string sync_mean = "%%__MEAN__%% "; + const std::string sync_stdev = "%%__STDEV__%% "; + const std::string sync_median = "%%__MEDIAN__%% "; + const std::string sync_95th_percentile = "%%__95TH PERCENTILE__%% "; + const std::string sync_end = "%%__PARSE__SYNC__END__%% "; + // TODO: calculate standard deviation and 95th percentile so it can be + // reported calculation to be done in CalcStats() function. Once calculated, + // output results as well. + + // Output test case information + std::cout << sync_start << std::endl; + std::cout << sync_query; + std::cout << test_case.query << " limit " << test_case.limit << std::endl; + std::cout << sync_case << test_case.test_case_num << ": " + << test_case.test_name << std::endl; + + if (test_case.status == error) { + std::cout << sync_status << "Error: " << test_case.err_msg << "\n\n"; + return; + } + + if (test_case.status == skip) { + std::cout << sync_status << "Skip test\n\n"; + return; + } + + std::cout << sync_status << "Success" << std::endl; + + // Output test case time results + if (_output_mode == 0 || _output_mode == 3) { + std::cout << sync_min << test_case.stat_info.min << " ms" << std::endl; + std::cout << sync_max << test_case.stat_info.max << " ms" << std::endl; + std::cout << sync_mean << test_case.stat_info.avg << " ms" << std::endl; + // std::cout << sync_stdev << test_case.stat_info.stdev << " ms" << + // std::endl; + std::cout << sync_median << test_case.stat_info.median << " ms" + << std::endl; + std::cout << sync_end << std::endl; + + std::cout << "SQLExecDirect->SQLBindCol->SQLFetch Time dump: "; + for (size_t i = 0; i < test_case.time_ms.size(); i++) { + std::cout << test_case.time_ms[i] << " ms"; + if (i != (test_case.time_ms.size() - 1)) + std::cout << ", "; + } + std::cout << "\n\n"; + + } else if (_output_mode == 1) { + std::cout << sync_min << test_case.stat_info_exec.min << " ms" << std::endl; + std::cout << sync_max << test_case.stat_info_exec.max << " ms" << std::endl; + std::cout << sync_mean << test_case.stat_info_exec.avg << " ms" + << std::endl; + // std::cout << sync_stdev << test_case.stat_info_exec.stdev << " ms" << + // std::endl; + std::cout << sync_median << test_case.stat_info_exec.median << " ms" + << std::endl; + std::cout << sync_end << std::endl; + + std::cout << "SQLExecDirect time dump: "; + for (size_t i = 0; i < test_case.time_exec_ms.size(); i++) { + std::cout << test_case.time_exec_ms[i] << " ms"; + if (i != (test_case.time_exec_ms.size() - 1)) + std::cout << ", "; + } + std::cout << "\n\n"; + + } else if (_output_mode == 2) { + std::cout << sync_min << test_case.stat_info_bind_fetch.min << " ms" + << std::endl; + std::cout << sync_max << test_case.stat_info_bind_fetch.max << " ms" + << std::endl; + std::cout << sync_mean << test_case.stat_info_bind_fetch.avg << " ms" + << std::endl; + // std::cout << sync_stdev << test_case.stat_info_bind_fetch.stdev << " + // ms" + // << std::endl; + std::cout << sync_median << test_case.stat_info_bind_fetch.median << " ms" + << std::endl; + std::cout << sync_end << std::endl; + + std::cout << "SQLBindCol and SQLFetch time dump: "; + for (size_t i = 0; i < test_case.time_ms.size(); i++) { + std::cout << test_case.time_ms[i] << " ms"; + if (i != (test_case.time_ms.size() - 1)) + std::cout << ", "; + } + std::cout << "\n\n"; + } +} - // col 7+ = results - if (_output_mode == 0) { - // Output total time exec->bind->fetch combined - if (test_case.status != success) { - ofs << ",,,\n"; - return; - } - ofs << test_case.stat_info.avg << ","; - // ofs << test_case.stat_info.stdev << ","; - ofs << test_case.stat_info.max << ","; - ofs << test_case.stat_info.min << ","; - ofs << test_case.stat_info.median << "\n"; - } else if (_output_mode == 1) { - // Output execution time only - if (test_case.status != success) { - ofs << ",,,\n"; - return; - } - ofs << test_case.stat_info_exec.avg << ","; - // ofs << test_case.stat_info_exec.stdev << ","; - ofs << test_case.stat_info_exec.max << ","; - ofs << test_case.stat_info_exec.min << ","; - ofs << test_case.stat_info_exec.median << "\n"; - } else if (_output_mode == 2) { - // Output bind->fetch time only - if (test_case.status != success) { - ofs << ",,,\n"; - return; - } - ofs << test_case.stat_info_bind_fetch.avg << ","; - // ofs << test_case.stat_info_bind_fetch.stdev << ","; - ofs << test_case.stat_info_bind_fetch.max << ","; - ofs << test_case.stat_info_bind_fetch.min << ","; - ofs << test_case.stat_info_bind_fetch.median << "\n"; - } else if (_output_mode == 3) { - if (test_case.status != success) { - ofs << ",,,,,,,,,,,\n"; - return; - } - - // Output total time exec->bind->fetch combined - ofs << test_case.stat_info.avg << ","; - // ofs << test_case.stat_info.stdev << ","; - ofs << test_case.stat_info.max << ","; - ofs << test_case.stat_info.min << ","; - ofs << test_case.stat_info.median << ","; - - // Output execution time - ofs << test_case.stat_info_exec.avg << ","; - // ofs << test_case.stat_info_exec.stdev << ","; - ofs << test_case.stat_info_exec.max << ","; - ofs << test_case.stat_info_exec.min << ","; - ofs << test_case.stat_info_exec.median << ","; - - // Output bind->fetch time - ofs << test_case.stat_info_bind_fetch.avg << ","; - // ofs << test_case.stat_info_bind_fetch.stdev << ","; - ofs << test_case.stat_info_bind_fetch.max << ","; - ofs << test_case.stat_info_bind_fetch.min << ","; - ofs << test_case.stat_info_bind_fetch.median << "\n"; - } +void performance::PerformanceTestRunner::OutputTestCase( + std::ofstream& ofs, const TestCase& test_case) const { + // TODO: once standard deviation and 95th percentile is calculated, then + // output results to csv file as well + + // col 1 = test # + ofs << test_case.test_case_num << ","; + + // col 2 = test name + if (HasCommaOrNewLine(test_case.test_name)) { + ofs << "\"" << test_case.test_name << "\"" + << ","; + } else { + ofs << test_case.test_name << ","; + } + + // col 3 = query + if (HasCommaOrNewLine(test_case.query)) { + ofs << "\"" << test_case.query << "\"" + << ","; + } else { + ofs << test_case.query << ","; + } + + // col 4 = limit + ofs << test_case.limit << ","; + + // col 5 = iterations + ofs << test_case.num_iterations << ","; + + // col 6 = status + if (test_case.status == error) { + ofs << "ERROR: " << test_case.err_msg << ","; + } else if (test_case.status == skip) { + ofs << "SKIP TEST,"; + } else { + ofs << "SUCCESS,"; + } + + // col 7+ = results + if (_output_mode == 0) { + // Output total time exec->bind->fetch combined + if (test_case.status != success) { + ofs << ",,,\n"; + return; + } + ofs << test_case.stat_info.avg << ","; + // ofs << test_case.stat_info.stdev << ","; + ofs << test_case.stat_info.max << ","; + ofs << test_case.stat_info.min << ","; + ofs << test_case.stat_info.median << "\n"; + } else if (_output_mode == 1) { + // Output execution time only + if (test_case.status != success) { + ofs << ",,,\n"; + return; + } + ofs << test_case.stat_info_exec.avg << ","; + // ofs << test_case.stat_info_exec.stdev << ","; + ofs << test_case.stat_info_exec.max << ","; + ofs << test_case.stat_info_exec.min << ","; + ofs << test_case.stat_info_exec.median << "\n"; + } else if (_output_mode == 2) { + // Output bind->fetch time only + if (test_case.status != success) { + ofs << ",,,\n"; + return; + } + ofs << test_case.stat_info_bind_fetch.avg << ","; + // ofs << test_case.stat_info_bind_fetch.stdev << ","; + ofs << test_case.stat_info_bind_fetch.max << ","; + ofs << test_case.stat_info_bind_fetch.min << ","; + ofs << test_case.stat_info_bind_fetch.median << "\n"; + } else if (_output_mode == 3) { + if (test_case.status != success) { + ofs << ",,,,,,,,,,,\n"; + return; + } + + // Output total time exec->bind->fetch combined + ofs << test_case.stat_info.avg << ","; + // ofs << test_case.stat_info.stdev << ","; + ofs << test_case.stat_info.max << ","; + ofs << test_case.stat_info.min << ","; + ofs << test_case.stat_info.median << ","; + + // Output execution time + ofs << test_case.stat_info_exec.avg << ","; + // ofs << test_case.stat_info_exec.stdev << ","; + ofs << test_case.stat_info_exec.max << ","; + ofs << test_case.stat_info_exec.min << ","; + ofs << test_case.stat_info_exec.median << ","; + + // Output bind->fetch time + ofs << test_case.stat_info_bind_fetch.avg << ","; + // ofs << test_case.stat_info_bind_fetch.stdev << ","; + ofs << test_case.stat_info_bind_fetch.max << ","; + ofs << test_case.stat_info_bind_fetch.min << ","; + ofs << test_case.stat_info_bind_fetch.median << "\n"; + } } /******************************************************** @@ -783,35 +777,36 @@ void performance::PerformanceTestRunner::OutputTestCase( *******************************************************/ performance::PerformanceTestRunner::PerformanceTestRunner() { - // check if DSN is installed - CheckDSN(kDsnDefault); + // check if DSN is installed + CheckDSN(kDsnDefault); } performance::PerformanceTestRunner::PerformanceTestRunner( const std::string test_plan_csv, const std::string output_file_csv, const std::string dsn, const int output_mode) { - // check input arguments - CheckFileExtension(test_plan_csv, ".csv"); - CheckFileExtension(output_file_csv, ".csv"); - CheckDSN(dsn); - CheckOutputMode(output_mode); - - _input_file = test_plan_csv; - _output_file = output_file_csv; - _dsn = dsn; - _output_mode = output_mode; + // check input arguments + CheckFileExtension(test_plan_csv, ".csv"); + CheckFileExtension(output_file_csv, ".csv"); + CheckDSN(dsn); + CheckOutputMode(output_mode); + + _input_file = test_plan_csv; + _output_file = output_file_csv; + _dsn = dsn; + _output_mode = output_mode; } performance::PerformanceTestRunner::~PerformanceTestRunner() { - // Statement handle is allocated and deallocated inside RunPerformanceTestPlan() function - // If SetupConnection() function is run, connection and environment handles are set - if (SQL_NULL_HDBC != _conn) { - SQLDisconnect(_conn); - SQLFreeHandle(SQL_HANDLE_DBC, _conn); - } - if (SQL_NULL_HENV != _env) { - SQLFreeHandle(SQL_HANDLE_ENV, _env); - } + // Statement handle is allocated and deallocated inside + // RunPerformanceTestPlan() function If SetupConnection() function is run, + // connection and environment handles are set + if (SQL_NULL_HDBC != _conn) { + SQLDisconnect(_conn); + SQLFreeHandle(SQL_HANDLE_DBC, _conn); + } + if (SQL_NULL_HENV != _env) { + SQLFreeHandle(SQL_HANDLE_ENV, _env); + } } /******************************************************** @@ -819,13 +814,13 @@ performance::PerformanceTestRunner::~PerformanceTestRunner() { *******************************************************/ void performance::PerformanceTestRunner::SetDSN(const std::string dsn) { - CheckDSN(dsn); - _dsn = dsn; + CheckDSN(dsn); + _dsn = dsn; } void performance::PerformanceTestRunner::SetOutputMode(const int output_mode) { - CheckOutputMode(output_mode); - _output_mode = output_mode; + CheckOutputMode(output_mode); + _output_mode = output_mode; } /******************************************************** @@ -833,176 +828,171 @@ void performance::PerformanceTestRunner::SetOutputMode(const int output_mode) { *******************************************************/ void performance::PerformanceTestRunner::ReadPerformanceTestPlan() { - // Read input csv file to string - std::ifstream ifs(_input_file, std::ios::binary); - Csv::Parser parser; - std::string error_msg; - - if (!ifs.is_open()) { - error_msg = - "INPUT FILE ERROR: failed to open input file " + _input_file + "."; - throw std::runtime_error(error_msg); - } + // Read input csv file to string + std::ifstream ifs(_input_file, std::ios::binary); + Csv::Parser parser; + std::string error_msg; + + if (!ifs.is_open()) { + error_msg = + "INPUT FILE ERROR: failed to open input file " + _input_file + "."; + throw std::runtime_error(error_msg); + } - std::string csv_data((std::istreambuf_iterator< char >(ifs)), - (std::istreambuf_iterator< char >())); + std::string csv_data((std::istreambuf_iterator< char >(ifs)), + (std::istreambuf_iterator< char >())); - _csv_data = csv_data; // store csv_data + _csv_data = csv_data; // store csv_data - ifs.close(); // close csv file - if (ifs.is_open()) { - error_msg = - "INPUT FILE ERROR: failed to close input file " + _input_file + "."; - throw std::runtime_error(error_msg); - } + ifs.close(); // close csv file + if (ifs.is_open()) { + error_msg = + "INPUT FILE ERROR: failed to close input file " + _input_file + "."; + throw std::runtime_error(error_msg); + } - // parse data into _cell_refs and check headers - parser.parseTo(_csv_data, _cell_refs); + // parse data into _cell_refs and check headers + parser.parseTo(_csv_data, _cell_refs); - CheckCsvHeaders(); + CheckCsvHeaders(); } void performance::PerformanceTestRunner::SetupConnection() { - SQLTCHAR out_conn_string[1024]; - SQLSMALLINT out_conn_string_length; - SQLRETURN ret; - test_string dsn = to_test_string("DSN=" + _dsn); - std::string error_msg; - - ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_env); - if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { - error_msg = - "SQLAllocHandle ERROR: failed to allocate environment handle."; - throw std::runtime_error(error_msg); - } - - ret = SQLSetEnvAttr(_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); - if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { - error_msg = "SQLSetEnvAttr ERROR: failed to set environment attribute."; - throw std::runtime_error(error_msg); - } + SQLTCHAR out_conn_string[1024]; + SQLSMALLINT out_conn_string_length; + SQLRETURN ret; + test_string dsn = to_test_string("DSN=" + _dsn); + std::string error_msg; + + ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &_env); + if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { + error_msg = "SQLAllocHandle ERROR: failed to allocate environment handle."; + throw std::runtime_error(error_msg); + } - ret = SQLAllocHandle(SQL_HANDLE_DBC, _env, &_conn); - if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { - error_msg = - "SQLAllocHandle ERROR: failed to allocate connection handle."; - throw std::runtime_error(error_msg); - } + ret = SQLSetEnvAttr(_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); + if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { + error_msg = "SQLSetEnvAttr ERROR: failed to set environment attribute."; + throw std::runtime_error(error_msg); + } - ret = SQLDriverConnect(_conn, NULL, (SQLTCHAR*)dsn.c_str(), SQL_NTS, - out_conn_string, IT_SIZEOF(out_conn_string), - &out_conn_string_length, SQL_DRIVER_COMPLETE); - if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { - error_msg = - "SQLDriverConnect ERROR: failed to connect to DSN = " + _dsn + "."; - throw std::runtime_error(error_msg); - } else if (ret == SQL_NO_DATA) { - error_msg = "SQLDriverConnect ERROR: no data in DSN = " + _dsn + "."; - throw std::runtime_error(error_msg); - } else if (ret == SQL_STILL_EXECUTING) { - error_msg = "SQLDriverConnect ERROR: still trying to connect to DSN = " - + _dsn + "."; - throw std::runtime_error(error_msg); - } - // Connection established: connection and environment handles are set + ret = SQLAllocHandle(SQL_HANDLE_DBC, _env, &_conn); + if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { + error_msg = "SQLAllocHandle ERROR: failed to allocate connection handle."; + throw std::runtime_error(error_msg); + } + + ret = SQLDriverConnect(_conn, NULL, (SQLTCHAR*)dsn.c_str(), SQL_NTS, + out_conn_string, IT_SIZEOF(out_conn_string), + &out_conn_string_length, SQL_DRIVER_COMPLETE); + if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { + error_msg = + "SQLDriverConnect ERROR: failed to connect to DSN = " + _dsn + "."; + throw std::runtime_error(error_msg); + } else if (ret == SQL_NO_DATA) { + error_msg = "SQLDriverConnect ERROR: no data in DSN = " + _dsn + "."; + throw std::runtime_error(error_msg); + } else if (ret == SQL_STILL_EXECUTING) { + error_msg = "SQLDriverConnect ERROR: still trying to connect to DSN = " + + _dsn + "."; + throw std::runtime_error(error_msg); + } + // Connection established: connection and environment handles are set } void performance::PerformanceTestRunner::RunPerformanceTestPlan() { - - std::size_t num_test_cases; - bool skip_test = true; - TestCase test_case; - std::string query; - std::string test_name; - int iteration_count; - int limit; - std::string error_msg; - SQLRETURN ret; - - // setup output file - std::ofstream ofs; - ofs.open(_output_file); - if (!ofs.is_open()) { - error_msg = "OUTPUT FILE ERROR: failed to open output file " - + _output_file + "."; + std::size_t num_test_cases; + bool skip_test = true; + TestCase test_case; + std::string query; + std::string test_name; + int iteration_count; + int limit; + std::string error_msg; + SQLRETURN ret; + + // setup output file + std::ofstream ofs; + ofs.open(_output_file); + if (!ofs.is_open()) { + error_msg = + "OUTPUT FILE ERROR: failed to open output file " + _output_file + "."; + throw std::runtime_error(error_msg); + } + OutputHeaders(ofs); + + // iterate through each test case and output results + num_test_cases = _cell_refs[_headers.idx_query].size(); + for (std::size_t row = 1; row < num_test_cases; ++row) { + try { + // get test case fields + const auto& cell_query = _cell_refs[_headers.idx_query][row]; + const auto& cell_limit = _cell_refs[_headers.idx_limit][row]; + const auto& cell_test_name = _cell_refs[_headers.idx_test_name][row]; + const auto& cell_iteration_count = + _cell_refs[_headers.idx_iteration_count][row]; + + query = GetQueryString(cell_query); + limit = GetLimit(cell_limit); + test_name = GetTestName(cell_test_name); + iteration_count = GetIterationCount(cell_iteration_count); + + // Store test case info + test_case.test_case_num = static_cast< int >(row); + test_case.test_name = test_name; + test_case.query = query; + test_case.limit = limit; + test_case.num_iterations = iteration_count; + + // check skip_test field + const auto& cell_skip_test = _cell_refs[_headers.idx_skip_test][row]; + skip_test = SkipTest(cell_skip_test); + if (skip_test) { + test_case.status = skip; + ReportTime(test_case); // reports that test was skipped + OutputTestCase(ofs, test_case); + _results.push_back(test_case); + continue; // skip test case + } + + // Allocate statement handle for test case + ret = SQLAllocHandle(SQL_HANDLE_STMT, _conn, &_hstmt); + if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { + error_msg = + "SQLAllocHandle ERROR: failed to allocate connection " + "statement " + "handle."; throw std::runtime_error(error_msg); - } - OutputHeaders(ofs); - - // iterate through each test case and output results - num_test_cases = _cell_refs[_headers.idx_query].size(); - for (std::size_t row = 1; row < num_test_cases; ++row) { - try { - // get test case fields - const auto& cell_query = _cell_refs[_headers.idx_query][row]; - const auto& cell_limit = _cell_refs[_headers.idx_limit][row]; - const auto& cell_test_name = - _cell_refs[_headers.idx_test_name][row]; - const auto& cell_iteration_count = - _cell_refs[_headers.idx_iteration_count][row]; - - query = GetQueryString(cell_query); - limit = GetLimit(cell_limit); - test_name = GetTestName(cell_test_name); - iteration_count = GetIterationCount(cell_iteration_count); - - // Store test case info - test_case.test_case_num = static_cast< int >(row); - test_case.test_name = test_name; - test_case.query = query; - test_case.limit = limit; - test_case.num_iterations = iteration_count; - - // check skip_test field - const auto& cell_skip_test = - _cell_refs[_headers.idx_skip_test][row]; - skip_test = SkipTest(cell_skip_test); - if (skip_test) { - test_case.status = skip; - ReportTime(test_case); // reports that test was skipped - OutputTestCase(ofs, test_case); - _results.push_back(test_case); - continue; // skip test case - } - - // Allocate statement handle for test case - ret = SQLAllocHandle(SQL_HANDLE_STMT, _conn, &_hstmt); - if (ret == SQL_INVALID_HANDLE || ret == SQL_ERROR) { - error_msg = - "SQLAllocHandle ERROR: failed to allocate connection " - "statement " - "handle."; - throw std::runtime_error(error_msg); - } - - // Exec -> Bind -> Fetch (record time) - RecordExecBindFetch(&_hstmt, test_case); - - // Calculate stats for recorded time - CalcStats(test_case); - ReportTime(test_case); - - // Output results to csv file - OutputTestCase(ofs, test_case); - _results.push_back(test_case); // store test case data - - // Reset test_case variable - test_case.query.clear(); - test_case.test_name.clear(); - test_case.time_ms.clear(); - - // Deallocate Statement Handle - if (SQL_NULL_HSTMT != _hstmt) { - CloseCursor(&_hstmt, true, true); - SQLFreeHandle(SQL_HANDLE_STMT, _hstmt); - } - - } catch (std::runtime_error& err) { - error_msg = "TESTCASE ERROR: " + (std::string)err.what() - + std::to_string(row) + "."; - ofs.close(); - throw std::runtime_error(error_msg); - } - } - ofs.close(); + } + + // Exec -> Bind -> Fetch (record time) + RecordExecBindFetch(&_hstmt, test_case); + + // Calculate stats for recorded time + CalcStats(test_case); + ReportTime(test_case); + + // Output results to csv file + OutputTestCase(ofs, test_case); + _results.push_back(test_case); // store test case data + + // Reset test_case variable + test_case.query.clear(); + test_case.test_name.clear(); + test_case.time_ms.clear(); + + // Deallocate Statement Handle + if (SQL_NULL_HSTMT != _hstmt) { + CloseCursor(&_hstmt, true, true); + SQLFreeHandle(SQL_HANDLE_STMT, _hstmt); + } + + } catch (std::runtime_error& err) { + error_msg = "TESTCASE ERROR: " + (std::string)err.what() + + std::to_string(row) + "."; + ofs.close(); + throw std::runtime_error(error_msg); + } + } + ofs.close(); }