You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/08/19 11:48:24 UTC
[07/53] [abbrv] ignite git commit: IGNITE-3587: ODBC: Added
distributed joins support. This closes #908.
IGNITE-3587: ODBC: Added distributed joins support. This closes #908.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/311428ee
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/311428ee
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/311428ee
Branch: refs/heads/ignite-3299
Commit: 311428eee8d52640a6efdac721335f63a4244d38
Parents: a596e67
Author: isapego <is...@gridgain.com>
Authored: Fri Aug 5 10:38:50 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Aug 5 10:38:50 2016 +0300
----------------------------------------------------------------------
.../processors/odbc/OdbcHandshakeRequest.java | 42 +++-
.../processors/odbc/OdbcHandshakeResult.java | 17 +-
.../processors/odbc/OdbcMessageParser.java | 34 ++-
.../processors/odbc/OdbcProtocolVersion.java | 125 +++++++++++
.../processors/odbc/OdbcRequestHandler.java | 26 ++-
modules/platforms/cpp/odbc-test/Makefile.am | 1 +
.../odbc-test/config/queries-test-noodbc.xml | 103 +++++++++
.../cpp/odbc-test/config/queries-test.xml | 45 ++--
.../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 +
.../project/vs/odbc-test.vcxproj.filters | 3 +
.../cpp/odbc-test/src/configuration_test.cpp | 148 +++++++++++--
.../cpp/odbc-test/src/queries_test.cpp | 218 +++++++++++++++++--
modules/platforms/cpp/odbc/Makefile.am | 1 +
modules/platforms/cpp/odbc/include/Makefile.am | 1 +
.../cpp/odbc/include/ignite/odbc/common_types.h | 3 +
.../include/ignite/odbc/config/configuration.h | 67 +++++-
.../cpp/odbc/include/ignite/odbc/connection.h | 16 +-
.../cpp/odbc/include/ignite/odbc/message.h | 35 ++-
.../cpp/odbc/include/ignite/odbc/parser.h | 3 -
.../odbc/include/ignite/odbc/protocol_version.h | 172 +++++++++++++++
.../platforms/cpp/odbc/project/vs/odbc.vcxproj | 2 +
.../cpp/odbc/project/vs/odbc.vcxproj.filters | 6 +
.../cpp/odbc/src/config/configuration.cpp | 92 ++++++--
modules/platforms/cpp/odbc/src/connection.cpp | 23 +-
.../odbc/src/diagnostic/diagnostic_record.cpp | 6 +
.../platforms/cpp/odbc/src/protocol_version.cpp | 134 ++++++++++++
26 files changed, 1204 insertions(+), 120 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeRequest.java
index 5e09041..55ff21f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeRequest.java
@@ -24,24 +24,58 @@ import org.apache.ignite.internal.util.typedef.internal.S;
*/
public class OdbcHandshakeRequest extends OdbcRequest {
/** Protocol version. */
- private final long ver;
+ private final OdbcProtocolVersion ver;
+
+ /** Distributed joins flag. */
+ private boolean distributedJoins = false;
+
+ /** Enforce join order flag. */
+ private boolean enforceJoinOrder = false;
/**
- * @param ver Protocol version.
+ * @param ver Long value for protocol version.
*/
public OdbcHandshakeRequest(long ver) {
super(HANDSHAKE);
- this.ver = ver;
+ this.ver = OdbcProtocolVersion.fromLong(ver);
}
/**
* @return Protocol version.
*/
- public long version() {
+ public OdbcProtocolVersion version() {
return ver;
}
+ /**
+ * @return Distributed joins flag.
+ */
+ public boolean distributedJoins() {
+ return distributedJoins;
+ }
+
+ /**
+ * @param distributedJoins Distributed joins flag.
+ */
+ public void distributedJoins(boolean distributedJoins) {
+ this.distributedJoins = distributedJoins;
+ }
+
+ /**
+ * @return Enforce join order flag.
+ */
+ public boolean enforceJoinOrder() {
+ return enforceJoinOrder;
+ }
+
+ /**
+ * @param enforceJoinOrder Enforce join order flag.
+ */
+ public void enforceJoinOrder(boolean enforceJoinOrder) {
+ this.enforceJoinOrder = enforceJoinOrder;
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(OdbcHandshakeRequest.class, this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeResult.java
index bf1c61e..74c5bd4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcHandshakeResult.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.processors.odbc;
-import org.jetbrains.annotations.Nullable;
+import org.apache.ignite.internal.util.typedef.internal.S;
/**
* ODBC handshake result.
@@ -33,11 +33,13 @@ public class OdbcHandshakeResult {
private final String curVer;
/**
- * @param accepted Handshake accepted.
+ * Constructor.
+ *
+ * @param accepted Indicates whether handshake accepted or not.
* @param protoVerSince Apache Ignite version when protocol version has been introduced.
* @param curVer Current Apache Ignite version.
*/
- public OdbcHandshakeResult(boolean accepted, @Nullable String protoVerSince, @Nullable String curVer) {
+ public OdbcHandshakeResult(boolean accepted, String protoVerSince, String curVer) {
this.accepted = accepted;
this.protoVerSince = protoVerSince;
this.curVer = curVer;
@@ -53,14 +55,19 @@ public class OdbcHandshakeResult {
/**
* @return Apache Ignite version when protocol version has been introduced.
*/
- @Nullable public String protoVerSince() {
+ public String protocolVersionSince() {
return protoVerSince;
}
/**
* @return Current Apache Ignite version.
*/
- @Nullable public String currentVer() {
+ public String currentVersion() {
return curVer;
}
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(OdbcHandshakeResult.class, this);
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
index fce8b1b..e8b594e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcMessageParser.java
@@ -34,12 +34,6 @@ import java.util.Collection;
* ODBC message parser.
*/
public class OdbcMessageParser {
- /** Current ODBC communication protocol version. */
- public static final long PROTO_VER = 1;
-
- /** Apache Ignite version when ODBC communication protocol version has been introduced. */
- public static final String PROTO_VER_SINCE = "1.6.0";
-
/** Initial output stream capacity. */
private static final int INIT_CAP = 1024;
@@ -82,10 +76,26 @@ public class OdbcMessageParser {
// we has not confirmed that the remote client uses the same protocol version.
if (!verConfirmed) {
if (cmd == OdbcRequest.HANDSHAKE)
- return new OdbcHandshakeRequest(reader.readLong());
+ {
+ long longVersion = reader.readLong();
+
+ OdbcHandshakeRequest res = new OdbcHandshakeRequest(longVersion);
+
+ OdbcProtocolVersion version = res.version();
+
+ if (version.isUnknown())
+ return res;
+
+ if (version.isDistributedJoinsSupported()) {
+ res.distributedJoins(reader.readBoolean());
+ res.enforceJoinOrder(reader.readBoolean());
+ }
+
+ return res;
+ }
else
- throw new IgniteException("Unexpected ODBC command (first message is not a handshake request): [cmd=" +
- cmd + ']');
+ throw new IgniteException("Unexpected ODBC command " +
+ "(first message is not a handshake request): [cmd=" + cmd + ']');
}
OdbcRequest res;
@@ -174,6 +184,8 @@ public class OdbcMessageParser {
Object res0 = msg.response();
+ if (res0 == null)
+ return writer.array();
if (res0 instanceof OdbcHandshakeResult) {
OdbcHandshakeResult res = (OdbcHandshakeResult) res0;
@@ -189,8 +201,8 @@ public class OdbcMessageParser {
}
else {
writer.writeBoolean(false);
- writer.writeString(res.protoVerSince());
- writer.writeString(res.currentVer());
+ writer.writeString(res.protocolVersionSince());
+ writer.writeString(res.currentVersion());
}
}
else if (res0 instanceof OdbcQueryExecuteResult) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolVersion.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolVersion.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolVersion.java
new file mode 100644
index 0000000..57efa02
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcProtocolVersion.java
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+package org.apache.ignite.internal.processors.odbc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ODBC protocol version.
+ */
+public enum OdbcProtocolVersion {
+ /** First version of the ODBC. Released with Ignite 1.6 */
+ VERSION_1_6_0(1),
+
+ /** Second version of the ODBC. Released with Ignite 1.8 */
+ VERSION_1_8_0(makeVersion(1,8,0)),
+
+ /** Unknown version. */
+ VERSION_UNKNOWN(Long.MIN_VALUE);
+
+ /** Mask to get 2 lowest bytes of the value and cast to long. */
+ private static final long LONG_MASK = 0x000000000000FFFFL;
+
+ /** Long value to enum map. */
+ private static final Map<Long, OdbcProtocolVersion> versions = new HashMap<>();
+
+ /** Enum value to Ignite version map */
+ private static final Map<OdbcProtocolVersion, String> since = new HashMap<>();
+
+ /**
+ * Map long values to version.
+ */
+ static {
+ for (OdbcProtocolVersion version : values())
+ versions.put(version.longValue(), version);
+
+ since.put(VERSION_1_6_0, "1.6.0");
+ since.put(VERSION_1_8_0, "1.8.0");
+ }
+
+ /** Long value for version. */
+ private final long longVal;
+
+ /**
+ * @param longVal Long value.
+ */
+ OdbcProtocolVersion(long longVal) {
+ this.longVal = longVal;
+ }
+
+ /**
+ * Make long value for the version.
+ *
+ * @param major Major version.
+ * @param minor Minor version.
+ * @param maintenance Maintenance version.
+ * @return Long value for the version.
+ */
+ private static long makeVersion(int major, int minor, int maintenance) {
+ return ((major & LONG_MASK) << 48) | ((minor & LONG_MASK) << 32) | ((maintenance & LONG_MASK) << 16);
+ }
+
+ /**
+ * @param longVal Long value.
+ * @return Protocol version.
+ */
+ public static OdbcProtocolVersion fromLong(long longVal) {
+ OdbcProtocolVersion res = versions.get(longVal);
+
+ return res == null ? VERSION_UNKNOWN : res;
+ }
+
+ /**
+ * @return Current version.
+ */
+ public static OdbcProtocolVersion current() {
+ return VERSION_1_8_0;
+ }
+
+ /**
+ * @return Long value.
+ */
+ public long longValue() {
+ return longVal;
+ }
+
+ /**
+ * @return {@code true} if this version is unknown.
+ */
+ public boolean isUnknown() {
+ return longVal == VERSION_UNKNOWN.longVal;
+ }
+
+ /**
+ * @return {@code true} if this version supports distributed joins.
+ */
+ public boolean isDistributedJoinsSupported() {
+ assert !isUnknown();
+
+ return longVal >= VERSION_1_8_0.longVal;
+ }
+
+ /**
+ * @return Ignite version when introduced.
+ */
+ public String since() {
+ assert !isUnknown();
+
+ return since.get(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
index 43a1fa4..8f2d092 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/OdbcRequestHandler.java
@@ -54,6 +54,12 @@ public class OdbcRequestHandler {
/** Current queries cursors. */
private final ConcurrentHashMap<Long, IgniteBiTuple<QueryCursor, Iterator>> qryCursors = new ConcurrentHashMap<>();
+ /** Distributed joins flag. */
+ private boolean distributedJoins = false;
+
+ /** Enforce join order flag. */
+ private boolean enforceJoinOrder = false;
+
/**
* Constructor.
*
@@ -115,16 +121,23 @@ public class OdbcRequestHandler {
* @return Response.
*/
private OdbcResponse performHandshake(OdbcHandshakeRequest req) {
- OdbcHandshakeResult res;
+ OdbcProtocolVersion version = req.version();
- if (req.version() == OdbcMessageParser.PROTO_VER)
- res = new OdbcHandshakeResult(true, null, null);
- else {
+ if (version.isUnknown()) {
IgniteProductVersion ver = ctx.grid().version();
String verStr = Byte.toString(ver.major()) + '.' + ver.minor() + '.' + ver.maintenance();
- res = new OdbcHandshakeResult(false, OdbcMessageParser.PROTO_VER_SINCE, verStr);
+ OdbcHandshakeResult res = new OdbcHandshakeResult(false, OdbcProtocolVersion.current().since(), verStr);
+
+ return new OdbcResponse(res);
+ }
+
+ OdbcHandshakeResult res = new OdbcHandshakeResult(true, null, null);
+
+ if (version.isDistributedJoinsSupported()) {
+ distributedJoins = req.distributedJoins();
+ enforceJoinOrder = req.enforceJoinOrder();
}
return new OdbcResponse(res);
@@ -151,6 +164,9 @@ public class OdbcRequestHandler {
qry.setArgs(req.arguments());
+ qry.setDistributedJoins(distributedJoins);
+ qry.setEnforceJoinOrder(enforceJoinOrder);
+
IgniteCache<Object, Object> cache = ctx.grid().cache(req.cacheName());
if (cache == null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index 48b193a..a878d02 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -66,6 +66,7 @@ ignite_odbc_tests_SOURCES = \
../odbc/src/app/application_data_buffer.cpp \
../odbc/src/config/configuration.cpp \
../odbc/src/row.cpp \
+ ../odbc/src/protocol_version.cpp \
../odbc/src/column.cpp \
../odbc/src/utility.cpp \
../odbc/src/result_page.cpp
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
new file mode 100644
index 0000000..18447c2
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/config/queries-test-noodbc.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ 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">
+ <property name="localHost" value="127.0.0.1"/>
+ <property name="connectorConfiguration"><null/></property>
+
+ <property name="cacheConfiguration">
+ <list>
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="cache"/>
+ <property name="cacheMode" value="PARTITIONED"/>
+ <property name="atomicityMode" value="TRANSACTIONAL"/>
+ <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+ <!-- Configure type metadata to enable queries. -->
+ <property name="queryEntities">
+ <list>
+ <bean class="org.apache.ignite.cache.QueryEntity">
+ <property name="keyType" value="java.lang.Long"/>
+ <property name="valueType" value="TestType"/>
+
+ <property name="fields">
+ <map>
+ <entry key="i8Field" value="java.lang.Byte"/>
+ <entry key="i16Field" value="java.lang.Short"/>
+ <entry key="i32Field" value="java.lang.Integer"/>
+ <entry key="i64Field" value="java.lang.Long"/>
+ <entry key="strField" value="java.lang.String"/>
+ <entry key="floatField" value="java.lang.Float"/>
+ <entry key="doubleField" value="java.lang.Double"/>
+ <entry key="boolField" value="java.lang.Boolean"/>
+ <entry key="guidField" value="java.util.UUID"/>
+ <entry key="dateField" value="java.util.Date"/>
+ <entry key="timestampField" value="java.sql.Timestamp"/>
+ </map>
+ </property>
+
+ <property name="indexes">
+ <list>
+ <bean class="org.apache.ignite.cache.QueryIndex">
+ <constructor-arg value="i32Field"/>
+ </bean>
+ <bean class="org.apache.ignite.cache.QueryIndex">
+ <constructor-arg value="i64Field"/>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </list>
+ </property>
+
+ <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <!--
+ Ignite provides several options for automatic discovery that can be used
+ instead os static IP based discovery.
+ -->
+ <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
+ <!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with actual host IP address. -->
+ <value>127.0.0.1:47500</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ <property name="socketTimeout" value="300" />
+ </bean>
+ </property>
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 054da42..54cb9be 100644
--- a/modules/platforms/cpp/odbc-test/config/queries-test.xml
+++ b/modules/platforms/cpp/odbc-test/config/queries-test.xml
@@ -41,17 +41,18 @@
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="cache"/>
<property name="cacheMode" value="PARTITIONED"/>
- <property name="atomicityMode" value="ATOMIC"/>
- <property name="writeSynchronizationMode" value="PRIMARY_SYNC"/>
+ <property name="atomicityMode" value="TRANSACTIONAL"/>
+ <property name="writeSynchronizationMode" value="FULL_SYNC"/>
<!-- Configure type metadata to enable queries. -->
- <property name="typeMetadata">
- <list>
- <bean class="org.apache.ignite.cache.CacheTypeMetadata">
- <property name="keyType" value="java.lang.Long"/>
- <property name="valueType" value="TestType"/>
- <property name="queryFields">
- <map>
+ <property name="queryEntities">
+ <list>
+ <bean class="org.apache.ignite.cache.QueryEntity">
+ <property name="keyType" value="java.lang.Long"/>
+ <property name="valueType" value="TestType"/>
+
+ <property name="fields">
+ <map>
<entry key="i8Field" value="java.lang.Byte"/>
<entry key="i16Field" value="java.lang.Short"/>
<entry key="i32Field" value="java.lang.Integer"/>
@@ -63,11 +64,22 @@
<entry key="guidField" value="java.util.UUID"/>
<entry key="dateField" value="java.util.Date"/>
<entry key="timestampField" value="java.sql.Timestamp"/>
- </map>
- </property>
- </bean>
- </list>
- </property>
+ </map>
+ </property>
+
+ <property name="indexes">
+ <list>
+ <bean class="org.apache.ignite.cache.QueryIndex">
+ <constructor-arg value="i32Field"/>
+ </bean>
+ <bean class="org.apache.ignite.cache.QueryIndex">
+ <constructor-arg value="i64Field"/>
+ </bean>
+ </list>
+ </property>
+ </bean>
+ </list>
+ </property>
</bean>
</list>
</property>
@@ -81,12 +93,11 @@
instead os static IP based discovery.
-->
<!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
- <!--<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">-->
- <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<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>
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index fbc0929..833904e 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -157,6 +157,7 @@
<ClCompile Include="..\..\..\odbc\src\config\configuration.cpp" />
<ClCompile Include="..\..\..\odbc\src\config\connection_info.cpp" />
<ClCompile Include="..\..\..\odbc\src\cursor.cpp" />
+ <ClCompile Include="..\..\..\odbc\src\protocol_version.cpp" />
<ClCompile Include="..\..\..\odbc\src\result_page.cpp" />
<ClCompile Include="..\..\..\odbc\src\row.cpp" />
<ClCompile Include="..\..\..\odbc\src\utility.cpp" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 2e38c24..aead2af 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -76,6 +76,9 @@
<ClCompile Include="..\..\src\queries_test.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\odbc\src\protocol_version.cpp">
+ <Filter>Externals</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\test_type.h">
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 10fd137..c0bb439 100644
--- a/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/configuration_test.cpp
@@ -20,6 +20,7 @@
#endif
#include <iostream>
+#include <set>
#include <boost/test/unit_test.hpp>
@@ -36,6 +37,8 @@ namespace
const uint16_t testServerPort = 4242;
const std::string testCacheName = "TestCache";
const std::string testDsn = "Ignite DSN";
+ const bool testDistributedJoins = true;
+ const bool testEnforceJoinOrder = true;
const std::string testAddress = testServerHost + ':' + ignite::common::LexicalCast<std::string>(testServerPort);
}
@@ -49,6 +52,42 @@ void CheckValidAddress(const char* connectStr, uint16_t port)
BOOST_CHECK_EQUAL(cfg.GetPort(), port);
}
+void CheckValidProtocolVersion(const char* connectStr, ignite::odbc::ProtocolVersion version)
+{
+ Configuration cfg;
+
+ BOOST_CHECK_NO_THROW(cfg.FillFromConnectString(connectStr));
+
+ BOOST_CHECK(cfg.GetProtocolVersion() == version);
+}
+
+void CheckInvalidProtocolVersion(const char* connectStr)
+{
+ Configuration cfg;
+
+ cfg.FillFromConnectString(connectStr);
+
+ BOOST_CHECK_THROW(cfg.GetProtocolVersion(), ignite::IgniteError);
+}
+
+void CheckValidBoolValue(const std::string& connectStr, const std::string& key, bool val)
+{
+ Configuration cfg;
+
+ BOOST_CHECK_NO_THROW(cfg.FillFromConnectString(connectStr));
+
+ BOOST_CHECK_EQUAL(cfg.GetBoolValue(key, val), val);
+}
+
+void CheckInvalidBoolValue(const std::string& connectStr, const std::string& key)
+{
+ Configuration cfg;
+
+ cfg.FillFromConnectString(connectStr);
+
+ BOOST_CHECK_THROW(cfg.GetBoolValue(key, false), ignite::IgniteError);
+}
+
void CheckConnectionConfig(const Configuration& cfg)
{
BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName);
@@ -57,16 +96,20 @@ void CheckConnectionConfig(const Configuration& cfg)
BOOST_CHECK_EQUAL(cfg.GetAddress(), testAddress);
BOOST_CHECK_EQUAL(cfg.GetCache(), testCacheName);
BOOST_CHECK_EQUAL(cfg.GetDsn(), std::string());
+ BOOST_CHECK_EQUAL(cfg.IsDistributedJoins(), testDistributedJoins);
+ BOOST_CHECK_EQUAL(cfg.IsEnforceJoinOrder(), testEnforceJoinOrder);
std::stringstream constructor;
constructor << "address=" << testAddress << ';'
<< "cache=" << testCacheName << ';'
- << "driver={" << testDriverName << "};";
+ << "distributed_joins=" << (testDistributedJoins ? "true" : "false") << ';'
+ << "driver={" << testDriverName << "};"
+ << "enforce_join_order=" << (testEnforceJoinOrder ? "true" : "false") << ';';
const std::string& expectedStr = constructor.str();
- BOOST_CHECK_EQUAL(cfg.ToConnectString(), expectedStr);
+ BOOST_CHECK_EQUAL(ignite::common::ToLower(cfg.ToConnectString()), ignite::common::ToLower(expectedStr));
}
void CheckDsnConfig(const Configuration& cfg)
@@ -76,7 +119,9 @@ void CheckDsnConfig(const Configuration& cfg)
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_CHECK_EQUAL(cfg.GetPort(), Configuration::DefaultValue::port);
+ BOOST_CHECK_EQUAL(cfg.IsDistributedJoins(), false);
+ BOOST_CHECK_EQUAL(cfg.IsEnforceJoinOrder(), false);
}
BOOST_AUTO_TEST_SUITE(ConfigurationTestSuite)
@@ -85,9 +130,11 @@ 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(testServerPort, Configuration::DefaultValue::port);
BOOST_CHECK_NE(testCacheName, Configuration::DefaultValue::cache);
BOOST_CHECK_NE(testDsn, Configuration::DefaultValue::dsn);
+ BOOST_CHECK_NE(testDistributedJoins, Configuration::DefaultValue::distributedJoins);
+ BOOST_CHECK_NE(testEnforceJoinOrder, Configuration::DefaultValue::enforceJoinOrder);
}
BOOST_AUTO_TEST_CASE(TestConnectStringUppercase)
@@ -98,7 +145,9 @@ BOOST_AUTO_TEST_CASE(TestConnectStringUppercase)
constructor << "DRIVER={" << testDriverName << "};"
<< "ADDRESS=" << testAddress << ';'
- << "CACHE=" << testCacheName;
+ << "CACHE=" << testCacheName << ';'
+ << "DISTRIBUTED_JOINS=" << (testDistributedJoins ? "TRUE" : "FALSE") << ';'
+ << "ENFORCE_JOIN_ORDER=" << (testEnforceJoinOrder ? "TRUE" : "FALSE");
const std::string& connectStr = constructor.str();
@@ -115,7 +164,9 @@ BOOST_AUTO_TEST_CASE(TestConnectStringLowercase)
constructor << "driver={" << testDriverName << "};"
<< "address=" << testAddress << ';'
- << "cache=" << testCacheName;
+ << "cache=" << testCacheName << ';'
+ << "distributed_joins=" << (testDistributedJoins ? "true" : "false") << ';'
+ << "enforce_join_order=" << (testEnforceJoinOrder ? "true" : "false");
const std::string& connectStr = constructor.str();
@@ -132,7 +183,9 @@ BOOST_AUTO_TEST_CASE(TestConnectStringZeroTerminated)
constructor << "driver={" << testDriverName << "};"
<< "address=" << testAddress << ';'
- << "cache=" << testCacheName;
+ << "cache=" << testCacheName << ';'
+ << "distributed_joins=" << (testDistributedJoins ? "true" : "false") << ';'
+ << "enforce_join_order=" << (testEnforceJoinOrder ? "true" : "false");
const std::string& connectStr = constructor.str();
@@ -149,7 +202,9 @@ BOOST_AUTO_TEST_CASE(TestConnectStringMixed)
constructor << "Driver={" << testDriverName << "};"
<< "Address=" << testAddress << ';'
- << "Cache=" << testCacheName;
+ << "Cache=" << testCacheName << ';'
+ << "Distributed_Joins=" << (testDistributedJoins ? "True" : "False") << ';'
+ << "Enforce_Join_Order=" << (testEnforceJoinOrder ? "True" : "False");
const std::string& connectStr = constructor.str();
@@ -166,7 +221,9 @@ BOOST_AUTO_TEST_CASE(TestConnectStringWhitepaces)
constructor << "DRIVER = {" << testDriverName << "} ;\n"
<< " ADDRESS =" << testAddress << "; "
- << "CACHE = \n\r" << testCacheName;
+ << "CACHE = \n\r" << testCacheName << ';'
+ << " DISTRIBUTED_JOINS=" << (testDistributedJoins ? "TRUE" : "FALSE") << ';'
+ << "ENFORCE_JOIN_ORDER= " << (testEnforceJoinOrder ? "TRUE " : "FALSE ");
const std::string& connectStr = constructor.str();
@@ -190,13 +247,74 @@ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidAddress)
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);
+ CheckValidAddress("Address=example.com;", Configuration::DefaultValue::port);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectStringInvalidVersion)
+{
+ CheckInvalidProtocolVersion("Protocol_Version=0;");
+ CheckInvalidProtocolVersion("Protocol_Version=1;");
+ CheckInvalidProtocolVersion("Protocol_Version=2;");
+ CheckInvalidProtocolVersion("Protocol_Version=1.6.1;");
+ CheckInvalidProtocolVersion("Protocol_Version=1.7.0;");
+ CheckInvalidProtocolVersion("Protocol_Version=1.8.1;");
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectStringValidVersion)
+{
+ CheckValidProtocolVersion("Protocol_Version=1.6.0;", ignite::odbc::ProtocolVersion::VERSION_1_6_0);
+ CheckValidProtocolVersion("Protocol_Version=1.8.0;", ignite::odbc::ProtocolVersion::VERSION_1_8_0);
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys)
+{
+ typedef std::set<std::string> Set;
+
+ Set keys;
+
+ keys.insert("distributed_joins");
+ keys.insert("enforce_join_order");
+
+ for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it)
+ {
+ const std::string& key = *it;
+
+ CheckInvalidBoolValue(key + "=1;", key);
+ CheckInvalidBoolValue(key + "=0;", key);
+ CheckInvalidBoolValue(key + "=42;", key);
+ CheckInvalidBoolValue(key + "=truee;", key);
+ CheckInvalidBoolValue(key + "=flase;", key);
+ CheckInvalidBoolValue(key + "=falsee;", key);
+ CheckInvalidBoolValue(key + "=yes;", key);
+ CheckInvalidBoolValue(key + "=no;", key);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectStringValidBoolKeys)
+{
+ typedef std::set<std::string> Set;
+
+ Set keys;
+
+ keys.insert("distributed_joins");
+ keys.insert("enforce_join_order");
+
+ for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it)
+ {
+ const std::string& key = *it;
+
+ CheckValidBoolValue(key + "=true;", key, true);
+ CheckValidBoolValue(key + "=True;", key, true);
+ CheckValidBoolValue(key + "=TRUE;", key, true);
+
+ CheckValidBoolValue(key + "=false;", key, false);
+ CheckValidBoolValue(key + "=False;", key, false);
+ CheckValidBoolValue(key + "=FALSE;", key, false);
+ }
}
BOOST_AUTO_TEST_CASE(TestDsnStringUppercase)
@@ -215,7 +333,7 @@ BOOST_AUTO_TEST_CASE(TestDsnStringUppercase)
CheckDsnConfig(cfg);
}
-BOOST_AUTO_TEST_CASE(TestDsnStrinLowercase)
+BOOST_AUTO_TEST_CASE(TestDsnStringLowercase)
{
Configuration cfg;
@@ -231,7 +349,7 @@ BOOST_AUTO_TEST_CASE(TestDsnStrinLowercase)
CheckDsnConfig(cfg);
}
-BOOST_AUTO_TEST_CASE(TestDsnStrinMixed)
+BOOST_AUTO_TEST_CASE(TestDsnStringMixed)
{
Configuration cfg;
@@ -247,7 +365,7 @@ BOOST_AUTO_TEST_CASE(TestDsnStrinMixed)
CheckDsnConfig(cfg);
}
-BOOST_AUTO_TEST_CASE(TestDsnStrinWhitespaces)
+BOOST_AUTO_TEST_CASE(TestDsnStringWhitespaces)
{
Configuration cfg;
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 ccb3a4d..58b5f64 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -122,6 +122,44 @@ struct QueriesTestSuiteFixture
BOOST_REQUIRE(stmt != NULL);
}
+ void Disconnect()
+ {
+ // Releasing statement handle.
+ SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+ // Disconneting from the server.
+ SQLDisconnect(dbc);
+
+ // Releasing allocated handles.
+ SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+ SQLFreeHandle(SQL_HANDLE_ENV, env);
+ }
+
+ static Ignite StartAdditionalNode(const char* name)
+ {
+ 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
+
+ cfg.springCfgPath.assign(getenv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH")).append("/queries-test-noodbc.xml");
+
+ IgniteError err;
+
+ return Ignition::Start(cfg, name);
+ }
+
/**
* Constructor.
*/
@@ -143,16 +181,11 @@ struct QueriesTestSuiteFixture
cfg.jvmMaxMem = 4096;
#endif
- char* cfgPath = getenv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH");
-
- cfg.springCfgPath = std::string(cfgPath).append("/").append("queries-test.xml");
+ cfg.springCfgPath.assign(getenv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH")).append("/queries-test.xml");
IgniteError err;
- grid = Ignition::Start(cfg, &err);
-
- if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
- BOOST_FAIL(err.GetText());
+ grid = Ignition::Start(cfg, "NodeMain");
testCache = grid.GetCache<int64_t, TestType>("cache");
}
@@ -162,17 +195,9 @@ struct QueriesTestSuiteFixture
*/
~QueriesTestSuiteFixture()
{
- // Releasing statement handle.
- SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-
- // Disconneting from the server.
- SQLDisconnect(dbc);
-
- // Releasing allocated handles.
- SQLFreeHandle(SQL_HANDLE_DBC, dbc);
- SQLFreeHandle(SQL_HANDLE_ENV, env);
+ Disconnect();
- Ignition::Stop(grid.GetName(), true);
+ Ignition::StopAll(true);
}
template<typename T>
@@ -269,6 +294,28 @@ struct QueriesTestSuiteFixture
BOOST_CHECK(ret == SQL_NO_DATA);
}
+ int CountRows(SQLHSTMT stmt)
+ {
+ int res = 0;
+
+ SQLRETURN ret = SQL_SUCCESS;
+
+ while (ret == SQL_SUCCESS)
+ {
+ ret = SQLFetch(stmt);
+
+ if (ret == SQL_NO_DATA)
+ break;
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ++res;
+ }
+
+ return res;
+ }
+
/** Node started during the test. */
Ignite grid;
@@ -292,6 +339,16 @@ BOOST_AUTO_TEST_CASE(TestLegacyConnection)
Connect("DRIVER={Apache Ignite};SERVER=127.0.0.1;PORT=11110;CACHE=cache");
}
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_1_6_0)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache;PROTOCOL_VERSION=1.6.0");
+}
+
+BOOST_AUTO_TEST_CASE(TestConnectionProtocolVersion_1_8_0)
+{
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache;PROTOCOL_VERSION=1.8.0");
+}
+
BOOST_AUTO_TEST_CASE(TestTwoRowsInt8)
{
CheckTwoRowsInt<int8_t>(SQL_C_STINYINT);
@@ -538,4 +595,131 @@ BOOST_AUTO_TEST_CASE(TestOneRowStringLen)
BOOST_CHECK(ret == SQL_NO_DATA);
}
+BOOST_AUTO_TEST_CASE(TestDistributedJoins)
+{
+ // Starting additional node.
+ Ignite node1 = StartAdditionalNode("Node1");
+ Ignite node2 = StartAdditionalNode("Node2");
+
+ const int entriesNum = 1000;
+
+ // Filling cache with data.
+ for (int i = 0; i < entriesNum; ++i)
+ {
+ TestType entry;
+
+ entry.i32Field = i;
+ entry.i64Field = entriesNum - i - 1;
+
+ testCache.Put(i, entry);
+ }
+
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
+ SQLRETURN ret;
+
+ const size_t columnsCnt = 2;
+
+ SQLBIGINT columns[columnsCnt] = { 0 };
+
+ // Binding colums.
+ for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+ {
+ ret = SQLBindCol(stmt, i + 1, SQL_C_SLONG, &columns[i], 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+ }
+
+ SQLCHAR request[] =
+ "SELECT T0.i32Field, T1.i64Field FROM TestType AS T0 "
+ "INNER JOIN TestType AS T1 "
+ "ON (T0.i32Field = T1.i64Field)";
+
+ ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ int rowsNum = CountRows(stmt);
+
+ BOOST_CHECK_GT(rowsNum, 0);
+ BOOST_CHECK_LT(rowsNum, entriesNum);
+
+ Disconnect();
+
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache;DISTRIBUTED_JOINS=true;");
+
+ // Binding colums.
+ for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+ {
+ ret = SQLBindCol(stmt, i + 1, SQL_C_SLONG, &columns[i], 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+ }
+
+ ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ rowsNum = CountRows(stmt);
+
+ BOOST_CHECK_EQUAL(rowsNum, entriesNum);
+}
+
+BOOST_AUTO_TEST_CASE(TestDistributedJoinsWithOldVersion)
+{
+ // Starting additional node.
+ Ignite node1 = StartAdditionalNode("Node1");
+ Ignite node2 = StartAdditionalNode("Node2");
+
+ const int entriesNum = 1000;
+
+ // Filling cache with data.
+ for (int i = 0; i < entriesNum; ++i)
+ {
+ TestType entry;
+
+ entry.i32Field = i;
+ entry.i64Field = entriesNum - i - 1;
+
+ testCache.Put(i, entry);
+ }
+
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache;DISTRIBUTED_JOINS=true;PROTOCOL_VERSION=1.6.0");
+
+ SQLRETURN ret;
+
+ const size_t columnsCnt = 2;
+
+ SQLBIGINT columns[columnsCnt] = { 0 };
+
+ // Binding colums.
+ for (SQLSMALLINT i = 0; i < columnsCnt; ++i)
+ {
+ ret = SQLBindCol(stmt, i + 1, SQL_C_SLONG, &columns[i], 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+ }
+
+ SQLCHAR request[] =
+ "SELECT T0.i32Field, T1.i64Field FROM TestType AS T0 "
+ "INNER JOIN TestType AS T1 "
+ "ON (T0.i32Field = T1.i64Field)";
+
+ ret = SQLExecDirect(stmt, request, SQL_NTS);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ int rowsNum = CountRows(stmt);
+
+ BOOST_CHECK_GT(rowsNum, 0);
+ BOOST_CHECK_LT(rowsNum, entriesNum);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am
index 29f0ef4..9faa999 100644
--- a/modules/platforms/cpp/odbc/Makefile.am
+++ b/modules/platforms/cpp/odbc/Makefile.am
@@ -69,6 +69,7 @@ libignite_odbc_la_SOURCES = \
src/query/table_metadata_query.cpp \
src/query/type_info_query.cpp \
src/query/special_columns_query.cpp \
+ src/protocol_version.cpp \
src/result_page.cpp \
src/row.cpp \
src/column.cpp \
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/Makefile.am b/modules/platforms/cpp/odbc/include/Makefile.am
index 192021d..0776548 100644
--- a/modules/platforms/cpp/odbc/include/Makefile.am
+++ b/modules/platforms/cpp/odbc/include/Makefile.am
@@ -27,6 +27,7 @@ noinst_HEADERS = \
ignite/odbc/query/column_metadata_query.h \
ignite/odbc/query/query.h \
ignite/odbc/query/primary_keys_query.h \
+ ignite/odbc/protocol_version.h \
ignite/odbc/statement.h \
ignite/odbc/config/configuration.h \
ignite/odbc/config/connection_info.h \
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
index 6636ca4..250eaf2 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/common_types.h
@@ -60,6 +60,9 @@ namespace ignite
/** Output data has been truncated. */
SQL_STATE_01004_DATA_TRUNCATED,
+ /** Invalid connection string attribute. */
+ SQL_STATE_01S00_INVALID_CONNECTION_STRING_ATTRIBUTE,
+
/** Error in row. */
SQL_STATE_01S01_ERROR_IN_ROW,
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 05fe8bf..30f9ad6 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/config/configuration.h
@@ -24,6 +24,7 @@
#include <ignite/common/common.h>
#include <ignite/common/utils.h>
+#include "ignite/odbc/protocol_version.h"
namespace ignite
{
@@ -60,6 +61,15 @@ namespace ignite
/** Connection attribute keyword for port attribute. */
static const std::string port;
+
+ /** Connection attribute keyword for distributed joins attribute. */
+ static const std::string distributedJoins;
+
+ /** Connection attribute keyword for enforce join order attribute. */
+ static const std::string enforceJoinOrder;
+
+ /** Connection attribute keyword for protocol version attribute. */
+ static const std::string protocolVersion;
};
/** Default values for configuration. */
@@ -80,11 +90,17 @@ namespace ignite
/** Default value for server attribute. */
static const std::string server;
+ /** Default value for protocol version. */
+ static const ProtocolVersion& protocolVersion;
+
/** Default value for port attribute. */
- static const std::string port;
+ static const uint16_t port;
- /** Default value for port attribute. Uint16 value. */
- static const uint16_t uintPort;
+ /** Default value for distributed joins attribute. */
+ static const bool distributedJoins;
+
+ /** Default value for enforce join order attribute. */
+ static const bool enforceJoinOrder;
};
/**
@@ -200,6 +216,33 @@ namespace ignite
}
/**
+ * Check distributed joins flag.
+ *
+ * @return True if distributed joins are enabled.
+ */
+ bool IsDistributedJoins() const
+ {
+ return GetBoolValue(Key::distributedJoins, DefaultValue::distributedJoins);
+ }
+
+ /**
+ * Check enforce join order flag.
+ *
+ * @return True if enforcing of join order is enabled.
+ */
+ bool IsEnforceJoinOrder() const
+ {
+ return GetBoolValue(Key::enforceJoinOrder, DefaultValue::enforceJoinOrder);
+ }
+
+ /**
+ * Get protocol version.
+ *
+ * @return Protocol version.
+ */
+ ProtocolVersion GetProtocolVersion() const;
+
+ /**
* Get string value from the config.
*
* @param key Configuration key.
@@ -208,6 +251,24 @@ namespace ignite
*/
const std::string& GetStringValue(const std::string& key, const std::string& dflt) const;
+ /**
+ * Get int 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.
+ */
+ int64_t GetIntValue(const std::string& key, int64_t dflt) const;
+
+ /**
+ * Get bool 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.
+ */
+ bool GetBoolValue(const std::string& key, bool dflt) const;
+
private:
/**
* Parse connect string into key-value storage.
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 00bdfc8..9fe46df 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/connection.h
@@ -41,15 +41,6 @@ namespace ignite
{
friend class Environment;
public:
- /** ODBC communication protocol version. */
- enum { PROTOCOL_VERSION = 1 };
-
- /**
- * Apache Ignite version when the current ODBC communication
- * protocol version has been introduced.
- */
- static const std::string PROTOCOL_VERSION_SINCE;
-
/**
* Destructor.
*/
@@ -263,6 +254,13 @@ namespace ignite
SqlResult MakeRequestHandshake();
/**
+ * Perform configure request.
+ *
+ * @return Operation result.
+ */
+ SqlResult MakeRequestConfigure();
+
+ /**
* Constructor.
*/
Connection();
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 f0b40e2..03fa627 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/message.h
@@ -66,8 +66,13 @@ namespace ignite
* Constructor.
*
* @param version Protocol version.
+ * @param distributedJoins Distributed joins flag.
+ * @param enforceJoinOrder Enforce join order flag.
*/
- HandshakeRequest(int64_t version) : version(version)
+ HandshakeRequest(int64_t version, bool distributedJoins, bool enforceJoinOrder) :
+ version(version),
+ distributedJoins(distributedJoins),
+ enforceJoinOrder(enforceJoinOrder)
{
// No-op.
}
@@ -89,11 +94,20 @@ namespace ignite
writer.WriteInt8(REQUEST_TYPE_HANDSHAKE);
writer.WriteInt64(version);
+
+ writer.WriteBool(distributedJoins);
+ writer.WriteBool(enforceJoinOrder);
}
private:
/** Protocol version. */
int64_t version;
+
+ /** Distributed joins flag. */
+ bool distributedJoins;
+
+ /** Enforce join order flag. */
+ bool enforceJoinOrder;
};
/**
@@ -153,6 +167,7 @@ namespace ignite
const app::ParameterBindingMap& params;
};
+
/**
* Query close request.
*/
@@ -348,13 +363,13 @@ namespace ignite
/**
* Query close response.
*/
- class QueryResponse
+ class Response
{
public:
/**
* Constructor.
*/
- QueryResponse() : status(RESPONSE_STATUS_FAILED), error()
+ Response() : status(RESPONSE_STATUS_FAILED), error()
{
// No-op.
}
@@ -362,7 +377,7 @@ namespace ignite
/**
* Destructor.
*/
- ~QueryResponse()
+ virtual ~Response()
{
// No-op.
}
@@ -426,7 +441,7 @@ namespace ignite
/**
* Handshake response.
*/
- class HandshakeResponse : public QueryResponse
+ class HandshakeResponse : public Response
{
public:
/**
@@ -504,7 +519,7 @@ namespace ignite
/**
* Query close response.
*/
- class QueryCloseResponse : public QueryResponse
+ class QueryCloseResponse : public Response
{
public:
/**
@@ -549,7 +564,7 @@ namespace ignite
/**
* Query execute response.
*/
- class QueryExecuteResponse : public QueryResponse
+ class QueryExecuteResponse : public Response
{
public:
/**
@@ -608,7 +623,7 @@ namespace ignite
/**
* Query fetch response.
*/
- class QueryFetchResponse : public QueryResponse
+ class QueryFetchResponse : public Response
{
public:
/**
@@ -659,7 +674,7 @@ namespace ignite
/**
* Query get column metadata response.
*/
- class QueryGetColumnsMetaResponse : public QueryResponse
+ class QueryGetColumnsMetaResponse : public Response
{
public:
/**
@@ -704,7 +719,7 @@ namespace ignite
/**
* Query get table metadata response.
*/
- class QueryGetTablesMetaResponse : public QueryResponse
+ class QueryGetTablesMetaResponse : public Response
{
public:
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h b/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
index c19e08c..a91af22 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/parser.h
@@ -42,9 +42,6 @@ namespace ignite
/** Default initial size of operational memory. */
enum { DEFAULT_MEM_ALLOCATION = 4096 };
- /** ODBC communication protocol version. */
- enum { PROTOCOL_VERSION = 1 };
-
/**
* Constructor.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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
new file mode 100644
index 0000000..747d78d
--- /dev/null
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/protocol_version.h
@@ -0,0 +1,172 @@
+/*
+ * 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_PROTOCOL_VERSION
+#define _IGNITE_ODBC_PROTOCOL_VERSION
+
+#include <stdint.h>
+
+#include <string>
+#include <map>
+
+namespace ignite
+{
+ namespace odbc
+ {
+ /** Protocol version. */
+ class ProtocolVersion
+ {
+ public:
+ /** String to version map type alias. */
+ typedef std::map<std::string, ProtocolVersion> StringToVersionMap;
+
+ /** Version to string map type alias. */
+ typedef std::map<ProtocolVersion, std::string> VersionToStringMap;
+
+ /** First version of the protocol that was introduced in Ignite 1.6.0. */
+ static const ProtocolVersion VERSION_1_6_0;
+
+ /** First version of the protocol that was introduced in Ignite 1.8.0. */
+ static const ProtocolVersion VERSION_1_8_0;
+
+ /** Unknown version of the protocol. */
+ static const ProtocolVersion VERSION_UNKNOWN;
+
+ /**
+ * Get current version.
+ *
+ * @return Current version.
+ */
+ static const ProtocolVersion& GetCurrent();
+
+ /**
+ * Parse string and extract protocol version.
+ *
+ * @throw IgniteException if version can not be parsed.
+ * @param version Version string to parse.
+ * @return Protocol version.
+ */
+ static ProtocolVersion FromString(const std::string& version);
+
+ /**
+ * Convert to string value.
+ *
+ * @throw IgniteException if version is unknow parsed.
+ * @param version Version string to parse.
+ * @return Protocol version.
+ */
+ const std::string& ToString() const;
+
+ /**
+ * Get int value.
+ *
+ * @return Integer value.
+ */
+ int64_t GetIntValue() const;
+
+ /**
+ * Check if the version is unknown.
+ *
+ * @return True if the version is unknown.
+ */
+ bool IsUnknown() const;
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if equal.
+ */
+ friend bool operator==(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if not equal.
+ */
+ friend bool operator!=(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if less.
+ */
+ friend bool operator<(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if less or equal.
+ */
+ friend bool operator<=(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if gretter.
+ */
+ friend bool operator>(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ /**
+ * Comparison operator.
+ *
+ * @param val1 First value.
+ * @param val2 Second value.
+ * @return True if gretter or equal.
+ */
+ friend bool operator>=(const ProtocolVersion& val1, const ProtocolVersion& val2);
+
+ private:
+ /**
+ * Constructor.
+ *
+ * @param val Underlying value.
+ */
+ explicit ProtocolVersion(int64_t val);
+
+ /**
+ * Make int value for the version.
+ *
+ * @param major Major version.
+ * @param minor Minor version.
+ * @param maintenance Maintenance version.
+ * @return Int value for the version.
+ */
+ static int64_t MakeVersion(uint16_t major, uint16_t minor, uint16_t maintenance);
+
+ /** String to version map. */
+ static const StringToVersionMap stringToVersionMap;
+
+ /** Version to string map. */
+ static const VersionToStringMap versionToStringMap;
+
+ /** Underlying int value. */
+ int64_t val;
+ };
+ }
+}
+
+#endif //_IGNITE_ODBC_PROTOCOL_VERSION
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 5820030..0e0f0d3 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj
@@ -170,6 +170,7 @@
<ClCompile Include="..\..\src\meta\column_meta.cpp" />
<ClCompile Include="..\..\src\meta\table_meta.cpp" />
<ClCompile Include="..\..\src\odbc.cpp" />
+ <ClCompile Include="..\..\src\protocol_version.cpp" />
<ClCompile Include="..\..\src\query\data_query.cpp" />
<ClCompile Include="..\..\src\query\column_metadata_query.cpp" />
<ClCompile Include="..\..\src\query\foreign_keys_query.cpp" />
@@ -206,6 +207,7 @@
<ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h" />
<ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" />
<ClInclude Include="..\..\include\ignite\odbc\parser.h" />
+ <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h" />
<ClInclude Include="..\..\include\ignite\odbc\query\data_query.h" />
<ClInclude Include="..\..\include\ignite\odbc\query\column_metadata_query.h" />
<ClInclude Include="..\..\include\ignite\odbc\query\foreign_keys_query.h" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 6ca58e2..9caf483 100644
--- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
+++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters
@@ -115,6 +115,9 @@
<ClCompile Include="..\..\src\entry_points.cpp">
<Filter>Code</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\protocol_version.cpp">
+ <Filter>Code</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="module.def">
@@ -224,5 +227,8 @@
<ClInclude Include="..\..\include\ignite\odbc.h">
<Filter>Code</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\ignite\odbc\protocol_version.h">
+ <Filter>Code</Filter>
+ </ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 45b0507..24c2bdf 100644
--- a/modules/platforms/cpp/odbc/src/config/configuration.cpp
+++ b/modules/platforms/cpp/odbc/src/config/configuration.cpp
@@ -20,6 +20,9 @@
#include <algorithm>
#include <iterator>
+#include "ignite/common/common.h"
+#include "ignite/common/utils.h"
+
#include "ignite/odbc/utility.h"
#include "ignite/odbc/config/configuration.h"
@@ -29,20 +32,29 @@ namespace ignite
{
namespace config
{
- 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);
+ 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::Key::distributedJoins = "distributed_joins";
+ const std::string Configuration::Key::enforceJoinOrder = "enforce_join_order";
+ const std::string Configuration::Key::protocolVersion = "protocol_version";
+
+ 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 uint16_t Configuration::DefaultValue::port = 10800;
+
+ const bool Configuration::DefaultValue::distributedJoins = false;
+ const bool Configuration::DefaultValue::enforceJoinOrder = false;
+
+ const ProtocolVersion& Configuration::DefaultValue::protocolVersion = ProtocolVersion::GetCurrent();
+
Configuration::Configuration() :
arguments()
@@ -80,7 +92,7 @@ namespace ignite
else
{
endPoint.host = GetStringValue(Key::server, DefaultValue::server);
- endPoint.port = common::LexicalCast<uint16_t>(GetStringValue(Key::port, DefaultValue::port));
+ endPoint.port = static_cast<uint16_t>(GetIntValue(Key::port, DefaultValue::port));
}
}
@@ -134,10 +146,20 @@ namespace ignite
else
{
endPoint.host = GetStringValue(Key::server, DefaultValue::server);
- endPoint.port = common::LexicalCast<uint16_t>(GetStringValue(Key::port, DefaultValue::port));
+ endPoint.port = static_cast<uint16_t>(GetIntValue(Key::port, DefaultValue::port));
}
}
+ ProtocolVersion Configuration::GetProtocolVersion() const
+ {
+ ArgumentMap::const_iterator it = arguments.find(Key::protocolVersion);
+
+ if (it != arguments.end())
+ return ProtocolVersion::FromString(it->second);
+
+ return DefaultValue::protocolVersion;
+ }
+
const std::string& Configuration::GetStringValue(const std::string& key, const std::string& dflt) const
{
ArgumentMap::const_iterator it = arguments.find(common::ToLower(key));
@@ -148,6 +170,42 @@ namespace ignite
return dflt;
}
+ int64_t Configuration::GetIntValue(const std::string& key, int64_t dflt) const
+ {
+ ArgumentMap::const_iterator it = arguments.find(common::ToLower(key));
+
+ if (it != arguments.end())
+ {
+ const std::string& val = it->second;
+
+ if (!common::AllOf(val.begin(), val.end(), isdigit))
+ IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid argument value: Integer value is expected.", "key", key);
+
+ return common::LexicalCast<int64_t>(val);
+ }
+
+ return dflt;
+ }
+
+ bool Configuration::GetBoolValue(const std::string& key, bool dflt) const
+ {
+ ArgumentMap::const_iterator it = arguments.find(common::ToLower(key));
+
+ if (it != arguments.end())
+ {
+ std::string lowercaseVal = common::ToLower(it->second);
+
+ if (lowercaseVal != "true" && lowercaseVal != "false")
+ IGNITE_ERROR_FORMATTED_1(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid argument value: Boolean value is expected (true or false).", "key", key);
+
+ return lowercaseVal == "true";
+ }
+
+ return dflt;
+ }
+
void Configuration::ParseAttributeList(const char * str, size_t len, char delimeter, ArgumentMap & args)
{
std::string connect_str(str, len);
@@ -199,7 +257,7 @@ namespace ignite
if (colonNum == 0)
{
res.host = address;
- res.port = DefaultValue::uintPort;
+ res.port = DefaultValue::port;
}
else if (colonNum == 1)
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/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 844ad70..4315698 100644
--- a/modules/platforms/cpp/odbc/src/connection.cpp
+++ b/modules/platforms/cpp/odbc/src/connection.cpp
@@ -39,8 +39,6 @@ namespace ignite
{
namespace odbc
{
- const std::string Connection::PROTOCOL_VERSION_SINCE = "1.6.0";
-
Connection::Connection() :
socket(),
connected(false),
@@ -309,7 +307,24 @@ namespace ignite
SqlResult Connection::MakeRequestHandshake()
{
- HandshakeRequest req(PROTOCOL_VERSION);
+ bool distributedJoins = false;
+ bool enforceJoinOrder = false;
+ int64_t protocolVersion = 0;
+
+ try
+ {
+ distributedJoins = config.IsDistributedJoins();
+ enforceJoinOrder = config.IsEnforceJoinOrder();
+ protocolVersion = config.GetProtocolVersion().GetIntValue();
+ }
+ catch (const IgniteError& err)
+ {
+ AddStatusRecord(SQL_STATE_01S00_INVALID_CONNECTION_STRING_ATTRIBUTE, err.GetText());
+
+ return SQL_RESULT_ERROR;
+ }
+
+ HandshakeRequest req(protocolVersion, distributedJoins, enforceJoinOrder);
HandshakeResponse rsp;
try
@@ -343,7 +358,7 @@ namespace ignite
constructor << "Node rejected handshake message. "
<< "Current node Apache Ignite version: " << rsp.CurrentVer() << ", "
<< "node protocol version introduced in version: " << rsp.ProtoVerSince() << ", "
- << "driver protocol version introduced in version: " << PROTOCOL_VERSION_SINCE << ".";
+ << "driver protocol version introduced in version: " << config.GetProtocolVersion().ToString() << ".";
AddStatusRecord(SQL_STATE_08001_CANNOT_CONNECT, constructor.str());
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
index 568c125..0fdfbc8 100644
--- a/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
+++ b/modules/platforms/cpp/odbc/src/diagnostic/diagnostic_record.cpp
@@ -34,6 +34,9 @@ namespace
/** SQL state 01004 constant. */
const std::string STATE_01004 = "01004";
+ /** SQL state 01S00 constant. */
+ const std::string STATE_01S00 = "01S00";
+
/** SQL state 01S01 constant. */
const std::string STATE_01S01 = "01S01";
@@ -190,6 +193,9 @@ namespace ignite
case SQL_STATE_01004_DATA_TRUNCATED:
return STATE_01004;
+ case SQL_STATE_01S00_INVALID_CONNECTION_STRING_ATTRIBUTE:
+ return STATE_01S00;
+
case SQL_STATE_01S01_ERROR_IN_ROW:
return STATE_01S01;
http://git-wip-us.apache.org/repos/asf/ignite/blob/311428ee/modules/platforms/cpp/odbc/src/protocol_version.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/protocol_version.cpp b/modules/platforms/cpp/odbc/src/protocol_version.cpp
new file mode 100644
index 0000000..c65099d
--- /dev/null
+++ b/modules/platforms/cpp/odbc/src/protocol_version.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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/protocol_version.h"
+#include <ignite/common/concurrent.h>
+#include <ignite/common/utils.h>
+#include <ignite/ignite_error.h>
+
+namespace ignite
+{
+ namespace odbc
+ {
+ const ProtocolVersion ProtocolVersion::VERSION_1_6_0(1);
+ const ProtocolVersion ProtocolVersion::VERSION_1_8_0(MakeVersion(1,8,0));
+ const ProtocolVersion ProtocolVersion::VERSION_UNKNOWN(INT64_MIN);
+
+ ProtocolVersion::StringToVersionMap::value_type s2vInitVals[] = {
+ std::make_pair("1.6.0", ProtocolVersion::VERSION_1_6_0),
+ std::make_pair("1.8.0", ProtocolVersion::VERSION_1_8_0)
+ };
+
+ const ProtocolVersion::StringToVersionMap ProtocolVersion::stringToVersionMap(s2vInitVals,
+ s2vInitVals + (sizeof(s2vInitVals) / sizeof(s2vInitVals[0])));
+
+ ProtocolVersion::VersionToStringMap::value_type v2sInitVals[] = {
+ std::make_pair(ProtocolVersion::VERSION_1_6_0, "1.6.0"),
+ std::make_pair(ProtocolVersion::VERSION_1_8_0, "1.8.0")
+ };
+
+ const ProtocolVersion::VersionToStringMap ProtocolVersion::versionToStringMap(v2sInitVals,
+ v2sInitVals + (sizeof(v2sInitVals) / sizeof(v2sInitVals[0])));
+
+ ProtocolVersion::ProtocolVersion(int64_t val) :
+ val(val)
+ {
+ // No-op.
+ }
+
+ int64_t ProtocolVersion::MakeVersion(uint16_t major, uint16_t minor, uint16_t maintenance)
+ {
+ const static int64_t MASK = 0x000000000000FFFFLL;
+ return ((major & MASK) << 48) | ((minor & MASK) << 32) | ((maintenance & MASK) << 16);
+ }
+
+ const ProtocolVersion& ProtocolVersion::GetCurrent()
+ {
+ return VERSION_1_8_0;
+ }
+
+ ProtocolVersion ProtocolVersion::FromString(const std::string& version)
+ {
+ StringToVersionMap::const_iterator it = stringToVersionMap.find(common::ToLower(version));
+
+ if (it == stringToVersionMap.end())
+ {
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Invalid version format. Valid format is X.Y.Z, where X, Y and Z are major, "
+ "minor and maintenance versions of Ignite since which protocol is introduced.");
+ }
+
+ return it->second;
+ }
+
+ const std::string& ProtocolVersion::ToString() const
+ {
+ VersionToStringMap::const_iterator it = versionToStringMap.find(*this);
+
+ if (it == versionToStringMap.end())
+ {
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Unknown protocol version can not be converted to string.");
+ }
+
+ return it->second;
+ }
+
+ int64_t ProtocolVersion::GetIntValue() const
+ {
+ assert(!IsUnknown());
+
+ return val;
+ }
+
+ bool ProtocolVersion::IsUnknown() const
+ {
+ return *this == VERSION_UNKNOWN;
+ }
+
+ bool operator==(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val == val2.val;
+ }
+
+ bool operator!=(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val != val2.val;
+ }
+
+ bool operator<(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val < val2.val;
+ }
+
+ bool operator<=(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val <= val2.val;
+ }
+
+ bool operator>(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val > val2.val;
+ }
+
+ bool operator>=(const ProtocolVersion& val1, const ProtocolVersion& val2)
+ {
+ return val1.val >= val2.val;
+ }
+ }
+}
+