IGNITE-6523 .NET: QueryField.NotNull
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8f599c57 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8f599c57 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8f599c57 Branch: refs/heads/ignite-3478 Commit: 8f599c57104513aa8ba940cca10f680467e12cb3 Parents: b8c4863 Author: Pavel Tupitsyn <[email protected]> Authored: Fri Sep 29 15:22:36 2017 +0300 Committer: Pavel Tupitsyn <[email protected]> Committed: Fri Sep 29 15:22:36 2017 +0300 ---------------------------------------------------------------------- .../utils/PlatformConfigurationUtils.java | 9 +++++ .../Cache/CacheConfigurationTest.cs | 3 +- .../Cache/Query/CacheDmlQueriesTest.cs | 40 +++++++++++++++++++- .../Query/CacheQueriesCodeConfigurationTest.cs | 5 ++- .../Cache/Query/CacheQueriesTest.cs | 11 +++++- .../Config/cache-query.xml | 5 +++ .../Config/full-config.xml | 2 +- .../IgniteConfigurationSerializerTest.cs | 7 +++- .../Cache/Configuration/QueryEntity.cs | 17 +++++---- .../Cache/Configuration/QueryField.cs | 32 ++++++++++++++++ .../Configuration/QuerySqlFieldAttribute.cs | 5 +++ .../IgniteConfigurationSection.xsd | 5 +++ 12 files changed, 126 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java index e223193..66160fb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java @@ -459,6 +459,7 @@ public class PlatformConfigurationUtils { // Fields int cnt = in.readInt(); Set<String> keyFields = new HashSet<>(cnt); + Set<String> notNullFields = new HashSet<>(cnt); if (cnt > 0) { LinkedHashMap<String, String> fields = new LinkedHashMap<>(cnt); @@ -471,12 +472,18 @@ public class PlatformConfigurationUtils { if (in.readBoolean()) keyFields.add(fieldName); + + if (in.readBoolean()) + notNullFields.add(fieldName); } res.setFields(fields); if (!keyFields.isEmpty()) res.setKeyFields(keyFields); + + if (!notNullFields.isEmpty()) + res.setNotNullFields(notNullFields); } // Aliases @@ -937,6 +944,7 @@ public class PlatformConfigurationUtils { if (fields != null) { Set<String> keyFields = queryEntity.getKeyFields(); + Set<String> notNullFields = queryEntity.getNotNullFields(); writer.writeInt(fields.size()); @@ -944,6 +952,7 @@ public class PlatformConfigurationUtils { writer.writeString(field.getKey()); writer.writeString(field.getValue()); writer.writeBoolean(keyFields != null && keyFields.contains(field.getKey())); + writer.writeBoolean(notNullFields != null && notNullFields.contains(field.getKey())); } } else http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs index 4e5d443..abf8af0 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/CacheConfigurationTest.cs @@ -511,6 +511,7 @@ namespace Apache.Ignite.Core.Tests.Cache Assert.AreEqual(x.Name, y.Name); Assert.AreEqual(x.FieldTypeName, y.FieldTypeName); Assert.AreEqual(x.IsKeyField, y.IsKeyField); + Assert.AreEqual(x.NotNull, y.NotNull); } /// <summary> @@ -587,7 +588,7 @@ namespace Apache.Ignite.Core.Tests.Cache { new QueryField("length", typeof(int)), new QueryField("name", typeof(string)) {IsKeyField = true}, - new QueryField("location", typeof(string)), + new QueryField("location", typeof(string)) {NotNull = true}, }, Aliases = new [] {new QueryAlias("length", "len") }, Indexes = new[] http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs index 9d16799..a6ddc8c 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheDmlQueriesTest.cs @@ -103,6 +103,44 @@ namespace Apache.Ignite.Core.Tests.Cache.Query } /// <summary> + /// Tests the NotNull constraint. + /// </summary> + [Test] + public void TestNotNull() + { + var cfg = new CacheConfiguration("not_null", new QueryEntity(typeof(int), typeof(Foo)) + { + Fields = new[] + { + new QueryField("id", typeof(int)) {NotNull = true}, + new QueryField("name", typeof(string)) + } + }); + + var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg); + + var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery( + "insert into foo(_key, name) values (?, ?)", 1, "bar")).GetAll()); + + Assert.AreEqual("Null value is not allowed for field 'ID'", ex.Message); + } + + /// <summary> + /// Tests the NotNull constraint. + /// </summary> + [Test] + public void TestNotNullAttribute() + { + var cfg = new CacheConfiguration("not_null_attr", new QueryEntity(typeof(int), typeof(Foo))); + var cache = Ignition.GetIgnite().CreateCache<int, Foo>(cfg); + + var ex = Assert.Throws<IgniteException>(() => cache.QueryFields(new SqlFieldsQuery( + "insert into foo(_key, id) values (?, ?)", 1, 2)).GetAll()); + + Assert.AreEqual("Null value is not allowed for field 'NAME'", ex.Message); + } + + /// <summary> /// Tests all primitive key types. /// </summary> [Test] @@ -388,7 +426,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query private class Foo { [QuerySqlField] public int Id { get; set; } - [QuerySqlField] public string Name { get; set; } + [QuerySqlField(NotNull = true)] public string Name { get; set; } } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs index 7421b95..2e24ff6 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesCodeConfigurationTest.cs @@ -125,6 +125,9 @@ namespace Apache.Ignite.Core.Tests.Cache.Query "GroupIndex1", "GroupIndex2", "GroupIndex3" }, fields.Select(x => x.Name)); + Assert.IsTrue(fields.Single(x => x.Name == "SqlField").NotNull); + Assert.IsFalse(fields.Single(x => x.Name == "IndexedField1").NotNull); + var idx = qe.Indexes.ToArray(); Assert.AreEqual(QueryIndexType.Sorted, idx[0].IndexType); @@ -314,7 +317,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query /// </summary> private class AttributeTest { - [QuerySqlField] + [QuerySqlField(NotNull = true)] public double SqlField { get; set; } [QuerySqlField(IsIndexed = true, Name = "IndexedField1", IsDescending = true, IndexInlineSize = 513)] http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs index 6361850..9c63c73 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/CacheQueriesTest.cs @@ -687,8 +687,15 @@ namespace Apache.Ignite.Core.Tests.Cache.Query { var entity = Cache().GetConfiguration().QueryEntities.Single(); - Assert.AreEqual(typeof(int), entity.Fields.Single(x => x.Name == "age").FieldType); - Assert.AreEqual(typeof(string), entity.Fields.Single(x => x.Name == "name").FieldType); + var ageField = entity.Fields.Single(x => x.Name == "age"); + Assert.AreEqual(typeof(int), ageField.FieldType); + Assert.IsFalse(ageField.NotNull); + Assert.IsFalse(ageField.IsKeyField); + + var nameField = entity.Fields.Single(x => x.Name == "name"); + Assert.AreEqual(typeof(string), nameField.FieldType); + Assert.IsTrue(nameField.NotNull); + Assert.IsFalse(nameField.IsKeyField); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml index 3b61d8d..87e65a2 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/cache-query.xml @@ -66,6 +66,11 @@ <entry key="name" value="java.lang.String" /> </util:map> </property> + <property name="notNullFields"> + <list> + <value>name</value> + </list> + </property> <property name="indexes"> <list> <bean class="org.apache.ignite.cache.QueryIndex"> http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml index f6854e1..229d42e 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Config/full-config.xml @@ -55,7 +55,7 @@ <queryEntities> <queryEntity keyType='System.Int32' valueType='System.String' tableName='myTable'> <fields> - <queryField name='length' fieldType='System.Int32' isKeyField='true' /> + <queryField name='length' fieldType='System.Int32' isKeyField='true' notNull='true' /> </fields> <aliases> <queryAlias fullName='somefield.field' alias='shortField' /> http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs index b04f466..edecccc 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs @@ -115,6 +115,7 @@ namespace Apache.Ignite.Core.Tests Assert.AreEqual("length", queryEntity.Fields.Single().Name); Assert.AreEqual(typeof(int), queryEntity.Fields.Single().FieldType); Assert.IsTrue(queryEntity.Fields.Single().IsKeyField); + Assert.IsTrue(queryEntity.Fields.Single().NotNull); Assert.AreEqual("somefield.field", queryEntity.Aliases.Single().FullName); Assert.AreEqual("shortField", queryEntity.Aliases.Single().Alias); @@ -600,7 +601,11 @@ namespace Apache.Ignite.Core.Tests { Fields = new[] { - new QueryField("field", typeof (int)) { IsKeyField = true } + new QueryField("field", typeof (int)) + { + IsKeyField = true, + NotNull = true + } }, Indexes = new[] { http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs index b40231c..e8d0c91 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryEntity.cs @@ -51,6 +51,7 @@ namespace Apache.Ignite.Core.Cache.Configuration /** */ private Dictionary<string, string> _aliasMap; + /** */ private ICollection<QueryAlias> _aliases; /// <summary> @@ -241,9 +242,7 @@ namespace Apache.Ignite.Core.Cache.Configuration var count = reader.ReadInt(); Fields = count == 0 ? null - : Enumerable.Range(0, count).Select(x => - new QueryField(reader.ReadString(), reader.ReadString()) {IsKeyField = reader.ReadBoolean()}) - .ToList(); + : Enumerable.Range(0, count).Select(x => new QueryField(reader)).ToList(); count = reader.ReadInt(); Aliases = count == 0 ? null : Enumerable.Range(0, count) @@ -271,9 +270,7 @@ namespace Apache.Ignite.Core.Cache.Configuration foreach (var field in Fields) { - writer.WriteString(field.Name); - writer.WriteString(field.FieldTypeName); - writer.WriteBoolean(field.IsKeyField); + field.Write(writer); } } else @@ -456,11 +453,15 @@ namespace Apache.Ignite.Core.Cache.Configuration indexes.Add(new QueryIndexEx(columnName, attr.IsDescending, QueryIndexType.Sorted, attr.IndexGroups) { - InlineSize = attr.IndexInlineSize + InlineSize = attr.IndexInlineSize, }); } - fields.Add(new QueryField(columnName, memberInfo.Value) {IsKeyField = isKey}); + fields.Add(new QueryField(columnName, memberInfo.Value) + { + IsKeyField = isKey, + NotNull = attr.NotNull + }); ScanAttributes(memberInfo.Value, fields, indexes, columnName, visitedTypes, isKey); } http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs index 596837a..b8142fd 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QueryField.cs @@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Cache.Configuration { using System; using System.Diagnostics; + using Apache.Ignite.Core.Binary; using Apache.Ignite.Core.Impl.Binary; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Log; @@ -73,6 +74,32 @@ namespace Apache.Ignite.Core.Cache.Configuration } /// <summary> + /// Initializes a new instance of the <see cref="QueryField"/> class. + /// </summary> + internal QueryField(IBinaryRawReader reader) + { + Debug.Assert(reader != null); + + Name = reader.ReadString(); + FieldTypeName = reader.ReadString(); + IsKeyField = reader.ReadBoolean(); + NotNull = reader.ReadBoolean(); + } + + /// <summary> + /// Writes this instance to the specified writer. + /// </summary> + internal void Write(IBinaryRawWriter writer) + { + Debug.Assert(writer != null); + + writer.WriteString(Name); + writer.WriteString(FieldTypeName); + writer.WriteBoolean(IsKeyField); + writer.WriteBoolean(NotNull); + } + + /// <summary> /// Gets or sets the field name. /// </summary> public string Name { get; set; } @@ -115,6 +142,11 @@ namespace Apache.Ignite.Core.Cache.Configuration public bool IsKeyField { get; set; } /// <summary> + /// Gets or sets a value indicating whether null value is allowed for the field. + /// </summary> + public bool NotNull { get; set; } + + /// <summary> /// Validates this instance and outputs information to the log, if necessary. /// </summary> internal void Validate(ILogger log, string logInfo) http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs index b920304..d15cc1a 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Cache/Configuration/QuerySqlFieldAttribute.cs @@ -71,5 +71,10 @@ namespace Apache.Ignite.Core.Cache.Configuration /// </summary> [DefaultValue(QueryIndex.DefaultInlineSize)] public int IndexInlineSize { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether null values are allowed for this field. + /// </summary> + public bool NotNull { get; set; } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/8f599c57/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd index 730cb9f..988fa1f 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd @@ -328,6 +328,11 @@ <xs:documentation>Indicates whether this field belongs to the cache key.</xs:documentation> </xs:annotation> </xs:attribute> + <xs:attribute name="notNull" type="xs:boolean"> + <xs:annotation> + <xs:documentation>Indicates whether null value is allowed for the field.</xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> </xs:sequence>
