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/11/09 09:27:20 UTC
[10/17] ignite git commit: Revert Revert Merge remote-tracking branch
'professional/ignite-1.6.11'
Revert Revert Merge remote-tracking branch 'professional/ignite-1.6.11'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9726421f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9726421f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9726421f
Branch: refs/heads/ignite-4154
Commit: 9726421ff9efb2b19813b2fd6ad27a3728b5ab1a
Parents: 865bbcf
Author: Dmitriy Govorukhin <dg...@gridgain.com>
Authored: Tue Nov 8 15:59:00 2016 +0300
Committer: Dmitriy Govorukhin <dg...@gridgain.com>
Committed: Tue Nov 8 15:59:00 2016 +0300
----------------------------------------------------------------------
.../internal/processors/job/GridJobWorker.java | 10 +-
.../service/GridServiceProcessor.java | 61 +++++++-
.../internal/util/SerializableTransient.java | 58 +++++++
.../ignite/marshaller/MarshallerUtils.java | 22 +++
.../optimized/OptimizedClassDescriptor.java | 90 ++++++++++-
modules/platforms/cpp/binary/Makefile.am | 4 +-
modules/platforms/cpp/core/Makefile.am | 4 +-
.../cpp/examples/odbc-example/Makefile.am | 4 +-
.../cpp/examples/putget-example/Makefile.am | 4 +-
.../cpp/examples/query-example/Makefile.am | 4 +-
modules/platforms/cpp/ignite/Makefile.am | 4 +-
modules/platforms/cpp/jni/Makefile.am | 4 +-
.../cpp/odbc-test/src/api_robustness_test.cpp | 63 ++++++++
.../cpp/odbc-test/src/queries_test.cpp | 9 +-
modules/platforms/cpp/odbc/Makefile.am | 4 +-
.../cpp/odbc/include/ignite/odbc/statement.h | 42 ++++++
modules/platforms/cpp/odbc/src/odbc.cpp | 116 +-------------
modules/platforms/cpp/odbc/src/statement.cpp | 151 +++++++++++++++++++
18 files changed, 526 insertions(+), 128 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
index 8169eb1..5f38b29 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/job/GridJobWorker.java
@@ -57,6 +57,7 @@ import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteRunnable;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.marshaller.MarshallerUtils;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.events.EventType.EVT_JOB_CANCELLED;
@@ -421,7 +422,14 @@ public class GridJobWorker extends GridWorker implements GridTimeoutObject {
try {
if (job == null) {
- job = U.unmarshal(marsh, jobBytes, U.resolveClassLoader(dep.classLoader(), ctx.config()));
+ MarshallerUtils.jobSenderVersion(taskNode.version());
+
+ try {
+ job = U.unmarshal(marsh, jobBytes, U.resolveClassLoader(dep.classLoader(), ctx.config()));
+ }
+ finally {
+ MarshallerUtils.jobSenderVersion(null);
+ }
// No need to hold reference any more.
jobBytes = null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
index 527d360..6c26363 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
@@ -20,11 +20,14 @@ package org.apache.ignite.internal.processors.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
@@ -87,6 +90,7 @@ import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.marshaller.Marshaller;
+import org.apache.ignite.internal.util.SerializableTransient;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.resources.JobContextResource;
import org.apache.ignite.resources.LoggerResource;
@@ -115,6 +119,9 @@ public class GridServiceProcessor extends GridProcessorAdapter {
/** */
public static final IgniteProductVersion LAZY_SERVICES_CFG_SINCE = IgniteProductVersion.fromString("1.5.22");
+ /** Versions that only compatible with each other, and from 1.5.33. */
+ private static final Set<IgniteProductVersion> SERVICE_TOP_CALLABLE_VER1;
+
/** */
private final Boolean srvcCompatibilitySysProp;
@@ -162,6 +169,31 @@ public class GridServiceProcessor extends GridProcessorAdapter {
/** Topology listener. */
private GridLocalEventListener topLsnr = new TopologyListener();
+ static {
+ Set<IgniteProductVersion> versions = new TreeSet<>(new Comparator<IgniteProductVersion>() {
+ @Override public int compare(final IgniteProductVersion o1, final IgniteProductVersion o2) {
+ return o1.compareToIgnoreTimestamp(o2);
+ }
+ });
+
+ versions.add(IgniteProductVersion.fromString("1.5.30"));
+ versions.add(IgniteProductVersion.fromString("1.5.31"));
+ versions.add(IgniteProductVersion.fromString("1.5.32"));
+ versions.add(IgniteProductVersion.fromString("1.6.3"));
+ versions.add(IgniteProductVersion.fromString("1.6.4"));
+ versions.add(IgniteProductVersion.fromString("1.6.5"));
+ versions.add(IgniteProductVersion.fromString("1.6.6"));
+ versions.add(IgniteProductVersion.fromString("1.6.7"));
+ versions.add(IgniteProductVersion.fromString("1.6.8"));
+ versions.add(IgniteProductVersion.fromString("1.6.9"));
+ versions.add(IgniteProductVersion.fromString("1.6.10"));
+ versions.add(IgniteProductVersion.fromString("1.7.0"));
+ versions.add(IgniteProductVersion.fromString("1.7.1"));
+ versions.add(IgniteProductVersion.fromString("1.7.2"));
+
+ SERVICE_TOP_CALLABLE_VER1 = Collections.unmodifiableSet(versions);
+ }
+
/**
* @param ctx Kernal context.
*/
@@ -668,9 +700,13 @@ public class GridServiceProcessor extends GridProcessorAdapter {
ClusterNode node = cache.affinity().mapKeyToNode(name);
if (node.version().compareTo(ServiceTopologyCallable.SINCE_VER) >= 0) {
+ final ServiceTopologyCallable call = new ServiceTopologyCallable(name);
+
+ call.serialize = SERVICE_TOP_CALLABLE_VER1.contains(node.version());
+
return ctx.closure().callAsyncNoFailover(
GridClosureCallMode.BROADCAST,
- new ServiceTopologyCallable(name),
+ call,
Collections.singletonList(node),
false
).get();
@@ -1829,6 +1865,7 @@ public class GridServiceProcessor extends GridProcessorAdapter {
/**
*/
@GridInternal
+ @SerializableTransient(methodName = "serializableTransient")
private static class ServiceTopologyCallable implements IgniteCallable<Map<UUID, Integer>> {
/** */
private static final long serialVersionUID = 0L;
@@ -1837,10 +1874,13 @@ public class GridServiceProcessor extends GridProcessorAdapter {
private static final IgniteProductVersion SINCE_VER = IgniteProductVersion.fromString("1.5.7");
/** */
+ private static final String[] SER_FIELDS = {"waitedCacheInit", "jCtx", "log"};
+
+ /** */
private final String svcName;
/** */
- private boolean waitedCacheInit;
+ private transient boolean waitedCacheInit;
/** */
@IgniteInstanceResource
@@ -1848,11 +1888,14 @@ public class GridServiceProcessor extends GridProcessorAdapter {
/** */
@JobContextResource
- private ComputeJobContext jCtx;
+ private transient ComputeJobContext jCtx;
/** */
@LoggerResource
- private IgniteLogger log;
+ private transient IgniteLogger log;
+
+ /** */
+ transient boolean serialize;
/**
* @param svcName Service name.
@@ -1898,6 +1941,16 @@ public class GridServiceProcessor extends GridProcessorAdapter {
return serviceTopology(cache, svcName);
}
+
+ /**
+ * @param self Instance of current class before serialization.
+ * @param ver Sender job version.
+ * @return List of serializable transient fields.
+ */
+ @SuppressWarnings("unused")
+ private static String[] serializableTransient(ServiceTopologyCallable self, IgniteProductVersion ver) {
+ return (self != null && self.serialize) || (ver != null && SERVICE_TOP_CALLABLE_VER1.contains(ver)) ? SER_FIELDS : null;
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/core/src/main/java/org/apache/ignite/internal/util/SerializableTransient.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/SerializableTransient.java b/modules/core/src/main/java/org/apache/ignite/internal/util/SerializableTransient.java
new file mode 100644
index 0000000..14a2f27
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/SerializableTransient.java
@@ -0,0 +1,58 @@
+/*
+ * 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.util;
+
+import org.apache.ignite.lang.IgniteProductVersion;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks class as it has transient fields that should be serialized.
+ * Annotated class must have method that returns list of transient
+ * fields that should be serialized.
+ * <p>
+ * Works only for jobs. For other messages node version is not available.
+ * </p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface SerializableTransient {
+ /**
+ * Name of the private static method that returns list of transient fields
+ * that should be serialized (String[]), and accepts itself (before serialization)
+ * and {@link IgniteProductVersion}, e.g.
+ * <pre>
+ * private static String[] fields(Object self, IgniteProductVersion ver){
+ * return ver.compareTo("1.5.30") > 0 ? SERIALIZABLE_FIELDS : null;
+ * }
+ * </pre>
+ * <p>
+ * On serialization version argument <tt>ver</tt> is null, on deserialization - <tt>self</tt> is null.
+ * </p>
+ * <p>
+ * If it returns empty array or null all transient fields will be normally
+ * ignored.
+ * </p>
+ *
+ * @return Name of the method.
+ */
+ String methodName();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
index 9668baf..ad63702 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/MarshallerUtils.java
@@ -17,6 +17,7 @@
package org.apache.ignite.marshaller;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.marshaller.jdk.JdkMarshaller;
import org.jetbrains.annotations.Nullable;
@@ -24,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
* Utility marshaller methods.
*/
public class MarshallerUtils {
+ /** Job sender node version. */
+ private static final ThreadLocal<IgniteProductVersion> JOB_SND_NODE_VER = new ThreadLocal<>();
+
/**
* Set node name to marshaller context if possible.
*
@@ -55,4 +59,22 @@ public class MarshallerUtils {
private MarshallerUtils() {
// No-op.
}
+
+ /**
+ * Sets thread local job sender node version.
+ *
+ * @param ver Thread local job sender node version.
+ */
+ public static void jobSenderVersion(IgniteProductVersion ver) {
+ JOB_SND_NODE_VER.set(ver);
+ }
+
+ /**
+ * Returns thread local job sender node version.
+ *
+ * @return Thread local job sender node version.
+ */
+ public static IgniteProductVersion jobSenderVersion() {
+ return JOB_SND_NODE_VER.get();
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
index 5a5b54d..160f2c1 100644
--- a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
@@ -47,8 +47,11 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.marshaller.MarshallerContext;
import org.apache.ignite.marshaller.MarshallerExclusions;
+import org.apache.ignite.internal.util.SerializableTransient;
+import org.apache.ignite.marshaller.MarshallerUtils;
import static java.lang.reflect.Modifier.isFinal;
import static java.lang.reflect.Modifier.isPrivate;
@@ -166,6 +169,9 @@ class OptimizedClassDescriptor {
/** Proxy interfaces. */
private Class<?>[] proxyIntfs;
+ /** Method returns serializable transient fields. */
+ private Method serTransMtd;
+
/**
* Creates descriptor for class.
*
@@ -441,6 +447,27 @@ class OptimizedClassDescriptor {
readObjMtds.add(mtd);
+ final SerializableTransient serTransAn = c.getAnnotation(SerializableTransient.class);
+
+ // Custom serialization policy for transient fields.
+ if (serTransAn != null) {
+ try {
+ serTransMtd = c.getDeclaredMethod(serTransAn.methodName(), cls, IgniteProductVersion.class);
+
+ int mod = serTransMtd.getModifiers();
+
+ if (isStatic(mod) && isPrivate(mod)
+ && serTransMtd.getReturnType() == String[].class)
+ serTransMtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ serTransMtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ serTransMtd = null;
+ }
+ }
+
Field[] clsFields0 = c.getDeclaredFields();
Map<String, Field> fieldNames = new HashMap<>();
@@ -797,7 +824,7 @@ class OptimizedClassDescriptor {
writeTypeData(out);
out.writeShort(checksum);
- out.writeSerializable(obj, writeObjMtds, fields);
+ out.writeSerializable(obj, writeObjMtds, serializableFields(obj.getClass(), obj, null));
break;
@@ -807,6 +834,60 @@ class OptimizedClassDescriptor {
}
/**
+ * Gets list of serializable fields. If {@link #serTransMtd} method
+ * returns list of transient fields, they will be added to other fields.
+ * Transient fields that are not included in that list will be normally
+ * ignored.
+ *
+ * @param cls Class.
+ * @param obj Object.
+ * @param ver Job sender version.
+ * @return Serializable fields.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private Fields serializableFields(Class<?> cls, Object obj, IgniteProductVersion ver) {
+ if (serTransMtd == null)
+ return fields;
+
+ try {
+ final String[] transFields = (String[])serTransMtd.invoke(cls, obj, ver);
+
+ if (transFields == null || transFields.length == 0)
+ return fields;
+
+ List<FieldInfo> clsFields = new ArrayList<>();
+
+ clsFields.addAll(fields.fields.get(0).fields);
+
+ for (int i = 0; i < transFields.length; i++) {
+ final String fieldName = transFields[i];
+
+ final Field f = cls.getDeclaredField(fieldName);
+
+ FieldInfo fieldInfo = new FieldInfo(f, f.getName(),
+ GridUnsafe.objectFieldOffset(f), fieldType(f.getType()));
+
+ clsFields.add(fieldInfo);
+ }
+
+ Collections.sort(clsFields, new Comparator<FieldInfo>() {
+ @Override public int compare(FieldInfo t1, FieldInfo t2) {
+ return t1.name().compareTo(t2.name());
+ }
+ });
+
+ List<ClassFields> fields = new ArrayList<>();
+
+ fields.add(new ClassFields(clsFields));
+
+ return new Fields(fields);
+ }
+ catch (Exception e) {
+ return fields;
+ }
+ }
+
+ /**
* @param out Output stream.
* @throws IOException In case of error.
*/
@@ -838,7 +919,12 @@ class OptimizedClassDescriptor {
case SERIALIZABLE:
verifyChecksum(in.readShort());
- return in.readSerializable(cls, readObjMtds, readResolveMtd, fields);
+ // If no serialize method, then unmarshal as usual.
+ if (serTransMtd != null)
+ return in.readSerializable(cls, readObjMtds, readResolveMtd,
+ serializableFields(cls, null, MarshallerUtils.jobSenderVersion()));
+ else
+ return in.readSerializable(cls, readObjMtds, readResolveMtd, fields);
default:
assert false : "Unexpected type: " + type;
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/binary/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/Makefile.am b/modules/platforms/cpp/binary/Makefile.am
index 4876776..ca301a6 100644
--- a/modules/platforms/cpp/binary/Makefile.am
+++ b/modules/platforms/cpp/binary/Makefile.am
@@ -26,7 +26,9 @@ AM_CPPFLAGS = \
-I$(srcdir)/include \
-I@top_srcdir@/common/include \
-I@top_srcdir@/common/os/linux/include \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/core/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/Makefile.am b/modules/platforms/cpp/core/Makefile.am
index bbb7720..97523cf 100644
--- a/modules/platforms/cpp/core/Makefile.am
+++ b/modules/platforms/cpp/core/Makefile.am
@@ -31,7 +31,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/jni/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/examples/odbc-example/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/examples/odbc-example/Makefile.am b/modules/platforms/cpp/examples/odbc-example/Makefile.am
index e584105..83cc63e 100644
--- a/modules/platforms/cpp/examples/odbc-example/Makefile.am
+++ b/modules/platforms/cpp/examples/odbc-example/Makefile.am
@@ -30,7 +30,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/../jni/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/examples/putget-example/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/examples/putget-example/Makefile.am b/modules/platforms/cpp/examples/putget-example/Makefile.am
index 5301ea1..cf39002 100644
--- a/modules/platforms/cpp/examples/putget-example/Makefile.am
+++ b/modules/platforms/cpp/examples/putget-example/Makefile.am
@@ -30,7 +30,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/../jni/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/examples/query-example/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/examples/query-example/Makefile.am b/modules/platforms/cpp/examples/query-example/Makefile.am
index 1437303..01231ec 100644
--- a/modules/platforms/cpp/examples/query-example/Makefile.am
+++ b/modules/platforms/cpp/examples/query-example/Makefile.am
@@ -30,7 +30,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/../jni/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/ignite/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/ignite/Makefile.am b/modules/platforms/cpp/ignite/Makefile.am
index 625f1df..2dbc4d6 100644
--- a/modules/platforms/cpp/ignite/Makefile.am
+++ b/modules/platforms/cpp/ignite/Makefile.am
@@ -30,7 +30,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/jni/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/jni/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/jni/Makefile.am b/modules/platforms/cpp/jni/Makefile.am
index b9b3913..2cb4b90 100644
--- a/modules/platforms/cpp/jni/Makefile.am
+++ b/modules/platforms/cpp/jni/Makefile.am
@@ -29,7 +29,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/common/os/linux/include \
-I$(JAVA_HOME)/include \
-I$(JAVA_HOME)/include/linux \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
index 008cf25..fbd5f12 100644
--- a/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/api_robustness_test.cpp
@@ -161,6 +161,54 @@ struct ApiRobustnessTestSuiteFixture
}
/**
+ * Check that SQLFetchScroll does not crash with unsupported orientation.
+ *
+ * @param orientation Fetch orientation.
+ */
+ void CheckFetchScrollUnsupportedOrientation(SQLUSMALLINT orientation)
+ {
+ Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache");
+
+ SQLRETURN ret;
+
+ const int64_t recordsNum = 100;
+
+ for (int i = 0; i < recordsNum; ++i)
+ {
+ TestType val;
+
+ val.i32Field = i * 10;
+
+ testCache.Put(i, val);
+ }
+
+ int32_t i32Field = -1;
+
+ // Binding column.
+ ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &i32Field, 0, 0);
+
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ SQLCHAR request[] = "SELECT i32Field FROM TestType ORDER BY _key";
+
+ ret = SQLExecDirect(stmt, request, SQL_NTS);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ ret = SQLFetchScroll(stmt, SQL_FETCH_NEXT, 0);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+ BOOST_CHECK_EQUAL(i32Field, 0);
+
+ ret = SQLFetchScroll(stmt, orientation, 0);
+
+ // Operation is not supported. However, there should be no crash.
+ BOOST_CHECK(ret == SQL_ERROR);
+ }
+
+ /**
* Destructor.
*/
~ApiRobustnessTestSuiteFixture()
@@ -1003,4 +1051,19 @@ BOOST_AUTO_TEST_CASE(TestSQLSpecialColumns)
SQLCloseCursor(stmt);
}
+BOOST_AUTO_TEST_CASE(TestFetchScrollLast)
+{
+ CheckFetchScrollUnsupportedOrientation(SQL_FETCH_LAST);
+}
+
+BOOST_AUTO_TEST_CASE(TestFetchScrollPrior)
+{
+ CheckFetchScrollUnsupportedOrientation(SQL_FETCH_PRIOR);
+}
+
+BOOST_AUTO_TEST_CASE(TestFetchScrollFirst)
+{
+ CheckFetchScrollUnsupportedOrientation(SQL_FETCH_FIRST);
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/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 eb6e153..82e9972 100644
--- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp
@@ -200,6 +200,8 @@ struct QueriesTestSuiteFixture
"floatField, doubleField, boolField, guidField, dateField, timestampField FROM TestType";
ret = SQLExecDirect(stmt, reinterpret_cast<SQLCHAR*>(request), SQL_NTS);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
@@ -364,6 +366,8 @@ BOOST_AUTO_TEST_CASE(TestTwoRowsString)
"floatField, doubleField, boolField, guidField, dateField, timestampField FROM TestType";
ret = SQLExecDirect(stmt, request, SQL_NTS);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
if (!SQL_SUCCEEDED(ret))
BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
@@ -460,6 +464,8 @@ BOOST_AUTO_TEST_CASE(TestOneRowString)
"floatField, doubleField, boolField, guidField, dateField, timestampField FROM TestType";
ret = SQLExecDirect(stmt, request, SQL_NTS);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
@@ -522,6 +528,8 @@ BOOST_AUTO_TEST_CASE(TestOneRowStringLen)
"floatField, doubleField, boolField, guidField, dateField, timestampField FROM TestType";
ret = SQLExecDirect(stmt, request, SQL_NTS);
+ if (!SQL_SUCCEEDED(ret))
+ BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
ret = SQLFetch(stmt);
if (!SQL_SUCCEEDED(ret))
@@ -666,5 +674,4 @@ BOOST_AUTO_TEST_CASE(TestDataAtExecution)
BOOST_CHECK(ret == SQL_NO_DATA);
}
-
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/odbc/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am
index 3c8b37a..b0cc5f8 100644
--- a/modules/platforms/cpp/odbc/Makefile.am
+++ b/modules/platforms/cpp/odbc/Makefile.am
@@ -27,7 +27,9 @@ AM_CPPFLAGS = \
-I@top_srcdir@/common/include \
-I@top_srcdir@/common/os/linux/include \
-I@top_srcdir@/binary/include \
- -DIGNITE_IMPL
+ -DIGNITE_IMPL \
+ -D__STDC_LIMIT_MACROS \
+ -D__STDC_CONSTANT_MACROS
AM_CXXFLAGS = \
-Wall \
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
index 35f1e98..db6205e 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/statement.h
@@ -118,6 +118,25 @@ namespace ignite
void UnbindAllParameters();
/**
+ * Set statement attribute.
+ *
+ * @param attr Attribute type.
+ * @param value Value pointer.
+ * @param valueLen Value length.
+ */
+ void SetAttribute(int attr, void* value, SQLINTEGER valueLen);
+
+ /**
+ * Get statement attribute.
+ *
+ * @param attr Attribute type.
+ * @param buf Buffer for value.
+ * @param bufLen Buffer length.
+ * @param valueLen Resulting value length.
+ */
+ void GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER *valueLen);
+
+ /**
* Get number of binded parameters.
*
* @return Number of binded parameters.
@@ -356,6 +375,29 @@ namespace ignite
SqlResult InternalBindParameter(uint16_t paramIdx, const app::Parameter& param);
/**
+ * Set statement attribute.
+ * Internal call.
+ *
+ * @param attr Attribute type.
+ * @param value Value pointer.
+ * @param valueLen Value length.
+ * @return Operation result.
+ */
+ SqlResult InternalSetAttribute(int attr, void* value, SQLINTEGER valueLen);
+
+ /**
+ * Get statement attribute.
+ * Internal call.
+ *
+ * @param attr Attribute type.
+ * @param buf Buffer for value.
+ * @param bufLen Buffer length.
+ * @param valueLen Resulting value length.
+ * @return Operation result.
+ */
+ SqlResult InternalGetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen);
+
+ /**
* Get value of the column in the result set.
*
* @param columnIdx Column index.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/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 7416ad2..612d51a 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -854,73 +854,9 @@ namespace ignite
if (!statement)
return SQL_INVALID_HANDLE;
- if (!valueBuf)
- return SQL_ERROR;
-
- switch (attr)
- {
- case SQL_ATTR_APP_ROW_DESC:
- case SQL_ATTR_APP_PARAM_DESC:
- case SQL_ATTR_IMP_ROW_DESC:
- case SQL_ATTR_IMP_PARAM_DESC:
- {
- SQLPOINTER *val = reinterpret_cast<SQLPOINTER*>(valueBuf);
-
- *val = static_cast<SQLPOINTER>(stmt);
-
- break;
- }
-
- case SQL_ATTR_ROW_ARRAY_SIZE:
- {
- SQLINTEGER *val = reinterpret_cast<SQLINTEGER*>(valueBuf);
-
- *val = static_cast<SQLINTEGER>(1);
-
- break;
- }
-
- case SQL_ATTR_ROWS_FETCHED_PTR:
- {
- SQLULEN** val = reinterpret_cast<SQLULEN**>(valueBuf);
-
- *val = reinterpret_cast<SQLULEN*>(statement->GetRowsFetchedPtr());
-
- break;
- }
+ statement->GetAttribute(attr, valueBuf, valueBufLen, valueResLen);
- case SQL_ATTR_ROW_STATUS_PTR:
- {
- SQLUSMALLINT** val = reinterpret_cast<SQLUSMALLINT**>(valueBuf);
-
- *val = reinterpret_cast<SQLUSMALLINT*>(statement->GetRowStatusesPtr());
-
- break;
- }
-
- case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
- {
- SQLULEN** val = reinterpret_cast<SQLULEN**>(valueBuf);
-
- *val = reinterpret_cast<SQLULEN*>(statement->GetParamBindOffsetPtr());
-
- break;
- }
-
- case SQL_ATTR_ROW_BIND_OFFSET_PTR:
- {
- SQLULEN** val = reinterpret_cast<SQLULEN**>(valueBuf);
-
- *val = reinterpret_cast<SQLULEN*>(statement->GetColumnBindOffsetPtr());
-
- break;
- }
-
- default:
- return SQL_ERROR;
- }
-
- return SQL_SUCCESS;
+ return statement->GetDiagnosticRecords().GetReturnCode();
}
SQLRETURN SQLSetStmtAttr(SQLHSTMT stmt,
@@ -943,53 +879,9 @@ namespace ignite
if (!statement)
return SQL_INVALID_HANDLE;
- switch (attr)
- {
- case SQL_ATTR_ROW_ARRAY_SIZE:
- {
- SQLULEN val = reinterpret_cast<SQLULEN>(value);
-
- LOG_MSG("Value: %d\n", val);
-
- if (val != 1)
- return SQL_ERROR;
-
- break;
- }
-
- case SQL_ATTR_ROWS_FETCHED_PTR:
- {
- statement->SetRowsFetchedPtr(reinterpret_cast<size_t*>(value));
-
- break;
- }
-
- case SQL_ATTR_ROW_STATUS_PTR:
- {
- statement->SetRowStatusesPtr(reinterpret_cast<uint16_t*>(value));
-
- break;
- }
-
- case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
- {
- statement->SetParamBindOffsetPtr(reinterpret_cast<int*>(value));
-
- break;
- }
-
- case SQL_ATTR_ROW_BIND_OFFSET_PTR:
- {
- statement->SetColumnBindOffsetPtr(reinterpret_cast<int*>(value));
+ statement->SetAttribute(attr, value, valueLen);
- break;
- }
-
- default:
- return SQL_ERROR;
- }
-
- return SQL_SUCCESS;
+ return statement->GetDiagnosticRecords().GetReturnCode();
}
SQLRETURN SQLPrimaryKeys(SQLHSTMT stmt,
http://git-wip-us.apache.org/repos/asf/ignite/blob/9726421f/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
index 32f7c3f..f1a577a 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -145,6 +145,157 @@ namespace ignite
paramBindings.clear();
}
+ void Statement::SetAttribute(int attr, void* value, SQLINTEGER valueLen)
+ {
+ IGNITE_ODBC_API_CALL(InternalSetAttribute(attr, value, valueLen));
+ }
+
+ SqlResult Statement::InternalSetAttribute(int attr, void* value, SQLINTEGER valueLen)
+ {
+ switch (attr)
+ {
+ case SQL_ATTR_ROW_ARRAY_SIZE:
+ {
+ SQLULEN val = reinterpret_cast<SQLULEN>(value);
+
+ LOG_MSG("SQL_ATTR_ROW_ARRAY_SIZE: %d\n", val);
+
+ if (val != 1)
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Fetching of more than one row by call is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ break;
+ }
+
+ case SQL_ATTR_ROWS_FETCHED_PTR:
+ {
+ SetRowsFetchedPtr(reinterpret_cast<size_t*>(value));
+
+ break;
+ }
+
+ case SQL_ATTR_ROW_STATUS_PTR:
+ {
+ SetRowStatusesPtr(reinterpret_cast<uint16_t*>(value));
+
+ break;
+ }
+
+ case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
+ {
+ SetParamBindOffsetPtr(reinterpret_cast<int*>(value));
+
+ break;
+ }
+
+ case SQL_ATTR_ROW_BIND_OFFSET_PTR:
+ {
+ SetColumnBindOffsetPtr(reinterpret_cast<int*>(value));
+
+ break;
+ }
+
+ default:
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Specified attribute is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
+ void Statement::GetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
+ {
+ IGNITE_ODBC_API_CALL(InternalGetAttribute(attr, buf, bufLen, valueLen));
+ }
+
+ SqlResult Statement::InternalGetAttribute(int attr, void* buf, SQLINTEGER bufLen, SQLINTEGER* valueLen)
+ {
+ if (!buf)
+ {
+ AddStatusRecord(SQL_STATE_HY000_GENERAL_ERROR, "Data buffer is NULL.");
+
+ return SQL_RESULT_ERROR;
+ }
+
+ switch (attr)
+ {
+ case SQL_ATTR_APP_ROW_DESC:
+ case SQL_ATTR_APP_PARAM_DESC:
+ case SQL_ATTR_IMP_ROW_DESC:
+ case SQL_ATTR_IMP_PARAM_DESC:
+ {
+ SQLPOINTER *val = reinterpret_cast<SQLPOINTER*>(buf);
+
+ *val = static_cast<SQLPOINTER>(this);
+
+ break;
+ }
+
+ case SQL_ATTR_ROW_ARRAY_SIZE:
+ {
+ SQLINTEGER *val = reinterpret_cast<SQLINTEGER*>(buf);
+
+ *val = static_cast<SQLINTEGER>(1);
+
+ break;
+ }
+
+ case SQL_ATTR_ROWS_FETCHED_PTR:
+ {
+ SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
+
+ *val = reinterpret_cast<SQLULEN*>(GetRowsFetchedPtr());
+
+ break;
+ }
+
+ case SQL_ATTR_ROW_STATUS_PTR:
+ {
+ SQLUSMALLINT** val = reinterpret_cast<SQLUSMALLINT**>(buf);
+
+ *val = reinterpret_cast<SQLUSMALLINT*>(GetRowStatusesPtr());
+
+ break;
+ }
+
+ case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
+ {
+ SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
+
+ *val = reinterpret_cast<SQLULEN*>(GetParamBindOffsetPtr());
+
+ break;
+ }
+
+ case SQL_ATTR_ROW_BIND_OFFSET_PTR:
+ {
+ SQLULEN** val = reinterpret_cast<SQLULEN**>(buf);
+
+ *val = reinterpret_cast<SQLULEN*>(GetColumnBindOffsetPtr());
+
+ break;
+ }
+
+ default:
+ {
+ AddStatusRecord(SQL_STATE_HYC00_OPTIONAL_FEATURE_NOT_IMPLEMENTED,
+ "Specified attribute is not supported.");
+
+ return SQL_RESULT_ERROR;
+ }
+ }
+
+ return SQL_RESULT_SUCCESS;
+ }
+
uint16_t Statement::GetParametersNumber()
{
IGNITE_ODBC_API_CALL_ALWAYS_SUCCESS;