You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/08/01 09:26:21 UTC
[38/47] ignite git commit: IGNITE-5621: Support BINARY and VARBINARY
SQL types for C++
IGNITE-5621: Support BINARY and VARBINARY SQL types for C++
(cherry picked from commit 96b43e5)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/97813a82
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/97813a82
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/97813a82
Branch: refs/heads/master
Commit: 97813a8280d54c9b4ce08dca954e05fa62393cbe
Parents: 3085b20
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Jul 28 19:30:35 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Jul 28 19:32:43 2017 +0300
----------------------------------------------------------------------
.../core-test/config/cache-query-default.xml | 29 +++
.../cpp/core-test/src/cache_query_test.cpp | 215 ++++++++++++++++++-
.../ignite/cache/query/query_fields_row.h | 28 +++
.../ignite/cache/query/query_sql_fields.h | 13 +-
.../ignite/impl/cache/query/query_argument.h | 63 ++++++
.../impl/cache/query/query_fields_row_impl.h | 29 +++
6 files changed, 373 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core-test/config/cache-query-default.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/config/cache-query-default.xml b/modules/platforms/cpp/core-test/config/cache-query-default.xml
index 16f601d..42ac80f 100644
--- a/modules/platforms/cpp/core-test/config/cache-query-default.xml
+++ b/modules/platforms/cpp/core-test/config/cache-query-default.xml
@@ -160,6 +160,35 @@
</list>
</property>
</bean>
+
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="name" value="ByteArrayCache"/>
+ <property name="cacheMode" value="PARTITIONED"/>
+ <property name="atomicityMode" value="TRANSACTIONAL"/>
+ <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+ <property name="affinity">
+ <bean class="org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction">
+ <property name="partitions" value="256"/>
+ </bean>
+ </property>
+
+ <!-- Configure type metadata to enable queries. -->
+ <property name="queryEntities">
+ <list>
+ <bean class="org.apache.ignite.cache.QueryEntity">
+ <property name="keyType" value="java.lang.Integer"/>
+ <property name="valueType" value="ByteArrayType"/>
+ <property name="fields">
+ <map>
+ <entry key="intVal" value="java.lang.Integer"/>
+ <entry key="arrayVal" value="[B"/>
+ </map>
+ </property>
+ </bean>
+ </list>
+ </property>
+ </bean>
</list>
</property>
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index e763e08..4993279 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -47,7 +47,7 @@ using ignite::impl::binary::BinaryUtils;
/**
* Person class for query tests.
*/
-class IGNITE_IMPORT_EXPORT QueryPerson
+class QueryPerson
{
public:
/**
@@ -203,7 +203,7 @@ private:
/**
* Relation class for query tests.
*/
-class IGNITE_IMPORT_EXPORT QueryRelation
+class QueryRelation
{
public:
/**
@@ -257,6 +257,40 @@ private:
int32_t someVal;
};
+/**
+ * Byte array test type.
+ */
+struct ByteArrayType
+{
+ /**
+ * Test constructor.
+ *
+ * @param val Init value.
+ */
+ ByteArrayType(int32_t val) :
+ intVal(val),
+ arrayVal(val + 1, val + 1)
+ {
+ // No-op.
+ }
+
+ /**
+ * Default constructor.
+ */
+ ByteArrayType() :
+ intVal(0),
+ arrayVal()
+ {
+ // No-op.
+ }
+
+ /** Int field. */
+ int32_t intVal;
+
+ /** Array field. */
+ std::vector<int8_t> arrayVal;
+};
+
namespace ignite
{
namespace binary
@@ -300,7 +334,7 @@ namespace ignite
IGNITE_BINARY_IS_NULL_FALSE(QueryRelation)
IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(QueryRelation)
- static void Write(BinaryWriter& writer, QueryRelation obj)
+ static void Write(BinaryWriter& writer, const QueryRelation& obj)
{
writer.WriteInt32("personId", obj.GetPersonId());
writer.WriteInt32("someVal", obj.GetHobbyId());
@@ -314,6 +348,32 @@ namespace ignite
dst = QueryRelation(personId, someVal);
}
IGNITE_BINARY_TYPE_END
+
+ /**
+ * Binary type definition for ByteArrayType.
+ */
+ IGNITE_BINARY_TYPE_START(ByteArrayType)
+ IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ByteArrayType)
+ IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ByteArrayType)
+ IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+ IGNITE_BINARY_IS_NULL_FALSE(ByteArrayType)
+ IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ByteArrayType)
+
+ static void Write(BinaryWriter& writer, const ByteArrayType& obj)
+ {
+ writer.WriteInt32("intVal", obj.intVal);
+ writer.WriteInt8Array("arrayVal", &obj.arrayVal[0], static_cast<int32_t>(obj.arrayVal.size()));
+ }
+
+ static void Read(BinaryReader& reader, ByteArrayType& dst)
+ {
+ dst.intVal = reader.ReadInt32("intVal");
+ int32_t arrayValSize = reader.ReadInt8Array("arrayVal", 0, 0);
+
+ dst.arrayVal.resize(static_cast<size_t>(arrayValSize));
+ reader.ReadInt8Array("arrayVal", &dst.arrayVal[0], arrayValSize);
+ }
+ IGNITE_BINARY_TYPE_END
}
}
@@ -1956,4 +2016,153 @@ BOOST_AUTO_TEST_CASE(TestFieldsQuerySetSchema)
CheckEmpty(cursor);
}
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArraySelect)
+{
+ Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+ int32_t entryCnt = 100; // Number of entries.
+
+ for (int32_t i = 0; i < entryCnt; i++)
+ byteArrayCache.Put(i, ByteArrayType(i));
+
+ SqlFieldsQuery qry("select intVal, arrayVal, intVal + 1 from ByteArrayType where _key=42");
+
+ QueryFieldsCursor cursor = byteArrayCache.Query(qry);
+
+ BOOST_REQUIRE(cursor.HasNext());
+
+ QueryFieldsRow row = cursor.GetNext();
+
+ BOOST_REQUIRE(row.HasNext());
+
+ int32_t intVal1 = row.GetNext<int32_t>();
+
+ BOOST_CHECK_EQUAL(intVal1, 42);
+
+ BOOST_REQUIRE(row.HasNext());
+
+ std::vector<int8_t> arrayVal;
+ int32_t arrayValSize = row.GetNextInt8Array(0, 0);
+
+ arrayVal.resize(static_cast<size_t>(arrayValSize));
+ row.GetNextInt8Array(&arrayVal[0], arrayValSize);
+
+ BOOST_CHECK_EQUAL(arrayValSize, 43);
+
+ for (int32_t i = 0; i < arrayValSize; ++i)
+ BOOST_CHECK_EQUAL(arrayVal[i], 43);
+
+ BOOST_REQUIRE(row.HasNext());
+
+ int32_t intVal2 = row.GetNext<int32_t>();
+
+ BOOST_CHECK_EQUAL(intVal2, 43);
+
+ BOOST_REQUIRE(!row.HasNext());
+
+ CheckEmpty(cursor);
+}
+
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArrayInsert)
+{
+ Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+ SqlFieldsQuery qry("insert into ByteArrayType(_key, intVal, arrayVal) values (?, ?, ?)");
+
+ int32_t entryCnt = 100; // Number of entries.
+
+ for (int32_t i = 0; i < entryCnt; i++)
+ {
+ int32_t key = i;
+ int32_t intVal = i;
+ std::vector<int8_t> arrayVal(i + 1, i + 1);
+
+ qry.AddArgument(key);
+ qry.AddArgument(intVal);
+ qry.AddInt8ArrayArgument(&arrayVal[0], i + 1);
+
+ byteArrayCache.Query(qry);
+
+ qry.ClearArguments();
+ }
+
+ ByteArrayType val = byteArrayCache.Get(42);
+
+ BOOST_CHECK_EQUAL(val.intVal, 42);
+ BOOST_CHECK_EQUAL(val.arrayVal.size(), 43);
+
+ for (int32_t i = 0; i < 43; ++i)
+ BOOST_CHECK_EQUAL(val.arrayVal[i], 43);
+}
+
+/**
+ * Test query for byte arrays.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryByteArrayInsertSelect)
+{
+ Cache<int32_t, ByteArrayType> byteArrayCache = grid.GetCache<int32_t, ByteArrayType>("ByteArrayCache");
+
+ SqlFieldsQuery qry("insert into ByteArrayType(_key, intVal, arrayVal) values (?, ?, ?)");
+
+ int32_t entryCnt = 100; // Number of entries.
+
+ for (int32_t i = 0; i < entryCnt; i++)
+ {
+ int32_t key = i;
+ int32_t intVal = i;
+ std::vector<int8_t> arrayVal(i + 1, i + 1);
+
+ qry.AddArgument(key);
+ qry.AddArgument(intVal);
+ qry.AddInt8ArrayArgument(&arrayVal[0], i + 1);
+
+ byteArrayCache.Query(qry);
+
+ qry.ClearArguments();
+ }
+
+ qry = SqlFieldsQuery("select intVal, arrayVal, intVal + 1 from ByteArrayType where _key=42");
+
+ QueryFieldsCursor cursor = byteArrayCache.Query(qry);
+
+ BOOST_REQUIRE(cursor.HasNext());
+
+ QueryFieldsRow row = cursor.GetNext();
+
+ BOOST_REQUIRE(row.HasNext());
+
+ int32_t intVal1 = row.GetNext<int32_t>();
+
+ BOOST_CHECK_EQUAL(intVal1, 42);
+
+ BOOST_REQUIRE(row.HasNext());
+
+ std::vector<int8_t> arrayVal;
+ int32_t arrayValSize = row.GetNextInt8Array(0, 0);
+
+ arrayVal.resize(static_cast<size_t>(arrayValSize));
+ row.GetNextInt8Array(&arrayVal[0], arrayValSize);
+
+ BOOST_CHECK_EQUAL(arrayValSize, 43);
+
+ for (int32_t i = 0; i < arrayValSize; ++i)
+ BOOST_CHECK_EQUAL(arrayVal[i], 43);
+
+ BOOST_REQUIRE(row.HasNext());
+
+ int32_t intVal2 = row.GetNext<int32_t>();
+
+ BOOST_CHECK_EQUAL(intVal2, 43);
+
+ BOOST_REQUIRE(!row.HasNext());
+
+ CheckEmpty(cursor);
+}
+
BOOST_AUTO_TEST_SUITE_END()
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
index d3ac2de..8ed587c 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
@@ -172,6 +172,34 @@ namespace ignite
}
/**
+ * Get next entry assuming it's an array of 8-byte signed
+ * integers. Maps to "byte[]" type in Java.
+ *
+ * This method should only be used on the valid instance.
+ *
+ * @param dst Array to store data to.
+ * @param len Expected length of array.
+ * @return Actual amount of elements read. If "len" argument is less than actual
+ * array size or resulting array is set to null, nothing will be written
+ * to resulting array and returned value will contain required array length.
+ * -1 will be returned in case array in stream was null.
+ *
+ * @throw IgniteError class instance in case of failure.
+ */
+ int32_t GetNextInt8Array(int8_t* dst, int32_t len)
+ {
+ impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get();
+
+ if (impl0)
+ return impl0->GetNextInt8Array(dst, len);
+ else
+ {
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+ }
+ }
+
+ /**
* Check if the instance is valid.
*
* Invalid instance can be returned if some of the previous
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
index bf8d7ac..96d794d 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
@@ -139,7 +139,7 @@ namespace ignite
using std::swap;
swap(sql, other.sql);
- swap(sql, other.schema);
+ swap(schema, other.schema);
swap(pageSize, other.pageSize);
swap(loc, other.loc);
swap(distributedJoins, other.distributedJoins);
@@ -274,6 +274,17 @@ namespace ignite
}
/**
+ * Add array of bytes as an argument.
+ *
+ * @param src Array pointer.
+ * @param len Array length in bytes.
+ */
+ void AddInt8ArrayArgument(const int8_t* src, int32_t len)
+ {
+ args.push_back(new impl::cache::query::QueryInt8ArrayArgument(src, len));
+ }
+
+ /**
* Remove all added arguments.
*/
void ClearArguments()
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
index f2f55bc..e9e7e51 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_argument.h
@@ -129,6 +129,69 @@ namespace ignite
/** Value. */
T val;
};
+
+ /**
+ * Query bytes array argument class.
+ */
+ class QueryInt8ArrayArgument : public QueryArgumentBase
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param src Array.
+ * @param len Array length.
+ */
+ QueryInt8ArrayArgument(const int8_t* src, int32_t len) :
+ val(src, src + len)
+ {
+ // No-op.
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other Other instance.
+ */
+ QueryInt8ArrayArgument(const QueryInt8ArrayArgument& other) :
+ val(other.val)
+ {
+ // No-op.
+ }
+
+ /**
+ * Assignment operator.
+ *
+ * @param other Other instance.
+ * @return *this.
+ */
+ QueryInt8ArrayArgument& operator=(const QueryInt8ArrayArgument& other)
+ {
+ if (this != &other)
+ val = other.val;
+
+ return *this;
+ }
+
+ virtual ~QueryInt8ArrayArgument()
+ {
+ // No-op.
+ }
+
+ virtual QueryArgumentBase* Copy() const
+ {
+ return new QueryInt8ArrayArgument(*this);
+ }
+
+ virtual void Write(ignite::binary::BinaryRawWriter& writer)
+ {
+ writer.WriteInt8Array(&val[0], static_cast<int32_t>(val.size()));
+ }
+
+ private:
+ /** Value. */
+ std::vector<int8_t> val;
+ };
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/97813a82/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
index 82cebd5..63e0523 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -127,6 +127,35 @@ namespace ignite
}
/**
+ * Get next entry assuming it's an array of 8-byte signed
+ * integers. Maps to "byte[]" type in Java.
+ *
+ * @param dst Array to store data to.
+ * @param len Expected length of array.
+ * @return Actual amount of elements read. If "len" argument is less than actual
+ * array size or resulting array is set to null, nothing will be written
+ * to resulting array and returned value will contain required array length.
+ * -1 will be returned in case array in stream was null.
+ */
+ int32_t GetNextInt8Array(int8_t* dst, int32_t len)
+ {
+ if (IsValid()) {
+
+ int32_t actualLen = reader.ReadInt8Array(dst, len);
+
+ if (actualLen == 0 || dst && len >= actualLen)
+ ++processed;
+
+ return actualLen;
+ }
+ else
+ {
+ throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+ }
+ }
+
+ /**
* Check if the instance is valid.
*
* Invalid instance can be returned if some of the previous