ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From voze...@apache.org
Subject ignite git commit: IGNITE-3577: ODBC: Added simplified "Address" porperty. This closes #898.
Date Thu, 28 Jul 2016 10:42:40 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-1.7 33d35b3ed -> 8386dd867


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-1.7
Commit: 8386dd867a82e9814b43d54cca588a5d7a82ef4b
Parents: 33d35b3
Author: isapego <isapego@gridgain.com>
Authored: Thu Jul 28 13:42:32 2016 +0300
Committer: vozerov-gridgain <vozerov@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();
     }


Mime
View raw message