You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2016/08/03 11:29:01 UTC
[19/48] ignite git commit: IGNITE-3577: ODBC: Added simplified
"Address" porperty. This closes #898.
IGNITE-3577: ODBC: Added simplified "Address" porperty. This closes #898.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8386dd86
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8386dd86
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8386dd86
Branch: refs/heads/ignite-3443
Commit: 8386dd867a82e9814b43d54cca588a5d7a82ef4b
Parents: 33d35b3
Author: isapego <is...@gridgain.com>
Authored: Thu Jul 28 13:42:32 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Thu Jul 28 13:42:32 2016 +0300
----------------------------------------------------------------------
.../cpp/common/include/ignite/common/utils.h | 18 ++
.../cpp/core-test/config/cache-query.xml | 3 +-
.../cpp/odbc-test/config/queries-test.xml | 9 +-
.../cpp/odbc-test/src/configuration_test.cpp | 110 ++++++---
.../cpp/odbc-test/src/queries_test.cpp | 91 +++++---
.../include/ignite/odbc/config/configuration.h | 121 ++++++++--
.../cpp/odbc/include/ignite/odbc/connection.h | 38 ++--
.../cpp/odbc/src/config/configuration.cpp | 227 +++++++++----------
modules/platforms/cpp/odbc/src/connection.cpp | 47 ++--
modules/platforms/cpp/odbc/src/odbc.cpp | 27 ++-
10 files changed, 436 insertions(+), 255 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/modules/platforms/cpp/common/include/ignite/common/utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/common/include/ignite/common/utils.h b/modules/platforms/cpp/common/include/ignite/common/utils.h
index c1046e2..331fcb2 100644
--- a/modules/platforms/cpp/common/include/ignite/common/utils.h
+++ b/modules/platforms/cpp/common/include/ignite/common/utils.h
@@ -179,6 +179,24 @@ namespace ignite
return res;
}
+
+ /**
+ * Check if the predicate returns true for all the elements of the
+ * sequence.
+ *
+ * @return True if the predicate returns true for all the elements
+ * of the sequence and false otherwise.
+ */
+ template<typename Iter, typename Pred>
+ bool AllOf(Iter begin, Iter end, Pred pred)
+ {
+ Iter i = begin;
+
+ while (i != end && pred(*i))
+ ++i;
+
+ return i == end;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/modules/platforms/cpp/core-test/config/cache-query.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/config/cache-query.xml b/modules/platforms/cpp/core-test/config/cache-query.xml
index 06bc7f5..c3b5389 100644
--- a/modules/platforms/cpp/core-test/config/cache-query.xml
+++ b/modules/platforms/cpp/core-test/config/cache-query.xml
@@ -119,11 +119,12 @@
<property name="addresses">
<list>
<!-- In distributed environment, replace with actual host IP address. -->
- <value>127.0.0.1:47500..47501</value>
+ <value>127.0.0.1:47500</value>
</list>
</property>
</bean>
</property>
+ <property name="socketTimeout" value="300" />
</bean>
</property>
</bean>
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/modules/platforms/cpp/odbc-test/config/queries-test.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test.xml b/modules/platforms/cpp/odbc-test/config/queries-test.xml
index f08f86d..054da42 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test.xml
@@ -26,12 +26,14 @@
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
- <!-- Set to true to enable distributed class loading for examples, default is false. -->
- <property name="peerClassLoadingEnabled" value="true"/>
+ <property name="localHost" value="127.0.0.1"/>
+ <property name="connectorConfiguration"><null/></property>
<!-- Enabling ODBC. -->
<property name="odbcConfiguration">
- <bean class="org.apache.ignite.configuration.OdbcConfiguration"></bean>
+ <bean class="org.apache.ignite.configuration.OdbcConfiguration">
+ <property name="endpointAddress" value="127.0.0.1:11110"/>
+ </bean>
</property>
<property name="cacheConfiguration">
@@ -89,6 +91,7 @@
</property>
</bean>
</property>
+ <property name="socketTimeout" value="300" />
</bean>
</property>
</bean>
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/configuration_test.cpp b/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
index 85aa3ff..10fd137 100644
--- a/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
@@ -24,47 +24,70 @@
#include <boost/test/unit_test.hpp>
#include <ignite/odbc/config/configuration.h>
+#include <ignite/ignite_error.h>
+#include <ignite/common/utils.h>
using namespace ignite::odbc::config;
namespace
{
- const char* testDriverName = "Ignite";
- const char* testServerHost = "testhost.com";
+ const std::string testDriverName = "Ignite Driver";
+ const std::string testServerHost = "testhost.com";
const uint16_t testServerPort = 4242;
- const char* testCacheName = "TestCache";
- const char* testDsn = "Ignite DSN";
+ const std::string testCacheName = "TestCache";
+ const std::string testDsn = "Ignite DSN";
+
+ const std::string testAddress = testServerHost + ':' + ignite::common::LexicalCast<std::string>(testServerPort);
}
-BOOST_AUTO_TEST_SUITE(ConfigurationTestSuite)
+void CheckValidAddress(const char* connectStr, uint16_t port)
+{
+ Configuration cfg;
+
+ BOOST_CHECK_NO_THROW(cfg.FillFromConnectString(connectStr));
+
+ BOOST_CHECK_EQUAL(cfg.GetPort(), port);
+}
void CheckConnectionConfig(const Configuration& cfg)
{
- BOOST_REQUIRE(cfg.GetDriver() == testDriverName);
- BOOST_REQUIRE(cfg.GetHost() == testServerHost);
- BOOST_REQUIRE(cfg.GetPort() == testServerPort);
- BOOST_REQUIRE(cfg.GetCache() == testCacheName);
- BOOST_REQUIRE(cfg.GetDsn().empty());
+ BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName);
+ BOOST_CHECK_EQUAL(cfg.GetHost(), testServerHost);
+ BOOST_CHECK_EQUAL(cfg.GetPort(), testServerPort);
+ BOOST_CHECK_EQUAL(cfg.GetAddress(), testAddress);
+ BOOST_CHECK_EQUAL(cfg.GetCache(), testCacheName);
+ BOOST_CHECK_EQUAL(cfg.GetDsn(), std::string());
std::stringstream constructor;
- constructor << "driver={" << testDriverName << "};"
- << "server=" << testServerHost << ";"
- << "port=" << testServerPort << ";"
- << "cache=" << testCacheName << ";";
+ constructor << "address=" << testAddress << ';'
+ << "cache=" << testCacheName << ';'
+ << "driver={" << testDriverName << "};";
const std::string& expectedStr = constructor.str();
- BOOST_REQUIRE(cfg.ToConnectString() == expectedStr);
+ BOOST_CHECK_EQUAL(cfg.ToConnectString(), expectedStr);
}
void CheckDsnConfig(const Configuration& cfg)
{
- BOOST_REQUIRE(cfg.GetDriver() == testDriverName);
- BOOST_REQUIRE(cfg.GetDsn() == testDsn);
- BOOST_REQUIRE(cfg.GetHost().empty());
- BOOST_REQUIRE(cfg.GetCache().empty());
- BOOST_REQUIRE(cfg.GetPort() == 0);
+ BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName);
+ BOOST_CHECK_EQUAL(cfg.GetDsn(), testDsn);
+ BOOST_CHECK_EQUAL(cfg.GetCache(), Configuration::DefaultValue::cache);
+ BOOST_CHECK_EQUAL(cfg.GetAddress(), Configuration::DefaultValue::address);
+ BOOST_CHECK_EQUAL(cfg.GetHost(), std::string());
+ BOOST_CHECK_EQUAL(cfg.GetPort(), Configuration::DefaultValue::uintPort);
+}
+
+BOOST_AUTO_TEST_SUITE(ConfigurationTestSuite)
+
+BOOST_AUTO_TEST_CASE(CheckTestValuesNotEquealDefault)
+{
+ BOOST_CHECK_NE(testDriverName, Configuration::DefaultValue::driver);
+ BOOST_CHECK_NE(testAddress, Configuration::DefaultValue::address);
+ BOOST_CHECK_NE(testServerPort, Configuration::DefaultValue::uintPort);
+ BOOST_CHECK_NE(testCacheName, Configuration::DefaultValue::cache);
+ BOOST_CHECK_NE(testDsn, Configuration::DefaultValue::dsn);
}
BOOST_AUTO_TEST_CASE(TestConnectStringUppercase)
@@ -74,13 +97,12 @@ BOOST_AUTO_TEST_CASE(TestConnectStringUppercase)
std::stringstream constructor;
constructor << "DRIVER={" << testDriverName << "};"
- << "SERVER=" << testServerHost <<";"
- << "PORT=" << testServerPort << ";"
+ << "ADDRESS=" << testAddress << ';'
<< "CACHE=" << testCacheName;
const std::string& connectStr = constructor.str();
- cfg.FillFromConnectString(connectStr.c_str(), connectStr.size());
+ cfg.FillFromConnectString(connectStr);
CheckConnectionConfig(cfg);
}
@@ -92,13 +114,12 @@ BOOST_AUTO_TEST_CASE(TestConnectStringLowercase)
std::stringstream constructor;
constructor << "driver={" << testDriverName << "};"
- << "server=" << testServerHost << ";"
- << "port=" << testServerPort << ";"
+ << "address=" << testAddress << ';'
<< "cache=" << testCacheName;
const std::string& connectStr = constructor.str();
- cfg.FillFromConnectString(connectStr.c_str(), connectStr.size());
+ cfg.FillFromConnectString(connectStr);
CheckConnectionConfig(cfg);
}
@@ -110,8 +131,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringZeroTerminated)
std::stringstream constructor;
constructor << "driver={" << testDriverName << "};"
- << "server=" << testServerHost << ";"
- << "port=" << testServerPort << ";"
+ << "address=" << testAddress << ';'
<< "cache=" << testCacheName;
const std::string& connectStr = constructor.str();
@@ -128,13 +148,12 @@ BOOST_AUTO_TEST_CASE(TestConnectStringMixed)
std::stringstream constructor;
constructor << "Driver={" << testDriverName << "};"
- << "Server=" << testServerHost << ";"
- << "Port=" << testServerPort << ";"
+ << "Address=" << testAddress << ';'
<< "Cache=" << testCacheName;
const std::string& connectStr = constructor.str();
- cfg.FillFromConnectString(connectStr.c_str(), connectStr.size());
+ cfg.FillFromConnectString(connectStr);
CheckConnectionConfig(cfg);
}
@@ -146,17 +165,40 @@ BOOST_AUTO_TEST_CASE(TestConnectStringWhitepaces)
std::stringstream constructor;
constructor << "DRIVER = {" << testDriverName << "} ;\n"
- << " SERVER =" << testServerHost << " ; \n"
- << "PORT= " << testServerPort << "; "
+ << " ADDRESS =" << testAddress << "; "
<< "CACHE = \n\r" << testCacheName;
const std::string& connectStr = constructor.str();
- cfg.FillFromConnectString(connectStr.c_str(), connectStr.size());
+ cfg.FillFromConnectString(connectStr);
CheckConnectionConfig(cfg);
}
+BOOST_AUTO_TEST_CASE(TestConnectStringInvalidAddress)
+{
+ Configuration cfg;
+
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:0;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:00000;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:fdsf;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:123:1;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:12322221;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:12322a;"), ignite::IgniteError);
+ BOOST_CHECK_THROW(cfg.FillFromConnectString("Address=example.com:;"), ignite::IgniteError);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectStringValidAddress)
+{
+ Configuration cfg;
+
+ CheckValidAddress("Address=example.com:1;", 1);
+ CheckValidAddress("Address=example.com:31242;", 31242);
+ CheckValidAddress("Address=example.com:55555;", 55555);
+ CheckValidAddress("Address=example.com:110;", 110);
+ CheckValidAddress("Address=example.com;", Configuration::DefaultValue::uintPort);
+}
+
BOOST_AUTO_TEST_CASE(TestDsnStringUppercase)
{
Configuration cfg;
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/modules/platforms/cpp/odbc-test/src/queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
index cc3fa8e..ccb3a4d 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -24,6 +24,7 @@
#include <vector>
#include <string>
+#include <algorithm>
#ifndef _MSC_VER
# define BOOST_TEST_DYN_LINK
@@ -76,39 +77,12 @@ std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle)
struct QueriesTestSuiteFixture
{
/**
- * Constructor.
+ * Establish connection to node.
+ *
+ * @param connectStr Connection string.
*/
- QueriesTestSuiteFixture() : testCache(0), env(NULL), dbc(NULL), stmt(NULL)
+ void Connect(const std::string& connectStr)
{
- IgniteConfiguration cfg;
-
- cfg.jvmOpts.push_back("-Xdebug");
- cfg.jvmOpts.push_back("-Xnoagent");
- cfg.jvmOpts.push_back("-Djava.compiler=NONE");
- cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
- cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
-
-#ifdef IGNITE_TESTS_32
- cfg.jvmInitMem = 256;
- cfg.jvmMaxMem = 768;
-#else
- cfg.jvmInitMem = 1024;
- cfg.jvmMaxMem = 4096;
-#endif
-
- char* cfgPath = getenv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH");
-
- cfg.springCfgPath = std::string(cfgPath).append("/").append("queries-test.xml");
-
- IgniteError err;
-
- grid = Ignition::Start(cfg, &err);
-
- if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
- BOOST_FAIL(err.GetText());
-
- testCache = grid.GetCache<int64_t, TestType>("cache");
-
// Allocate an environment handle
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
@@ -123,13 +97,16 @@ struct QueriesTestSuiteFixture
BOOST_REQUIRE(dbc != NULL);
// Connect string
- SQLCHAR connectStr[] = "DRIVER={Apache Ignite};SERVER=localhost;PORT=10800;CACHE=cache";
+ std::vector<SQLCHAR> connectStr0;
+
+ connectStr0.reserve(connectStr.size() + 1);
+ std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
SQLCHAR outstr[ODBC_BUFFER_SIZE];
SQLSMALLINT outstrlen;
// Connecting to ODBC server.
- SQLRETURN ret = SQLDriverConnect(dbc, NULL, connectStr, static_cast<SQLSMALLINT>(sizeof(connectStr)),
+ SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
if (!SQL_SUCCEEDED(ret))
@@ -146,6 +123,41 @@ struct QueriesTestSuiteFixture
}
/**
+ * Constructor.
+ */
+ QueriesTestSuiteFixture() : testCache(0), env(NULL), dbc(NULL), stmt(NULL)
+ {
+ IgniteConfiguration cfg;
+
+ cfg.jvmOpts.push_back("-Xdebug");
+ cfg.jvmOpts.push_back("-Xnoagent");
+ cfg.jvmOpts.push_back("-Djava.compiler=NONE");
+ cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005");
+ cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError");
+
+#ifdef IGNITE_TESTS_32
+ cfg.jvmInitMem = 256;
+ cfg.jvmMaxMem = 768;
+#else
+ cfg.jvmInitMem = 1024;
+ cfg.jvmMaxMem = 4096;
+#endif
+
+ char* cfgPath = getenv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH");
+
+ cfg.springCfgPath = std::string(cfgPath).append("/").append("queries-test.xml");
+
+ IgniteError err;
+
+ grid = Ignition::Start(cfg, &err);
+
+ if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
+ BOOST_FAIL(err.GetText());
+
+ testCache = grid.GetCache<int64_t, TestType>("cache");
+ }
+
+ /**
* Destructor.
*/
~QueriesTestSuiteFixture()
@@ -166,6 +178,8 @@ struct QueriesTestSuiteFixture
template<typename T>
void CheckTwoRowsInt(SQLSMALLINT type)
{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
SQLRETURN ret;
TestType in1(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456));
@@ -273,6 +287,11 @@ struct QueriesTestSuiteFixture
BOOST_FIXTURE_TEST_SUITE(QueriesTestSuite, QueriesTestSuiteFixture)
+BOOST_AUTO_TEST_CASE(TestLegacyConnection)
+{
+ Connect("DRIVER={Apache Ignite};SERVER=127.0.0.1;PORT=11110;CACHE=cache");
+}
+
BOOST_AUTO_TEST_CASE(TestTwoRowsInt8)
{
CheckTwoRowsInt<int8_t>(SQL_C_STINYINT);
@@ -315,6 +334,8 @@ BOOST_AUTO_TEST_CASE(TestTwoRowsUint64)
BOOST_AUTO_TEST_CASE(TestTwoRowsString)
{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
SQLRETURN ret;
TestType in1(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456));
@@ -408,6 +429,8 @@ BOOST_AUTO_TEST_CASE(TestTwoRowsString)
BOOST_AUTO_TEST_CASE(TestOneRowString)
{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
SQLRETURN ret;
TestType in(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456));
@@ -469,6 +492,8 @@ BOOST_AUTO_TEST_CASE(TestOneRowString)
BOOST_AUTO_TEST_CASE(TestOneRowStringLen)
{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
SQLRETURN ret;
TestType in(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456));
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/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 d6d7944..05fe8bf 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
@@ -23,6 +23,7 @@
#include <map>
#include <ignite/common/common.h>
+#include <ignite/common/utils.h>
namespace ignite
{
@@ -36,6 +37,68 @@ namespace ignite
class Configuration
{
public:
+ /** Map containing connect arguments. */
+ typedef std::map<std::string, std::string> ArgumentMap;
+
+ /** Connection attribute keywords. */
+ struct Key
+ {
+ /** Connection attribute keyword for DSN attribute. */
+ static const std::string dsn;
+
+ /** Connection attribute keyword for Driver attribute. */
+ static const std::string driver;
+
+ /** Connection attribute keyword for cache attribute. */
+ static const std::string cache;
+
+ /** Connection attribute keyword for address attribute. */
+ static const std::string address;
+
+ /** Connection attribute keyword for server attribute. */
+ static const std::string server;
+
+ /** Connection attribute keyword for port attribute. */
+ static const std::string port;
+ };
+
+ /** Default values for configuration. */
+ struct DefaultValue
+ {
+ /** Default value for DSN attribute. */
+ static const std::string dsn;
+
+ /** Default value for Driver attribute. */
+ static const std::string driver;
+
+ /** Default value for cache attribute. */
+ static const std::string cache;
+
+ /** Default value for address attribute. */
+ static const std::string address;
+
+ /** Default value for server attribute. */
+ static const std::string server;
+
+ /** Default value for port attribute. */
+ static const std::string port;
+
+ /** Default value for port attribute. Uint16 value. */
+ static const uint16_t uintPort;
+ };
+
+ /**
+ * Connection end point structure.
+ */
+ struct EndPoint
+ {
+ /** Remote host. */
+ std::string host;
+
+ /** TCP port. */
+ uint16_t port;
+ };
+
/**
* Default constructor.
*/
@@ -83,7 +146,7 @@ namespace ignite
*/
uint16_t GetPort() const
{
- return port;
+ return endPoint.port;
}
/**
@@ -93,7 +156,7 @@ namespace ignite
*/
const std::string& GetDsn() const
{
- return dsn;
+ return GetStringValue(Key::dsn, DefaultValue::dsn);
}
/**
@@ -103,7 +166,7 @@ namespace ignite
*/
const std::string& GetDriver() const
{
- return driver;
+ return GetStringValue(Key::driver, DefaultValue::driver);
}
/**
@@ -113,7 +176,7 @@ namespace ignite
*/
const std::string& GetHost() const
{
- return host;
+ return endPoint.host;
}
/**
@@ -123,15 +186,29 @@ namespace ignite
*/
const std::string& GetCache() const
{
- return cache;
+ return GetStringValue(Key::cache, DefaultValue::cache);
}
- private:
- IGNITE_NO_COPY_ASSIGNMENT(Configuration);
+ /**
+ * Get address.
+ *
+ * @return Address.
+ */
+ const std::string& GetAddress() const
+ {
+ return GetStringValue(Key::address, DefaultValue::address);
+ }
- /** Map containing connect arguments. */
- typedef std::map<std::string, std::string> ArgumentMap;
+ /**
+ * Get string value from the config.
+ *
+ * @param key Configuration key.
+ * @param dflt Default value to be returned if there is no value stored.
+ * @return Found or default value.
+ */
+ const std::string& GetStringValue(const std::string& key, const std::string& dflt) const;
+ private:
/**
* Parse connect string into key-value storage.
*
@@ -139,22 +216,22 @@ namespace ignite
* @param len String length.
* @param params Parsing result.
*/
- void ParseAttributeList(const char* str, size_t len, char delimeter, ArgumentMap& args) const;
+ static void ParseAttributeList(const char* str, size_t len, char delimeter, ArgumentMap& args);
- /** Data Source Name. */
- std::string dsn;
-
- /** Driver name. */
- std::string driver;
-
- /** Server hostname. */
- std::string host;
+ /**
+ * Parse address and extract connection end-point.
+ *
+ * @throw IgniteException if address can not be parsed.
+ * @param address Address string to parse.
+ * @param res Result is placed here.
+ */
+ static void ParseAddress(const std::string& address, EndPoint& res);
- /** Port of the server. */
- uint16_t port;
+ /** Arguments. */
+ ArgumentMap arguments;
- /** Cache name. */
- std::string cache;
+ /** Connection end-point. */
+ EndPoint endPoint;
};
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/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 10ceb19..00bdfc8 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -25,6 +25,7 @@
#include "ignite/odbc/parser.h"
#include "ignite/odbc/system/socket_client.h"
#include "ignite/odbc/config/connection_info.h"
+#include "ignite/odbc/config/configuration.h"
#include "ignite/odbc/diagnostic/diagnosable_adapter.h"
namespace ignite
@@ -74,18 +75,16 @@ namespace ignite
/**
* Establish connection to ODBC server.
*
- * @param server Server (DSN).
+ * @param connectStr Connection string.
*/
- void Establish(const std::string& server);
+ void Establish(const std::string& connectStr);
/**
* Establish connection to ODBC server.
*
- * @param host Host.
- * @param port Port.
- * @param cache Cache name to connect to.
+ * @param cfg Configuration.
*/
- void Establish(const std::string& host, uint16_t port, const std::string& cache);
+ void Establish(const config::Configuration cfg);
/**
* Release established connection.
@@ -124,6 +123,13 @@ namespace ignite
const std::string& GetCache() const;
/**
+ * Get configuration.
+ *
+ * @return Connection configuration.
+ */
+ const config::Configuration& GetConfiguration() const;
+
+ /**
* Create diagnostic record associated with the Connection instance.
*
* @param sqlState SQL state.
@@ -132,8 +138,8 @@ namespace ignite
* @param columnNum Associated column number.
* @return DiagnosticRecord associated with the instance.
*/
- diagnostic::DiagnosticRecord CreateStatusRecord(SqlState sqlState,
- const std::string& message, int32_t rowNum = 0, int32_t columnNum = 0) const;
+ static diagnostic::DiagnosticRecord CreateStatusRecord(SqlState sqlState,
+ const std::string& message, int32_t rowNum = 0, int32_t columnNum = 0);
/**
* Synchronously send request message and receive response.
@@ -172,21 +178,19 @@ namespace ignite
* Establish connection to ODBC server.
* Internal call.
*
- * @param server Server (DNS).
+ * @param connectStr Connection string.
* @return Operation result.
*/
- SqlResult InternalEstablish(const std::string& server);
+ SqlResult InternalEstablish(const std::string& connectStr);
/**
* Establish connection to ODBC server.
* Internal call.
*
- * @param host Host.
- * @param port Port.
- * @param cache Cache name to connect to.
+ * @param cfg Configuration.
* @return Operation result.
*/
- SqlResult InternalEstablish(const std::string& host, uint16_t port, const std::string& cache);
+ SqlResult InternalEstablish(const config::Configuration cfg);
/**
* Release established connection.
@@ -269,11 +273,11 @@ namespace ignite
/** State flag. */
bool connected;
- /** Cache name. */
- std::string cache;
-
/** Message parser. */
Parser parser;
+
+ /** Configuration. */
+ config::Configuration config;
};
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/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 8d57dee..45b0507 100644
--- a/modules/platforms/cpp/odbc/src/config/configuration.cpp
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -15,8 +15,6 @@
* limitations under the License.
*/
-#include <cstring>
-
#include <string>
#include <sstream>
#include <algorithm>
@@ -31,50 +29,25 @@ namespace ignite
{
namespace config
{
- /** Default values for configuration. */
- namespace dflt
- {
- /** Default value for DSN attribute. */
- const std::string dsn = "Default Apache Ignite DSN";
-
- /** Default value for Driver attribute. */
- const std::string driver = "Apache Ignite";
-
- /** Default value for host attribute. */
- const std::string host = "localhost";
-
- /** Default value for port attribute. */
- const uint16_t port = 10800;
-
- /** Default value for cache attribute. */
- const std::string cache = "";
- }
-
- /** Connection attribute keywords. */
- namespace attrkey
- {
- /** Connection attribute keyword for DSN attribute. */
- const std::string dsn = "dsn";
-
- /** Connection attribute keyword for Driver attribute. */
- const std::string driver = "driver";
-
- /** Connection attribute keyword for server host attribute. */
- const std::string host = "server";
-
- /** Connection attribute keyword for server port attribute. */
- const std::string port = "port";
-
- /** Connection attribute keyword for cache attribute. */
- const std::string cache = "cache";
- }
+ const std::string Configuration::Key::dsn = "dsn";
+ const std::string Configuration::Key::driver = "driver";
+ const std::string Configuration::Key::cache = "cache";
+ const std::string Configuration::Key::address = "address";
+ const std::string Configuration::Key::server = "server";
+ const std::string Configuration::Key::port = "port";
+
+ const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN";
+ const std::string Configuration::DefaultValue::driver = "Apache Ignite";
+ const std::string Configuration::DefaultValue::cache = "";
+ const std::string Configuration::DefaultValue::address = "";
+ const std::string Configuration::DefaultValue::server = "";
+ const std::string Configuration::DefaultValue::port = "10800";
+ const uint16_t Configuration::DefaultValue::uintPort = common::LexicalCast<uint16_t>(port);
Configuration::Configuration() :
- dsn(dflt::dsn), driver(dflt::driver),
- host(dflt::host), port(dflt::port),
- cache(dflt::cache)
+ arguments()
{
- // No-op.
+ ParseAddress(DefaultValue::address, endPoint);
}
Configuration::~Configuration()
@@ -84,7 +57,11 @@ namespace ignite
void Configuration::FillFromConnectString(const char* str, size_t len)
{
- ArgumentMap connect_attributes;
+ // Initializing map.
+ arguments.clear();
+
+ // Initializing DSN to empty string.
+ arguments[Key::dsn].clear();
// Ignoring terminating zero byte if present.
// Some Driver Managers pass zero-terminated connection string
@@ -92,39 +69,19 @@ namespace ignite
if (len && !str[len - 1])
--len;
- ParseAttributeList(str, len, ';', connect_attributes);
-
- ArgumentMap::const_iterator it;
+ ParseAttributeList(str, len, ';', arguments);
- it = connect_attributes.find(attrkey::dsn);
- if (it != connect_attributes.end())
- dsn = it->second;
- else
- dsn.clear();
-
- it = connect_attributes.find(attrkey::driver);
- if (it != connect_attributes.end())
- driver = it->second;
- else
- driver = dflt::driver;
-
- it = connect_attributes.find(attrkey::host);
- if (it != connect_attributes.end())
- host = it->second;
- else
- host = dflt::host;
-
- it = connect_attributes.find(attrkey::port);
- if (it != connect_attributes.end())
- port = atoi(it->second.c_str());
- else
- port = dflt::port;
-
- it = connect_attributes.find(attrkey::cache);
- if (it != connect_attributes.end())
- cache = it->second;
+ ArgumentMap::const_iterator it = arguments.find(Key::address);
+ if (it != arguments.end())
+ {
+ // Parsing address.
+ ParseAddress(it->second, endPoint);
+ }
else
- cache = dflt::cache;
+ {
+ endPoint.host = GetStringValue(Key::server, DefaultValue::server);
+ endPoint.port = common::LexicalCast<uint16_t>(GetStringValue(Key::port, DefaultValue::port));
+ }
}
void Configuration::FillFromConnectString(const std::string& str)
@@ -136,27 +93,27 @@ namespace ignite
{
std::stringstream connect_string_buffer;
- if (!driver.empty())
- connect_string_buffer << attrkey::driver << "={" << driver << "};";
-
- if (!host.empty())
- connect_string_buffer << attrkey::host << '=' << host << ';';
-
- if (port)
- connect_string_buffer << attrkey::port << '=' << port << ';';
+ for (ArgumentMap::const_iterator it = arguments.begin(); it != arguments.end(); ++it)
+ {
+ const std::string& key = it->first;
+ const std::string& value = it->second;
- if (!dsn.empty())
- connect_string_buffer << attrkey::dsn << '=' << dsn << ';';
+ if (value.empty())
+ continue;
- if (!cache.empty())
- connect_string_buffer << attrkey::cache << '=' << cache << ';';
+ if (value.find(' ') == std::string::npos)
+ connect_string_buffer << key << '=' << value << ';';
+ else
+ connect_string_buffer << key << "={" << value << "};";
+ }
return connect_string_buffer.str();
}
void Configuration::FillFromConfigAttributes(const char * attributes)
{
- ArgumentMap config_attributes;
+ // Initializing map.
+ arguments.clear();
size_t len = 0;
@@ -166,45 +123,34 @@ namespace ignite
++len;
- ParseAttributeList(attributes, len, '\0', config_attributes);
-
- ArgumentMap::const_iterator it;
-
- it = config_attributes.find(attrkey::dsn);
- if (it != config_attributes.end())
- dsn = it->second;
- else
- dsn = dflt::dsn;
+ ParseAttributeList(attributes, len, '\0', arguments);
- it = config_attributes.find(attrkey::driver);
- if (it != config_attributes.end())
- driver = it->second;
+ ArgumentMap::const_iterator it = arguments.find(Key::address);
+ if (it != arguments.end())
+ {
+ // Parsing address.
+ ParseAddress(it->second, endPoint);
+ }
else
- driver.clear();
+ {
+ endPoint.host = GetStringValue(Key::server, DefaultValue::server);
+ endPoint.port = common::LexicalCast<uint16_t>(GetStringValue(Key::port, DefaultValue::port));
+ }
+ }
- it = config_attributes.find(attrkey::host);
- if (it != config_attributes.end())
- host = it->second;
- else
- host.clear();
+ const std::string& Configuration::GetStringValue(const std::string& key, const std::string& dflt) const
+ {
+ ArgumentMap::const_iterator it = arguments.find(common::ToLower(key));
- it = config_attributes.find(attrkey::port);
- if (it != config_attributes.end())
- port = atoi(it->second.c_str());
- else
- port = 0;
+ if (it != arguments.end())
+ return it->second;
- it = config_attributes.find(attrkey::cache);
- if (it != config_attributes.end())
- cache = it->second;
- else
- cache.clear();
+ return dflt;
}
- void Configuration::ParseAttributeList(const char * str, size_t len, char delimeter, ArgumentMap & args) const
+ void Configuration::ParseAttributeList(const char * str, size_t len, char delimeter, ArgumentMap & args)
{
std::string connect_str(str, len);
- args.clear();
while (!connect_str.empty())
{
@@ -245,6 +191,51 @@ namespace ignite
connect_str.erase(attr_begin - 1);
}
}
+
+ void Configuration::ParseAddress(const std::string& address, EndPoint& res)
+ {
+ int64_t colonNum = std::count(address.begin(), address.end(), ':');
+
+ if (colonNum == 0)
+ {
+ res.host = address;
+ res.port = DefaultValue::uintPort;
+ }
+ else if (colonNum == 1)
+ {
+ size_t pos = address.find(':');
+
+ if (pos == address.size() - 1)
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid address format: no port after colon");
+
+ res.host = address.substr(0, pos);
+
+ std::string port = address.substr(pos + 1);
+
+ if (!common::AllOf(port.begin(), port.end(), isdigit))
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid address format: port can only contain digits");
+
+ int32_t intPort = common::LexicalCast<int32_t>(port);
+
+ if (port.size() > sizeof("65535") - 1 || intPort > UINT16_MAX)
+ {
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid address format: Port value is too large,"
+ " valid value should be in range from 1 to 65535");
+ }
+
+ if (intPort == 0)
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid address format: Port value can not be zero");
+
+ res.port = static_cast<uint16_t>(intPort);
+ }
+ else
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid address format: too many colons");
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/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 2441759..844ad70 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -41,7 +41,11 @@ namespace ignite
{
const std::string Connection::PROTOCOL_VERSION_SINCE = "1.6.0";
- Connection::Connection() : socket(), connected(false), cache(), parser()
+ Connection::Connection() :
+ socket(),
+ connected(false),
+ parser(),
+ config()
{
// No-op.
}
@@ -53,8 +57,8 @@ namespace ignite
const config::ConnectionInfo& Connection::GetInfo() const
{
- // Connection info is the same for all connections now.
- static config::ConnectionInfo info;
+ // Connection info is constant and the same for all connections now.
+ const static config::ConnectionInfo info;
return info;
}
@@ -76,32 +80,38 @@ namespace ignite
return res;
}
- void Connection::Establish(const std::string& server)
+ void Connection::Establish(const std::string& connectStr)
{
- IGNITE_ODBC_API_CALL(InternalEstablish(server));
+ IGNITE_ODBC_API_CALL(InternalEstablish(connectStr));
}
- SqlResult Connection::InternalEstablish(const std::string& server)
+ SqlResult Connection::InternalEstablish(const std::string& connectStr)
{
config::Configuration config;
- if (server != config.GetDsn())
+ try
+ {
+ config.FillFromConnectString(connectStr);
+ }
+ catch (IgniteError& e)
{
- AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Unknown server.");
+ AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, e.GetText());
return SQL_RESULT_ERROR;
}
- return InternalEstablish(config.GetHost(), config.GetPort(), config.GetCache());
+ return InternalEstablish(config);
}
- void Connection::Establish(const std::string& host, uint16_t port, const std::string& cache)
+ void Connection::Establish(const config::Configuration cfg)
{
- IGNITE_ODBC_API_CALL(InternalEstablish(host, port, cache));
+ IGNITE_ODBC_API_CALL(InternalEstablish(cfg));
}
- SqlResult Connection::InternalEstablish(const std::string & host, uint16_t port, const std::string & cache)
+ SqlResult Connection::InternalEstablish(const config::Configuration cfg)
{
+ config = cfg;
+
if (connected)
{
AddStatusRecord(SQL_STATE_08002_ALREADY_CONNECTED, "Already connected.");
@@ -109,9 +119,7 @@ namespace ignite
return SQL_RESULT_ERROR;
}
- this->cache = cache;
-
- connected = socket.Connect(host.c_str(), port);
+ connected = socket.Connect(cfg.GetHost().c_str(), cfg.GetPort());
if (!connected)
{
@@ -262,11 +270,16 @@ namespace ignite
const std::string& Connection::GetCache() const
{
- return cache;
+ return config.GetCache();
+ }
+
+ const config::Configuration& Connection::GetConfiguration() const
+ {
+ return config;
}
diagnostic::DiagnosticRecord Connection::CreateStatusRecord(SqlState sqlState,
- const std::string& message, int32_t rowNum, int32_t columnNum) const
+ const std::string& message, int32_t rowNum, int32_t columnNum)
{
return diagnostic::DiagnosticRecord(sqlState, message, "", "", rowNum, columnNum);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/8386dd86/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 3b31f1d..9b4179e 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -42,7 +42,16 @@ namespace ignite
ignite::odbc::config::Configuration config;
- config.FillFromConfigAttributes(attributes);
+ try
+ {
+ config.FillFromConfigAttributes(attributes);
+ }
+ catch (IgniteError& e)
+ {
+ SQLPostInstallerError(e.GetCode(), e.GetText());
+
+ return SQL_FALSE;
+ }
if (!SQLValidDSN(config.GetDsn().c_str()))
return SQL_FALSE;
@@ -323,18 +332,14 @@ namespace ignite
std::string connectStr = SqlStringToString(inConnectionString, inConnectionStringLen);
- ignite::odbc::config::Configuration config;
-
- config.FillFromConnectString(connectStr);
-
- connection->Establish(config.GetHost(), config.GetPort(), config.GetCache());
+ connection->Establish(connectStr);
const DiagnosticRecordStorage& diag = connection->GetDiagnosticRecords();
if (!diag.IsSuccessful())
return diag.GetReturnCode();
- std::string outConnectStr = config.ToConnectString();
+ std::string outConnectStr = connection->GetConfiguration().ToConnectString();
size_t reslen = CopyStringToBuffer(outConnectStr,
reinterpret_cast<char*>(outConnectionString),
@@ -357,7 +362,7 @@ namespace ignite
SQLSMALLINT authLen)
{
using ignite::odbc::Connection;
- using ignite::odbc::diagnostic::DiagnosticRecordStorage;
+ using ignite::odbc::config::Configuration;
using ignite::utility::SqlStringToString;
LOG_MSG("SQLConnect called\n");
@@ -367,9 +372,11 @@ namespace ignite
if (!connection)
return SQL_INVALID_HANDLE;
- std::string server = SqlStringToString(serverName, serverNameLen);
+ //std::string server = SqlStringToString(serverName, serverNameLen);
+
+ Configuration config;
- connection->Establish(server);
+ connection->Establish(config);
return connection->GetDiagnosticRecords().GetReturnCode();
}