From: <fab...@us...> - 2011-04-05 20:53:37
|
Revision: 5616 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5616&view=rev Author: fabiomaulo Date: 2011-04-05 20:53:30 +0000 (Tue, 05 Apr 2011) Log Message: ----------- Starting id-bag support Modified Paths: -------------- trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionIdMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/IIdBagPropertiesMapper.cs trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/FakeUserCollectionType.cs trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdBagMapperTest.cs Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionIdMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionIdMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/ICollectionIdMapper.cs 2011-04-05 20:53:30 UTC (rev 5616) @@ -0,0 +1,15 @@ +using System; +using NHibernate.Type; + +namespace NHibernate.Mapping.ByCode +{ + public interface ICollectionIdMapper + { + void Generator(IGeneratorDef generator); + void Generator(IGeneratorDef generator, Action<IGeneratorMapper> generatorMapping); + + void Type(IIdentifierType persistentType); + void Column(string name); + void Length(int length); + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/IIdBagPropertiesMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/IIdBagPropertiesMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/IIdBagPropertiesMapper.cs 2011-04-05 20:53:30 UTC (rev 5616) @@ -0,0 +1,13 @@ +using System; +namespace NHibernate.Mapping.ByCode +{ + public interface IIdBagPropertiesMapper : ICollectionPropertiesMapper + { + void Id(Action<ICollectionIdMapper> idMapper); + } + + public interface IIdBagPropertiesMapper<TEntity, TElement> : ICollectionPropertiesMapper<TEntity, TElement> where TEntity : class + { + void Id(Action<ICollectionIdMapper> idMapper); + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Mapping/ByCode/Impl/IdBagMapper.cs 2011-04-05 20:53:30 UTC (rev 5616) @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using NHibernate.Cfg.MappingSchema; +using NHibernate.UserTypes; + +namespace NHibernate.Mapping.ByCode.Impl +{ + public class IdBagMapper : IIdBagPropertiesMapper + { + private readonly IAccessorPropertyMapper entityPropertyMapper; + private readonly KeyMapper keyMapper; + private readonly HbmIdbag mapping; + private ICacheMapper cacheMapper; + + public IdBagMapper(System.Type ownerType, System.Type elementType, System.Type idType, HbmIdbag mapping) + { + if (ownerType == null) + { + throw new ArgumentNullException("ownerType"); + } + if (elementType == null) + { + throw new ArgumentNullException("elementType"); + } + if (mapping == null) + { + throw new ArgumentNullException("mapping"); + } + OwnerType = ownerType; + ElementType = elementType; + this.mapping = mapping; + if (mapping.Key == null) + { + mapping.key = new HbmKey(); + } + keyMapper = new KeyMapper(ownerType, mapping.Key); + entityPropertyMapper = new AccessorPropertyMapper(ownerType, mapping.Name, x => mapping.access = x); + } + + public System.Type OwnerType { get; private set; } + public System.Type ElementType { get; private set; } + + #region Implementation of ICollectionPropertiesMapper + + public void Inverse(bool value) + { + mapping.inverse = value; + } + + public void Mutable(bool value) + { + mapping.mutable = value; + } + + public void Where(string sqlWhereClause) + { + mapping.where = sqlWhereClause; + } + + public void BatchSize(int value) + { + if (value > 0) + { + mapping.batchsize = value; + mapping.batchsizeSpecified = true; + } + else + { + mapping.batchsize = 0; + mapping.batchsizeSpecified = false; + } + } + + public void Lazy(CollectionLazy collectionLazy) + { + mapping.lazySpecified = true; + switch (collectionLazy) + { + case CollectionLazy.Lazy: + mapping.lazy = HbmCollectionLazy.True; + break; + case CollectionLazy.NoLazy: + mapping.lazy = HbmCollectionLazy.False; + break; + case CollectionLazy.Extra: + mapping.lazy = HbmCollectionLazy.Extra; + break; + } + } + + public void Key(Action<IKeyMapper> keyMapping) + { + keyMapping(keyMapper); + } + + public void OrderBy(MemberInfo property) + { + // TODO: read the mapping of the element to know the column of the property (second-pass) + mapping.orderby = property.Name; + } + + public void OrderBy(string sqlOrderByClause) + { + mapping.orderby = sqlOrderByClause; + } + + public void Sort() {} + public void Sort<TComparer>() {} + + public void Cascade(Cascade cascadeStyle) + { + mapping.cascade = cascadeStyle.ToCascadeString(); + } + + public void Type<TCollection>() where TCollection : IUserCollectionType + { + mapping.collectiontype = typeof (TCollection).AssemblyQualifiedName; + } + + public void Type(System.Type collectionType) + { + if (collectionType == null) + { + throw new ArgumentNullException("collectionType"); + } + if (!typeof (IUserCollectionType).IsAssignableFrom(collectionType)) + { + throw new ArgumentOutOfRangeException("collectionType", + string.Format( + "The collection type should be an implementation of IUserCollectionType.({0})", + collectionType)); + } + mapping.collectiontype = collectionType.AssemblyQualifiedName; + } + + public void Table(string tableName) + { + mapping.table = tableName; + } + + public void Catalog(string catalogName) + { + mapping.catalog = catalogName; + } + + public void Schema(string schemaName) + { + mapping.schema = schemaName; + } + + public void Cache(Action<ICacheMapper> cacheMapping) + { + if (cacheMapper == null) + { + var hbmCache = new HbmCache(); + mapping.cache = hbmCache; + cacheMapper = new CacheMapper(hbmCache); + } + cacheMapping(cacheMapper); + } + + public void Filter(string filterName, Action<IFilterMapper> filterMapping) + { + if (filterMapping == null) + { + filterMapping = x => { }; + } + var hbmFilter = new HbmFilter(); + var filterMapper = new FilterMapper(filterName, hbmFilter); + filterMapping(filterMapper); + Dictionary<string, HbmFilter> filters = mapping.filter != null ? mapping.filter.ToDictionary(f => f.name, f => f) : new Dictionary<string, HbmFilter>(1); + filters[filterName] = hbmFilter; + mapping.filter = filters.Values.ToArray(); + } + + public void Fetch(CollectionFetchMode fetchMode) + { + if (fetchMode == null) + { + return; + } + mapping.fetch = fetchMode.ToHbm(); + mapping.fetchSpecified = mapping.fetch != HbmCollectionFetchMode.Select; + } + + public void Id(Action<ICollectionIdMapper> idMapper) + { + throw new NotImplementedException(); + } + + #endregion + + #region Implementation of IEntityPropertyMapper + + public void Access(Accessor accessor) + { + entityPropertyMapper.Access(accessor); + } + + public void Access(System.Type accessorType) + { + entityPropertyMapper.Access(accessorType); + } + + public void OptimisticLock(bool takeInConsiderationForOptimisticLock) + { + mapping.optimisticlock = takeInConsiderationForOptimisticLock; + } + + #endregion + + #region IIdBagPropertiesMapper Members + + public void Loader(string namedQueryReference) + { + if (mapping.SqlLoader == null) + { + mapping.loader = new HbmLoader(); + } + mapping.loader.queryref = namedQueryReference; + } + + public void SqlInsert(string sql) + { + if (mapping.SqlInsert == null) + { + mapping.sqlinsert = new HbmCustomSQL(); + } + mapping.sqlinsert.Text = new[] {sql}; + } + + public void SqlUpdate(string sql) + { + if (mapping.SqlUpdate == null) + { + mapping.sqlupdate = new HbmCustomSQL(); + } + mapping.sqlupdate.Text = new[] {sql}; + } + + public void SqlDelete(string sql) + { + if (mapping.SqlDelete == null) + { + mapping.sqldelete = new HbmCustomSQL(); + } + mapping.sqldelete.Text = new[] {sql}; + } + + public void SqlDeleteAll(string sql) + { + if (mapping.SqlDeleteAll == null) + { + mapping.sqldeleteall = new HbmCustomSQL(); + } + mapping.sqldeleteall.Text = new[] {sql}; + } + + public void Subselect(string sql) + { + if (mapping.Subselect == null) + { + mapping.subselect = new HbmSubselect(); + } + mapping.subselect.Text = new[] {sql}; + } + + #endregion + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-05 18:57:28 UTC (rev 5615) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2011-04-05 20:53:30 UTC (rev 5616) @@ -290,6 +290,7 @@ <Compile Include="Mapping\ByCode\ICacheMapper.cs" /> <Compile Include="Mapping\ByCode\IClassMapper.cs" /> <Compile Include="Mapping\ByCode\ICollectionElementRelation.cs" /> + <Compile Include="Mapping\ByCode\ICollectionIdMapper.cs" /> <Compile Include="Mapping\ByCode\ICollectionPropertiesMapper.cs" /> <Compile Include="Mapping\ByCode\ICollectionSqlsMapper.cs" /> <Compile Include="Mapping\ByCode\IColumnMapper.cs" /> @@ -307,6 +308,7 @@ <Compile Include="Mapping\ByCode\IGenerator.cs" /> <Compile Include="Mapping\ByCode\IGeneratorDef.cs" /> <Compile Include="Mapping\ByCode\IGeneratorMapper.cs" /> + <Compile Include="Mapping\ByCode\IIdBagPropertiesMapper.cs" /> <Compile Include="Mapping\ByCode\IIdMapper.cs" /> <Compile Include="Mapping\ByCode\IJoinedSubclassMapper.cs" /> <Compile Include="Mapping\ByCode\IJoinMapper.cs" /> @@ -370,6 +372,7 @@ <Compile Include="Mapping\ByCode\Generators.cs" /> <Compile Include="Mapping\ByCode\Impl\ICandidatePersistentMembersProvider.cs" /> <Compile Include="Mapping\ByCode\Impl\ICustomizersHolder.cs" /> + <Compile Include="Mapping\ByCode\Impl\IdBagMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\IdMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\JoinedSubclassMapper.cs" /> <Compile Include="Mapping\ByCode\Impl\JoinMapper.cs" /> Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/FakeUserCollectionType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/FakeUserCollectionType.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/FakeUserCollectionType.cs 2011-04-05 20:53:30 UTC (rev 5616) @@ -0,0 +1,51 @@ +using System; +using System.Collections; +using NHibernate.Collection; +using NHibernate.Engine; +using NHibernate.Persister.Collection; +using NHibernate.UserTypes; + +namespace NHibernate.Test.MappingByCode.MappersTests +{ + public class FakeUserCollectionType: IUserCollectionType + { + #region Implementation of IUserCollectionType + + public IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister) + { + throw new NotImplementedException(); + } + + public IPersistentCollection Wrap(ISessionImplementor session, object collection) + { + throw new NotImplementedException(); + } + + public IEnumerable GetElements(object collection) + { + throw new NotImplementedException(); + } + + public bool Contains(object collection, object entity) + { + throw new NotImplementedException(); + } + + public object IndexOf(object collection, object entity) + { + throw new NotImplementedException(); + } + + public object ReplaceElements(object original, object target, ICollectionPersister persister, object owner, IDictionary copyCache, ISessionImplementor session) + { + throw new NotImplementedException(); + } + + public object Instantiate(int anticipatedSize) + { + throw new NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdBagMapperTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdBagMapperTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/MappingByCode/MappersTests/IdBagMapperTest.cs 2011-04-05 20:53:30 UTC (rev 5616) @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.Cfg.MappingSchema; +using NHibernate.Mapping.ByCode; +using NHibernate.Mapping.ByCode.Impl; +using NUnit.Framework; +using SharpTestsEx; + +namespace NHibernate.Test.MappingByCode.MappersTests +{ + public class IdBagMapperTest + { + private class Animal + { + public int Id { get; set; } + private ICollection<Animal> children; + public ICollection<Animal> Children + { + get { return children; } + } + } + + [Test] + public void SetInverse() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Inverse(true); + hbm.Inverse.Should().Be.True(); + mapper.Inverse(false); + hbm.Inverse.Should().Be.False(); + } + + [Test] + public void SetMutable() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Mutable(true); + hbm.Mutable.Should().Be.True(); + mapper.Mutable(false); + hbm.Mutable.Should().Be.False(); + } + + [Test] + public void SetWhere() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Where("c > 10"); + hbm.Where.Should().Be.EqualTo("c > 10"); + } + + [Test] + public void SetBatchSize() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.BatchSize(10); + hbm.BatchSize.Should().Be.EqualTo(10); + } + + [Test] + public void SetLazy() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Lazy(CollectionLazy.Extra); + hbm.Lazy.Should().Be.EqualTo(HbmCollectionLazy.Extra); + mapper.Lazy(CollectionLazy.NoLazy); + hbm.Lazy.Should().Be.EqualTo(HbmCollectionLazy.False); + mapper.Lazy(CollectionLazy.Lazy); + hbm.Lazy.Should().Be.EqualTo(HbmCollectionLazy.True); + } + + [Test] + public void CallKeyMapper() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + bool kmCalled = false; + mapper.Key(km => kmCalled = true); + hbm.Key.Should().Not.Be.Null(); + kmCalled.Should().Be.True(); + } + + [Test] + public void SetCollectionTypeByWrongTypeShouldThrow() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + Executing.This(() => mapper.Type(null)).Should().Throw<ArgumentNullException>(); + Executing.This(() => mapper.Type(typeof(object))).Should().Throw<ArgumentOutOfRangeException>(); + } + + [Test] + public void SetCollectionTypeByGenericType() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Type<FakeUserCollectionType>(); + hbm.CollectionType.Should().Contain("FakeUserCollectionType"); + } + + [Test] + public void SetCollectionTypeByType() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Type(typeof(FakeUserCollectionType)); + hbm.CollectionType.Should().Contain("FakeUserCollectionType"); + } + + [Test] + public void CanChangeAccessor() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Access(Accessor.Field); + + hbm.Access.Should().Not.Be.Null(); + } + + [Test] + public void CanSetCache() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Cache(x => x.Region("pizza")); + + hbm.cache.Should().Not.Be.Null(); + } + + [Test] + public void WhenSetTwoCachePropertiesInTwoActionsThenSetTheTwoValuesWithoutLostTheFirst() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Cache(ch => ch.Region("pizza")); + mapper.Cache(ch => ch.Usage(CacheUsage.NonstrictReadWrite)); + + var hbmCache = hbm.cache; + hbmCache.Should().Not.Be.Null(); + hbmCache.region.Should().Be("pizza"); + hbmCache.usage.Should().Be(HbmCacheUsage.NonstrictReadWrite); + } + + [Test] + public void CanSetAFilterThroughAction() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Filter("filter1", f => f.Condition("condition1")); + hbm.filter.Length.Should().Be(1); + hbm.filter[0].Satisfy(f => f.name == "filter1" && f.condition == "condition1"); + } + + [Test] + public void CanSetMoreFiltersThroughAction() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Filter("filter1", f => f.Condition("condition1")); + mapper.Filter("filter2", f => f.Condition("condition2")); + hbm.filter.Length.Should().Be(2); + hbm.filter.Satisfy(filters => filters.Any(f => f.name == "filter1" && f.condition == "condition1")); + hbm.filter.Satisfy(filters => filters.Any(f => f.name == "filter2" && f.condition == "condition2")); + } + + [Test] + public void WhenSameNameThenOverrideCondition() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Filter("filter1", f => f.Condition("condition1")); + mapper.Filter("filter2", f => f.Condition("condition2")); + mapper.Filter("filter1", f => f.Condition("anothercondition1")); + hbm.filter.Length.Should().Be(2); + hbm.filter.Satisfy(filters => filters.Any(f => f.name == "filter1" && f.condition == "anothercondition1")); + hbm.filter.Satisfy(filters => filters.Any(f => f.name == "filter2" && f.condition == "condition2")); + } + + [Test] + public void WhenActionIsNullThenAddFilterName() + { + var hbm = new HbmIdbag { name = "Children" }; + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Filter("filter1", null); + hbm.filter.Length.Should().Be(1); + hbm.filter[0].Satisfy(f => f.name == "filter1" && f.condition == null); + } + + [Test] + public void SetFetchMode() + { + var hbm = new HbmIdbag(); + var mapper = new IdBagMapper(typeof(Animal), typeof(Animal), typeof(int), hbm); + mapper.Fetch(CollectionFetchMode.Subselect); + hbm.fetch.Should().Be(HbmCollectionFetchMode.Subselect); + hbm.fetchSpecified.Should().Be.True(); + mapper.Fetch(CollectionFetchMode.Join); + hbm.fetch.Should().Be(HbmCollectionFetchMode.Join); + hbm.fetchSpecified.Should().Be.True(); + mapper.Fetch(CollectionFetchMode.Select); + hbm.fetch.Should().Be(HbmCollectionFetchMode.Select); + hbm.fetchSpecified.Should().Be.False(); + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-05 18:57:28 UTC (rev 5615) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-05 20:53:30 UTC (rev 5616) @@ -528,6 +528,8 @@ <Compile Include="MappingByCode\For.cs" /> <Compile Include="MappingByCode\MappersTests\AbstractPropertyContainerMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\ClassMapperWithJoinPropertiesTest.cs" /> + <Compile Include="MappingByCode\MappersTests\FakeUserCollectionType.cs" /> + <Compile Include="MappingByCode\MappersTests\IdBagMapperTest.cs" /> <Compile Include="MappingByCode\MappersTests\JoinMapperTests.cs" /> <Compile Include="MappingByCode\MappersTests\SubclassMapperWithJoinPropertiesTest.cs" /> <Compile Include="MappingByCode\NatureDemo\Naturalness\Address.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |