From b23a9be66ab708c85bc47258d7b55c3c186e4695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Fri, 14 Sep 2018 13:33:06 +0200 Subject: [PATCH 1/2] Add in ByCode support of all type mappings on Id --- .../MappersTests/IdMapperTest.cs | 84 +++++++++++++++++++ src/NHibernate/Mapping/ByCode/IIdMapper.cs | 37 ++++++-- .../Mapping/ByCode/Impl/IdMapper.cs | 45 +++++++++- 3 files changed, 159 insertions(+), 7 deletions(-) diff --git a/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs b/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs index d36fbb5cdc8..9b9f4eb4b5f 100644 --- a/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs +++ b/src/NHibernate.Test/MappingByCode/MappersTests/IdMapperTest.cs @@ -1,8 +1,10 @@ +using System; using System.Linq; using System.Reflection; using NHibernate.Mapping.ByCode; using NHibernate.Cfg.MappingSchema; using NHibernate.Mapping.ByCode.Impl; +using NHibernate.Type; using NUnit.Framework; namespace NHibernate.Test.MappingByCode.MappersTests @@ -80,6 +82,11 @@ private class Related public int Id { get; set; } } + private enum MyEnum + { + One + } + [Test] public void CanSetGeneratorForeign() { @@ -210,5 +217,82 @@ public void CanSqlType() mapper.Column(x => x.SqlType("CHAR(10)")); Assert.That(hbmId.column[0].sqltype, Is.EqualTo("CHAR(10)")); } + + [Test] + public void WhenSetTypeByITypeThenSetTypeName() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type(NHibernateUtil.String); + + Assert.That(hbmId.Type.name, Is.EqualTo("String")); + } + + [Test] + public void WhenSetTypeByIUserTypeThenSetTypeName() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type(); + + Assert.That(hbmId.Type.name, Does.Contain("MyType")); + Assert.That(hbmId.type, Is.Null); + } + + [Test] + public void WhenSetTypeByICompositeUserTypeThenSetTypeName() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type(); + + Assert.That(hbmId.Type.name, Does.Contain("MyCompoType")); + Assert.That(hbmId.type, Is.Null); + } + + [Test] + public void WhenSetTypeByIUserTypeWithParamsThenSetType() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type(new { Param1 = "a", Param2 = 12 }); + + Assert.That(hbmId.type1, Is.Null); + Assert.That(hbmId.Type.name, Does.Contain("MyType")); + Assert.That(hbmId.Type.param, Has.Length.EqualTo(2)); + Assert.That(hbmId.Type.param.Select(p => p.name), Is.EquivalentTo(new [] {"Param1", "Param2"})); + Assert.That(hbmId.Type.param.Select(p => p.GetText()), Is.EquivalentTo(new [] {"a", "12"})); + } + + [Test] + public void WhenSetTypeByIUserTypeWithNullParamsThenSetTypeName() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type(null); + + Assert.That(hbmId.Type.name, Does.Contain("MyType")); + Assert.That(hbmId.type, Is.Null); + } + + [Test] + public void WhenSetTypeByITypeTypeThenSetType() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + mapper.Type>(); + + Assert.That(hbmId.Type.name, Does.Contain(typeof(EnumStringType).FullName)); + Assert.That(hbmId.type, Is.Null); + } + + [Test] + public void WhenSetInvalidTypeThenThrow() + { + var hbmId = new HbmId(); + var mapper = new IdMapper(null, hbmId); + Assert.That(() => mapper.Type(typeof(object), null), Throws.TypeOf()); + Assert.That(() => mapper.Type(null, null), Throws.TypeOf()); + } } } diff --git a/src/NHibernate/Mapping/ByCode/IIdMapper.cs b/src/NHibernate/Mapping/ByCode/IIdMapper.cs index ef9627d9f6b..b3fc22365c2 100644 --- a/src/NHibernate/Mapping/ByCode/IIdMapper.cs +++ b/src/NHibernate/Mapping/ByCode/IIdMapper.cs @@ -1,20 +1,45 @@ using System; +using NHibernate.Mapping.ByCode.Impl; using NHibernate.Type; +using NHibernate.Util; namespace NHibernate.Mapping.ByCode { + // 6.0 TODO: move into IIdMapper, + // and probably add an ITypeMapper for mutualizing the four Type methods with IElementMapper and IPropertyMapper + // (Note that there is no IKeyPropertyMapper to be concerned with, the KeyPropertyMapper use IPropertyMapper + // directly instead.) + public static class IdMapperExtensions + { + public static void Type(this IIdMapper idMapper) where TPersistentType : IIdentifierType + { + ReflectHelper + .CastOrThrow(idMapper, "generic Type method") + .Type(); + } + + public static void Type(this IIdMapper idMapper, object parameters) where TPersistentType : IIdentifierType + { + ReflectHelper + .CastOrThrow(idMapper, "generic parameterized Type method") + .Type(parameters); + } + + public static void Type(this IIdMapper idMapper, System.Type persistentType, object parameters) + { + ReflectHelper + .CastOrThrow(idMapper, "parameterized Type method") + .Type(persistentType, parameters); + } + } + public interface IIdMapper : IAccessorPropertyMapper, IColumnsMapper { void Generator(IGeneratorDef generator); void Generator(IGeneratorDef generator, Action generatorMapping); void Type(IIdentifierType persistentType); - //void Type() where TPersistentType : IIdentifierType; - //void Type(object parameters) where TPersistentType : IIdentifierType; - //void Type(System.System.Type persistentType, object parameters); - //void Column(Action columnMapper); - //void Columns(params Action[] columnMapper); void UnsavedValue(object value); void Length(int length); } -} \ No newline at end of file +} diff --git a/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs b/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs index 29164265b1d..6ce7958f5a2 100644 --- a/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs +++ b/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs @@ -4,6 +4,7 @@ using System.Reflection; using NHibernate.Cfg.MappingSchema; using NHibernate.Type; +using NHibernate.UserTypes; namespace NHibernate.Mapping.ByCode.Impl { @@ -66,6 +67,48 @@ public void Type(IIdentifierType persistentType) } } + public void Type() + { + Type(typeof (TPersistentType), null); + } + + public void Type(object parameters) + { + Type(typeof (TPersistentType), parameters); + } + + public void Type(System.Type persistentType, object parameters) + { + if (persistentType == null) + { + throw new ArgumentNullException(nameof(persistentType)); + } + if (!typeof (IUserType).IsAssignableFrom(persistentType) && !typeof (IType).IsAssignableFrom(persistentType) && !typeof (ICompositeUserType).IsAssignableFrom(persistentType)) + { + throw new ArgumentOutOfRangeException(nameof(persistentType), "Expected type implementing IUserType, ICompositeUserType or IType."); + } + if (parameters != null) + { + hbmId.type1 = null; + var hbmType = new HbmType + { + name = persistentType.AssemblyQualifiedName, + param = (from pi in parameters.GetType().GetProperties() + let pname = pi.Name + let pvalue = pi.GetValue(parameters, null) + select + new HbmParam {name = pname, Text = new[] {ReferenceEquals(pvalue, null) ? "null" : pvalue.ToString()}}) + .ToArray() + }; + hbmId.type = hbmType; + } + else + { + hbmId.type1 = persistentType.AssemblyQualifiedName; + hbmId.type = null; + } + } + public void UnsavedValue(object value) { hbmId.unsavedvalue = value != null ? value.ToString() : "null"; @@ -182,4 +225,4 @@ public void Access(System.Type accessorType) {} #endregion } -} \ No newline at end of file +} From d26d8097f7462e5222174d9a8c2c39bfb4a3e700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= <12201973+fredericDelaporte@users.noreply.github.com> Date: Fri, 14 Sep 2018 15:46:15 +0200 Subject: [PATCH 2/2] fixup! Add in ByCode support of all type mappings on Id As per review --- src/NHibernate/Mapping/ByCode/IIdMapper.cs | 42 +++++++++---------- .../Mapping/ByCode/Impl/IdMapper.cs | 10 ----- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/NHibernate/Mapping/ByCode/IIdMapper.cs b/src/NHibernate/Mapping/ByCode/IIdMapper.cs index b3fc22365c2..0830ab9b958 100644 --- a/src/NHibernate/Mapping/ByCode/IIdMapper.cs +++ b/src/NHibernate/Mapping/ByCode/IIdMapper.cs @@ -5,41 +5,37 @@ namespace NHibernate.Mapping.ByCode { - // 6.0 TODO: move into IIdMapper, - // and probably add an ITypeMapper for mutualizing the four Type methods with IElementMapper and IPropertyMapper - // (Note that there is no IKeyPropertyMapper to be concerned with, the KeyPropertyMapper use IPropertyMapper - // directly instead.) + public interface IIdMapper : IAccessorPropertyMapper, IColumnsMapper + { + void Generator(IGeneratorDef generator); + void Generator(IGeneratorDef generator, Action generatorMapping); + + void Type(IIdentifierType persistentType); + void UnsavedValue(object value); + void Length(int length); + } + public static class IdMapperExtensions { - public static void Type(this IIdMapper idMapper) where TPersistentType : IIdentifierType + public static void Type(this IIdMapper idMapper) { - ReflectHelper - .CastOrThrow(idMapper, "generic Type method") - .Type(); + Type(idMapper, null); } - public static void Type(this IIdMapper idMapper, object parameters) where TPersistentType : IIdentifierType + public static void Type(this IIdMapper idMapper, object parameters) { - ReflectHelper - .CastOrThrow(idMapper, "generic parameterized Type method") - .Type(parameters); + Type(idMapper, typeof (TPersistentType), parameters); } + // 6.0 TODO: move into IIdMapper, + // and probably add an ITypeMapper for mutualizing it with IElementMapper and IPropertyMapper + // (Note that there is no IKeyPropertyMapper to be concerned with, the KeyPropertyMapper use IPropertyMapper + // directly instead.) public static void Type(this IIdMapper idMapper, System.Type persistentType, object parameters) { ReflectHelper - .CastOrThrow(idMapper, "parameterized Type method") + .CastOrThrow(idMapper, "Type method with a type argument") .Type(persistentType, parameters); } } - - public interface IIdMapper : IAccessorPropertyMapper, IColumnsMapper - { - void Generator(IGeneratorDef generator); - void Generator(IGeneratorDef generator, Action generatorMapping); - - void Type(IIdentifierType persistentType); - void UnsavedValue(object value); - void Length(int length); - } } diff --git a/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs b/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs index 6ce7958f5a2..759065ffb2c 100644 --- a/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs +++ b/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs @@ -67,16 +67,6 @@ public void Type(IIdentifierType persistentType) } } - public void Type() - { - Type(typeof (TPersistentType), null); - } - - public void Type(object parameters) - { - Type(typeof (TPersistentType), parameters); - } - public void Type(System.Type persistentType, object parameters) { if (persistentType == null)