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..0830ab9b958 100644 --- a/src/NHibernate/Mapping/ByCode/IIdMapper.cs +++ b/src/NHibernate/Mapping/ByCode/IIdMapper.cs @@ -1,5 +1,7 @@ using System; +using NHibernate.Mapping.ByCode.Impl; using NHibernate.Type; +using NHibernate.Util; namespace NHibernate.Mapping.ByCode { @@ -9,12 +11,31 @@ public interface IIdMapper : IAccessorPropertyMapper, IColumnsMapper 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 + + public static class IdMapperExtensions + { + public static void Type(this IIdMapper idMapper) + { + Type(idMapper, null); + } + + public static void Type(this IIdMapper idMapper, object 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, "Type method with a type argument") + .Type(persistentType, parameters); + } + } +} diff --git a/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs b/src/NHibernate/Mapping/ByCode/Impl/IdMapper.cs index 29164265b1d..759065ffb2c 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,38 @@ public void Type(IIdentifierType persistentType) } } + 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 +215,4 @@ public void Access(System.Type accessorType) {} #endregion } -} \ No newline at end of file +}