You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/09/20 12:48:14 UTC
[16/33] ignite git commit: IGNITE-6244 .NET: Thin client: ScanQuery
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ScanQueryTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ScanQueryTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ScanQueryTest.cs
new file mode 100644
index 0000000..bc1e8ee
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Cache/ScanQueryTest.cs
@@ -0,0 +1,241 @@
+/*
+ * 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.Collections.Generic;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Linq;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Query;
+ using Apache.Ignite.Core.Common;
+ using Apache.Ignite.Core.Configuration;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Tests scan queries.
+ /// </summary>
+ public class ScanQueryTest : ClientTestBase
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ScanQueryTest"/> class.
+ /// </summary>
+ public ScanQueryTest() : base(2)
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ protected override IgniteConfiguration GetIgniteConfiguration()
+ {
+ var cfg = base.GetIgniteConfiguration();
+
+ cfg.SqlConnectorConfiguration = new SqlConnectorConfiguration
+ {
+ MaxOpenCursorsPerConnection = 3
+ };
+
+ return cfg;
+ }
+
+ /// <summary>
+ /// Tests scan query without filter.
+ /// </summary>
+ [Test]
+ [SuppressMessage("ReSharper", "ReturnValueOfPureMethodIsNotUsed")]
+ public void TestNoFilter()
+ {
+ var cache = GetPersonCache();
+
+ Action<IEnumerable<ICacheEntry<int, Person>>> checkResults = e =>
+ {
+ Assert.AreEqual(cache.Select(x => x.Value.Name).OrderBy(x => x).ToArray(),
+ e.Select(x => x.Value.Name).OrderBy(x => x).ToArray());
+ };
+
+ using (var client = GetClient())
+ {
+ var clientCache = client.GetCache<int, Person>(CacheName);
+
+ var query = new ScanQuery<int, Person>();
+
+ // GetAll.
+ var cursor = clientCache.Query(query);
+ checkResults(cursor.GetAll());
+
+ // Can't iterate or call GetAll again.
+ Assert.Throws<InvalidOperationException>(() => cursor.ToArray());
+ Assert.Throws<InvalidOperationException>(() => cursor.GetAll());
+
+ // Iterator.
+ using (cursor = clientCache.Query(query))
+ {
+ checkResults(cursor.ToArray());
+
+ // Can't iterate or call GetAll again.
+ Assert.Throws<InvalidOperationException>(() => cursor.ToArray());
+ Assert.Throws<InvalidOperationException>(() => cursor.GetAll());
+ }
+
+ // Partial iterator.
+ using (cursor = clientCache.Query(query))
+ {
+ var item = cursor.First();
+ Assert.AreEqual(item.Key.ToString(), item.Value.Name);
+ }
+
+ // Local.
+ query.Local = true;
+ var localRes = clientCache.Query(query).ToList();
+ Assert.Less(localRes.Count, cache.GetSize());
+ }
+ }
+
+ /// <summary>
+ /// Tests scan query with .NET filter.
+ /// </summary>
+ [Test]
+ public void TestWithFilter()
+ {
+ GetPersonCache();
+
+ using (var client = GetClient())
+ {
+ var clientCache = client.GetCache<int, Person>(CacheName);
+
+ // One result.
+ var single = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x.Id == 3))).Single();
+ Assert.AreEqual(3, single.Key);
+
+ // Multiple results.
+ var res = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x.Name.Length == 1)))
+ .ToList();
+ Assert.AreEqual(9, res.Count);
+
+ // No results.
+ res = clientCache.Query(new ScanQuery<int, Person>(new PersonFilter(x => x == null))).ToList();
+ Assert.AreEqual(0, res.Count);
+ }
+ }
+
+ /// <summary>
+ /// Tests multiple cursors with the same client.
+ /// </summary>
+ [Test]
+ [SuppressMessage("ReSharper", "GenericEnumeratorNotDisposed")]
+ public void TestMultipleCursors()
+ {
+ var cache = GetPersonCache();
+
+ using (var client = GetClient())
+ {
+ var clientCache = client.GetCache<int, Person>(CacheName);
+
+ var qry = new ScanQuery<int, Person>();
+
+ var cur1 = clientCache.Query(qry).GetEnumerator();
+ var cur2 = clientCache.Query(qry).GetEnumerator();
+ var cur3 = clientCache.Query(qry).GetEnumerator();
+
+ // MaxCursors = 3
+ var ex = Assert.Throws<IgniteException>(() => clientCache.Query(qry));
+ Assert.AreEqual("Too many open cursors", ex.Message.Substring(0, 21));
+
+ var count = 0;
+
+ while (cur1.MoveNext())
+ {
+ count++;
+
+ Assert.IsTrue(cur2.MoveNext());
+ Assert.IsTrue(cur3.MoveNext());
+
+ Assert.AreEqual(cur1.Current.Key, cur2.Current.Key);
+ Assert.AreEqual(cur1.Current.Key, cur3.Current.Key);
+ }
+
+ Assert.AreEqual(cache.GetSize(), count);
+
+ // Old cursors were auto-closed on last page, we can open new cursors now.
+ var c1 = clientCache.Query(qry);
+ var c2 = clientCache.Query(qry);
+ var c3 = clientCache.Query(qry);
+
+ Assert.Throws<IgniteException>(() => clientCache.Query(qry));
+
+ // Close one of the cursors.
+ c1.Dispose();
+ c1 = clientCache.Query(qry);
+ Assert.Throws<IgniteException>(() => clientCache.Query(qry));
+
+ // Close cursor via GetAll.
+ c1.GetAll();
+ c1 = clientCache.Query(qry);
+ Assert.Throws<IgniteException>(() => clientCache.Query(qry));
+
+ c1.Dispose();
+ c2.Dispose();
+ c3.Dispose();
+ }
+ }
+
+ /// <summary>
+ /// Gets the string cache.
+ /// </summary>
+ private static ICache<int, Person> GetPersonCache()
+ {
+ var cache = GetCache<Person>();
+
+ cache.RemoveAll();
+ cache.PutAll(Enumerable.Range(1, 10000).ToDictionary(x => x, x => new Person
+ {
+ Id = x,
+ Name = x.ToString()
+ }));
+
+ return cache;
+ }
+
+ /// <summary>
+ /// Person filter.
+ /// </summary>
+ private class PersonFilter : ICacheEntryFilter<int, Person>
+ {
+ /** Filter predicate. */
+ private readonly Func<Person, bool> _filter;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonFilter"/> class.
+ /// </summary>
+ /// <param name="filter">The filter.</param>
+ public PersonFilter(Func<Person, bool> filter)
+ {
+ Debug.Assert(filter != null);
+
+ _filter = filter;
+ }
+
+ /** <inheritdoc /> */
+ public bool Invoke(ICacheEntry<int, Person> entry)
+ {
+ return _filter(entry.Value);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
deleted file mode 100644
index 3b0daa1..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTest.cs
+++ /dev/null
@@ -1,200 +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.
- */
-
-namespace Apache.Ignite.Core.Tests.Client
-{
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using Apache.Ignite.Core.Binary;
- using Apache.Ignite.Core.Cache;
- using Apache.Ignite.Core.Client;
- using NUnit.Framework;
-
- /// <summary>
- /// Thin client cache test.
- /// </summary>
- public sealed class CacheTest
- {
- /** Cache name. */
- private const string CacheName = "cache";
-
- /// <summary>
- /// Fixture tear down.
- /// </summary>
- [TestFixtureSetUp]
- public void FixtureSetUp()
- {
- Ignition.Start(TestUtils.GetTestConfiguration());
- }
-
- /// <summary>
- /// Fixture tear down.
- /// </summary>
- [TestFixtureTearDown]
- public void FixtureTearDown()
- {
- Ignition.StopAll(true);
- }
-
- /// <summary>
- /// Tests the cache put / get with primitive data types.
- /// </summary>
- [Test]
- public void TestPutGetPrimitives()
- {
- using (var client = GetClient())
- {
- GetCache<string>().Put(1, "foo");
-
- var clientCache = client.GetCache<int?, string>(CacheName);
-
- clientCache.Put(2, "bar");
- clientCache[3] = "baz";
-
- // Existing key.
- Assert.AreEqual("foo", clientCache.Get(1));
- Assert.AreEqual("foo", clientCache[1]);
- Assert.AreEqual("bar", clientCache[2]);
- Assert.AreEqual("baz", clientCache[3]);
-
- // Missing key.
- Assert.Throws<KeyNotFoundException>(() => clientCache.Get(-1));
-
- // Null key.
- Assert.Throws<ArgumentNullException>(() => clientCache.Get(null));
- }
- }
-
- /// <summary>
- /// Tests the cache put / get with user data types.
- /// </summary>
- [Test]
- public void TestPutGetUserObjects([Values(true, false)] bool compactFooter)
- {
- var cfg = GetClientConfiguration();
-
- cfg.BinaryConfiguration = new BinaryConfiguration
- {
- CompactFooter = compactFooter
- };
-
- using (var client = Ignition.StartClient(cfg))
- {
- var person = new Person {Id = 100, Name = "foo"};
- var person2 = new Person2 {Id = 200, Name = "bar"};
-
- var serverCache = GetCache<Person>();
- var clientCache = client.GetCache<int?, Person>(CacheName);
-
- Assert.AreEqual(CacheName, clientCache.Name);
-
- // Put through server cache.
- serverCache.Put(1, person);
-
- // Put through client cache.
- clientCache.Put(2, person2);
- clientCache[3] = person2;
-
- // Read from client cache.
- Assert.AreEqual("foo", clientCache.Get(1).Name);
- Assert.AreEqual(100, clientCache[1].Id);
- Assert.AreEqual(200, clientCache[2].Id);
- Assert.AreEqual(200, clientCache[3].Id);
-
- // Read from server cache.
- Assert.AreEqual("foo", serverCache.Get(1).Name);
- Assert.AreEqual(100, serverCache[1].Id);
- Assert.AreEqual(200, serverCache[2].Id);
- Assert.AreEqual(200, serverCache[3].Id);
-
- // Null key or value.
- Assert.Throws<ArgumentNullException>(() => clientCache.Put(10, null));
- Assert.Throws<ArgumentNullException>(() => clientCache.Put(null, person));
- }
- }
-
- /// <summary>
- /// Tests client get in multiple threads with a single client.
- /// </summary>
- [Test]
- [Category(TestUtils.CategoryIntensive)]
- public void TestGetMultithreadedSingleClient()
- {
- GetCache<string>().Put(1, "foo");
-
- using (var client = GetClient())
- {
- var clientCache = client.GetCache<int, string>(CacheName);
-
- TestUtils.RunMultiThreaded(() => Assert.AreEqual("foo", clientCache.Get(1)),
- Environment.ProcessorCount, 5);
- }
- }
-
- /// <summary>
- /// Tests client get in multiple threads with multiple clients.
- /// </summary>
- [Test]
- [Category(TestUtils.CategoryIntensive)]
- public void TestGetMultithreadedMultiClient()
- {
- GetCache<string>().Put(1, "foo");
-
- // One client per thread.
- var clients = new ConcurrentDictionary<int, IIgniteClient>();
-
- TestUtils.RunMultiThreaded(() =>
- {
- var client = clients.GetOrAdd(Thread.CurrentThread.ManagedThreadId, _ => GetClient());
-
- var clientCache = client.GetCache<int, string>(CacheName);
-
- Assert.AreEqual("foo", clientCache.Get(1));
- },
- Environment.ProcessorCount, 5);
-
- clients.ToList().ForEach(x => x.Value.Dispose());
- }
-
- /// <summary>
- /// Gets the cache.
- /// </summary>
- private static ICache<int, T> GetCache<T>()
- {
- return Ignition.GetIgnite().GetOrCreateCache<int, T>(CacheName);
- }
-
- /// <summary>
- /// Gets the client.
- /// </summary>
- private static IIgniteClient GetClient()
- {
- return Ignition.StartClient(GetClientConfiguration());
- }
-
- /// <summary>
- /// Gets the client configuration.
- /// </summary>
- private static IgniteClientConfiguration GetClientConfiguration()
- {
- return new IgniteClientConfiguration {Host = "127.0.0.1"};
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
deleted file mode 100644
index a011583..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/CacheTestNoMeta.cs
+++ /dev/null
@@ -1,159 +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.
- */
-
-namespace Apache.Ignite.Core.Tests.Client
-{
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using Apache.Ignite.Core.Binary;
- using Apache.Ignite.Core.Cache.Configuration;
- using Apache.Ignite.Core.Cache.Query;
- using Apache.Ignite.Core.Client;
- using Apache.Ignite.Core.Impl.Binary;
- using Apache.Ignite.Core.Impl.Binary.Metadata;
- using NUnit.Framework;
-
- /// <summary>
- /// Client cache test without metadata (no-op binary processor).
- /// </summary>
- public class CacheTestNoMeta
- {
- /** Cache name. */
- private const string CacheName = "cache";
-
- /// <summary>
- /// Fixture tear down.
- /// </summary>
- [TestFixtureSetUp]
- public void FixtureSetUp()
- {
- Ignition.Start(TestUtils.GetTestConfiguration());
- }
-
- /// <summary>
- /// Fixture tear down.
- /// </summary>
- [TestFixtureTearDown]
- public void FixtureTearDown()
- {
- Ignition.StopAll(true);
- }
-
- /// <summary>
- /// Tests the cache put / get with user data types.
- /// </summary>
- [Test]
- public void TestPutGetUserObjects()
- {
- var cfg = new IgniteClientConfiguration
- {
- BinaryProcessor = new NoopBinaryProcessor(),
- BinaryConfiguration = new BinaryConfiguration
- {
- CompactFooter = false
- },
- Host = IPAddress.Loopback.ToString()
- };
-
- using (var client = Ignition.StartClient(cfg))
- {
- var serverCache = Ignition.GetIgnite().GetOrCreateCache<int?, Person>(
- new CacheConfiguration(CacheName, new QueryEntity
- {
- KeyType = typeof(int),
- ValueType = typeof(Person),
- Fields = new[]
- {
- new QueryField("id", typeof(int)),
- new QueryField("name", typeof(string))
- }
- }));
-
- var clientCache = client.GetCache<int?, Person>(CacheName);
-
- // Put through client cache.
- clientCache.Put(1, new Person { Id = 100, Name = "foo" });
- clientCache[2] = new Person { Id = 200, Name = "bar" };
-
- // Read from client cache.
- Assert.AreEqual("foo", clientCache.Get(1).Name);
- Assert.AreEqual(100, clientCache[1].Id);
- Assert.AreEqual(200, clientCache[2].Id);
-
- // Read from server cache.
- Assert.AreEqual("foo", serverCache.Get(1).Name);
- Assert.AreEqual(100, serverCache[1].Id);
- Assert.AreEqual(200, serverCache[2].Id);
-
- // SQL from server cache.
- var sqlRes = serverCache.Query(new SqlQuery(typeof(Person), "where id = 100")).GetAll().Single();
- Assert.AreEqual(1, sqlRes.Key);
- Assert.AreEqual(100, sqlRes.Value.Id);
- Assert.AreEqual("foo", sqlRes.Value.Name);
- }
- }
-
- /// <summary>
- /// No-op binary processor (does not send meta to cluster).
- /// </summary>
- private class NoopBinaryProcessor : IBinaryProcessor
- {
- /** <inheritdoc /> */
- public BinaryType GetBinaryType(int typeId)
- {
- return null;
- }
-
- /** <inheritdoc /> */
- public List<IBinaryType> GetBinaryTypes()
- {
- return null;
- }
-
- /** <inheritdoc /> */
- public int[] GetSchema(int typeId, int schemaId)
- {
- return null;
- }
-
- /** <inheritdoc /> */
- public void PutBinaryTypes(ICollection<BinaryType> types)
- {
- // No-op.
- }
-
- /** <inheritdoc /> */
- public bool RegisterType(int id, string typeName)
- {
- return false;
- }
-
- /** <inheritdoc /> */
- public BinaryType RegisterEnum(string typeName, IEnumerable<KeyValuePair<string, int>> values)
- {
- return null;
- }
-
- /** <inheritdoc /> */
- public string GetTypeName(int id)
- {
- return null;
- }
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/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
new file mode 100644
index 0000000..81e1418
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/ClientTestBase.cs
@@ -0,0 +1,113 @@
+/*
+ * 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
+{
+ using System.Net;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Client;
+ using NUnit.Framework;
+
+ /// <summary>
+ /// Base class for client tests.
+ /// </summary>
+ public class ClientTestBase
+ {
+ /** Cache name. */
+ protected const string CacheName = "cache";
+
+ /** Grid count. */
+ private readonly int _gridCount = 1;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ClientTestBase"/> class.
+ /// </summary>
+ public ClientTestBase()
+ {
+ // No-op.
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ClientTestBase"/> class.
+ /// </summary>
+ public ClientTestBase(int gridCount)
+ {
+ _gridCount = gridCount;
+ }
+
+ /// <summary>
+ /// Fixture tear down.
+ /// </summary>
+ [TestFixtureSetUp]
+ public void FixtureSetUp()
+ {
+ var cfg = GetIgniteConfiguration();
+ Ignition.Start(cfg);
+
+ cfg.AutoGenerateIgniteInstanceName = true;
+
+ for (var i = 1; i < _gridCount; i++)
+ {
+ Ignition.Start(cfg);
+ }
+ }
+
+ /// <summary>
+ /// Fixture tear down.
+ /// </summary>
+ [TestFixtureTearDown]
+ public void FixtureTearDown()
+ {
+ Ignition.StopAll(true);
+ }
+
+ /// <summary>
+ /// Gets the cache.
+ /// </summary>
+ protected static ICache<int, T> GetCache<T>()
+ {
+ return Ignition.GetIgnite().GetOrCreateCache<int, T>(CacheName);
+ }
+
+ /// <summary>
+ /// Gets the client.
+ /// </summary>
+ protected IIgniteClient GetClient()
+ {
+ return Ignition.StartClient(GetClientConfiguration());
+ }
+
+ /// <summary>
+ /// Gets the client configuration.
+ /// </summary>
+ protected IgniteClientConfiguration GetClientConfiguration()
+ {
+ return new IgniteClientConfiguration
+ {
+ Host = IPAddress.Loopback.ToString()
+ };
+ }
+
+ /// <summary>
+ /// Gets the Ignite configuration.
+ /// </summary>
+ protected virtual IgniteConfiguration GetIgniteConfiguration()
+ {
+ return TestUtils.GetTestConfiguration();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
deleted file mode 100644
index 7f0309f..0000000
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/Person.cs
+++ /dev/null
@@ -1,48 +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.
- */
-
-namespace Apache.Ignite.Core.Tests.Client
-{
- /// <summary>
- /// Test person.
- /// </summary>
- public class Person
- {
- /// <summary>
- /// Gets or sets the identifier.
- /// </summary>
- public int Id { get; set; }
-
- /// <summary>
- /// Gets or sets the name.
- /// </summary>
- public string Name { get; set; }
-
- /// <summary>
- /// Gets or sets the parent.
- /// </summary>
- public Person Parent { get;set; }
- }
-
- /// <summary>
- /// Test person 2.
- /// </summary>
- public class Person2 : Person
- {
- // No-op.
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
index 9e2200f..48bd3dd 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Client/RawSocketTest.cs
@@ -81,6 +81,9 @@ namespace Apache.Ignite.Core.Tests.Client
var requestId = reader.ReadLong();
Assert.AreEqual(1, requestId);
+ var success = reader.ReadBoolean();
+ Assert.IsTrue(success);
+
var res = reader.ReadObject<string>();
Assert.AreEqual(cache[1], res);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/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 615ce90..ed34675 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -103,6 +103,8 @@
<Compile Include="Common\ExceptionFactory.cs" />
<Compile Include="Configuration\Package-Info.cs" />
<Compile Include="Impl\Binary\BinaryTypeId.cs" />
+ <Compile Include="Impl\Client\Cache\CacheFlags.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" />
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/ScanQuery.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/ScanQuery.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/ScanQuery.cs
index 2c9cf35..bb9852d 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/ScanQuery.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Query/ScanQuery.cs
@@ -52,7 +52,7 @@ namespace Apache.Ignite.Core.Cache.Query
writer.WriteInt(PageSize);
writer.WriteBoolean(Partition.HasValue);
-
+
if (Partition.HasValue)
writer.WriteInt(Partition.Value);
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/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 b8bd6fe..edd411c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Client/Cache/ICacheClient.cs
@@ -18,6 +18,8 @@
namespace Apache.Ignite.Core.Client.Cache
{
using System.Collections.Generic;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Query;
/// <summary>
/// Client cache API. See <see cref="IIgniteClient.GetCache{K, V}"/>.
@@ -56,5 +58,12 @@ namespace Apache.Ignite.Core.Client.Cache
/// <returns>Cache value with the specified key.</returns>
/// <exception cref="KeyNotFoundException">If the key is not present in the cache.</exception>
TV this[TK key] { get; set; }
+
+ /// <summary>
+ /// Executes a Scan query.
+ /// </summary>
+ /// <param name="scanQuery">Scan query.</param>
+ /// <returns>Query cursor.</returns>
+ IQueryCursor<ICacheEntry<TK, TV>> Query(ScanQuery<TK, TV> scanQuery);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/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 418bb24..8f00a2e 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
@@ -54,35 +54,45 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
/** Disposed flag. */
private volatile bool _disposed;
+ /** Whether next batch is available. */
+ private bool _hasNext = true;
+
/// <summary>
/// Constructor.
/// </summary>
/// <param name="marsh">Marshaller.</param>
/// <param name="keepBinary">Keep binary flag.</param>
- protected QueryCursorBase(Marshaller marsh, bool keepBinary)
+ /// <param name="initialBatchStream">Optional stream with initial batch.</param>
+ protected QueryCursorBase(Marshaller marsh, bool keepBinary, IBinaryStream initialBatchStream = null)
{
Debug.Assert(marsh != null);
_keepBinary = keepBinary;
_marsh = marsh;
+
+ if (initialBatchStream != null)
+ {
+ _batch = ConvertGetBatch(initialBatchStream);
+ }
}
/** <inheritdoc /> */
public IList<T> GetAll()
{
- ThrowIfDisposed();
+ if (_getAllCalled)
+ throw new InvalidOperationException("Failed to get all entries because GetAll() " +
+ "method has already been called.");
if (_iterCalled)
- throw new InvalidOperationException("Failed to get all entries because GetEnumerator() " +
- "method has already been called.");
+ throw new InvalidOperationException("Failed to get all entries because GetEnumerator() " +
+ "method has already been called.");
- if (_getAllCalled)
- throw new InvalidOperationException("Failed to get all entries because GetAll() " +
- "method has already been called.");
+ ThrowIfDisposed();
var res = GetAllInternal();
_getAllCalled = true;
+ _hasNext = false;
return res;
}
@@ -92,20 +102,20 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
/** <inheritdoc /> */
public IEnumerator<T> GetEnumerator()
{
- ThrowIfDisposed();
-
- if (_iterCalled)
+ if (_getAllCalled)
{
throw new InvalidOperationException("Failed to get enumerator entries because " +
- "GetEnumerator() method has already been called.");
+ "GetAll() method has already been called.");
}
- if (_getAllCalled)
+ if (_iterCalled)
{
throw new InvalidOperationException("Failed to get enumerator entries because " +
- "GetAll() method has already been called.");
+ "GetEnumerator() method has already been called.");
}
+ ThrowIfDisposed();
+
InitIterator();
_iterCalled = true;
@@ -196,7 +206,7 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
/// </summary>
private void RequestBatch()
{
- _batch = GetBatch();
+ _batch = _hasNext ? GetBatch() : null;
_batchPos = 0;
}
@@ -237,12 +247,19 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
var size = reader.ReadInt();
if (size == 0)
+ {
+ _hasNext = false;
return null;
+ }
var res = new T[size];
for (var i = 0; i < size; i++)
+ {
res[i] = Read(reader);
+ }
+
+ _hasNext = stream.ReadBool();
return res;
}
@@ -253,9 +270,14 @@ namespace Apache.Ignite.Core.Impl.Cache.Query
lock (this)
{
if (_disposed)
+ {
return;
+ }
- Dispose(true);
+ if (_hasNext)
+ {
+ Dispose(true);
+ }
GC.SuppressFinalize(this);
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
index affa815..974bab3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheClient.cs
@@ -21,11 +21,15 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Cache.Query;
using Apache.Ignite.Core.Client;
using Apache.Ignite.Core.Client.Cache;
using Apache.Ignite.Core.Impl.Binary;
using Apache.Ignite.Core.Impl.Binary.IO;
+ using Apache.Ignite.Core.Impl.Cache;
using Apache.Ignite.Core.Impl.Client;
+ using Apache.Ignite.Core.Impl.Client.Cache.Query;
using Apache.Ignite.Core.Impl.Common;
using BinaryWriter = Apache.Ignite.Core.Impl.Binary.BinaryWriter;
@@ -34,6 +38,9 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
/// </summary>
internal class CacheClient<TK, TV> : ICacheClient<TK, TV>
{
+ /** Scan query filter platform code: .NET filter. */
+ private const byte FilterPlatformDotnet = 2;
+
/** Cache name. */
private readonly string _name;
@@ -46,6 +53,9 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
/** Marshaller. */
private readonly Marshaller _marsh;
+ /** Keep binary flag. */
+ private bool _keepBinary = false;
+
/// <summary>
/// Initializes a new instance of the <see cref="CacheClient{TK, TV}" /> class.
/// </summary>
@@ -102,6 +112,17 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
});
}
+ /** <inheritDoc /> */
+ public IQueryCursor<ICacheEntry<TK, TV>> Query(ScanQuery<TK, TV> scanQuery)
+ {
+ IgniteArgumentCheck.NotNull(scanQuery, "query");
+
+ // Filter is a binary object for all platforms.
+ // For .NET it is a CacheEntryFilterHolder with a predefined id (BinaryTypeId.CacheEntryPredicateHolder).
+ return DoOutInOp(ClientOp.QueryScan, w => WriteScanQuery(w, scanQuery),
+ s => new ClientQueryCursor<TK, TV>(_ignite, s.ReadLong(), _keepBinary, s));
+ }
+
/// <summary>
/// Does the out in op.
/// </summary>
@@ -150,6 +171,34 @@ namespace Apache.Ignite.Core.Impl.Client.Cache
}
/// <summary>
+ /// Writes the scan query.
+ /// </summary>
+ private void WriteScanQuery(BinaryWriter writer, ScanQuery<TK, TV> qry)
+ {
+ Debug.Assert(qry != null);
+
+ if (qry.Filter == null)
+ {
+ writer.WriteByte(BinaryUtils.HdrNull);
+ }
+ else
+ {
+ var holder = new CacheEntryFilterHolder(qry.Filter, (key, val) => qry.Filter.Invoke(
+ new CacheEntry<TK, TV>((TK)key, (TV)val)), writer.Marshaller, _keepBinary);
+
+ writer.WriteObject(holder);
+
+ writer.WriteByte(FilterPlatformDotnet);
+ }
+
+ writer.WriteInt(qry.PageSize);
+
+ writer.WriteInt(qry.Partition ?? -1);
+
+ writer.WriteBoolean(qry.Local);
+ }
+
+ /// <summary>
/// Gets the key not found exception.
/// </summary>
private static KeyNotFoundException GetKeyNotFoundException()
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheFlags.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheFlags.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheFlags.cs
new file mode 100644
index 0000000..e24d952
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/CacheFlags.cs
@@ -0,0 +1,38 @@
+/*
+ * 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.Impl.Client.Cache
+{
+ using System;
+
+ /// <summary>
+ /// Cache operation flags.
+ /// </summary>
+ [Flags]
+ internal enum CacheFlags : byte
+ {
+ /// <summary>
+ /// No flags.
+ /// </summary>
+ None = 0x00,
+
+ /// <summary>
+ /// Keep binary.
+ /// </summary>
+ KeepBinary = 0x01
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
new file mode 100644
index 0000000..898bbbe
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/Cache/Query/ClientQueryCursor.cs
@@ -0,0 +1,94 @@
+/*
+ * 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.Impl.Client.Cache.Query
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using Apache.Ignite.Core.Cache;
+ using Apache.Ignite.Core.Impl.Binary;
+ using Apache.Ignite.Core.Impl.Binary.IO;
+ using Apache.Ignite.Core.Impl.Cache;
+ using Apache.Ignite.Core.Impl.Cache.Query;
+ using Apache.Ignite.Core.Impl.Client;
+
+ /// <summary>
+ /// Client query cursor.
+ /// </summary>
+ internal class ClientQueryCursor<TK, TV> : QueryCursorBase<ICacheEntry<TK, TV>>
+ {
+ /** Ignite. */
+ private readonly IgniteClient _ignite;
+
+ /** Cursor ID. */
+ private readonly long _cursorId;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ClientQueryCursor{TK, TV}" /> class.
+ /// </summary>
+ /// <param name="ignite">The ignite.</param>
+ /// <param name="cursorId">The cursor identifier.</param>
+ /// <param name="keepBinary">Keep binary flag.</param>
+ /// <param name="initialBatchStream">Optional stream with initial batch.</param>
+ public ClientQueryCursor(IgniteClient ignite, long cursorId, bool keepBinary,
+ IBinaryStream initialBatchStream)
+ : base(ignite.Marshaller, keepBinary, initialBatchStream)
+ {
+ _ignite = ignite;
+ _cursorId = cursorId;
+ }
+
+ /** <inheritdoc /> */
+ protected override void InitIterator()
+ {
+ // No-op.
+ }
+
+ /** <inheritdoc /> */
+ protected override IList<ICacheEntry<TK, TV>> GetAllInternal()
+ {
+ return this.ToArray();
+ }
+
+ /** <inheritdoc /> */
+ protected override ICacheEntry<TK, TV> Read(BinaryReader reader)
+ {
+ return new CacheEntry<TK, TV>(reader.ReadObject<TK>(), reader.ReadObject<TV>());
+ }
+
+ /** <inheritdoc /> */
+ protected override ICacheEntry<TK, TV>[] GetBatch()
+ {
+ return _ignite.Socket.DoOutInOp(ClientOp.QueryScanCursorGetPage,
+ w => w.WriteLong(_cursorId),
+ s => ConvertGetBatch(s));
+ }
+
+ /** <inheritdoc /> */
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ _ignite.Socket.DoOutInOp<object>(ClientOp.ResourceClose, w => w.WriteLong(_cursorId), null);
+ }
+ finally
+ {
+ base.Dispose(disposing);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
index 79d7c9e..c39b68f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientOp.cs
@@ -27,6 +27,9 @@ namespace Apache.Ignite.Core.Impl.Client
BinaryTypeGet = 3,
CachePut = 4,
BinaryTypeNamePut = 5,
- BinaryTypePut = 6
+ BinaryTypePut = 6,
+ QueryScan = 7,
+ QueryScanCursorGetPage = 8,
+ ResourceClose = 9
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
index 0204ef8..1a245a1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/ClientSocket.cs
@@ -88,6 +88,12 @@ namespace Apache.Ignite.Core.Impl.Client
var resRequestId = stream.ReadLong();
Debug.Assert(requestId == resRequestId);
+ if (!stream.ReadBool())
+ {
+ // Error.
+ throw new IgniteException(BinaryUtils.Marshaller.StartUnmarshal(stream).ReadString());
+ }
+
if (readFunc != null)
{
return readFunc(stream);
@@ -159,7 +165,11 @@ namespace Apache.Ignite.Core.Impl.Client
buf = new byte[size];
received = sock.Receive(buf);
- Debug.Assert(received == buf.Length);
+
+ while (received < size)
+ {
+ received += sock.Receive(buf, received, size - received, SocketFlags.None);
+ }
return buf;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/86372dee/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
index 29b8a2c..d05355a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Client/IgniteClient.cs
@@ -144,9 +144,16 @@ namespace Apache.Ignite.Core.Impl.Client
/// <summary>
/// Gets the client not supported exception.
/// </summary>
- private static NotSupportedException GetClientNotSupportedException()
+ public static NotSupportedException GetClientNotSupportedException(string info = null)
{
- return new NotSupportedException("Operation is not supported in thin client mode.");
+ var msg = "Operation is not supported in thin client mode.";
+
+ if (info != null)
+ {
+ msg += " " + info;
+ }
+
+ return new NotSupportedException(msg);
}
}
}