IGNITE-6337 .NET: Thin client: SQL queries This closes #2832
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0bd712dd Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0bd712dd Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0bd712dd Branch: refs/heads/ignite-zk Commit: 0bd712ddb3df9408b80bf0da6d19480ef737b7bc Parents: 25048f8 Author: Pavel Tupitsyn <ptupit...@apache.org> Authored: Fri Nov 17 17:16:38 2017 +0300 Committer: Pavel Tupitsyn <ptupit...@apache.org> Committed: Fri Nov 17 17:16:38 2017 +0300 ---------------------------------------------------------------------- .../odbc/jdbc/JdbcQueryExecuteRequest.java | 2 +- .../processors/odbc/jdbc/JdbcStatementType.java | 13 + .../platform/cache/PlatformCache.java | 2 +- .../platform/client/ClientMessageParser.java | 34 ++- .../cache/ClientCacheEntryQueryCursor.java | 46 ++++ .../cache/ClientCacheFieldsQueryCursor.java | 53 ++++ .../client/cache/ClientCacheQueryCursor.java | 141 ++++++++++ .../cache/ClientCacheQueryNextPageRequest.java | 49 ++++ .../cache/ClientCacheQueryNextPageResponse.java | 50 ++++ .../client/cache/ClientCacheQueryResponse.java | 52 ++++ .../client/cache/ClientCacheRequest.java | 30 ++- .../cache/ClientCacheScanQueryCursor.java | 135 ---------- .../ClientCacheScanQueryNextPageRequest.java | 49 ---- .../ClientCacheScanQueryNextPageResponse.java | 50 ---- .../cache/ClientCacheScanQueryRequest.java | 5 +- .../cache/ClientCacheScanQueryResponse.java | 52 ---- .../cache/ClientCacheSqlFieldsQueryRequest.java | 126 +++++++++ .../ClientCacheSqlFieldsQueryResponse.java | 75 ++++++ .../cache/ClientCacheSqlQueryRequest.java | 79 ++++++ .../Apache.Ignite.Core.Tests.csproj | 1 + .../Client/Cache/CacheTestNoMeta.cs | 11 +- .../Client/Cache/Person.cs | 29 ++ .../Client/Cache/SqlQueryTest.cs | 268 +++++++++++++++++++ .../Client/ClientTestBase.cs | 11 +- .../Apache.Ignite.Core.csproj | 4 + .../Cache/Query/IFieldsQueryCursor.cs | 34 +++ .../Client/Cache/ICacheClient.cs | 14 + .../Impl/Cache/Query/FieldsQueryCursor.cs | 29 +- .../Impl/Cache/Query/PlatformQueryQursorBase.cs | 8 +- .../Impl/Cache/Query/QueryCursor.cs | 16 +- .../Impl/Cache/Query/QueryCursorBase.cs | 22 +- .../Impl/Client/Cache/CacheClient.cs | 80 +++++- .../Cache/Query/ClientFieldsQueryCursor.cs | 79 ++++++ .../Client/Cache/Query/ClientQueryCursor.cs | 62 +---- .../Client/Cache/Query/ClientQueryCursorBase.cs | 89 ++++++ .../Impl/Client/Cache/Query/StatementType.cs | 42 +++ .../Apache.Ignite.Core/Impl/Client/ClientOp.cs | 6 +- 37 files changed, 1428 insertions(+), 420 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java index 1c6262e..3e54fc8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQueryExecuteRequest.java @@ -156,7 +156,7 @@ public class JdbcQueryExecuteRequest extends JdbcRequest { try { if (reader.available() > 0) - stmtType = JdbcStatementType.values()[reader.readByte()]; + stmtType = JdbcStatementType.fromOrdinal(reader.readByte()); else stmtType = JdbcStatementType.ANY_STATEMENT_TYPE; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java index aec2d12..ebe303f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcStatementType.java @@ -29,4 +29,17 @@ public enum JdbcStatementType { /** DML / DDL statement type. */ UPDATE_STMT_TYPE; + + /** Enumerated values. */ + private static final JdbcStatementType[] VALS = values(); + + /** + * Efficiently gets enumerated value from its ordinal. + * + * @param ord Ordinal value. + * @return Enumerated value or {@code null} if ordinal out of range. + */ + public static JdbcStatementType fromOrdinal(int ord) { + return ord >= 0 && ord < VALS.length ? VALS[ord] : null; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java index 0e227f5..bbdd6d2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cache/PlatformCache.java @@ -930,7 +930,7 @@ public class PlatformCache extends PlatformAbstractTarget { * @param reader Reader. * @return Arguments. */ - @Nullable private Object[] readQueryArgs(BinaryRawReaderEx reader) { + @Nullable public static Object[] readQueryArgs(BinaryRawReaderEx reader) { int cnt = reader.readInt(); if (cnt > 0) { http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java index 4ad6a90..626b7ff 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/ClientMessageParser.java @@ -54,14 +54,16 @@ import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheGe import org.apache.ignite.internal.processors.platform.client.cache.ClientCachePutAllRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCachePutIfAbsentRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCachePutRequest; -import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveIfEqualsRequest; +import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheQueryNextPageRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveAllRequest; -import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveKeysRequest; +import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveIfEqualsRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveKeyRequest; +import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheRemoveKeysRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheReplaceIfEqualsRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheReplaceRequest; -import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheScanQueryNextPageRequest; import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheScanQueryRequest; +import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheSqlFieldsQueryRequest; +import org.apache.ignite.internal.processors.platform.client.cache.ClientCacheSqlQueryRequest; /** * Thin client message parser. @@ -172,6 +174,18 @@ public class ClientMessageParser implements ClientListenerMessageParser { /** */ private static final short OP_CACHE_GET_OR_CREATE_WITH_CONFIGURATION = 35; + /** */ + private static final short OP_QUERY_SQL = 36; + + /** */ + private static final short OP_QUERY_SQL_CURSOR_GET_PAGE = 37; + + /** */ + private static final short OP_QUERY_SQL_FIELDS = 38; + + /** */ + private static final short OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE = 39; + /** Marshaller. */ private final GridBinaryMarshaller marsh; @@ -229,7 +243,7 @@ public class ClientMessageParser implements ClientListenerMessageParser { return new ClientCacheScanQueryRequest(reader); case OP_QUERY_SCAN_CURSOR_GET_PAGE: - return new ClientCacheScanQueryNextPageRequest(reader); + return new ClientCacheQueryNextPageRequest(reader); case OP_RESOURCE_CLOSE: return new ClientResourceCloseRequest(reader); @@ -311,6 +325,18 @@ public class ClientMessageParser implements ClientListenerMessageParser { case OP_CACHE_GET_OR_CREATE_WITH_CONFIGURATION: return new ClientCacheGetOrCreateWithConfigurationRequest(reader); + + case OP_QUERY_SQL: + return new ClientCacheSqlQueryRequest(reader); + + case OP_QUERY_SQL_CURSOR_GET_PAGE: + return new ClientCacheQueryNextPageRequest(reader); + + case OP_QUERY_SQL_FIELDS: + return new ClientCacheSqlFieldsQueryRequest(reader); + + case OP_QUERY_SQL_FIELDS_CURSOR_GET_PAGE: + return new ClientCacheQueryNextPageRequest(reader); } return new ClientRawRequest(reader.readLong(), ClientStatus.INVALID_OP_CODE, http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheEntryQueryCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheEntryQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheEntryQueryCursor.java new file mode 100644 index 0000000..5269342 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheEntryQueryCursor.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; + +import javax.cache.Cache; + +/** + * Query cursor holder. + */ +class ClientCacheEntryQueryCursor extends ClientCacheQueryCursor<Cache.Entry> { + /** + * Ctor. + * + * @param cursor Cursor. + * @param pageSize Page size. + * @param ctx Context. + */ + ClientCacheEntryQueryCursor(QueryCursor<Cache.Entry> cursor, int pageSize, ClientConnectionContext ctx) { + super(cursor, pageSize, ctx); + } + + /** {@inheritDoc} */ + @Override void writeEntry(BinaryRawWriterEx writer, Cache.Entry e) { + writer.writeObjectDetached(e.getKey()); + writer.writeObjectDetached(e.getValue()); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheFieldsQueryCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheFieldsQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheFieldsQueryCursor.java new file mode 100644 index 0000000..98b747b --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheFieldsQueryCursor.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.cache.query.FieldsQueryCursor; +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; + +import java.util.List; + +/** + * Query cursor holder. + */ +class ClientCacheFieldsQueryCursor extends ClientCacheQueryCursor<List> { + /** Column count. */ + private final int columnCount; + + /** + * Ctor. + * + * @param cursor Cursor. + * @param pageSize Page size. + * @param ctx Context. + */ + ClientCacheFieldsQueryCursor(FieldsQueryCursor<List> cursor, int pageSize, ClientConnectionContext ctx) { + super(cursor, pageSize, ctx); + + columnCount = cursor.getColumnsCount(); + } + + /** {@inheritDoc} */ + @Override void writeEntry(BinaryRawWriterEx writer, List e) { + assert e.size() == columnCount; + + for (Object o : e) + writer.writeObjectDetached(o); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryCursor.java new file mode 100644 index 0000000..080ab74 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryCursor.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientCloseableResource; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; + +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Base query cursor holder. + */ +abstract class ClientCacheQueryCursor<T> implements ClientCloseableResource { + /** Cursor. */ + private final QueryCursor<T> cursor; + + /** Page size. */ + private final int pageSize; + + /** Context. */ + private final ClientConnectionContext ctx; + + /** Id. */ + private long id; + + /** Iterator. */ + private Iterator<T> iterator; + + /** Close guard. */ + private final AtomicBoolean closeGuard = new AtomicBoolean(); + + /** + * Ctor. + * @param cursor Cursor. + * @param pageSize Page size. + * @param ctx Context. + */ + ClientCacheQueryCursor(QueryCursor<T> cursor, int pageSize, ClientConnectionContext ctx) { + assert cursor != null; + assert pageSize > 0; + assert ctx != null; + + this.cursor = cursor; + this.pageSize = pageSize; + this.ctx = ctx; + } + + /** + * Writes next page to the writer. + * + * @param writer Writer. + */ + void writePage(BinaryRawWriterEx writer) { + Iterator<T> iter = iterator(); + + int cntPos = writer.reserveInt(); + int cnt = 0; + + while (cnt < pageSize && iter.hasNext()) { + T e = iter.next(); + + writeEntry(writer, e); + + cnt++; + } + + writer.writeInt(cntPos, cnt); + + writer.writeBoolean(iter.hasNext()); + + if (!iter.hasNext()) + ctx.resources().release(id); + } + + /** + * Writes cursor entry. + * + * @param writer Writer. + * @param e Entry. + */ + abstract void writeEntry(BinaryRawWriterEx writer, T e); + + /** + * Closes the cursor. + */ + @Override public void close() { + if (closeGuard.compareAndSet(false, true)) { + cursor.close(); + + ctx.decrementCursors(); + } + } + + /** + * Sets the cursor id. + * + * @param id Id. + */ + public void id(long id) { + this.id = id; + } + + /** + * Gets the cursor id. + * + * @return Id. + */ + public long id() { + return id; + } + + /** + * Gets the iterator. + * + * @return Iterator. + */ + private Iterator<T> iterator() { + if (iterator == null) + iterator = cursor.iterator(); + + return iterator; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageRequest.java new file mode 100644 index 0000000..a6aa799 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageRequest.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.binary.BinaryRawReader; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; +import org.apache.ignite.internal.processors.platform.client.ClientRequest; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; + +/** + * Query cursor next page request. + */ +public class ClientCacheQueryNextPageRequest extends ClientRequest { + /** Cursor id. */ + private final long cursorId; + + /** + * Ctor. + * + * @param reader Reader. + */ + public ClientCacheQueryNextPageRequest(BinaryRawReader reader) { + super(reader); + + cursorId = reader.readLong(); + } + + /** {@inheritDoc} */ + @Override public ClientResponse process(ClientConnectionContext ctx) { + ClientCacheQueryCursor cur = ctx.resources().get(cursorId); + + return new ClientCacheQueryNextPageResponse(requestId(), cur); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageResponse.java new file mode 100644 index 0000000..af81ac5 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryNextPageResponse.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; + +/** + * Query cursor next page response. + */ +class ClientCacheQueryNextPageResponse extends ClientResponse { + /** Cursor. */ + private final ClientCacheQueryCursor cursor; + + /** + * Ctor. + * + * @param requestId Request id. + * @param cursor Cursor. + */ + ClientCacheQueryNextPageResponse(long requestId, ClientCacheQueryCursor cursor) { + super(requestId); + + assert cursor != null; + + this.cursor = cursor; + } + + /** {@inheritDoc} */ + @Override public void encode(BinaryRawWriterEx writer) { + super.encode(writer); + + cursor.writePage(writer); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryResponse.java new file mode 100644 index 0000000..ab76387 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheQueryResponse.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; + +/** + * Scan query response. + */ +class ClientCacheQueryResponse extends ClientResponse { + /** Cursor. */ + private final ClientCacheQueryCursor cursor; + + /** + * Ctor. + * + * @param requestId Request id. + * @param cursor Cursor. + */ + ClientCacheQueryResponse(long requestId, ClientCacheQueryCursor cursor) { + super(requestId); + + assert cursor != null; + + this.cursor = cursor; + } + + /** {@inheritDoc} */ + @Override public void encode(BinaryRawWriterEx writer) { + super.encode(writer); + + writer.writeLong(cursor.id()); + + cursor.writePage(writer); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java index b290a5b..44416be 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheRequest.java @@ -77,14 +77,34 @@ class ClientCacheRequest extends ClientRequest { * @return Cache. */ protected IgniteCache rawCache(ClientConnectionContext ctx) { - DynamicCacheDescriptor cacheDesc = ctx.kernalContext().cache().cacheDescriptor(cacheId); - - if (cacheDesc == null) - throw new IgniteClientException(ClientStatus.CACHE_DOES_NOT_EXIST, "Cache does not exist [cacheId= " + - cacheId + "]", null); + DynamicCacheDescriptor cacheDesc = cacheDescriptor(ctx); String cacheName = cacheDesc.cacheName(); return ctx.kernalContext().grid().cache(cacheName); } + + /** + * Gets the cache descriptor. + * + * @return Cache descriptor. + */ + protected DynamicCacheDescriptor cacheDescriptor(ClientConnectionContext ctx) { + DynamicCacheDescriptor desc = ctx.kernalContext().cache().cacheDescriptor(cacheId); + + if (desc == null) + throw new IgniteClientException(ClientStatus.CACHE_DOES_NOT_EXIST, "Cache does not exist [cacheId= " + + cacheId + "]", null); + + return desc; + } + + /** + * Gets the cache id. + * + * @return Cache id. + */ + protected int cacheId() { + return cacheId; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryCursor.java deleted file mode 100644 index 9d3d158..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryCursor.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.platform.client.cache; - -import org.apache.ignite.internal.binary.BinaryRawWriterEx; -import org.apache.ignite.internal.processors.cache.query.QueryCursorEx; -import org.apache.ignite.internal.processors.platform.client.ClientCloseableResource; -import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; - -import javax.cache.Cache; -import java.util.Iterator; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Query cursor holder. - */ -class ClientCacheScanQueryCursor implements ClientCloseableResource { - /** Cursor. */ - private final QueryCursorEx<Cache.Entry> cursor; - - /** Page size. */ - private final int pageSize; - - /** Context. */ - private final ClientConnectionContext ctx; - - /** Id. */ - private long id; - - /** Iterator. */ - private Iterator<Cache.Entry> iterator; - - /** Close guard. */ - private final AtomicBoolean closeGuard = new AtomicBoolean(); - - /** - * Ctor. - * @param cursor Cursor. - * @param pageSize Page size. - * @param ctx Context. - */ - ClientCacheScanQueryCursor(QueryCursorEx<Cache.Entry> cursor, int pageSize, ClientConnectionContext ctx) { - assert cursor != null; - assert pageSize > 0; - assert ctx != null; - - this.cursor = cursor; - this.pageSize = pageSize; - this.ctx = ctx; - } - - /** - * Writes next page to the writer. - * - * @param writer Writer. - */ - void writePage(BinaryRawWriterEx writer) { - Iterator<Cache.Entry> iter = iterator(); - - int cntPos = writer.reserveInt(); - int cnt = 0; - - while (cnt < pageSize && iter.hasNext()) { - Cache.Entry e = iter.next(); - - writer.writeObjectDetached(e.getKey()); - writer.writeObjectDetached(e.getValue()); - - cnt++; - } - - writer.writeInt(cntPos, cnt); - - writer.writeBoolean(iter.hasNext()); - - if (!iter.hasNext()) - ctx.resources().release(id); - } - - /** - * Closes the cursor. - */ - @Override public void close() { - if (closeGuard.compareAndSet(false, true)) { - cursor.close(); - - ctx.decrementCursors(); - } - } - - /** - * Sets the cursor id. - * - * @param id Id. - */ - public void id(long id) { - this.id = id; - } - - /** - * Gets the cursor id. - * - * @return Id. - */ - public long id() { - return id; - } - - /** - * Gets the iterator. - * - * @return Iterator. - */ - private Iterator<Cache.Entry> iterator() { - if (iterator == null) - iterator = cursor.iterator(); - - return iterator; - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageRequest.java deleted file mode 100644 index a9620d2..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageRequest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.platform.client.cache; - -import org.apache.ignite.binary.BinaryRawReader; -import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; -import org.apache.ignite.internal.processors.platform.client.ClientRequest; -import org.apache.ignite.internal.processors.platform.client.ClientResponse; - -/** - * Query cursor next page request. - */ -public class ClientCacheScanQueryNextPageRequest extends ClientRequest { - /** Cursor id. */ - private final long cursorId; - - /** - * Ctor. - * - * @param reader Reader. - */ - public ClientCacheScanQueryNextPageRequest(BinaryRawReader reader) { - super(reader); - - cursorId = reader.readLong(); - } - - /** {@inheritDoc} */ - @Override public ClientResponse process(ClientConnectionContext ctx) { - ClientCacheScanQueryCursor cur = ctx.resources().get(cursorId); - - return new ClientCacheScanQueryNextPageResponse(requestId(), cur); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageResponse.java deleted file mode 100644 index e4ffe6d..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryNextPageResponse.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.platform.client.cache; - -import org.apache.ignite.internal.binary.BinaryRawWriterEx; -import org.apache.ignite.internal.processors.platform.client.ClientResponse; - -/** - * Query cursor next page response. - */ -class ClientCacheScanQueryNextPageResponse extends ClientResponse { - /** Cursor. */ - private final ClientCacheScanQueryCursor cursor; - - /** - * Ctor. - * - * @param requestId Request id. - * @param cursor Cursor. - */ - ClientCacheScanQueryNextPageResponse(long requestId, ClientCacheScanQueryCursor cursor) { - super(requestId); - - assert cursor != null; - - this.cursor = cursor; - } - - /** {@inheritDoc} */ - @Override public void encode(BinaryRawWriterEx writer) { - super.encode(writer); - - cursor.writePage(writer); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryRequest.java index 7c163e3..26ab236 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryRequest.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryRequest.java @@ -23,7 +23,6 @@ import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.cache.query.QueryCursor; import org.apache.ignite.cache.query.ScanQuery; import org.apache.ignite.internal.binary.BinaryRawReaderEx; -import org.apache.ignite.internal.processors.cache.query.QueryCursorEx; import org.apache.ignite.internal.processors.platform.PlatformContext; import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; import org.apache.ignite.internal.processors.platform.client.ClientResponse; @@ -94,13 +93,13 @@ public class ClientCacheScanQueryRequest extends ClientCacheRequest { try { QueryCursor cur = cache.query(qry); - ClientCacheScanQueryCursor cliCur = new ClientCacheScanQueryCursor((QueryCursorEx)cur, pageSize, ctx); + ClientCacheEntryQueryCursor cliCur = new ClientCacheEntryQueryCursor(cur, pageSize, ctx); long cursorId = ctx.resources().put(cliCur); cliCur.id(cursorId); - return new ClientCacheScanQueryResponse(requestId(), cliCur); + return new ClientCacheQueryResponse(requestId(), cliCur); } catch (Exception e) { ctx.decrementCursors(); http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryResponse.java deleted file mode 100644 index 0623804..0000000 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheScanQueryResponse.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.ignite.internal.processors.platform.client.cache; - -import org.apache.ignite.internal.binary.BinaryRawWriterEx; -import org.apache.ignite.internal.processors.platform.client.ClientResponse; - -/** - * Scan query response. - */ -class ClientCacheScanQueryResponse extends ClientResponse { - /** Cursor. */ - private final ClientCacheScanQueryCursor cursor; - - /** - * Ctor. - * - * @param requestId Request id. - * @param cursor Cursor. - */ - ClientCacheScanQueryResponse(long requestId, ClientCacheScanQueryCursor cursor) { - super(requestId); - - assert cursor != null; - - this.cursor = cursor; - } - - /** {@inheritDoc} */ - @Override public void encode(BinaryRawWriterEx writer) { - super.encode(writer); - - writer.writeLong(cursor.id()); - - cursor.writePage(writer); - } -} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java new file mode 100644 index 0000000..ca3595d --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryRequest.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.cache.query.FieldsQueryCursor; +import org.apache.ignite.cache.query.SqlFieldsQuery; +import org.apache.ignite.internal.binary.BinaryRawReaderEx; +import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor; +import org.apache.ignite.internal.processors.cache.query.SqlFieldsQueryEx; +import org.apache.ignite.internal.processors.odbc.jdbc.JdbcStatementType; +import org.apache.ignite.internal.processors.platform.cache.PlatformCache; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; +import org.apache.ignite.internal.processors.query.QueryUtils; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Sql query request. + */ +@SuppressWarnings("unchecked") +public class ClientCacheSqlFieldsQueryRequest extends ClientCacheRequest { + /** Query. */ + private final SqlFieldsQuery qry; + + /** Include field names flag. */ + private final boolean includeFieldNames; + + /** + * Ctor. + * + * @param reader Reader. + */ + public ClientCacheSqlFieldsQueryRequest(BinaryRawReaderEx reader) { + super(reader); + + // Same request format as in JdbcQueryExecuteRequest. + String schema = reader.readString(); + int pageSize = reader.readInt(); + reader.readInt(); // maxRows + String sql = reader.readString(); + Object[] args = PlatformCache.readQueryArgs(reader); + JdbcStatementType stmtType = JdbcStatementType.fromOrdinal(reader.readByte()); + boolean distributedJoins = reader.readBoolean(); + boolean loc = reader.readBoolean(); + boolean replicatedOnly = reader.readBoolean(); + boolean enforceJoinOrder = reader.readBoolean(); + boolean collocated = reader.readBoolean(); + boolean lazy = reader.readBoolean(); + int timeout = (int) reader.readLong(); + includeFieldNames = reader.readBoolean(); + + SqlFieldsQuery qry = stmtType == JdbcStatementType.ANY_STATEMENT_TYPE + ? new SqlFieldsQuery(sql) + : new SqlFieldsQueryEx(sql,stmtType == JdbcStatementType.SELECT_STATEMENT_TYPE); + + qry.setSchema(schema) + .setPageSize(pageSize) + .setArgs(args) + .setDistributedJoins(distributedJoins) + .setLocal(loc) + .setReplicatedOnly(replicatedOnly) + .setEnforceJoinOrder(enforceJoinOrder) + .setCollocated(collocated) + .setLazy(lazy) + .setTimeout(timeout, TimeUnit.MILLISECONDS); + + this.qry = qry; + } + + /** {@inheritDoc} */ + @Override public ClientResponse process(ClientConnectionContext ctx) { + ctx.incrementCursors(); + + try { + // If cacheId is provided, we must check the cache for existence. + if (cacheId() != 0) { + DynamicCacheDescriptor desc = cacheDescriptor(ctx); + + if (qry.getSchema() == null) { + String schema = QueryUtils.normalizeSchemaName(desc.cacheName(), + desc.cacheConfiguration().getSqlSchema()); + + qry.setSchema(schema); + } + } + + List<FieldsQueryCursor<List<?>>> curs = ctx.kernalContext().query() + .querySqlFieldsNoCache(qry, true, true); + + assert curs.size() == 1; + + FieldsQueryCursor cur = curs.get(0); + + ClientCacheFieldsQueryCursor cliCur = new ClientCacheFieldsQueryCursor( + cur, qry.getPageSize(), ctx); + + long cursorId = ctx.resources().put(cliCur); + + cliCur.id(cursorId); + + return new ClientCacheSqlFieldsQueryResponse(requestId(), cliCur, cur, includeFieldNames); + } + catch (Exception e) { + ctx.decrementCursors(); + + throw e; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryResponse.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryResponse.java new file mode 100644 index 0000000..1ff2ea5 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlFieldsQueryResponse.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.cache.query.FieldsQueryCursor; +import org.apache.ignite.internal.binary.BinaryRawWriterEx; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; + +import java.util.List; + +/** + * Scan query response. + */ +class ClientCacheSqlFieldsQueryResponse extends ClientResponse { + /** Cursor. */ + private final ClientCacheQueryCursor cursor; + + /** Fields cursor. */ + private final FieldsQueryCursor<List> fieldsCursor; + + /** Include field names flag. */ + private final boolean includeFieldNames; + + /** + * Ctor. + * @param requestId Request id. + * @param cursor Client cursor. + * @param fieldsCursor Fields cursor. + * @param includeFieldNames Whether to include field names. + */ + ClientCacheSqlFieldsQueryResponse(long requestId, ClientCacheQueryCursor cursor, + FieldsQueryCursor<List> fieldsCursor, boolean includeFieldNames) { + super(requestId); + + assert cursor != null; + assert fieldsCursor != null; + + this.cursor = cursor; + this.fieldsCursor = fieldsCursor; + this.includeFieldNames = includeFieldNames; + } + + /** {@inheritDoc} */ + @Override public void encode(BinaryRawWriterEx writer) { + super.encode(writer); + + writer.writeLong(cursor.id()); + + int cnt = fieldsCursor.getColumnsCount(); + writer.writeInt(cnt); + + if (includeFieldNames) { + for (int i = 0; i < cnt; i++) { + writer.writeString(fieldsCursor.getFieldName(i)); + } + } + + cursor.writePage(writer); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlQueryRequest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlQueryRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlQueryRequest.java new file mode 100644 index 0000000..8c21be1 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/client/cache/ClientCacheSqlQueryRequest.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.platform.client.cache; + +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.cache.query.SqlQuery; +import org.apache.ignite.internal.binary.BinaryRawReaderEx; +import org.apache.ignite.internal.processors.platform.cache.PlatformCache; +import org.apache.ignite.internal.processors.platform.client.ClientConnectionContext; +import org.apache.ignite.internal.processors.platform.client.ClientResponse; + +import java.util.concurrent.TimeUnit; + +/** + * Sql query request. + */ +@SuppressWarnings("unchecked") +public class ClientCacheSqlQueryRequest extends ClientCacheRequest { + /** Query. */ + private final SqlQuery qry; + + /** + * Ctor. + * + * @param reader Reader. + */ + public ClientCacheSqlQueryRequest(BinaryRawReaderEx reader) { + super(reader); + + qry = new SqlQuery(reader.readString(), reader.readString()) + .setArgs(PlatformCache.readQueryArgs(reader)) + .setDistributedJoins(reader.readBoolean()) + .setLocal(reader.readBoolean()) + .setReplicatedOnly(reader.readBoolean()) + .setPageSize(reader.readInt()) + .setTimeout((int) reader.readLong(), TimeUnit.MILLISECONDS); + } + + /** {@inheritDoc} */ + @Override public ClientResponse process(ClientConnectionContext ctx) { + IgniteCache cache = cache(ctx); + + ctx.incrementCursors(); + + try { + QueryCursor cur = cache.query(qry); + + ClientCacheEntryQueryCursor cliCur = new ClientCacheEntryQueryCursor( + cur, qry.getPageSize(), ctx); + + long cursorId = ctx.resources().put(cliCur); + + cliCur.id(cursorId); + + return new ClientCacheQueryResponse(requestId(), cliCur); + } + catch (Exception e) { + ctx.decrementCursors(); + + throw e; + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj index 2e34ba2..2d5a54b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj @@ -112,6 +112,7 @@ <Compile Include="Client\Cache\CreateCacheTest.cs" /> <Compile Include="Client\Cache\ScanQueryTest.cs" /> <Compile Include="Client\Cache\Person.cs" /> + <Compile Include="Client\Cache\SqlQueryTest.cs" /> <Compile Include="Client\ClientTestBase.cs" /> <Compile Include="Client\RawSocketTest.cs" /> <Compile Include="Client\ClientConnectionTest.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTestNoMeta.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTestNoMeta.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTestNoMeta.cs index 782e3cc..a2ca65d 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTestNoMeta.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/CacheTestNoMeta.cs @@ -52,16 +52,7 @@ namespace Apache.Ignite.Core.Tests.Client.Cache using (var client = Ignition.StartClient(cfg)) { var serverCache = Ignition.GetIgnite().GetOrCreateCache<int?, Person>( - new CacheConfiguration("person", new QueryEntity - { - KeyType = typeof(int), - ValueType = typeof(Person), - Fields = new[] - { - new QueryField("id", typeof(int)), - new QueryField("name", typeof(string)) - } - })); + new CacheConfiguration("person", typeof(Person))); var clientCache = client.GetCache<int?, Person>(serverCache.Name); http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/Person.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/Person.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/Person.cs index a6bc9d7..327e707 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/Person.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/Person.cs @@ -17,22 +17,51 @@ namespace Apache.Ignite.Core.Tests.Client.Cache { + using System; + using Apache.Ignite.Core.Cache.Configuration; + /// <summary> /// Test person. /// </summary> public class Person { /// <summary> + /// Initializes a new instance of the <see cref="Person"/> class. + /// </summary> + public Person() + { + DateTime = DateTime.UtcNow; + } + + /// <summary> + /// Initializes a new instance of the <see cref="Person"/> class. + /// </summary> + public Person(int id) + { + Id = id; + Name = "Person " + id; + DateTime = DateTime.UtcNow.AddDays(id); + } + + /// <summary> /// Gets or sets the identifier. /// </summary> + [QuerySqlField(IsIndexed = true)] public int Id { get; set; } /// <summary> /// Gets or sets the name. /// </summary> + [QuerySqlField] public string Name { get; set; } /// <summary> + /// Gets or sets the date time. + /// </summary> + [QuerySqlField] + public DateTime DateTime { get; set; } + + /// <summary> /// Gets or sets the parent. /// </summary> public Person Parent { get;set; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs new file mode 100644 index 0000000..720a71b --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/SqlQueryTest.cs @@ -0,0 +1,268 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Tests.Client.Cache +{ + using System; + using System.Linq; + using Apache.Ignite.Core.Cache.Configuration; + using Apache.Ignite.Core.Cache.Query; + using Apache.Ignite.Core.Client; + using NUnit.Framework; + + /// <summary> + /// Tests SQL queries via thin client. + /// </summary> + public class SqlQueryTest : ClientTestBase + { + /// <summary> + /// Cache item count. + /// </summary> + private const int Count = 10; + + /// <summary> + /// Second cache name. + /// </summary> + private const string CacheName2 = CacheName + "2"; + + /// <summary> + /// Initializes a new instance of the <see cref="ScanQueryTest"/> class. + /// </summary> + public SqlQueryTest() : base(2) + { + // No-op. + } + + /// <summary> + /// Sets up the test. + /// </summary> + public override void TestSetUp() + { + InitCache(CacheName); + InitCache(CacheName2); + } + + /// <summary> + /// Tests the SQL query. + /// </summary> + [Test] + public void TestSqlQuery() + { + var cache = GetClientCache<Person>(); + + // All items. + var qry = new SqlQuery(typeof(Person), "where 1 = 1"); + Assert.AreEqual(Count, cache.Query(qry).Count()); + + // All items local. + qry.Local = true; + Assert.Greater(Count, cache.Query(qry).Count()); + + // Filter. + qry = new SqlQuery(typeof(Person), "where Name like '%7'"); + Assert.AreEqual(7, cache.Query(qry).Single().Key); + + // Args. + qry = new SqlQuery(typeof(Person), "where Id = ?", 3); + Assert.AreEqual(3, cache.Query(qry).Single().Value.Id); + + // DateTime. + qry = new SqlQuery(typeof(Person), "where DateTime > ?", DateTime.UtcNow.AddDays(Count - 1)); + Assert.AreEqual(Count, cache.Query(qry).Single().Key); + + // Invalid args. + qry.Sql = null; + Assert.Throws<ArgumentNullException>(() => cache.Query(qry)); + + qry.Sql = "abc"; + qry.QueryType = null; + Assert.Throws<ArgumentNullException>(() => cache.Query(qry)); + } + + /// <summary> + /// Tests the SQL query with distributed joins. + /// </summary> + [Test] + public void TestSqlQueryDistributedJoins() + { + var cache = GetClientCache<Person>(); + + // Non-distributed join returns incomplete results. + var qry = new SqlQuery(typeof(Person), + string.Format("from \"{0}\".Person, \"{1}\".Person as p2 where Person.Id = 11 - p2.Id", + CacheName, CacheName2)); + + Assert.Greater(Count, cache.Query(qry).Count()); + + // Distributed join fixes the problem. + qry.EnableDistributedJoins = true; + Assert.AreEqual(Count, cache.Query(qry).Count()); + } + + /// <summary> + /// Tests the fields query. + /// </summary> + [Test] + public void TestFieldsQuery() + { + var cache = GetClientCache<Person>(); + + // All items. + var qry = new SqlFieldsQuery("select Id from Person"); + var cursor = cache.Query(qry); + CollectionAssert.AreEquivalent(Enumerable.Range(1, Count), cursor.Select(x => (int) x[0])); + Assert.AreEqual("ID", cursor.FieldNames.Single()); + + // All items local. + // TODO: IGNITE-5571 - exception should be fixed. + qry.Local = true; + Assert.Throws<IgniteClientException>(() => Assert.Greater(Count, cache.Query(qry).Count())); + + // Filter. + qry = new SqlFieldsQuery("select Name from Person where Id = ?", 1) + { + Lazy = true, + PageSize = 5, + }; + Assert.AreEqual("Person 1", cache.Query(qry).Single().Single()); + + // DateTime. + qry = new SqlFieldsQuery("select Id, DateTime from Person where DateTime > ?", DateTime.UtcNow.AddDays(9)); + Assert.AreEqual(cache[Count].DateTime, cache.Query(qry).Single().Last()); + + // Invalid args. + qry.Sql = null; + Assert.Throws<ArgumentNullException>(() => cache.Query(qry)); + } + + /// <summary> + /// Tests the SQL fields query with distributed joins. + /// </summary> + [Test] + public void TestFieldsQueryDistributedJoins() + { + var cache = GetClientCache<Person>(); + + // Non-distributed join returns incomplete results. + var qry = new SqlFieldsQuery(string.Format( + "select p2.Name from \"{0}\".Person, \"{1}\".Person as p2 where Person.Id = 11 - p2.Id", + CacheName, CacheName2)); + + Assert.Greater(Count, cache.Query(qry).Count()); + + // Distributed join fixes the problem. + qry.EnableDistributedJoins = true; + Assert.AreEqual(Count, cache.Query(qry).Count()); + } + + /// <summary> + /// Tests the fields query timeout. + /// </summary> + [Test] + public void TestFieldsQueryTimeout() + { + var cache = GetClientCache<Person>(); + + cache.PutAll(Enumerable.Range(1, 30000).ToDictionary(x => x, x => new Person(x))); + + var qry = new SqlFieldsQuery("select * from Person where Name like '%ers%'") + { + Timeout = TimeSpan.FromMilliseconds(1) + }; + + Assert.Throws<IgniteClientException>(() => cache.Query(qry).GetAll()); + } + + /// <summary> + /// Tests the fields query on a missing cache. + /// </summary> + [Test] + public void TestFieldsQueryMissingCache() + { + var cache = Client.GetCache<int, Person>("I do not exist"); + var qry = new SqlFieldsQuery("select name from person") + { + Schema = CacheName + }; + + // Schema is set => we still check for cache existence. + var ex = Assert.Throws<IgniteClientException>(() => cache.Query(qry).GetAll()); + Assert.AreEqual("Cache doesn't exist: I do not exist", ex.Message); + + // Schema not set => also exception. + qry.Schema = null; + ex = Assert.Throws<IgniteClientException>(() => cache.Query(qry).GetAll()); + Assert.AreEqual("Cache doesn't exist: I do not exist", ex.Message); + } + + /// <summary> + /// Tests fields query with custom schema. + /// </summary> + [Test] + public void TestFieldsQueryCustomSchema() + { + var cache1 = Client.GetCache<int, Person>(CacheName); + var cache2 = Client.GetCache<int, Person>(CacheName2); + + cache1.RemoveAll(); + + var qry = new SqlFieldsQuery("select name from person"); + + // Schema not set: cache name is used. + Assert.AreEqual(0, cache1.Query(qry).Count()); + Assert.AreEqual(Count, cache2.Query(qry).Count()); + + // Schema set to first cache: no results both cases. + qry.Schema = cache1.Name; + Assert.AreEqual(0, cache1.Query(qry).Count()); + Assert.AreEqual(0, cache2.Query(qry).Count()); + + // Schema set to second cache: full results both cases. + qry.Schema = cache2.Name; + Assert.AreEqual(Count, cache1.Query(qry).Count()); + Assert.AreEqual(Count, cache2.Query(qry).Count()); + } + + /// <summary> + /// Tests the DML. + /// </summary> + [Test] + public void TestDml() + { + var cache = GetClientCache<Person>(); + + var qry = new SqlFieldsQuery("insert into Person (_key, id, name) values (?, ?, ?)", -10, 1, "baz"); + var res = cache.Query(qry).GetAll(); + + Assert.AreEqual(1, res[0][0]); + Assert.AreEqual("baz", cache[-10].Name); + } + + /// <summary> + /// Initializes the cache. + /// </summary> + private static void InitCache(string cacheName) + { + var cache = Ignition.GetIgnite().GetOrCreateCache<int, Person>( + new CacheConfiguration(cacheName, new QueryEntity(typeof(int), typeof(Person)))); + + cache.RemoveAll(); + + cache.PutAll(Enumerable.Range(1, Count).ToDictionary(x => x, x => new Person(x))); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs index 9b7a566..e1d30b9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs @@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.Tests.Client using System.Net; using Apache.Ignite.Core.Cache; using Apache.Ignite.Core.Client; + using Apache.Ignite.Core.Client.Cache; using NUnit.Framework; /// <summary> @@ -81,7 +82,7 @@ namespace Apache.Ignite.Core.Tests.Client /// Sets up the test. /// </summary> [SetUp] - public void TestSetUp() + public virtual void TestSetUp() { GetCache<int>().RemoveAll(); } @@ -100,6 +101,14 @@ namespace Apache.Ignite.Core.Tests.Client } /// <summary> + /// Gets the client cache. + /// </summary> + protected ICacheClient<int, T> GetClientCache<T>() + { + return Client.GetCache<int, T>(CacheName); + } + + /// <summary> /// Gets the client. /// </summary> protected IIgniteClient GetClient() http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index 0076d47..21738a2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -104,6 +104,7 @@ <Compile Include="Cache\Configuration\MemoryPolicyConfiguration.cs" /> <Compile Include="Cache\Configuration\PartitionLossPolicy.cs" /> <Compile Include="Cache\IMemoryMetrics.cs" /> + <Compile Include="Cache\Query\IFieldsQueryCursor.cs" /> <Compile Include="Client\Cache\ICacheClient.cs" /> <Compile Include="Client\IgniteClientConfiguration.cs" /> <Compile Include="Client\IgniteClientException.cs" /> @@ -121,10 +122,13 @@ <Compile Include="Impl\Binary\MultidimensionalArraySerializer.cs" /> <Compile Include="Impl\Client\Cache\CacheFlags.cs" /> <Compile Include="Impl\Client\Cache\ClientCacheConfigurationSerializer.cs" /> + <Compile Include="Impl\Client\Cache\Query\ClientFieldsQueryCursor.cs" /> <Compile Include="Impl\Client\Cache\Query\ClientQueryCursor.cs" /> <Compile Include="Impl\Cache\Query\PlatformQueryQursorBase.cs" /> <Compile Include="Impl\Binary\BinaryProcessorClient.cs" /> <Compile Include="Impl\Binary\IBinaryProcessor.cs" /> + <Compile Include="Impl\Client\Cache\Query\ClientQueryCursorBase.cs" /> + <Compile Include="Impl\Client\Cache\Query\StatementType.cs" /> <Compile Include="Impl\Client\ClientStatus.cs" /> <Compile Include="Events\LocalEventListener.cs" /> <Compile Include="Impl\DataStorageMetrics.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/IFieldsQueryCursor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/IFieldsQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/IFieldsQueryCursor.cs new file mode 100644 index 0000000..fbeaf8c --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/IFieldsQueryCursor.cs @@ -0,0 +1,34 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Cache.Query +{ + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + + /// <summary> + /// Fields query cursor. + /// </summary> + [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] + public interface IFieldsQueryCursor : IQueryCursor<IList<object>> + { + /// <summary> + /// Gets the field names. + /// </summary> + IList<string> FieldNames { get; } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs index a3964c6..eb91b0a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs @@ -100,6 +100,20 @@ namespace Apache.Ignite.Core.Client.Cache IQueryCursor<ICacheEntry<TK, TV>> Query(ScanQuery<TK, TV> scanQuery); /// <summary> + /// Executes an SQL query. + /// </summary> + /// <param name="sqlQuery">SQL query.</param> + /// <returns>Query cursor.</returns> + IQueryCursor<ICacheEntry<TK, TV>> Query(SqlQuery sqlQuery); + + /// <summary> + /// Executes an SQL Fields query. + /// </summary> + /// <param name="sqlFieldsQuery">SQL query.</param> + /// <returns>Query cursor.</returns> + IFieldsQueryCursor Query(SqlFieldsQuery sqlFieldsQuery); + + /// <summary> /// Associates the specified value with the specified key in this cache, /// returning an existing value if one existed. /// </summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs index 17dc93b..c60e010 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/FieldsQueryCursor.cs @@ -18,19 +18,13 @@ namespace Apache.Ignite.Core.Impl.Cache.Query { using System; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; using Apache.Ignite.Core.Binary; - using Apache.Ignite.Core.Impl.Binary; /// <summary> /// Cursor for entry-based queries. /// </summary> internal class FieldsQueryCursor<T> : PlatformQueryQursorBase<T> { - /** */ - private readonly Func<IBinaryRawReader, int, T> _readerFunc; - /// <summary> /// Constructor. /// </summary> @@ -39,23 +33,18 @@ namespace Apache.Ignite.Core.Impl.Cache.Query /// <param name="readerFunc">The reader function.</param> public FieldsQueryCursor(IPlatformTargetInternal target, bool keepBinary, Func<IBinaryRawReader, int, T> readerFunc) - : base(target, keepBinary) - { - Debug.Assert(readerFunc != null); - - _readerFunc = readerFunc; - } + : base(target, keepBinary, r => + { + // Reading and skipping row size in bytes. + r.ReadInt(); - /** <inheritdoc /> */ - [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] - protected override T Read(BinaryReader reader) - { - // Reading and skipping row size in bytes. - reader.ReadInt(); + int cnt = r.ReadInt(); - int cnt = reader.ReadInt(); + return readerFunc(r, cnt); - return _readerFunc(reader, cnt); + }) + { + // No-op. } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs index 8a51dab..fc78392 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/PlatformQueryQursorBase.cs @@ -17,7 +17,9 @@ namespace Apache.Ignite.Core.Impl.Cache.Query { + using System; using System.Collections.Generic; + using Apache.Ignite.Core.Impl.Binary; /// <summary> /// Base for platform cursors. @@ -44,8 +46,10 @@ namespace Apache.Ignite.Core.Impl.Cache.Query /// </summary> /// <param name="target">The target.</param> /// <param name="keepBinary">Keep binary flag.</param> - protected PlatformQueryQursorBase(IPlatformTargetInternal target, bool keepBinary) - : base(target.Marshaller, keepBinary) + /// <param name="readFunc"></param> + protected PlatformQueryQursorBase(IPlatformTargetInternal target, bool keepBinary, + Func<BinaryReader, T> readFunc) + : base(target.Marshaller, keepBinary, readFunc) { _target = target; } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursor.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursor.cs index b967d6a..ca773fe 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursor.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursor.cs @@ -17,9 +17,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query { - using System.Diagnostics.CodeAnalysis; using Apache.Ignite.Core.Cache; - using Apache.Ignite.Core.Impl.Binary; /// <summary> /// Cursor for entry-based queries. @@ -31,19 +29,11 @@ namespace Apache.Ignite.Core.Impl.Cache.Query /// </summary> /// <param name="target">Target.</param> /// <param name="keepBinary">Keep poratble flag.</param> - public QueryCursor(IPlatformTargetInternal target, bool keepBinary) : base(target, keepBinary) + public QueryCursor(IPlatformTargetInternal target, bool keepBinary) + : base(target, keepBinary, + r => new CacheEntry<TK, TV>(r.ReadObject<TK>(), r.ReadObject<TV>())) { // No-op. } - - /** <inheritdoc /> */ - [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")] - protected override ICacheEntry<TK, TV> Read(BinaryReader reader) - { - TK key = reader.ReadObject<TK>(); - TV val = reader.ReadObject<TV>(); - - return new CacheEntry<TK, TV>(key, val); - } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/0bd712dd/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs index 216d7ea..c8c02ad 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cache/Query/QueryCursorBase.cs @@ -21,7 +21,6 @@ namespace Apache.Ignite.Core.Impl.Cache.Query using System.Collections; using System.Collections.Generic; using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; using Apache.Ignite.Core.Cache.Query; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Binary.IO; @@ -40,6 +39,9 @@ namespace Apache.Ignite.Core.Impl.Cache.Query /** Marshaller. */ private readonly Marshaller _marsh; + /** Read func. */ + private readonly Func<BinaryReader, T> _readFunc; + /** Wherther "GetAll" was called. */ private bool _getAllCalled; @@ -63,14 +65,15 @@ namespace Apache.Ignite.Core.Impl.Cache.Query /// </summary> /// <param name="marsh">Marshaller.</param> /// <param name="keepBinary">Keep binary flag.</param> + /// <param name="readFunc">The read function.</param> /// <param name="initialBatchStream">Optional stream with initial batch.</param> - [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", - Justification = "ConvertGetBatch calls Read, which does not rely on constructor being run.")] - protected QueryCursorBase(Marshaller marsh, bool keepBinary, IBinaryStream initialBatchStream = null) + protected QueryCursorBase(Marshaller marsh, bool keepBinary, Func<BinaryReader, T> readFunc, + IBinaryStream initialBatchStream = null) { Debug.Assert(marsh != null); _keepBinary = keepBinary; + _readFunc = readFunc; _marsh = marsh; if (initialBatchStream != null) @@ -198,13 +201,6 @@ namespace Apache.Ignite.Core.Impl.Cache.Query protected abstract IList<T> GetAllInternal(); /// <summary> - /// Reads entry from the reader. - /// </summary> - /// <param name="reader">Reader.</param> - /// <returns>Entry.</returns> - protected abstract T Read(BinaryReader reader); - - /// <summary> /// Requests next batch. /// </summary> private void RequestBatch() @@ -233,7 +229,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query var res = new List<T>(size); for (var i = 0; i < size; i++) - res.Add(Read(reader)); + res.Add(_readFunc(reader)); return res; } @@ -259,7 +255,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query for (var i = 0; i < size; i++) { - res[i] = Read(reader); + res[i] = _readFunc(reader); } _hasNext = stream.ReadBool();