You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/11/02 17:36:56 UTC
[13/33] ignite git commit: IGNITE-1647: Implemented SQL fields query.
IGNITE-1647: Implemented SQL fields query.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/667c2e65
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/667c2e65
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/667c2e65
Branch: refs/heads/ignite-1753-1282
Commit: 667c2e65de65cf6486b7ef56bb03c85b02ebee66
Parents: 09339de
Author: isapego <is...@gridgain.com>
Authored: Fri Oct 30 12:20:54 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Oct 30 12:20:54 2015 +0300
----------------------------------------------------------------------
.../cpp/core-test/src/cache_query_test.cpp | 214 ++++++++++++++++++-
modules/platforms/cpp/core/include/Makefile.am | 4 +
.../cpp/core/include/ignite/cache/cache.h | 33 +++
.../cpp/core/include/ignite/cache/query/query.h | 1 +
.../include/ignite/cache/query/query_cursor.h | 11 +-
.../ignite/cache/query/query_fields_cursor.h | 153 +++++++++++++
.../ignite/cache/query/query_fields_row.h | 154 +++++++++++++
.../core/include/ignite/cache/query/query_sql.h | 76 +++----
.../ignite/cache/query/query_sql_fields.h | 210 ++++++++++++++++++
.../core/include/ignite/impl/cache/cache_impl.h | 10 +
.../impl/cache/query/query_fields_row_impl.h | 174 +++++++++++++++
.../ignite/impl/cache/query/query_impl.h | 10 +
.../platforms/cpp/core/project/vs/core.vcxproj | 4 +
.../cpp/core/project/vs/core.vcxproj.filters | 12 ++
.../cpp/core/src/impl/cache/cache_impl.cpp | 5 +
.../core/src/impl/cache/query/query_impl.cpp | 39 +++-
16 files changed, 1048 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/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 1605d74..8625fa1 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -28,6 +28,7 @@
#include "ignite/cache/query/query_cursor.h"
#include "ignite/cache/query/query_sql.h"
#include "ignite/cache/query/query_text.h"
+#include "ignite/cache/query/query_sql_fields.h"
#include "ignite/ignite.h"
#include "ignite/ignition.h"
@@ -58,7 +59,7 @@ public:
* @param name Name.
* @param age Age.
*/
- QueryPerson(std::string name, int age) : name(CopyChars(name.c_str())), age(age)
+ QueryPerson(const std::string& name, int age) : name(CopyChars(name.c_str())), age(age)
{
// No-op.
}
@@ -230,7 +231,8 @@ struct CacheQueryTestSuiteFixture {
*
* @param cur Cursor.
*/
-void CheckHasNextFail(QueryCursor<int, QueryPerson>& cur)
+template<typename Cursor>
+void CheckHasNextFail(Cursor& cur)
{
try
{
@@ -249,7 +251,8 @@ void CheckHasNextFail(QueryCursor<int, QueryPerson>& cur)
*
* @param cur Cursor.
*/
-void CheckGetNextFail(QueryCursor<int, QueryPerson>& cur)
+template<typename Cursor>
+void CheckGetNextFail(Cursor& cur)
{
try
{
@@ -268,7 +271,8 @@ void CheckGetNextFail(QueryCursor<int, QueryPerson>& cur)
*
* @param cur Cursor.
*/
-void CheckGetAllFail(QueryCursor<int, QueryPerson>& cur)
+template<typename Cursor>
+void CheckGetAllFail(Cursor& cur)
{
try
{
@@ -298,11 +302,24 @@ void CheckEmpty(QueryCursor<int, QueryPerson>& cur)
}
/**
+* Check empty result through iteration.
+*
+* @param cur Cursor.
+*/
+void CheckEmpty(QueryFieldsCursor& cur)
+{
+ BOOST_REQUIRE(!cur.HasNext());
+
+ CheckGetNextFail(cur);
+}
+
+/**
* Check empty result through GetAll().
*
* @param cur Cursor.
*/
-void CheckEmptyGetAll(QueryCursor<int, QueryPerson>& cur)
+template<typename Cursor>
+void CheckEmptyGetAll(Cursor& cur)
{
std::vector<CacheEntry<int, QueryPerson>> res;
@@ -322,7 +339,8 @@ void CheckEmptyGetAll(QueryCursor<int, QueryPerson>& cur)
* @param name1 Name.
* @param age1 Age.
*/
-void CheckSingle(QueryCursor<int, QueryPerson>& cur, int key, std::string name, int age)
+template<typename Cursor>
+void CheckSingle(Cursor& cur, int key, const std::string& name, int age)
{
BOOST_REQUIRE(cur.HasNext());
@@ -350,7 +368,8 @@ void CheckSingle(QueryCursor<int, QueryPerson>& cur, int key, std::string name,
* @param name1 Name.
* @param age1 Age.
*/
-void CheckSingleGetAll(QueryCursor<int, QueryPerson>& cur, int key, std::string name, int age)
+template<typename Cursor>
+void CheckSingleGetAll(Cursor& cur, int key, const std::string& name, int age)
{
std::vector<CacheEntry<int, QueryPerson>> res;
@@ -382,8 +401,9 @@ void CheckSingleGetAll(QueryCursor<int, QueryPerson>& cur, int key, std::string
* @param name2 Name 2.
* @param age2 Age 2.
*/
-void CheckMultiple(QueryCursor<int, QueryPerson>& cur, int key1, std::string name1,
- int age1, int key2, std::string name2, int age2)
+template<typename Cursor>
+void CheckMultiple(Cursor& cur, int key1, const std::string& name1,
+ int age1, int key2, const std::string& name2, int age2)
{
for (int i = 0; i < 2; i++)
{
@@ -426,8 +446,9 @@ void CheckMultiple(QueryCursor<int, QueryPerson>& cur, int key1, std::string nam
* @param name2 Name 2.
* @param age2 Age 2.
*/
-void CheckMultipleGetAll(QueryCursor<int, QueryPerson>& cur, int key1, std::string name1, int age1,
- int key2, std::string name2, int age2)
+template<typename Cursor>
+void CheckMultipleGetAll(Cursor& cur, int key1, const std::string& name1,
+ int age1, int key2, const std::string& name2, int age2)
{
std::vector<CacheEntry<int, QueryPerson>> res;
@@ -646,4 +667,175 @@ BOOST_AUTO_TEST_CASE(TestScanQueryPartitioned)
BOOST_REQUIRE(keys.size() == entryCnt);
}
+/**
+ * Test fields query with single entry.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQuerySingle)
+{
+ // Test simple query.
+ Cache<int, QueryPerson> cache = GetCache();
+
+ // Test query with two fields of different type.
+ SqlFieldsQuery qry("select age, name from QueryPerson");
+
+ QueryFieldsCursor cursor = cache.Query(qry);
+ CheckEmpty(cursor);
+
+ // Test simple query.
+ cache.Put(1, QueryPerson("A1", 10));
+
+ cursor = cache.Query(qry);
+
+ IgniteError error;
+
+ BOOST_REQUIRE(cursor.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ QueryFieldsRow row = cursor.GetNext(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(row.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ int age = row.GetNext<int>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(age == 10);
+
+ std::string name = row.GetNext<std::string>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(name == "A1");
+
+ BOOST_REQUIRE(!row.HasNext());
+
+ CheckEmpty(cursor);
+}
+
+/**
+ * Test fields query with two simultaneously handled rows.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQueryTwo)
+{
+ // Test simple query.
+ Cache<int, QueryPerson> cache = GetCache();
+
+ // Test query with two fields of different type.
+ SqlFieldsQuery qry("select age, name from QueryPerson");
+
+ QueryFieldsCursor cursor = cache.Query(qry);
+ CheckEmpty(cursor);
+
+ // Test simple query.
+ cache.Put(1, QueryPerson("A1", 10));
+ cache.Put(2, QueryPerson("A2", 20));
+
+ cursor = cache.Query(qry);
+
+ IgniteError error;
+
+ BOOST_REQUIRE(cursor.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ QueryFieldsRow row1 = cursor.GetNext(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ QueryFieldsRow row2 = cursor.GetNext(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(row1.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(row2.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ int age2 = row2.GetNext<int>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(age2 == 20);
+
+ int age1 = row1.GetNext<int>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(age1 == 10);
+
+ std::string name1 = row1.GetNext<std::string>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(name1 == "A1");
+
+ std::string name2 = row2.GetNext<std::string>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(name2 == "A2");
+
+ BOOST_REQUIRE(!row1.HasNext());
+ BOOST_REQUIRE(!row2.HasNext());
+
+ CheckEmpty(cursor);
+}
+
+/**
+ * Test fields query with several entries.
+ */
+BOOST_AUTO_TEST_CASE(TestFieldsQuerySeveral)
+{
+ // Test simple query.
+ Cache<int, QueryPerson> cache = GetCache();
+
+ // Test query with two fields of different type.
+ SqlFieldsQuery qry("select name, age from QueryPerson");
+
+ QueryFieldsCursor cursor = cache.Query(qry);
+ CheckEmpty(cursor);
+
+ int32_t entryCnt = 1000; // Number of entries.
+
+ for (int i = 0; i < entryCnt; i++)
+ {
+ std::stringstream stream;
+
+ stream << "A" << i;
+
+ cache.Put(i, QueryPerson(stream.str(), i * 10));
+ }
+
+ cursor = cache.Query(qry);
+
+ IgniteError error;
+
+ for (int i = 0; i < entryCnt; i++)
+ {
+ std::stringstream stream;
+
+ stream << "A" << i;
+
+ std::string expected_name = stream.str();
+ int expected_age = i * 10;
+
+ BOOST_REQUIRE(cursor.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ QueryFieldsRow row = cursor.GetNext(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(row.HasNext(error));
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ std::string name = row.GetNext<std::string>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(name == expected_name);
+
+ int age = row.GetNext<int>(error);
+ BOOST_REQUIRE(error.GetCode() == IgniteError::IGNITE_SUCCESS);
+
+ BOOST_REQUIRE(age == expected_age);
+
+ BOOST_REQUIRE(!row.HasNext());
+ }
+
+ CheckEmpty(cursor);
+}
+
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/Makefile.am b/modules/platforms/cpp/core/include/Makefile.am
index da9d95e..b20e2f7 100644
--- a/modules/platforms/cpp/core/include/Makefile.am
+++ b/modules/platforms/cpp/core/include/Makefile.am
@@ -22,12 +22,16 @@ nobase_include_HEADERS = ignite/cache/cache.h \
ignite/cache/cache_peek_mode.h \
ignite/cache/query/query_argument.h \
ignite/cache/query/query_cursor.h \
+ ignite/cache/query/query_fields_cursor.h \
+ ignite/cache/query/query_fields_row.h \
ignite/cache/query/query_scan.h \
ignite/cache/query/query_sql.h \
+ ignite/cache/query/query_sql_fields.h \
ignite/cache/query/query_text.h \
ignite/cache/query/query.h \
ignite/impl/cache/cache_impl.h \
ignite/impl/cache/query/query_impl.h \
+ ignite/impl/cache/query/query_fields_row_impl.h \
ignite/impl/interop/interop.h \
ignite/impl/interop/interop_input_stream.h \
ignite/impl/interop/interop_memory.h \
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/cache/cache.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache.h b/modules/platforms/cpp/core/include/ignite/cache/cache.h
index 6a51a5f..7581d86 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache.h
@@ -26,9 +26,11 @@
#include "ignite/cache/cache_peek_mode.h"
#include "ignite/cache/query/query_cursor.h"
+#include "ignite/cache/query/query_fields_cursor.h"
#include "ignite/cache/query/query_scan.h"
#include "ignite/cache/query/query_sql.h"
#include "ignite/cache/query/query_text.h"
+#include "ignite/cache/query/query_sql_fields.h"
#include "ignite/impl/cache/cache_impl.h"
#include "ignite/impl/operations.h"
#include "ignite/ignite_error.h"
@@ -1143,6 +1145,37 @@ namespace ignite
return query::QueryCursor<K, V>(cursorImpl);
}
+ /*
+ * Perform sql fields query.
+ *
+ * @param qry Query.
+ * @return Query cursor.
+ */
+ query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry)
+ {
+ IgniteError err;
+
+ query::QueryFieldsCursor res = Query(qry, err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /*
+ * Perform sql fields query.
+ *
+ * @param qry Query.
+ * @param err Error.
+ * @return Query cursor.
+ */
+ query::QueryFieldsCursor Query(const query::SqlFieldsQuery& qry, IgniteError& err)
+ {
+ impl::cache::query::QueryCursorImpl* cursorImpl = impl.Get()->QuerySqlFields(qry, &err);
+
+ return query::QueryFieldsCursor(cursorImpl);
+ }
+
/**
* Check if the instance is valid.
*
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/cache/query/query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query.h b/modules/platforms/cpp/core/include/ignite/cache/query/query.h
index f2d19cd..c469e85 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query.h
@@ -22,6 +22,7 @@
#include "ignite/cache/query/query_cursor.h"
#include "ignite/cache/query/query_scan.h"
#include "ignite/cache/query/query_sql.h"
+#include "ignite/cache/query/query_sql_fields.h"
#include "ignite/cache/query/query_text.h"
#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
index e3fe99f..4ef2405 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
@@ -28,11 +28,11 @@
#include "ignite/impl/operations.h"
namespace ignite
-{
+{
namespace cache
{
namespace query
- {
+ {
/**
* Query cursor.
*/
@@ -53,12 +53,11 @@ namespace ignite
*
* @param impl Implementation.
*/
- QueryCursor(impl::cache::query::QueryCursorImpl* impl) :
- impl(ignite::common::concurrent::SharedPointer<impl::cache::query::QueryCursorImpl>(impl))
+ QueryCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl)
{
// No-op.
}
-
+
/**
* Check whether next entry exists.
*
@@ -109,7 +108,7 @@ namespace ignite
IgniteError::ThrowIfNeeded(err);
- return res;
+ return res;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
new file mode 100644
index 0000000..8410c81
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_cursor.h
@@ -0,0 +1,153 @@
+/*
+ * 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_CACHE_QUERY_FIELDS_CURSOR
+#define _IGNITE_CACHE_QUERY_FIELDS_CURSOR
+
+#include <vector>
+
+#include <ignite/common/concurrent.h>
+
+#include "ignite/cache/cache_entry.h"
+#include "ignite/ignite_error.h"
+#include "ignite/cache/query/query_fields_row.h"
+#include "ignite/impl/cache/query/query_impl.h"
+#include "ignite/impl/operations.h"
+
+namespace ignite
+{
+ namespace cache
+ {
+ namespace query
+ {
+ /**
+ * Query fields cursor.
+ */
+ class QueryFieldsCursor
+ {
+ public:
+ /**
+ * Default constructor.
+ */
+ QueryFieldsCursor() : impl(NULL)
+ {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param impl Implementation.
+ */
+ QueryFieldsCursor(impl::cache::query::QueryCursorImpl* impl) : impl(impl)
+ {
+ // No-op.
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @return True if next entry exists.
+ */
+ bool HasNext()
+ {
+ IgniteError err;
+
+ bool res = HasNext(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @param err Error.
+ * @return True if next entry exists.
+ */
+ bool HasNext(IgniteError& err)
+ {
+ impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
+
+ if (impl0)
+ return impl0->HasNext(&err);
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return false;
+ }
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @return Next entry.
+ */
+ QueryFieldsRow GetNext()
+ {
+ IgniteError err;
+
+ QueryFieldsRow res = GetNext(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @param err Error.
+ * @return Next entry.
+ */
+ QueryFieldsRow GetNext(IgniteError& err)
+ {
+ impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
+
+ if (impl0)
+ return impl0->GetNextRow(&err);
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return QueryFieldsRow();
+ }
+ }
+
+ /**
+ * Check if the instance is valid.
+ *
+ * @return True if the instance is valid and can be used.
+ */
+ bool IsValid()
+ {
+ return impl.IsValid();
+ }
+
+ private:
+ /** Implementation delegate. */
+ ignite::common::concurrent::SharedPointer<impl::cache::query::QueryCursorImpl> impl;
+ };
+ }
+ }
+}
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/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
new file mode 100644
index 0000000..1e70a8d
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_fields_row.h
@@ -0,0 +1,154 @@
+/*
+ * 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_CACHE_QUERY_FIELDS_ROW
+#define _IGNITE_CACHE_QUERY_FIELDS_ROW
+
+#include <vector>
+
+#include <ignite/common/concurrent.h>
+
+#include "ignite/cache/cache_entry.h"
+#include "ignite/ignite_error.h"
+#include "ignite/impl/cache/query/query_fields_row_impl.h"
+#include "ignite/impl/operations.h"
+
+namespace ignite
+{
+ namespace cache
+ {
+ namespace query
+ {
+ /**
+ * Query fields cursor.
+ */
+ class QueryFieldsRow
+ {
+ public:
+ /**
+ * Default constructor.
+ */
+ QueryFieldsRow() : impl(NULL)
+ {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param impl Implementation.
+ */
+ QueryFieldsRow(impl::cache::query::QueryFieldsRowImpl* impl) : impl(impl)
+ {
+ // No-op.
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @return True if next entry exists.
+ */
+ bool HasNext()
+ {
+ IgniteError err;
+
+ bool res = HasNext(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @param err Error.
+ * @return True if next entry exists.
+ */
+ bool HasNext(IgniteError& err)
+ {
+ impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get();
+
+ if (impl0)
+ return impl0->HasNext();
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return false;
+ }
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @return Next entry.
+ */
+ template<typename T>
+ T GetNext()
+ {
+ IgniteError err;
+
+ QueryFieldsRow res = GetNext<T>(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @param err Error.
+ * @return Next entry.
+ */
+ template<typename T>
+ T GetNext(IgniteError& err)
+ {
+ impl::cache::query::QueryFieldsRowImpl* impl0 = impl.Get();
+
+ if (impl0)
+ return impl0->GetNext<T>(err);
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return T();
+ }
+ }
+
+ /**
+ * Check if the instance is valid.
+ *
+ * @return True if the instance is valid and can be used.
+ */
+ bool IsValid()
+ {
+ return impl.IsValid();
+ }
+
+ private:
+ /** Implementation delegate. */
+ ignite::common::concurrent::SharedPointer<impl::cache::query::QueryFieldsRowImpl> impl;
+ };
+ }
+ }
+}
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
index 103557e..d623536 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql.h
@@ -54,23 +54,14 @@ namespace ignite
*
* @param other Other instance.
*/
- SqlQuery(const SqlQuery& other)
+ SqlQuery(const SqlQuery& other) : type(other.type), sql(other.sql), pageSize(other.pageSize),
+ loc(other.loc), args()
{
- type = other.type;
- sql = other.sql;
- pageSize = other.pageSize;
- loc = other.loc;
+ args.reserve(other.args.size());
- if (other.args)
- {
- args = new std::vector<QueryArgumentBase*>();
-
- for (std::vector<QueryArgumentBase*>::iterator it = other.args->begin();
- it != other.args->end(); ++it)
- args->push_back((*it)->Copy());
- }
- else
- args = NULL;
+ for (std::vector<QueryArgumentBase*>::const_iterator i = other.args.begin();
+ i != other.args.end(); ++i)
+ args.push_back((*i)->Copy());
}
/**
@@ -82,18 +73,13 @@ namespace ignite
{
if (this != &other)
{
- type = other.type;
- sql = other.sql;
- pageSize = other.pageSize;
- loc = other.loc;
-
SqlQuery tmp(other);
- std::vector<QueryArgumentBase*>* args0 = args;
-
- args = tmp.args;
-
- tmp.args = args0;
+ std::swap(type, tmp.type);
+ std::swap(sql, tmp.sql);
+ std::swap(pageSize, tmp.pageSize);
+ std::swap(loc, tmp.loc);
+ std::swap(args, tmp.args);
}
return *this;
@@ -104,12 +90,24 @@ namespace ignite
*/
~SqlQuery()
{
- if (args)
- {
- for (std::vector<QueryArgumentBase*>::iterator it = args->begin(); it != args->end(); ++it)
- delete (*it);
+ for (std::vector<QueryArgumentBase*>::iterator it = args.begin(); it != args.end(); ++it)
+ delete *it;
+ }
- delete args;
+ /**
+ * Efficiently swaps contents with another SqlQuery instance.
+ *
+ * @param other Other instance.
+ */
+ void Swap(SqlQuery& other)
+ {
+ if (this != &other)
+ {
+ std::swap(type, other.type);
+ std::swap(sql, other.sql);
+ std::swap(pageSize, other.pageSize);
+ std::swap(loc, other.loc);
+ std::swap(args, other.args);
}
}
@@ -201,10 +199,7 @@ namespace ignite
template<typename T>
void AddArgument(const T& arg)
{
- if (!args)
- args = new std::vector<QueryArgumentBase*>();
-
- args->push_back(new QueryArgument<T>(arg));
+ args.push_back(new QueryArgument<T>(arg));
}
/**
@@ -219,15 +214,10 @@ namespace ignite
writer.WriteString(type);
writer.WriteInt32(pageSize);
- if (args)
- {
- writer.WriteInt32(static_cast<int32_t>(args->size()));
+ writer.WriteInt32(static_cast<int32_t>(args.size()));
- for (std::vector<QueryArgumentBase*>::iterator it = args->begin(); it != args->end(); ++it)
- (*it)->Write(writer);
- }
- else
- writer.WriteInt32(0);
+ for (std::vector<QueryArgumentBase*>::const_iterator it = args.begin(); it != args.end(); ++it)
+ (*it)->Write(writer);
}
private:
@@ -244,7 +234,7 @@ namespace ignite
bool loc;
/** Arguments. */
- std::vector<QueryArgumentBase*>* args;
+ std::vector<QueryArgumentBase*> args;
};
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/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
new file mode 100644
index 0000000..945bf71
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_sql_fields.h
@@ -0,0 +1,210 @@
+/*
+ * 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_CACHE_QUERY_SQL_FIELDS
+#define _IGNITE_CACHE_QUERY_SQL_FIELDS
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include "ignite/cache/query/query_argument.h"
+#include "ignite/portable/portable_raw_writer.h"
+
+namespace ignite
+{
+ namespace cache
+ {
+ namespace query
+ {
+ /**
+ * Sql fields query.
+ */
+ class SqlFieldsQuery
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param sql SQL string.
+ */
+ SqlFieldsQuery(const std::string& sql) : sql(sql), pageSize(1024), loc(false), args()
+ {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param sql SQL string.
+ * @param loc Whether query should be executed locally.
+ */
+ SqlFieldsQuery(const std::string& sql, bool loc) : sql(sql), pageSize(1024), loc(false), args()
+ {
+ // No-op.
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param other Other instance.
+ */
+ SqlFieldsQuery(const SqlFieldsQuery& other) : sql(other.sql), pageSize(other.pageSize), loc(other.loc),
+ args()
+ {
+ args.reserve(other.args.size());
+
+ for (std::vector<QueryArgumentBase*>::const_iterator i = other.args.begin();
+ i != other.args.end(); ++i)
+ args.push_back((*i)->Copy());
+ }
+
+ /**
+ * Assignment operator.
+ *
+ * @param other Other instance.
+ */
+ SqlFieldsQuery& operator=(const SqlFieldsQuery& other)
+ {
+ if (this != &other)
+ {
+ SqlFieldsQuery tmp(other);
+
+ std::swap(sql, tmp.sql);
+ std::swap(pageSize, tmp.pageSize);
+ std::swap(loc, tmp.loc);
+ std::swap(args, tmp.args);
+ }
+
+ return *this;
+ }
+
+ /**
+ * Destructor.
+ */
+ ~SqlFieldsQuery()
+ {
+ for (std::vector<QueryArgumentBase*>::iterator it = args.begin(); it != args.end(); ++it)
+ delete *it;
+ }
+
+ /**
+ * Get SQL string.
+ *
+ * @return SQL string.
+ */
+ const std::string& GetSql() const
+ {
+ return sql;
+ }
+
+ /**
+ * Set SQL string.
+ *
+ * @param sql SQL string.
+ */
+ void SetSql(const std::string& sql)
+ {
+ this->sql = sql;
+ }
+
+ /**
+ * Get page size.
+ *
+ * @return Page size.
+ */
+ int32_t GetPageSize() const
+ {
+ return pageSize;
+ }
+
+ /**
+ * Set page size.
+ *
+ * @param pageSize Page size.
+ */
+ void SetPageSize(int32_t pageSize)
+ {
+ this->pageSize = pageSize;
+ }
+
+ /**
+ * Get local flag.
+ *
+ * @return Local flag.
+ */
+ bool IsLocal() const
+ {
+ return loc;
+ }
+
+ /**
+ * Set local flag.
+ *
+ * @param loc Local flag.
+ */
+ void SetLocal(bool loc)
+ {
+ this->loc = loc;
+ }
+
+ /**
+ * Add argument.
+ *
+ * @param arg Argument.
+ */
+ template<typename T>
+ void AddArgument(const T& arg)
+ {
+ args.push_back(new QueryArgument<T>(arg));
+ }
+
+ /**
+ * Write query info to the stream.
+ *
+ * @param writer Writer.
+ */
+ void Write(portable::PortableRawWriter& writer) const
+ {
+ writer.WriteBool(loc);
+ writer.WriteString(sql);
+ writer.WriteInt32(pageSize);
+
+ writer.WriteInt32(static_cast<int32_t>(args.size()));
+
+ for (std::vector<QueryArgumentBase*>::const_iterator it = args.begin(); it != args.end(); ++it)
+ (*it)->Write(writer);
+ }
+
+ private:
+ /** SQL string. */
+ std::string sql;
+
+ /** Page size. */
+ int32_t pageSize;
+
+ /** Local flag. */
+ bool loc;
+
+ /** Arguments. */
+ std::vector<QueryArgumentBase*> args;
+ };
+ }
+ }
+}
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
index b7596bf..803ef04 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/cache_impl.h
@@ -21,6 +21,7 @@
#include "ignite/cache/query/query_scan.h"
#include "ignite/cache/query/query_sql.h"
#include "ignite/cache/query/query_text.h"
+#include "ignite/cache/query/query_sql_fields.h"
#include "ignite/impl/ignite_environment.h"
#include "ignite/impl/cache/query/query_impl.h"
#include "ignite/impl/operations.h"
@@ -316,6 +317,15 @@ namespace ignite
* @return Query cursor.
*/
query::QueryCursorImpl* QueryScan(const ignite::cache::query::ScanQuery& qry, IgniteError* err);
+
+ /*
+ * Invoke sql fields query.
+ *
+ * @param qry Query.
+ * @param err Error.
+ * @return Query cursor.
+ */
+ query::QueryCursorImpl* QuerySqlFields(const ignite::cache::query::SqlFieldsQuery& qry, IgniteError* err);
private:
/** Name. */
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/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
new file mode 100644
index 0000000..ff04c09
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -0,0 +1,174 @@
+/*
+ * 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_CACHE_QUERY_FIELDS_ROW_IMPL
+#define _IGNITE_CACHE_QUERY_FIELDS_ROW_IMPL
+
+#include <vector>
+#include <memory>
+
+#include <ignite/common/concurrent.h>
+
+#include "ignite/cache/cache_entry.h"
+#include "ignite/ignite_error.h"
+#include "ignite/impl/cache/query/query_impl.h"
+#include "ignite/impl/operations.h"
+
+namespace ignite
+{
+ namespace impl
+ {
+ namespace cache
+ {
+ namespace query
+ {
+ /**
+ * Query fields cursor implementation.
+ */
+ class QueryFieldsRowImpl
+ {
+ public:
+ typedef common::concurrent::SharedPointer<interop::InteropMemory> InteropMemorySharedPtr;
+
+ /**
+ * Default constructor.
+ */
+ QueryFieldsRowImpl() : mem(NULL), stream(NULL), reader(NULL), size(0),
+ processed(0)
+ {
+ // No-op.
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param mem Memory containig row data.
+ */
+ QueryFieldsRowImpl(InteropMemorySharedPtr mem) : mem(mem), stream(mem.Get()),
+ reader(&stream), size(reader.ReadInt32()), processed(0)
+ {
+ // No-op.
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @return True if next entry exists.
+ */
+ bool HasNext()
+ {
+ IgniteError err;
+
+ bool res = HasNext(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Check whether next entry exists.
+ *
+ * @param err Error.
+ * @return True if next entry exists.
+ */
+ bool HasNext(IgniteError& err)
+ {
+ if (IsValid())
+ return processed < size;
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return false;
+ }
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @return Next entry.
+ */
+ template<typename T>
+ T GetNext()
+ {
+ IgniteError err;
+
+ QueryFieldsRowImpl res = GetNext<T>(err);
+
+ IgniteError::ThrowIfNeeded(err);
+
+ return res;
+ }
+
+ /**
+ * Get next entry.
+ *
+ * @param err Error.
+ * @return Next entry.
+ */
+ template<typename T>
+ T GetNext(IgniteError& err)
+ {
+ if (IsValid()) {
+ ++processed;
+ return reader.ReadTopObject<T>();
+ }
+ else
+ {
+ err = IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+ "Instance is not usable (did you check for error?).");
+
+ return T();
+ }
+ }
+
+ /**
+ * Check if the instance is valid.
+ *
+ * @return True if the instance is valid and can be used.
+ */
+ bool IsValid()
+ {
+ return mem.Get() != NULL;
+ }
+
+ private:
+ /** Row memory. */
+ InteropMemorySharedPtr mem;
+
+ /** Row data stream. */
+ interop::InteropInputStream stream;
+
+ /** Row data reader. */
+ portable::PortableReaderImpl reader;
+
+ /** Number of elements in a row. */
+ int32_t size;
+
+ /** Number of elements that have been read by now. */
+ int32_t processed;
+
+ IGNITE_NO_COPY_ASSIGNMENT(QueryFieldsRowImpl)
+ };
+ }
+ }
+ }
+}
+
+#endif
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
index e65eeb6..e553e24 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
@@ -30,6 +30,8 @@ namespace ignite
{
namespace query
{
+ class QueryFieldsRowImpl;
+
/**
* Query cursor implementation.
*/
@@ -66,6 +68,14 @@ namespace ignite
void GetNext(OutputOperation& op, IgniteError* err);
/**
+ * Get next row.
+ *
+ * @param err Error.
+ * @return Output row.
+ */
+ QueryFieldsRowImpl* GetNextRow(IgniteError* err);
+
+ /**
* Get all cursor entries.
*
* @param op Operation.
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/project/vs/core.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj b/modules/platforms/cpp/core/project/vs/core.vcxproj
index b7e4f7c..dfed87b 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj
@@ -194,8 +194,11 @@
<ClInclude Include="..\..\include\ignite\cache\query\query.h" />
<ClInclude Include="..\..\include\ignite\cache\query\query_argument.h" />
<ClInclude Include="..\..\include\ignite\cache\query\query_cursor.h" />
+ <ClInclude Include="..\..\include\ignite\cache\query\query_fields_cursor.h" />
+ <ClInclude Include="..\..\include\ignite\cache\query\query_fields_row.h" />
<ClInclude Include="..\..\include\ignite\cache\query\query_scan.h" />
<ClInclude Include="..\..\include\ignite\cache\query\query_sql.h" />
+ <ClInclude Include="..\..\include\ignite\cache\query\query_sql_fields.h" />
<ClInclude Include="..\..\include\ignite\cache\query\query_text.h" />
<ClInclude Include="..\..\include\ignite\ignite.h" />
<ClInclude Include="..\..\include\ignite\ignite_configuration.h" />
@@ -203,6 +206,7 @@
<ClInclude Include="..\..\include\ignite\ignition.h" />
<ClInclude Include="..\..\include\ignite\guid.h" />
<ClInclude Include="..\..\include\ignite\impl\cache\cache_impl.h" />
+ <ClInclude Include="..\..\include\ignite\impl\cache\query\query_fields_row_impl.h" />
<ClInclude Include="..\..\include\ignite\impl\cache\query\query_impl.h" />
<ClInclude Include="..\..\include\ignite\impl\ignite_environment.h" />
<ClInclude Include="..\..\include\ignite\impl\ignite_impl.h" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
index 83f2fc7..67dd455 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
@@ -213,6 +213,18 @@
<ClInclude Include="..\..\include\ignite\cache\query\query_scan.h">
<Filter>Code\cache\query</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\ignite\cache\query\query_sql_fields.h">
+ <Filter>Code\cache\query</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\cache\query\query_fields_cursor.h">
+ <Filter>Code\cache\query</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\cache\query\query_fields_row.h">
+ <Filter>Code\cache\query</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\ignite\impl\cache\query\query_fields_row_impl.h">
+ <Filter>Code\impl\cache\query</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\ignite\impl\interop\interop_stream_position_guard.h">
<Filter>Code\impl\interop</Filter>
</ClInclude>
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
index 024e435..05c3e38 100644
--- a/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/cache_impl.cpp
@@ -294,6 +294,11 @@ namespace ignite
return QueryInternal(qry, OP_QRY_SCAN, err);
}
+ QueryCursorImpl* CacheImpl::QuerySqlFields(const SqlFieldsQuery& qry, IgniteError* err)
+ {
+ return QueryInternal(qry, OP_QRY_SQL_FIELDS, err);
+ }
+
int64_t CacheImpl::WriteTo(InteropMemory* mem, InputOperation& inOp, IgniteError* err)
{
PortableMetadataManager* metaMgr = env.Get()->GetMetadataManager();
http://git-wip-us.apache.org/repos/asf/ignite/blob/667c2e65/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
index 7d89321..786779b 100644
--- a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
@@ -16,6 +16,7 @@
*/
#include "ignite/impl/cache/query/query_impl.h"
+#include "ignite/impl/cache/query/query_fields_row_impl.h"
using namespace ignite::common::concurrent;
using namespace ignite::common::java;
@@ -89,8 +90,9 @@ namespace ignite
JniErrorInfo jniErr;
SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
-
- env.Get()->Context()->TargetOutStream(javaRef, OP_GET_SINGLE, inMem.Get()->PointerLong(), &jniErr);
+
+ env.Get()->Context()->TargetOutStream(
+ javaRef, OP_GET_SINGLE, inMem.Get()->PointerLong(), &jniErr);
IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
@@ -113,6 +115,39 @@ namespace ignite
}
}
+ QueryFieldsRowImpl* QueryCursorImpl::GetNextRow(IgniteError* err)
+ {
+ // Create iterator in Java if needed.
+ if (!CreateIteratorIfNeeded(err))
+ return NULL;
+
+ if (hasNext)
+ {
+ JniErrorInfo jniErr;
+
+ SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
+
+ env.Get()->Context()->TargetOutStream(javaRef, OP_GET_SINGLE, inMem.Get()->PointerLong(), &jniErr);
+
+ IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+
+ if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
+ {
+ hasNext = IteratorHasNext(err);
+
+ return new QueryFieldsRowImpl(inMem);
+ }
+ }
+ else
+ {
+ // Ensure we do not overwrite possible previous error.
+ if (err->GetCode() == IgniteError::IGNITE_SUCCESS)
+ *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "No more elements available.");
+ }
+
+ return NULL;
+ }
+
void QueryCursorImpl::GetAll(OutputOperation& op, IgniteError* err)
{
// Check whether any of iterator methods were called.