You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2018/08/30 12:24:12 UTC
[06/45] ignite git commit: IGNITE-4191: MVCC and transactional SQL
support. Joint multi-man-years efforts of Semen Boikov, Igor Seliverstov,
Alexander Paschenko, Igor Sapego, Sergey Kalashnikov, Roman Kondakov,
Pavel Kuznetsov, Ivan Pavlukhin, Andrey Mas
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp b/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
index 630597c..7842704 100644
--- a/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/sql_get_info_test.cpp
@@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
CheckStrInfo(SQL_LIKE_ESCAPE_CLAUSE, "N");
CheckStrInfo(SQL_MAX_ROW_SIZE_INCLUDES_LONG, "Y");
CheckStrInfo(SQL_MULT_RESULT_SETS, "N");
- CheckStrInfo(SQL_MULTIPLE_ACTIVE_TXN, "N");
+ CheckStrInfo(SQL_MULTIPLE_ACTIVE_TXN, "Y");
CheckStrInfo(SQL_ORDER_BY_COLUMNS_IN_SELECT, "N");
CheckStrInfo(SQL_PROCEDURE_TERM, "stored procedure");
CheckStrInfo(SQL_PROCEDURES, "N");
@@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
CheckIntInfo(SQL_CREATE_VIEW, 0);
CheckIntInfo(SQL_CURSOR_SENSITIVITY, SQL_INSENSITIVE);
CheckIntInfo(SQL_DDL_INDEX, SQL_DI_CREATE_INDEX | SQL_DI_DROP_INDEX);
- CheckIntInfo(SQL_DEFAULT_TXN_ISOLATION, 0);
+ CheckIntInfo(SQL_DEFAULT_TXN_ISOLATION, SQL_TXN_REPEATABLE_READ);
CheckIntInfo(SQL_DROP_ASSERTION, 0);
CheckIntInfo(SQL_DROP_CHARACTER_SET, 0);
CheckIntInfo(SQL_DROP_COLLATION, 0);
@@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
CheckIntInfo(SQL_SQL92_GRANT, 0);
CheckIntInfo(SQL_SQL92_REVOKE, 0);
CheckIntInfo(SQL_STANDARD_CLI_CONFORMANCE, 0);
- CheckIntInfo(SQL_TXN_ISOLATION_OPTION, 0);
+ CheckIntInfo(SQL_TXN_ISOLATION_OPTION, SQL_TXN_REPEATABLE_READ);
CheckIntInfo(SQL_UNION, SQL_U_UNION | SQL_U_UNION_ALL);
CheckIntInfo(SQL_SCHEMA_USAGE, SQL_SU_DML_STATEMENTS | SQL_SU_TABLE_DEFINITION | SQL_SU_PRIVILEGE_DEFINITION |
@@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE(TestValues)
CheckShortInfo(SQL_MAX_CONCURRENT_ACTIVITIES, 0);
CheckShortInfo(SQL_CURSOR_COMMIT_BEHAVIOR, SQL_CB_PRESERVE);
CheckShortInfo(SQL_CURSOR_ROLLBACK_BEHAVIOR, SQL_CB_PRESERVE);
- CheckShortInfo(SQL_TXN_CAPABLE, SQL_TC_NONE);
+ CheckShortInfo(SQL_TXN_CAPABLE, SQL_TC_DDL_COMMIT);
CheckShortInfo(SQL_QUOTED_IDENTIFIER_CASE, SQL_IC_SENSITIVE);
CheckShortInfo(SQL_ACTIVE_ENVIRONMENTS, 0);
CheckShortInfo(SQL_CONCAT_NULL_BEHAVIOR, SQL_CB_NULL);
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/transaction_test.cpp b/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
new file mode 100644
index 0000000..fb2b6c9
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/transaction_test.cpp
@@ -0,0 +1,738 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <string>
+
+#ifndef _MSC_VER
+# define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignition.h"
+
+#include "test_utils.h"
+#include "odbc_test_suite.h"
+
+using namespace ignite;
+using namespace ignite_test;
+
+using namespace boost::unit_test;
+
+/**
+ * Test setup fixture.
+ */
+struct TransactionTestSuiteFixture : public odbc::OdbcTestSuite
+{
+ static Ignite StartAdditionalNode(const char* name)
+ {
+ return StartTestNode("queries-transaction.xml", name);
+ }
+
+ /**
+ * Constructor.
+ */
+ TransactionTestSuiteFixture() :
+ grid(StartAdditionalNode("NodeMain"))
+ {
+ // No-op.
+ }
+
+ /**
+ * Destructor.
+ */
+ ~TransactionTestSuiteFixture()
+ {
+ // No-op.
+ }
+
+ /**
+ * Insert test string value in cache and make all the neccessary checks.
+ *
+ * @param key Key.
+ * @param value Value.
+ */
+ void InsertTestValue(int64_t key, const std::string& value)
+ {
+ SQLCHAR insertReq[] = "INSERT INTO TestType(_key, strField) VALUES(?, ?)";
+
+ SQLRETURN ret;
+
+ ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ char strField[1024] = { 0 };
+ SQLLEN strFieldLen = 0;
+
+ ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(strField),
+ sizeof(strField), &strField, sizeof(strField), &strFieldLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ strncpy(strField, value.c_str(), sizeof(strField));
+ strFieldLen = SQL_NTS;
+
+ ret = SQLExecute(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLLEN affected = 0;
+ ret = SQLRowCount(stmt, &affected);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_CHECK_EQUAL(affected, 1);
+
+ ret = SQLMoreResults(stmt);
+
+ if (ret != SQL_NO_DATA)
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ResetStatement();
+ }
+
+ /**
+ * Update test string value in cache and make all the neccessary checks.
+ *
+ * @param key Key.
+ * @param value Value.
+ */
+ void UpdateTestValue(int64_t key, const std::string& value)
+ {
+ SQLCHAR insertReq[] = "UPDATE TestType SET strField=? WHERE _key=?";
+
+ SQLRETURN ret;
+
+ ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ char strField[1024] = { 0 };
+ SQLLEN strFieldLen = 0;
+
+ ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(strField),
+ sizeof(strField), &strField, sizeof(strField), &strFieldLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ strncpy(strField, value.c_str(), sizeof(strField));
+ strFieldLen = SQL_NTS;
+
+ ret = SQLExecute(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLLEN affected = 0;
+ ret = SQLRowCount(stmt, &affected);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_CHECK_EQUAL(affected, 1);
+
+ ret = SQLMoreResults(stmt);
+
+ if (ret != SQL_NO_DATA)
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ResetStatement();
+ }
+
+ /**
+ * Delete test string value.
+ *
+ * @param key Key.
+ */
+ void DeleteTestValue(int64_t key)
+ {
+ SQLCHAR insertReq[] = "DELETE FROM TestType WHERE _key=?";
+
+ SQLRETURN ret;
+
+ ret = SQLPrepare(stmt, insertReq, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLExecute(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLLEN affected = 0;
+ ret = SQLRowCount(stmt, &affected);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_CHECK_EQUAL(affected, 1);
+
+ ret = SQLMoreResults(stmt);
+
+ if (ret != SQL_NO_DATA)
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ResetStatement();
+ }
+
+ /**
+ * Selects and checks the value.
+ *
+ * @param key Key.
+ * @param expect Expected value.
+ */
+ void CheckTestValue(int64_t key, const std::string& expect)
+ {
+ // Just selecting everything to make sure everything is OK
+ SQLCHAR selectReq[] = "SELECT strField FROM TestType WHERE _key = ?";
+
+ char strField[1024] = { 0 };
+ SQLLEN strFieldLen = 0;
+
+ SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_CHAR, &strField, sizeof(strField), &strFieldLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFetch(stmt);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_CHECK_EQUAL(std::string(strField, strFieldLen), expect);
+
+ ret = SQLFetch(stmt);
+
+ BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
+
+ ret = SQLMoreResults(stmt);
+
+ if (ret != SQL_NO_DATA)
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ResetStatement();
+ }
+
+ /**
+ * Selects and checks that value is absent.
+ *
+ * @param key Key.
+ */
+ void CheckNoTestValue(int64_t key)
+ {
+ // Just selecting everything to make sure everything is OK
+ SQLCHAR selectReq[] = "SELECT strField FROM TestType WHERE _key = ?";
+
+ char strField[1024] = { 0 };
+ SQLLEN strFieldLen = 0;
+
+ SQLRETURN ret = SQLBindCol(stmt, 1, SQL_C_CHAR, &strField, sizeof(strField), &strFieldLen);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_BIGINT, 0, 0, &key, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLExecDirect(stmt, selectReq, sizeof(selectReq));
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFetch(stmt);
+
+ BOOST_CHECK_EQUAL(ret, SQL_NO_DATA);
+
+ ret = SQLMoreResults(stmt);
+
+ if (ret != SQL_NO_DATA)
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ResetStatement();
+ }
+
+ /**
+ * Reset statement state.
+ */
+ void ResetStatement()
+ {
+ SQLRETURN ret = SQLFreeStmt(stmt, SQL_RESET_PARAMS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFreeStmt(stmt, SQL_UNBIND);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+ }
+
+ /** Node started during the test. */
+ Ignite grid;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TransactionTestSuite, TransactionTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionCommit)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackInsert)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackUpdate1)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackUpdate2)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackDelete1)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ DeleteTestValue(42);
+
+ CheckNoTestValue(42);
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionRollbackDelete2)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+
+ DeleteTestValue(42);
+
+ CheckNoTestValue(42);
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeError)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=error");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ BOOST_CHECK_EQUAL(ret, SQL_ERROR);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeIgnore)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=ignore");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionConnectionTxModeCommit)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=commit");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentCommit)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackInsert)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackUpdate1)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackUpdate2)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackDelete1)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ DeleteTestValue(42);
+
+ CheckNoTestValue(42);
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentRollbackDelete2)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ CheckTestValue(42, "Some");
+
+ ret = SQLEndTran(SQL_HANDLE_DBC, dbc, SQL_COMMIT);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+
+ DeleteTestValue(42);
+
+ CheckNoTestValue(42);
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeError)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=error");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ BOOST_CHECK_EQUAL(ret, SQL_ERROR);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeIgnore)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=ignore");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckNoTestValue(42);
+}
+
+BOOST_AUTO_TEST_CASE(TransactionEnvironmentTxModeCommit)
+{
+ Connect("DRIVER={Apache Ignite};address=127.0.0.1:11110;schema=cache;nested_tx_mode=commit");
+
+ SQLRETURN ret = SQLSetConnectAttr(dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ InsertTestValue(42, "Some");
+
+ ret = ExecQuery("BEGIN");
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_DBC, dbc);
+
+ UpdateTestValue(42, "Other");
+
+ CheckTestValue(42, "Other");
+
+ ret = SQLEndTran(SQL_HANDLE_ENV, env, SQL_ROLLBACK);
+
+ ODBC_FAIL_ON_ERROR(ret, SQL_HANDLE_ENV, env);
+
+ CheckTestValue(42, "Some");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am
index 90e4dc9..f706f4f 100644
--- a/modules/platforms/cpp/odbc/Makefile.am
+++ b/modules/platforms/cpp/odbc/Makefile.am
@@ -83,6 +83,7 @@ libignite_odbc_la_SOURCES = \
src/protocol_version.cpp \
src/result_page.cpp \
src/row.cpp \
+ src/nested_tx_mode.cpp \
src/message.cpp \
src/column.cpp \
src/statement.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
index c19f29d..27de7e8 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
@@ -26,6 +26,7 @@
#include "ignite/odbc/config/settable_value.h"
#include "ignite/odbc/ssl/ssl_mode.h"
#include "ignite/odbc/end_point.h"
+#include "ignite/odbc/nested_tx_mode.h"
namespace ignite
{
@@ -104,6 +105,9 @@ namespace ignite
/** Default value for password attribute. */
static const std::string password;
+
+ /** Default value for nestedTxMode attribute. */
+ static const NestedTxMode::Type nestedTxMode;
};
/**
@@ -537,6 +541,27 @@ namespace ignite
bool IsPasswordSet() const;
/**
+ * Get nested transaction mode.
+ *
+ * @return Nested transaction mode.
+ */
+ NestedTxMode::Type GetNestedTxMode() const;
+
+ /**
+ * Set nested transaction mode.
+ *
+ * @param mode Nested transaction mode.
+ */
+ void SetNestedTxMode(NestedTxMode::Type mode);
+
+ /**
+ * Check if the value set.
+ *
+ * @return @true if the value set.
+ */
+ bool IsNestedTxModeSet() const;
+
+ /**
* Get argument map.
*
* @param res Resulting argument map.
@@ -613,6 +638,9 @@ namespace ignite
/** Password. */
SettableValue<std::string> password;
+
+ /** Nested transaction mode. */
+ SettableValue<NestedTxMode::Type> nestedTxMode;
};
template<>
@@ -642,6 +670,10 @@ namespace ignite
template<>
void Configuration::AddToMap<ssl::SslMode::Type>(ArgumentMap& map, const std::string& key,
const SettableValue<ssl::SslMode::Type>& value);
+
+ template<>
+ void Configuration::AddToMap<NestedTxMode::Type>(ArgumentMap& map, const std::string& key,
+ const SettableValue<NestedTxMode::Type>& value);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h b/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
index 2bfe331..605109e 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/connection_string_parser.h
@@ -97,6 +97,9 @@ namespace ignite
/** Connection attribute keyword for password attribute. */
static const std::string password;
+
+ /** Connection attribute keyword for nestedTxMode attribute. */
+ static const std::string nestedTxMode;
};
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
index 68d7816..b3ae5fc 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -33,6 +33,7 @@ namespace ignite
{
namespace odbc
{
+ class Environment;
class Statement;
/**
@@ -99,6 +100,11 @@ namespace ignite
void Release();
/**
+ * Deregister self from the parent.
+ */
+ void Deregister();
+
+ /**
* Create statement associated with the connection.
*
* @return Pointer to valid instance on success and NULL on failure.
@@ -141,6 +147,13 @@ namespace ignite
const config::Configuration& GetConfiguration() const;
/**
+ * Is auto commit.
+ *
+ * @return @c true if the auto commit is enabled.
+ */
+ bool IsAutoCommit();
+
+ /**
* Create diagnostic record associated with the Connection instance.
*
* @param sqlState SQL state.
@@ -432,7 +445,10 @@ namespace ignite
/**
* Constructor.
*/
- Connection();
+ Connection(Environment* env);
+
+ /** Parent. */
+ Environment* env;
/** Client Socket. */
std::auto_ptr<SocketClient> socket;
@@ -443,6 +459,9 @@ namespace ignite
/** Login timeout in seconds. */
int32_t loginTimeout;
+ /** Autocommit flag. */
+ bool autoCommit;
+
/** Message parser. */
Parser parser;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
index 46d79ce..613cbf4 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable.h
@@ -82,6 +82,13 @@ namespace ignite
*/
virtual void AddStatusRecord(const OdbcError& err) = 0;
+ /**
+ * Add new status record.
+ *
+ * @param rec Record.
+ */
+ virtual void AddStatusRecord(const DiagnosticRecord& rec) = 0;
+
protected:
/**
* Default constructor.
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
index f1e9164..d8cfeb7 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/diagnostic/diagnosable_adapter.h
@@ -69,7 +69,7 @@ namespace ignite
*
* @return Diagnostic record.
*/
- virtual const diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords() const
+ virtual const DiagnosticRecordStorage& GetDiagnosticRecords() const
{
return diagnosticRecords;
}
@@ -79,7 +79,7 @@ namespace ignite
*
* @return Diagnostic record.
*/
- virtual diagnostic::DiagnosticRecordStorage& GetDiagnosticRecords()
+ virtual DiagnosticRecordStorage& GetDiagnosticRecords()
{
return diagnosticRecords;
}
@@ -110,6 +110,13 @@ namespace ignite
*/
virtual void AddStatusRecord(const OdbcError& err);
+ /**
+ * Add new status record.
+ *
+ * @param rec Record.
+ */
+ virtual void AddStatusRecord(const DiagnosticRecord& rec);
+
protected:
/** Diagnostic records. */
DiagnosticRecordStorage diagnosticRecords;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h b/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
index 3eeade6..e6a171f 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/environment.h
@@ -18,6 +18,8 @@
#ifndef _IGNITE_ODBC_ENVIRONMENT
#define _IGNITE_ODBC_ENVIRONMENT
+#include <set>
+
#include "ignite/odbc/diagnostic/diagnosable_adapter.h"
namespace ignite
@@ -32,6 +34,9 @@ namespace ignite
class Environment : public diagnostic::DiagnosableAdapter
{
public:
+ /** Connection set type. */
+ typedef std::set<Connection*> ConnectionSet;
+
/**
* Constructor.
*/
@@ -50,6 +55,13 @@ namespace ignite
Connection* CreateConnection();
/**
+ * Deregister connection.
+ *
+ * @param conn Connection to deregister.
+ */
+ void DeregisterConnection(Connection* conn);
+
+ /**
* Perform transaction commit on all the associated connections.
*/
void TransactionCommit();
@@ -125,6 +137,9 @@ namespace ignite
*/
SqlResult::Type InternalGetAttribute(int32_t attr, app::ApplicationDataBuffer& buffer);
+ /** Assotiated connections. */
+ ConnectionSet connections;
+
/** ODBC version. */
int32_t odbcVersion;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
index e119d1f..87ba064 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
@@ -109,9 +109,10 @@ namespace ignite
* @param sql SQL query.
* @param params Query arguments.
* @param timeout Timeout.
+ * @param autoCommit Auto commit flag.
*/
QueryExecuteRequest(const std::string& schema, const std::string& sql, const app::ParameterSet& params,
- int32_t timeout);
+ int32_t timeout, bool autoCommit);
/**
* Destructor.
@@ -137,6 +138,9 @@ namespace ignite
/** Timeout. */
int32_t timeout;
+
+ /** Auto commit. */
+ bool autoCommit;
};
/**
@@ -154,9 +158,11 @@ namespace ignite
* @param begin Beginng of the interval.
* @param end End of the interval.
* @param timeout Timeout.
+ * @param autoCommit Auto commit flag.
*/
QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql,
- const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout);
+ const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout,
+ bool autoCommit);
/**
* Destructor.
@@ -191,6 +197,9 @@ namespace ignite
/** Timeout. */
int32_t timeout;
+
+ /** Auto commit. */
+ bool autoCommit;
};
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h b/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
new file mode 100644
index 0000000..eb2598d
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/nested_tx_mode.h
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _IGNITE_ODBC_NESTED_TX_MODE
+#define _IGNITE_ODBC_NESTED_TX_MODE
+
+#include <set>
+#include <string>
+
+namespace ignite
+{
+ namespace odbc
+ {
+ /**
+ * Nested transaction mode.
+ */
+ struct NestedTxMode
+ {
+ /**
+ * Values.
+ */
+ enum Type
+ {
+ /** Commit current transaction if a new one started. */
+ AI_COMMIT = 1,
+
+ /** Ignore start of a new transaction. */
+ AI_IGNORE = 2,
+
+ /** Throw an error. */
+ AI_ERROR = 3,
+
+ /** Returned when value is unknown. */
+ AI_UNKNOWN = 100
+ };
+
+ /** Mode set type. */
+ typedef std::set<Type> ModeSet;
+
+ /**
+ * Get value from a string value.
+ *
+ * @param str String.
+ * @param dflt Value to return on error.
+ * @return Corresponding value on success and @c dflt on failure.
+ */
+ static Type FromString(const std::string& str, Type dflt = AI_UNKNOWN);
+
+ /**
+ * Convert value to a string.
+ *
+ * @param value Value.
+ * @return String value.
+ */
+ static std::string ToString(Type value);
+
+ /**
+ * Get set of all valid values.
+ *
+ * @return Set of all valid values.
+ */
+ static const ModeSet& GetValidValues();
+ };
+ }
+}
+
+#endif //_IGNITE_ODBC_NESTED_TX_MODE
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
index 0b64536..1a722e3 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
@@ -43,7 +43,7 @@ namespace ignite
/** Version 2.3.2: added multiple statements support. */
static const ProtocolVersion VERSION_2_3_2;
- /** Version 2.5.0: added multiple statements support. */
+ /** Version 2.5.0: added authentication and transactions support. */
static const ProtocolVersion VERSION_2_5_0;
/** Version 2.7.0: added fields precision and scale. */
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
index 1666863..77974ad 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h
@@ -61,6 +61,8 @@ namespace ignite
SKIP_REDUCER_ON_UPDATE_CHECK_BOX,
PROTOCOL_VERSION_LABEL,
PROTOCOL_VERSION_COMBO_BOX,
+ NESTED_TX_MODE_LABEL,
+ NESTED_TX_MODE_COMBO_BOX,
SSL_MODE_LABEL,
SSL_MODE_COMBO_BOX,
SSL_KEY_FILE_LABEL,
@@ -312,6 +314,12 @@ namespace ignite
/** Password edit. */
std::auto_ptr<Window> passwordEdit;
+ /** Nested transaction mode label. */
+ std::auto_ptr<Window> nestedTxModeLabel;
+
+ /** Nested transaction mode combo box. */
+ std::auto_ptr<Window> nestedTxModeComboBox;
+
/** Configuration. */
config::Configuration& config;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
index a94b479..e3bbb4e 100644
--- a/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
+++ b/modules/platforms/cpp/odbc/os/win/src/system/ui/dsn_configuration_window.cpp
@@ -36,7 +36,7 @@ namespace ignite
DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config):
CustomWindow(parent, "IgniteConfigureDsn", "Configure Apache Ignite DSN"),
width(360),
- height(580),
+ height(600),
connectionSettingsGroupBox(),
sslSettingsGroupBox(),
authSettingsGroupBox(),
@@ -59,6 +59,7 @@ namespace ignite
userEdit(),
passwordLabel(),
passwordEdit(),
+ nestedTxModeComboBox(),
okButton(),
cancelButton(),
config(config),
@@ -286,7 +287,7 @@ namespace ignite
int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX)
{
- enum { LABEL_WIDTH = 80 };
+ enum { LABEL_WIDTH = 130 };
int labelPosX = posX + INTERVAL;
@@ -309,6 +310,29 @@ namespace ignite
rowPos += INTERVAL + ROW_HEIGHT;
+ nestedTxModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT,
+ "Nested Transaction Mode:", ChildId::NESTED_TX_MODE_LABEL);
+ nestedTxModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT,
+ "", ChildId::NESTED_TX_MODE_COMBO_BOX);
+
+ int id = 0;
+
+ const NestedTxMode::ModeSet& supported = NestedTxMode::GetValidValues();
+
+ for (NestedTxMode::ModeSet::const_iterator it = supported.begin(); it != supported.end(); ++it)
+ {
+ nestedTxModeComboBox->AddString(NestedTxMode::ToString(*it));
+
+ if (*it == config.GetNestedTxMode())
+ nestedTxModeComboBox->SetSelection(id);
+
+ ++id;
+ }
+
+ nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0);
+
+ rowPos += INTERVAL + ROW_HEIGHT;
+
distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT,
"Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, config.IsDistributedJoins());
@@ -429,6 +453,7 @@ namespace ignite
ProtocolVersion version = ProtocolVersion::FromString(versionStr);
lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5);
skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0);
+ nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0);
break;
}
@@ -568,13 +593,6 @@ namespace ignite
{
std::string pageSizeStr;
- bool distributedJoins;
- bool enforceJoinOrder;
- bool replicatedOnly;
- bool collocated;
- bool lazy;
- bool skipReducerOnUpdate;
-
pageSizeEdit->GetText(pageSizeStr);
int32_t pageSize = common::LexicalCast<int32_t>(pageSizeStr);
@@ -582,15 +600,22 @@ namespace ignite
if (pageSize <= 0)
pageSize = config.GetPageSize();
- distributedJoins = distributedJoinsCheckBox->IsChecked();
- enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked();
- replicatedOnly = replicatedOnlyCheckBox->IsChecked();
- collocated = collocatedCheckBox->IsChecked();
- lazy = lazyCheckBox->IsChecked();
- skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked();
+ std::string nestedTxModeStr;
+
+ nestedTxModeComboBox->GetText(nestedTxModeStr);
+
+ NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode());
+
+ bool distributedJoins = distributedJoinsCheckBox->IsChecked();
+ bool enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked();
+ bool replicatedOnly = replicatedOnlyCheckBox->IsChecked();
+ bool collocated = collocatedCheckBox->IsChecked();
+ bool lazy = lazyCheckBox->IsChecked();
+ bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked();
LOG_MSG("Retrieving arguments:");
LOG_MSG("Page size: " << pageSize);
+ LOG_MSG("Nested TX Mode: " << NestedTxMode::ToString(mode));
LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false"));
LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false"));
LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false"));
@@ -599,6 +624,7 @@ namespace ignite
LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false"));
cfg.SetPageSize(pageSize);
+ cfg.SetNestedTxMode(mode);
cfg.SetDistributedJoins(distributedJoins);
cfg.SetEnforceJoinOrder(enforceJoinOrder);
cfg.SetReplicatedOnly(replicatedOnly);
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
index 352913e..630dc27 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
@@ -182,6 +182,7 @@
<ClCompile Include="..\..\src\message.cpp" />
<ClCompile Include="..\..\src\meta\column_meta.cpp" />
<ClCompile Include="..\..\src\meta\table_meta.cpp" />
+ <ClCompile Include="..\..\src\nested_tx_mode.cpp" />
<ClCompile Include="..\..\src\odbc.cpp" />
<ClCompile Include="..\..\src\protocol_version.cpp" />
<ClCompile Include="..\..\src\query\batch_query.cpp" />
@@ -230,6 +231,7 @@
<ClInclude Include="..\..\include\ignite\odbc\meta\column_meta.h" />
<ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h" />
<ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\nested_tx_mode.h" />
<ClInclude Include="..\..\include\ignite\odbc\odbc_error.h" />
<ClInclude Include="..\..\include\ignite\odbc\parser.h" />
<ClInclude Include="..\..\include\ignite\odbc\protocol_version.h" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
index b1956aa..6da0111 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
@@ -166,6 +166,9 @@
<ClCompile Include="..\..\src\config\config_tools.cpp">
<Filter>Code\config</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\nested_tx_mode.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="module.def">
@@ -329,5 +332,8 @@
<ClInclude Include="..\..\include\ignite\odbc\end_point.h">
<Filter>Code</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\nested_tx_mode.h">
+ <Filter>Code</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/configuration.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/configuration.cpp b/modules/platforms/cpp/odbc/src/config/configuration.cpp
index ef102d2..a99894d 100644
--- a/modules/platforms/cpp/odbc/src/config/configuration.cpp
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -56,6 +56,8 @@ namespace ignite
const std::string Configuration::DefaultValue::user = "";
const std::string Configuration::DefaultValue::password = "";
+ const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR;
+
Configuration::Configuration() :
dsn(DefaultValue::dsn),
driver(DefaultValue::driver),
@@ -76,7 +78,8 @@ namespace ignite
sslCertFile(DefaultValue::sslCertFile),
sslCaFile(DefaultValue::sslCaFile),
user(DefaultValue::user),
- password(DefaultValue::password)
+ password(DefaultValue::password),
+ nestedTxMode(DefaultValue::nestedTxMode)
{
// No-op.
}
@@ -404,6 +407,21 @@ namespace ignite
return password.IsSet();
}
+ NestedTxMode::Type Configuration::GetNestedTxMode() const
+ {
+ return nestedTxMode.GetValue();
+ }
+
+ void Configuration::SetNestedTxMode(NestedTxMode::Type mode)
+ {
+ this->nestedTxMode.SetValue(mode);
+ }
+
+ bool Configuration::IsNestedTxModeSet() const
+ {
+ return nestedTxMode.IsSet();
+ }
+
int32_t Configuration::GetPageSize() const
{
return pageSize.GetValue();
@@ -431,6 +449,7 @@ namespace ignite
AddToMap(res, ConnectionStringParser::Key::sslCaFile, sslCaFile);
AddToMap(res, ConnectionStringParser::Key::user, user);
AddToMap(res, ConnectionStringParser::Key::password, password);
+ AddToMap(res, ConnectionStringParser::Key::nestedTxMode, nestedTxMode);
}
template<>
@@ -486,6 +505,14 @@ namespace ignite
if (value.IsSet())
map[key] = ssl::SslMode::ToString(value.GetValue());
}
+
+ template<>
+ void Configuration::AddToMap(ArgumentMap& map, const std::string& key,
+ const SettableValue<NestedTxMode::Type>& value)
+ {
+ if (value.IsSet())
+ map[key] = NestedTxMode::ToString(value.GetValue());
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/connection_info.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_info.cpp b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
index 7279ea6..5885381 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_info.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_info.cpp
@@ -766,7 +766,7 @@ namespace ignite
#ifdef SQL_MULTIPLE_ACTIVE_TXN
// A character string: "Y" if the driver supports more than one active transaction at the same time,
// "N" if only one transaction can be active at any time.
- strParams[SQL_MULTIPLE_ACTIVE_TXN] = "N";
+ strParams[SQL_MULTIPLE_ACTIVE_TXN] = "Y";
#endif // SQL_MULTIPLE_ACTIVE_TXN
#ifdef SQL_ORDER_BY_COLUMNS_IN_SELECT
@@ -1596,7 +1596,7 @@ namespace ignite
// SQL_TXN_REPEATABLE_READ = Dirty reads and nonrepeatable reads are not possible. Phantoms are possible
// SQL_TXN_SERIALIZABLE = Transactions are serializable. Serializable transactions do not allow dirty
// reads, nonrepeatable reads, or phantoms.
- intParams[SQL_DEFAULT_TXN_ISOLATION] = 0;
+ intParams[SQL_DEFAULT_TXN_ISOLATION] = SQL_TXN_REPEATABLE_READ;
#endif // SQL_DEFAULT_TXN_ISOLATION
#ifdef SQL_DROP_ASSERTION
@@ -2170,7 +2170,7 @@ namespace ignite
// SQL_ATTR_TXN_ISOLATION attribute. For more information, see SQLSetConnectAttr Function.
// An SQL-92 Entry level-conformant driver will always return SQL_TXN_SERIALIZABLE as supported.
// A FIPS Transitional level-conformant driver will always return all of these options as supported.
- intParams[SQL_TXN_ISOLATION_OPTION] = 0;
+ intParams[SQL_TXN_ISOLATION_OPTION] = SQL_TXN_REPEATABLE_READ;
#endif // SQL_TXN_ISOLATION_OPTION
#ifdef SQL_UNION
@@ -2312,7 +2312,7 @@ namespace ignite
#ifdef SQL_TXN_CAPABLE
// Describs the transaction support in the driver or data source.
- shortParams[SQL_TXN_CAPABLE] = SQL_TC_NONE;
+ shortParams[SQL_TXN_CAPABLE] = SQL_TC_DDL_COMMIT;
#endif // SQL_TXN_CAPABLE
#ifdef SQL_QUOTED_IDENTIFIER_CASE
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp b/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
index d23c2cb..7f7c2f4 100644
--- a/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
+++ b/modules/platforms/cpp/odbc/src/config/connection_string_parser.cpp
@@ -24,6 +24,7 @@
#include "ignite/odbc/ssl/ssl_mode.h"
#include "ignite/odbc/config/connection_string_parser.h"
#include "ignite/odbc/config/config_tools.h"
+#include "ignite/odbc/nested_tx_mode.h"
namespace ignite
{
@@ -51,6 +52,7 @@ namespace ignite
const std::string ConnectionStringParser::Key::sslCaFile = "ssl_ca_file";
const std::string ConnectionStringParser::Key::user = "user";
const std::string ConnectionStringParser::Key::password = "password";
+ const std::string ConnectionStringParser::Key::nestedTxMode = "nested_tx_mode";
ConnectionStringParser::ConnectionStringParser(Configuration& cfg):
cfg(cfg)
@@ -424,6 +426,23 @@ namespace ignite
{
cfg.SetPassword(value);
}
+ else if (lKey == Key::nestedTxMode)
+ {
+ NestedTxMode::Type mode = NestedTxMode::FromString(value);
+
+ if (mode == NestedTxMode::AI_UNKNOWN)
+ {
+ if (diag)
+ {
+ diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED,
+ "Specified nested transaction mode is not supported. Default value used ('error').");
+ }
+
+ return;
+ }
+
+ cfg.SetNestedTxMode(mode);
+ }
else if (diag)
{
std::stringstream stream;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/connection.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp
index 894efb7..5538549 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -25,6 +25,7 @@
#include "ignite/odbc/log.h"
#include "ignite/odbc/utility.h"
+#include "ignite/odbc/environment.h"
#include "ignite/odbc/statement.h"
#include "ignite/odbc/connection.h"
#include "ignite/odbc/message.h"
@@ -54,10 +55,12 @@ namespace ignite
{
namespace odbc
{
- Connection::Connection() :
+ Connection::Connection(Environment* env) :
+ env(env),
socket(),
timeout(0),
loginTimeout(SocketClient::DEFALT_CONNECT_TIMEOUT),
+ autoCommit(true),
parser(),
config(),
info(config)
@@ -186,6 +189,11 @@ namespace ignite
IGNITE_ODBC_API_CALL(InternalRelease());
}
+ void Connection::Deregister()
+ {
+ env->DeregisterConnection(this);
+ }
+
SqlResult::Type Connection::InternalRelease()
{
if (socket.get() == 0)
@@ -367,6 +375,11 @@ namespace ignite
return config;
}
+ bool Connection::IsAutoCommit()
+ {
+ return autoCommit;
+ }
+
diagnostic::DiagnosticRecord Connection::CreateStatusRecord(SqlState::Type sqlState,
const std::string& message, int32_t rowNum, int32_t columnNum)
{
@@ -380,6 +393,37 @@ namespace ignite
SqlResult::Type Connection::InternalTransactionCommit()
{
+ std::string schema = config.GetSchema();
+
+ app::ParameterSet empty;
+
+ QueryExecuteRequest req(schema, "COMMIT", empty, timeout, autoCommit);
+ QueryExecuteResponse rsp;
+
+ try
+ {
+ bool sent = SyncMessage(req, rsp, timeout);
+
+ if (!sent)
+ {
+ AddStatusRecord(SqlState::S08S01_LINK_FAILURE, "Failed to send commit request.");
+
+ return SqlResult::AI_ERROR;
+ }
+ }
+ catch (const OdbcError& err)
+ {
+ AddStatusRecord(err);
+
+ return SqlResult::AI_ERROR;
+ }
+ catch (const IgniteError& err)
+ {
+ AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
+
+ return SqlResult::AI_ERROR;
+ }
+
return SqlResult::AI_SUCCESS;
}
@@ -390,10 +434,38 @@ namespace ignite
SqlResult::Type Connection::InternalTransactionRollback()
{
- AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
- "Rollback operation is not supported.");
+ std::string schema = config.GetSchema();
+
+ app::ParameterSet empty;
- return SqlResult::AI_ERROR;
+ QueryExecuteRequest req(schema, "ROLLBACK", empty, timeout, autoCommit);
+ QueryExecuteResponse rsp;
+
+ try
+ {
+ bool sent = SyncMessage(req, rsp, timeout);
+
+ if (!sent)
+ {
+ AddStatusRecord(SqlState::S08S01_LINK_FAILURE, "Failed to send rollback request.");
+
+ return SqlResult::AI_ERROR;
+ }
+ }
+ catch (const OdbcError& err)
+ {
+ AddStatusRecord(err);
+
+ return SqlResult::AI_ERROR;
+ }
+ catch (const IgniteError& err)
+ {
+ AddStatusRecord(SqlState::SHY000_GENERAL_ERROR, err.GetText());
+
+ return SqlResult::AI_ERROR;
+ }
+
+ return SqlResult::AI_SUCCESS;
}
void Connection::GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
@@ -452,7 +524,10 @@ namespace ignite
{
SQLUINTEGER *val = reinterpret_cast<SQLUINTEGER*>(buf);
- *val = SQL_AUTOCOMMIT_ON;
+ *val = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
+
+ if (valueLen)
+ *valueLen = SQL_IS_INTEGER;
break;
}
@@ -507,10 +582,17 @@ namespace ignite
case SQL_ATTR_AUTOCOMMIT:
{
- SQLUINTEGER val = static_cast<SQLUINTEGER>(reinterpret_cast<ptrdiff_t>(value));
+ SQLUINTEGER mode = static_cast<SQLUINTEGER>(reinterpret_cast<ptrdiff_t>(value));
+
+ if (mode != SQL_AUTOCOMMIT_ON && mode != SQL_AUTOCOMMIT_OFF)
+ {
+ AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Specified attribute is not supported.");
- if (val != SQL_AUTOCOMMIT_ON)
return SqlResult::AI_ERROR;
+ }
+
+ autoCommit = mode == SQL_AUTOCOMMIT_ON;
break;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
index 143d949..6de0716 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnosable_adapter.cpp
@@ -52,6 +52,11 @@ namespace ignite
{
AddStatusRecord(err.GetStatus(), err.GetErrorMessage(), 0, 0);
}
+
+ void DiagnosableAdapter::AddStatusRecord(const DiagnosticRecord& rec)
+ {
+ diagnosticRecords.AddStatusRecord(rec);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/dsn_config.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/dsn_config.cpp b/modules/platforms/cpp/odbc/src/dsn_config.cpp
index 1307d7e..dcdb8f4 100644
--- a/modules/platforms/cpp/odbc/src/dsn_config.cpp
+++ b/modules/platforms/cpp/odbc/src/dsn_config.cpp
@@ -212,6 +212,11 @@ namespace ignite
if (password.IsSet() && !config.IsPasswordSet())
config.SetPassword(password.GetValue());
+
+ SettableValue<std::string> nestedTxModeStr = ReadDsnString(dsn, ConnectionStringParser::Key::nestedTxMode);
+
+ if (nestedTxModeStr.IsSet() && !config.IsNestedTxModeSet())
+ config.SetNestedTxMode(NestedTxMode::FromString(nestedTxModeStr.GetValue(), config.GetNestedTxMode()));
}
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/environment.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/environment.cpp b/modules/platforms/cpp/odbc/src/environment.cpp
index 417fedc..5a2ac4f 100644
--- a/modules/platforms/cpp/odbc/src/environment.cpp
+++ b/modules/platforms/cpp/odbc/src/environment.cpp
@@ -25,7 +25,8 @@ namespace ignite
{
namespace odbc
{
- Environment::Environment() :
+ Environment::Environment() :
+ connections(),
odbcVersion(SQL_OV_ODBC3),
odbcNts(SQL_TRUE)
{
@@ -46,9 +47,14 @@ namespace ignite
return connection;
}
+ void Environment::DeregisterConnection(Connection* conn)
+ {
+ connections.erase(conn);
+ }
+
SqlResult::Type Environment::InternalCreateConnection(Connection*& connection)
{
- connection = new Connection;
+ connection = new Connection(this);
if (!connection)
{
@@ -57,6 +63,8 @@ namespace ignite
return SqlResult::AI_ERROR;
}
+ connections.insert(connection);
+
return SqlResult::AI_SUCCESS;
}
@@ -67,7 +75,25 @@ namespace ignite
SqlResult::Type Environment::InternalTransactionCommit()
{
- return SqlResult::AI_SUCCESS;
+ SqlResult::Type res = SqlResult::AI_SUCCESS;
+
+ for (ConnectionSet::iterator it = connections.begin(); it != connections.end(); ++it)
+ {
+ Connection* conn = *it;
+
+ conn->TransactionCommit();
+
+ diagnostic::DiagnosticRecordStorage& diag = conn->GetDiagnosticRecords();
+
+ if (diag.GetStatusRecordsNumber() > 0)
+ {
+ AddStatusRecord(diag.GetStatusRecord(1));
+
+ res = SqlResult::AI_SUCCESS_WITH_INFO;
+ }
+ }
+
+ return res;
}
void Environment::TransactionRollback()
@@ -77,10 +103,25 @@ namespace ignite
SqlResult::Type Environment::InternalTransactionRollback()
{
- AddStatusRecord(SqlState::SHYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
- "Rollback operation is not supported.");
+ SqlResult::Type res = SqlResult::AI_SUCCESS;
- return SqlResult::AI_ERROR;
+ for (ConnectionSet::iterator it = connections.begin(); it != connections.end(); ++it)
+ {
+ Connection* conn = *it;
+
+ conn->TransactionRollback();
+
+ diagnostic::DiagnosticRecordStorage& diag = conn->GetDiagnosticRecords();
+
+ if (diag.GetStatusRecordsNumber() > 0)
+ {
+ AddStatusRecord(diag.GetStatusRecord(1));
+
+ res = SqlResult::AI_SUCCESS_WITH_INFO;
+ }
+ }
+
+ return res;
}
void Environment::SetAttribute(int32_t attr, void* value, int32_t len)
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/message.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/message.cpp b/modules/platforms/cpp/odbc/src/message.cpp
index 5b909b8..5730842 100644
--- a/modules/platforms/cpp/odbc/src/message.cpp
+++ b/modules/platforms/cpp/odbc/src/message.cpp
@@ -82,15 +82,18 @@ namespace ignite
{
utility::WriteString(writer, config.GetUser());
utility::WriteString(writer, config.GetPassword());
+
+ writer.WriteInt8(config.GetNestedTxMode());
}
}
QueryExecuteRequest::QueryExecuteRequest(const std::string& schema, const std::string& sql,
- const app::ParameterSet& params, int32_t timeout):
+ const app::ParameterSet& params, int32_t timeout, bool autoCommit):
schema(schema),
sql(sql),
params(params),
- timeout(timeout)
+ timeout(timeout),
+ autoCommit(autoCommit)
{
// No-op.
}
@@ -115,17 +118,21 @@ namespace ignite
if (ver >= ProtocolVersion::VERSION_2_3_2)
writer.WriteInt32(timeout);
+
+ if (ver >= ProtocolVersion::VERSION_2_5_0)
+ writer.WriteBool(autoCommit);
}
QueryExecuteBatchtRequest::QueryExecuteBatchtRequest(const std::string& schema, const std::string& sql,
- const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout):
+ const app::ParameterSet& params, SqlUlen begin, SqlUlen end, bool last, int32_t timeout, bool autoCommit) :
schema(schema),
sql(sql),
params(params),
begin(begin),
end(end),
last(last),
- timeout(timeout)
+ timeout(timeout),
+ autoCommit(autoCommit)
{
// No-op.
}
@@ -150,6 +157,9 @@ namespace ignite
if (ver >= ProtocolVersion::VERSION_2_3_2)
writer.WriteInt32(timeout);
+
+ if (ver >= ProtocolVersion::VERSION_2_5_0)
+ writer.WriteBool(autoCommit);
}
QueryCloseRequest::QueryCloseRequest(int64_t queryId): queryId(queryId)
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp b/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
new file mode 100644
index 0000000..e4e6118
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/nested_tx_mode.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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/nested_tx_mode.h"
+#include "ignite/common/utils.h"
+
+namespace
+{
+ using ignite::odbc::NestedTxMode;
+ NestedTxMode::Type validValues0[] = {
+ NestedTxMode::AI_COMMIT,
+ NestedTxMode::AI_IGNORE,
+ NestedTxMode::AI_ERROR
+ };
+
+ NestedTxMode::ModeSet validValues(validValues0, validValues0 + (sizeof(validValues0) / sizeof(validValues0[0])));
+}
+
+
+namespace ignite
+{
+ namespace odbc
+ {
+ NestedTxMode::Type NestedTxMode::FromString(const std::string& str, Type dflt)
+ {
+ std::string lower = common::ToLower(str);
+
+ if (lower == "commit")
+ return AI_COMMIT;
+
+ if (lower == "ignore")
+ return AI_IGNORE;
+
+ if (lower == "error")
+ return AI_ERROR;
+
+ return dflt;
+ }
+
+ std::string NestedTxMode::ToString(Type value)
+ {
+ switch (value)
+ {
+ case AI_COMMIT:
+ return "commit";
+
+ case AI_IGNORE:
+ return "ignore";
+
+ case AI_ERROR:
+ return "error";
+
+ default:
+ break;
+ }
+
+ return "default";
+ }
+
+ const NestedTxMode::ModeSet& NestedTxMode::GetValidValues()
+ {
+ return validValues;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index 3aad52f..5b37da3 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -204,6 +204,8 @@ namespace ignite
if (!connection)
return SQL_INVALID_HANDLE;
+ connection->Deregister();
+
delete connection;
return SQL_SUCCESS;
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index 8dada3c..1256c94 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -144,7 +144,9 @@ namespace ignite
{
const std::string& schema = connection.GetSchema();
- QueryExecuteBatchtRequest req(schema, sql, params, begin, end, last, timeout);
+ QueryExecuteBatchtRequest req(schema, sql, params, begin, end, last, timeout,
+ connection.IsAutoCommit());
+
QueryExecuteBatchResponse rsp;
try
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 6974c7f..69208b8 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -206,7 +206,7 @@ namespace ignite
{
const std::string& schema = connection.GetSchema();
- QueryExecuteRequest req(schema, sql, params, timeout);
+ QueryExecuteRequest req(schema, sql, params, timeout, connection.IsAutoCommit());
QueryExecuteResponse rsp;
try
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
new file mode 100644
index 0000000..32068d3
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-messages.sh
@@ -0,0 +1,98 @@
+#
+# 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.
+#
+
+#
+# Configuration to measure increased messages load with mvcc turned on.
+#
+
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 1 client node (driver itself) and many (4 for instance) server nodes.
+SERVER_HOSTS=localhost,localhost,localhost,localhost
+DRIVER_HOSTS=localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=1
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+ -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+ --clientNodesAfterId 100 \
+ -sn IgniteNode -cl --range 1000000 \
+ --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+ \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc, \
+ \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-2-mvcc-off -b 2 --sqlRange 1, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1-backup-2-mvcc-on -b 2 --sqlRange 1 --mvcc, \
+ \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-2-mvcc-off -b 2 --sqlRange 1000, \
+${commonParams} -dn NativeSqlUpdateRangeBenchmark -ds ${ver}sql-update-batch-1000-backup-2-mvcc-on -b 2 --sqlRange 1000 --mvcc, \
+"
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
new file mode 100644
index 0000000..db45199
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-processor.sh
@@ -0,0 +1,95 @@
+#
+# 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.
+#
+
+#
+# Configuration to compare mvcc on/off. This benchmark creates load on mvcc processor.
+#
+
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 4 client nodes (drivers) and 1 server node.
+SERVER_HOSTS=localhost
+DRIVER_HOSTS=localhost,localhost,localhost,localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=16
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+ -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+ --clientNodesAfterId 100 \
+ -sn IgniteNode -cl --range 1000000 \
+ --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+ \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-off -b 0 --sqlRange 25, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-on -b 0 --sqlRange 25 --mvcc, \
+ \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn MvccProcessorBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc \
+"
http://git-wip-us.apache.org/repos/asf/ignite/blob/00bb4d4d/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
----------------------------------------------------------------------
diff --git a/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh b/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
new file mode 100644
index 0000000..0a92bce
--- /dev/null
+++ b/modules/yardstick/config/mvcc/benchmark-mvcc-updates-contention.sh
@@ -0,0 +1,96 @@
+#
+# 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.
+#
+
+#
+# Configuration to measure performance of concurrent sql updates with contention.
+# Update keys are shared among the threads/hosts.
+#
+now0=`date +'%H%M%S'`
+
+# JVM options.
+JVM_OPTS=${JVM_OPTS}" -DIGNITE_QUIET=false"
+
+# Uncomment to enable concurrent garbage collection (GC) if you encounter long GC pauses.
+JVM_OPTS=${JVM_OPTS}" \
+-Xms8g \
+-Xmx8g \
+-Xloggc:./gc${now0}.log \
+-XX:+PrintGCDetails \
+-verbose:gc \
+-XX:+UseParNewGC \
+-XX:+UseConcMarkSweepGC \
+-XX:+PrintGCDateStamps \
+"
+
+#Ignite version
+ver="RELEASE-"
+
+# List of default probes.
+# Add DStatProbe or VmStatProbe if your OS supports it (e.g. if running on Linux).
+BENCHMARK_DEFAULT_PROBES=ThroughputLatencyProbe,PercentileProbe,DStatProbe
+
+# Packages where the specified benchmark is searched by reflection mechanism.
+BENCHMARK_PACKAGES=org.yardstickframework,org.apache.ignite.yardstick
+
+# Flag which indicates to restart the servers before every benchmark execution.
+RESTART_SERVERS=true
+
+# Probe point writer class name.
+# BENCHMARK_WRITER=
+
+# The benchmark is designed to run with 4 client node (drivers) and several (2 for instance) server nodes
+SERVER_HOSTS=localhost,localhost
+DRIVER_HOSTS=localhost,localhost,localhost,localhost
+
+# Remote username.
+# REMOTE_USER=
+
+# Number of nodes, used to wait for the specified number of nodes to start.
+nodesNum=$((`echo ${SERVER_HOSTS} | tr ',' '\n' | wc -l` + `echo ${DRIVER_HOSTS} | tr ',' '\n' | wc -l`))
+
+# Warmup.
+w=30
+
+# Duration.
+d=300
+
+# Threads count.
+t=16
+
+# Sync mode.
+sm=FULL_SYNC
+
+# Parameters that should be the same across all the benchmarks launches.
+commonParams="-cfg ${SCRIPT_DIR}/../config/ignite-localhost-config.xml -nn ${nodesNum} -w ${w} -d ${d} \
+ -jdbc jdbc:ignite:thin://auto.find/ -t ${t} -sm ${sm} \
+ --clientNodesAfterId 100 \
+ -sn IgniteNode -cl \
+ --range 1000000 --mvcc-contention-range 10000 \
+ --atomic-mode TRANSACTIONAL"
+
+# Run configuration which contains all benchmarks.
+# Note that each benchmark is set to run for 300 seconds (5 min) with warm-up set to 60 seconds (1 minute).
+CONFIGS="\
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-off -b 0 --sqlRange 1, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1-backup-0-mvcc-on -b 0 --sqlRange 1 --mvcc, \
+ \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-off -b 0 --sqlRange 25, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-25-backup-0-mvcc-on -b 0 --sqlRange 25 --mvcc, \
+ \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-off -b 0 --sqlRange 1000, \
+${commonParams} -dn MvccUpdateContentionBenchmark -ds ${ver}sql-update-batch-1000-backup-0-mvcc-on -b 0 --sqlRange 1000 --mvcc \
+"