Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5548/nhibernate/src/NHibernate/Collection Modified Files: ArrayHolder.cs Bag.cs CollectionPersister.cs IdentifierBag.cs List.cs Map.cs PersistentCollection.cs Set.cs SortedMap.cs SortedSet.cs Added Files: AbstractCollectionPersister.cs BasicCollectionPersister.cs CollectionPropertyMapping.cs CompositeElementPropertyMapping.cs ElementPropertyMapping.cs ICollectionPersister.cs IQueryableCollection.cs OneToManyPersister.cs Log Message: Various refactorings on the way to 2.1 querying capability --- NEW FILE: CompositeElementPropertyMapping.cs --- using NHibernate.Engine; using NHibernate.Persister; using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Collection { /// <summary> /// Summary description for CompositeElementPropertyMapping. /// </summary> public class CompositeElementPropertyMapping : AbstractPropertyMapping { private readonly IAbstractComponentType compositeType; /// <summary> /// /// </summary> /// <param name="elementColumns"></param> /// <param name="compositeType"></param> /// <param name="factory"></param> public CompositeElementPropertyMapping( string[] elementColumns, IAbstractComponentType compositeType, ISessionFactoryImplementor factory ) { this.compositeType = compositeType; InitComponentPropertyPaths( null, compositeType, elementColumns, factory ); } /// <summary></summary> public override IType Type { get { return compositeType; } } /// <summary></summary> public override string ClassName { get { return compositeType.Name; } } } } --- NEW FILE: ICollectionPersister.cs --- using System.Data; using NHibernate.Cache; using NHibernate.Engine; using NHibernate.Id; using NHibernate.Metadata; using NHibernate.Type; namespace NHibernate.Collection { /// <summary> /// <p>A strategy for persisting a collection role. Defines a contract between /// the persistence strategy and the actual persistent collection framework /// and session. Does not define operations that are required for querying /// collections, or loading by outer join.</p> /// <p> /// Implements persistence of a collection instance while the instance is /// referenced in a particular role.</p> /// <p> /// This class is highly coupled to the <tt>PersistentCollection</tt> /// hierarchy, since double dispatch is used to load and update collection /// elements.</p> /// </summary> /// <remarks> /// May be considered an immutable view of the mapping object /// </remarks> public interface ICollectionPersister { /// <summary> /// Initialize the given collection with the given key /// </summary> /// <param name="key"></param> /// <param name="owner"></param> /// <param name="session"></param> void Initialize( object key, object owner, ISessionImplementor session ); /// <summary> /// Get the cache /// </summary> ICacheConcurrencyStrategy Cache { get; } /// <summary> /// Is this collection role cacheable /// </summary> bool HasCache { get; } /// <summary> /// Get the associated <c>IType</c> /// </summary> PersistentCollectionType CollectionType { get; } /// <summary> /// Get the "key" type (the type of the foreign key) /// </summary> IType KeyType { get; } /// <summary> /// Get the "index" type for a list or map (optional operation) /// </summary> IType IndexType { get; } /// <summary> /// Get the "element" type /// </summary> IType ElementType { get; } /// <summary> /// Return the element class of an array, or null otherwise /// </summary> System.Type ElementClass { get; } /// <summary> /// Read the key from a row of the <tt>IDataReader</tt> /// </summary> /// <param name="rs"></param> /// <param name="session"></param> /// <returns></returns> object ReadKey( IDataReader rs, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="rs"></param> /// <param name="owner"></param> /// <param name="session"></param> /// <returns></returns> object ReadElement( IDataReader rs, object owner, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="rs"></param> /// <param name="session"></param> /// <returns></returns> object ReadIdentifier( IDataReader rs, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="rs"></param> /// <param name="session"></param> /// <returns></returns> object ReadIndex( IDataReader rs, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="st"></param> /// <param name="key"></param> /// <param name="writeOrder"></param> /// <param name="session"></param> void WriteKey( IDbCommand st, object key, bool writeOrder, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="st"></param> /// <param name="elt"></param> /// <param name="writeOrder"></param> /// <param name="session"></param> void WriteElement( IDbCommand st, object elt, bool writeOrder, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="st"></param> /// <param name="idx"></param> /// <param name="writeOrder"></param> /// <param name="session"></param> void WriteIndex( IDbCommand st, object idx, bool writeOrder, ISessionImplementor session ); /// <summary> /// /// </summary> /// <param name="st"></param> /// <param name="idx"></param> /// <param name="writeOrder"></param> /// <param name="session"></param> void WriteIdentifier( IDbCommand st, object idx, bool writeOrder, ISessionImplementor session ); /// <summary> /// Is this an array or primitive values? /// </summary> bool IsPrimitiveArray { get; } /// <summary> /// Is this an array? /// </summary> bool IsArray { get; } /// <summary> /// Is this a one-to-many association? /// </summary> bool IsOneToMany { get; } /// <summary> /// Is this an "indexed" collection? (list or map) /// </summary> bool HasIndex { get; } /// <summary> /// Is this collection lazyily initialized? /// </summary> bool IsLazy { get; } /// <summary> /// Is this collection "inverse", so state changes are not propogated to the database. /// </summary> bool IsInverse { get; } /// <summary> /// Completely remove the persistent state of the collection /// </summary> /// <param name="id"></param> /// <param name="session"></param> void Remove( object id, ISessionImplementor session ); /// <summary> /// (Re)create the collection's persistent state /// </summary> /// <param name="collection"></param> /// <param name="key"></param> /// <param name="session"></param> void Recreate( PersistentCollection collection, object key, ISessionImplementor session ); /// <summary> /// Delete the persistent state of any elements that were removed from the collection /// </summary> /// <param name="collection"></param> /// <param name="key"></param> /// <param name="session"></param> void DeleteRows( PersistentCollection collection, object key, ISessionImplementor session ); /// <summary> /// Update the persistent state of any elements that were modified /// </summary> /// <param name="collection"></param> /// <param name="key"></param> /// <param name="session"></param> void UpdateRows( PersistentCollection collection, object key, ISessionImplementor session ); /// <summary> /// Insert the persistent state of any new collection elements /// </summary> /// <param name="collection"></param> /// <param name="key"></param> /// <param name="session"></param> void InsertRows( PersistentCollection collection, object key, ISessionImplementor session ); /// <summary> /// Get the name of this collection role (the fully qualified class name, extended by a "property path") /// </summary> string Role { get; } /// <summary> /// Get the entity class that "owns" this collection /// </summary> System.Type OwnerClass { get; } /// <summary> /// Get the surrogate key generation strategy (optional operation) /// </summary> IIdentifierGenerator IdentifierGenerator { get; } /// <summary> /// Get the type of the surrogate key /// </summary> IType IdentifierType { get; } /// <summary> /// Does this collection implement "orphan delete"? /// </summary> bool HasOrphanDelete { get; } /// <summary> /// Is this an ordered collection? (An ordered collection is /// ordered by the initialization operation, not by sorting /// that happens in memory, as in the case of a sorted collection.) /// </summary> bool HasOrdering { get; } /// <summary> /// Get the "space" that holds the persistent state /// </summary> object CollectionSpace { get; } /// <summary> /// /// </summary> ICollectionMetadata CollectionMetadata { get; } } } Index: Map.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Map.cs,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** Map.cs 14 Feb 2005 03:35:19 -0000 1.20 --- Map.cs 1 Mar 2005 16:24:44 -0000 1.21 *************** *** 23,27 **** /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( CollectionPersister persister ) { Hashtable clonedMap = new Hashtable( map.Count ); --- 23,27 ---- /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( ICollectionPersister persister ) { Hashtable clonedMap = new Hashtable( map.Count ); *************** *** 70,73 **** --- 70,83 ---- /// <summary> + /// + /// </summary> + /// <param name="collection"></param> + /// <returns></returns> + public override bool IsWrapper( object collection ) + { + return map == collection; + } + + /// <summary> /// Construct an uninitialized Map. /// </summary> *************** *** 93,97 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { if( persister.HasOrdering ) --- 103,107 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { if( persister.HasOrdering ) *************** *** 278,282 **** /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, CollectionPersister persister, object entry, int i, bool writeOrder ) { DictionaryEntry e = ( DictionaryEntry ) entry; --- 288,292 ---- /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { DictionaryEntry e = ( DictionaryEntry ) entry; *************** *** 292,296 **** /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); --- 302,306 ---- /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); *************** *** 318,322 **** /// <param name="disassembled">The disassembled Map.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); --- 328,332 ---- /// <param name="disassembled">The disassembled Map.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { BeforeInitialize( persister ); *************** *** 335,339 **** /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( CollectionPersister persister ) { object[ ] result = new object[map.Count*2]; --- 345,349 ---- /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( ICollectionPersister persister ) { object[ ] result = new object[map.Count*2]; --- NEW FILE: CollectionPropertyMapping.cs --- using NHibernate.Persister; using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Collection { /// <summary> /// Summary description for CollectionPropertyMapping. /// </summary> public class CollectionPropertyMapping : IPropertyMapping { /// <summary></summary> public const string CollectionSize = "size"; /// <summary></summary> public const string CollectionElements = "elements"; /// <summary></summary> public const string CollectionIndices = "indices"; /// <summary></summary> public const string CollectionMaxIndex = "maxIndex"; /// <summary></summary> public const string CollectionMinIndex = "minIndex"; /// <summary></summary> public const string CollectionMaxElement = "maxElement"; /// <summary></summary> public const string CollectionMinElement = "minElement"; private readonly IQueryableCollection memberPersister; private const string InvalidPropertyMessage = "expecting 'elements' or 'indicies' after {0}"; /// <summary> /// /// </summary> /// <param name="memberPersister"></param> public CollectionPropertyMapping( IQueryableCollection memberPersister ) { this.memberPersister = memberPersister; } /// <summary> /// /// </summary> public IType Type { get { return memberPersister.CollectionType; } } /// <summary> /// /// </summary> /// <param name="propertyName"></param> /// <returns></returns> public IType ToType( string propertyName ) { switch ( propertyName ) { case CollectionElements: case CollectionMaxElement: case CollectionMinElement: return memberPersister.ElementType; case CollectionIndices: case CollectionMaxIndex: case CollectionMinIndex: CheckIndex( propertyName ); return memberPersister.IndexType; case CollectionSize: return NHibernateUtil.Int32; default: throw new QueryException( string.Format( InvalidPropertyMessage, propertyName ) ); } } /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="propertyName"></param> /// <returns></returns> public string[] ToColumns( string alias, string propertyName ) { string[] cols; switch ( propertyName ) { case CollectionElements: cols = memberPersister.ElementColumnNames; return StringHelper.Qualify( alias, cols ); case CollectionIndices: CheckIndex( propertyName ); cols = memberPersister.IndexColumnNames; return StringHelper.Qualify( alias, cols ); case CollectionSize: return new string[] { "count(*)" }; case CollectionMaxIndex: CheckIndex( propertyName ); return ColumnFunction( propertyName, "max", memberPersister.IndexColumnNames ) ; case CollectionMinIndex: CheckIndex( propertyName ); return ColumnFunction( propertyName, "min", memberPersister.IndexColumnNames ) ; case CollectionMaxElement: return ColumnFunction( propertyName, "max", memberPersister.IndexColumnNames ) ; case CollectionMinElement: return ColumnFunction( propertyName, "min", memberPersister.IndexColumnNames ) ; default: throw new QueryException( string.Format( InvalidPropertyMessage, propertyName ) ); } } private void CheckIndex( string propertyName ) { if ( !memberPersister.HasIndex ) { throw new QueryException( string.Format( "unindexed collection before {0}", propertyName ) ); } } private string[] ColumnFunction( string propertyName, string function, string[] cols ) { if ( cols.Length !=1 ) { throw new QueryException( string.Format( "composite collection element in {0}", propertyName ) ); } return new string[] { function + StringHelper.OpenParen + cols[0] + StringHelper.ClosedParen }; } } } Index: CollectionPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/CollectionPersister.cs,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** CollectionPersister.cs 14 Feb 2005 03:35:19 -0000 1.33 --- CollectionPersister.cs 1 Mar 2005 16:24:44 -0000 1.34 *************** *** 11,14 **** --- 11,15 ---- using NHibernate.Mapping; using NHibernate.Metadata; + using NHibernate.Persister; using NHibernate.SqlCommand; using NHibernate.Type; *************** *** 25,29 **** /// May be considered an immutable view of the mapping object /// </remarks> ! public sealed class CollectionPersister : ICollectionMetadata { private static readonly ILog log = LogManager.GetLogger( typeof( CollectionPersister ) ); --- 26,30 ---- /// May be considered an immutable view of the mapping object /// </remarks> ! public sealed class CollectionPersister : ICollectionMetadata, IQueryableCollection { private static readonly ILog log = LogManager.GetLogger( typeof( CollectionPersister ) ); *************** *** 65,69 **** private readonly ICacheConcurrencyStrategy cache; private readonly PersistentCollectionType collectionType; ! private readonly OuterJoinLoaderType enableJoinedFetch; private readonly System.Type ownerClass; --- 66,70 ---- private readonly ICacheConcurrencyStrategy cache; private readonly PersistentCollectionType collectionType; ! private readonly OuterJoinFetchStrategy enableJoinedFetch; private readonly System.Type ownerClass; *************** *** 81,84 **** --- 82,87 ---- private readonly Dialect.Dialect dialect; private readonly ISessionFactoryImplementor factory; + private readonly IPropertyMapping elementPropertyMapping; + private readonly IClassPersister elementPersister; /// <summary> *************** *** 92,96 **** this.factory = factory; this.dialect = factory.Dialect; ! collectionType = collection.Type; role = collection.Role; ownerClass = collection.OwnerClass; --- 95,99 ---- this.factory = factory; this.dialect = factory.Dialect; ! collectionType = collection.CollectionType; role = collection.Role; ownerClass = collection.OwnerClass; *************** *** 100,104 **** hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? Template.RenderOrderByStringTemplate( sqlOrderByString, dialect ) : null; - sqlWhereString = collection.Where; hasWhere = sqlWhereString != null; --- 103,106 ---- *************** *** 107,110 **** --- 109,114 ---- hasOrphanDelete = collection.OrphanDelete; + //batchSize = collection.BatchSize; + cache = collection.Cache; *************** *** 131,147 **** ICollection iter; if( isOneToMany ) { ! EntityType type = collection.OneToMany.Type; elementType = type; ! PersistentClass associatedClass = datastore.GetClassMapping( type.PersistentClass ); span = associatedClass.Identifier.ColumnSpan; iter = associatedClass.Key.ColumnCollection; table = associatedClass.Table; ! enableJoinedFetch = OuterJoinLoaderType.Eager; } else { ! table = collection.Table; elementType = collection.Element.Type; span = collection.Element.ColumnSpan; --- 135,162 ---- ICollection iter; + elementType = collection.Element.Type; + + if ( elementType.IsEntityType ) + { + elementPersister = factory.GetPersister( ( (EntityType) elementType).AssociatedClass ); + } + else + { + elementPersister = null; + } + if( isOneToMany ) { ! EntityType type = (EntityType) collection.Element.Type; elementType = type; ! PersistentClass associatedClass = datastore.GetClassMapping( type.AssociatedClass ); span = associatedClass.Identifier.ColumnSpan; iter = associatedClass.Key.ColumnCollection; table = associatedClass.Table; ! enableJoinedFetch = OuterJoinFetchStrategy.Eager; } else { ! table = collection.CollectionTable; elementType = collection.Element.Type; span = collection.Element.ColumnSpan; *************** *** 149,153 **** iter = collection.Element.ColumnCollection; CheckColumnDuplication( distinctColumns, collection.Element.ColumnCollection ); - } --- 164,167 ---- *************** *** 257,260 **** --- 271,312 ---- } loader = CreateCollectionQuery( factory ); + + if ( elementType.IsComponentType ) + { + elementPropertyMapping = new CompositeElementPropertyMapping( elementColumnNames, (IAbstractComponentType) elementType, factory ); + } + else if ( !elementType.IsEntityType ) + { + elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType ); + } + else + { + IClassPersister persister = factory.GetPersister( ( (EntityType) elementType).AssociatedClass ); + // Not all classpersisters implement IPropertyMapping! + if ( persister is IPropertyMapping ) + { + elementPropertyMapping = (IPropertyMapping) persister; + } + else + { + elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType ); + } + } + } + + /// <summary> + /// + /// </summary> + public ICollectionMetadata CollectionMetadata + { + get { return this; } + } + + /// <summary> + /// + /// </summary> + public object CollectionSpace + { + get { return QualifiedTableName; } } *************** *** 282,296 **** /// /// </summary> ! public ICacheConcurrencyStrategy Cache ! { ! get { return cache; } ! } ! ! /// <summary> ! /// ! /// </summary> ! public bool HasCache { ! get { return cache != null; } } --- 334,343 ---- /// /// </summary> ! /// <param name="key"></param> ! /// <param name="owner"></param> ! /// <param name="session"></param> ! public void Initialize( object key, object owner, ISessionImplementor session ) { ! Initializer.Initialize( key, null, owner, session ); } *************** *** 298,308 **** /// /// </summary> ! /// <param name="id"></param> ! public void Softlock( object id ) { ! if( cache != null ) ! { ! cache.Lock( id ); ! } } --- 345,351 ---- /// /// </summary> ! public ICacheConcurrencyStrategy Cache { ! get { return cache; } } *************** *** 310,320 **** /// /// </summary> ! /// <param name="id"></param> ! public void ReleaseSoftlock( object id ) { ! if( cache != null ) ! { ! cache.Release( id ); ! } } --- 353,359 ---- /// /// </summary> ! public bool HasCache { ! get { return cache != null; } } *************** *** 365,369 **** /// /// </summary> ! public OuterJoinLoaderType EnableJoinFetch { get { return enableJoinedFetch; } --- 404,414 ---- /// /// </summary> ! public OuterJoinFetchStrategy EnableJoinFetch ! { ! get { return enableJoinedFetch; } ! } ! ! /// <summary></summary> ! public OuterJoinFetchStrategy EnableJoinedFetch { get { return enableJoinedFetch; } *************** *** 591,594 **** --- 636,647 ---- } + /// <summary> + /// + /// </summary> + public bool IsCollection + { + get { return true; } + } + /// <summary></summary> public bool IsArray *************** *** 604,622 **** public string SelectClauseFragment( string alias ) { - SelectFragment frag = new SelectFragment( factory.Dialect ) - .SetSuffix( String.Empty ) - .AddColumns( alias, elementColumnNames, elementColumnAliases ); - if( hasIndex ) - { - frag.AddColumns( alias, indexColumnNames, indexColumnAliases ); - } - if( hasIdentifier ) - { - frag.AddColumn( alias, identifierColumnName, identifierColumnAlias ); - } // TODO: fix this once the interface is changed from a String to a SqlString // this works for now because there are no parameters in the select string. ! return frag.ToSqlStringFragment( false ) ! .ToString(); } --- 657,663 ---- public string SelectClauseFragment( string alias ) { // TODO: fix this once the interface is changed from a String to a SqlString // this works for now because there are no parameters in the select string. ! return SelectFragment( alias).ToString(); } *************** *** 828,831 **** --- 869,878 ---- /// <summary></summary> + public string TableName + { + get { return qualifiedTableName; } + } + + /// <summary></summary> public string QualifiedTableName { *************** *** 1220,1223 **** --- 1267,1425 ---- } + #region IJoinable 2.1 bits + /// <summary> + /// + /// </summary> + public string Name + { + get { return Role; } + } + + /// <summary> + /// + /// </summary> + /// <returns></returns> + public bool ConsumesAlias( ) + { + return false; + } + + /// <summary> + /// + /// </summary> + public bool IsManyToMany + { + get { return ElementType.IsEntityType; } + } + + /// <summary> + /// + /// </summary> + public string[] JoinKeyColumns + { + get { return KeyColumnNames; } + } + + /// <summary> + /// + /// </summary> + /// <param name="alias"></param> + /// <param name="suffix"></param> + /// <param name="includeCollectionColumns"></param> + /// <returns></returns> + public SqlString SelectFragment( string alias, string suffix, bool includeCollectionColumns ) + { + return includeCollectionColumns ? SelectFragment( alias ) : null; + } + + /// <summary> + /// + /// </summary> + /// <param name="alias"></param> + /// <param name="innerJoin"></param> + /// <param name="includeSubclasses"></param> + /// <returns></returns> + public SqlString FromJoinFragment( string alias, bool innerJoin, bool includeSubclasses ) + { + return null; + } + + /// <summary> + /// + /// </summary> + /// <param name="alias"></param> + /// <param name="innerJoin"></param> + /// <param name="includeSubclasses"></param> + /// <returns></returns> + public SqlString WhereJoinFragment( string alias, bool innerJoin, bool includeSubclasses ) + { + return null; + } + #endregion + + #region IPropertyMapping 2.1 bits + + /// <summary> + /// + /// </summary> + /// <param name="alias"></param> + /// <param name="propertyName"></param> + /// <returns></returns> + public string[] ToColumns( string alias, string propertyName ) + { + if ( "index".Equals( propertyName ) ) + { + if ( IsManyToMany ) + { + throw new QueryException( "index() function not supported for many-to-many association" ); + } + return StringHelper.Qualify( alias, indexColumnNames ); + } + return elementPropertyMapping.ToColumns( alias, propertyName ); + } + + /// <summary> + /// + /// </summary> + /// <param name="propertyName"></param> + /// <returns></returns> + public IType ToType( string propertyName ) + { + if ( "index".Equals( propertyName ) ) + { + return indexType; + } + return elementPropertyMapping.ToType( propertyName ); + } + + /// <summary> + /// + /// </summary> + public IType Type + { + get { return elementPropertyMapping.Type; } + } + #endregion + + #region IQueryableCollection 2.1 bits + /// <summary> + /// + /// </summary> + public IClassPersister ElementPersister + { + get + { + if ( elementPersister == null ) + { + throw new AssertionFailure( "Not an association" ); + } + + return (ILoadable) elementPersister; + } + } + + /// <summary> + /// + /// </summary> + /// <param name="alias"></param> + /// <returns></returns> + public SqlString SelectFragment( string alias ) + { + SelectFragment frag = new SelectFragment( factory.Dialect ) + .SetSuffix( String.Empty ) + .AddColumns( alias, elementColumnNames, elementColumnAliases ); + if( hasIndex ) + { + frag.AddColumns( alias, indexColumnNames, indexColumnAliases ); + } + if( hasIdentifier ) + { + frag.AddColumn( alias, identifierColumnName, identifierColumnAlias ); + } + // TODO: fix this once the interface is changed from a String to a SqlString + // this works for now because there are no parameters in the select string. + return frag.ToSqlStringFragment( false ); + } + #endregion } } \ No newline at end of file Index: Set.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Set.cs,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** Set.cs 14 Feb 2005 03:35:19 -0000 1.25 --- Set.cs 1 Mar 2005 16:24:44 -0000 1.26 *************** *** 43,47 **** /// </summary> /// <param name="persister"></param> ! protected override object Snapshot( CollectionPersister persister ) { Hashtable clonedMap = new Hashtable( internalSet.Count ); --- 43,47 ---- /// </summary> /// <param name="persister"></param> ! protected override object Snapshot( ICollectionPersister persister ) { Hashtable clonedMap = new Hashtable( internalSet.Count ); *************** *** 97,100 **** --- 97,110 ---- /// /// </summary> + /// <param name="collection"></param> + /// <returns></returns> + public override bool IsWrapper( object collection ) + { + return internalSet == collection; + } + + /// <summary> + /// + /// </summary> /// <param name="session"></param> internal Set( ISessionImplementor session ) : base( session ) *************** *** 123,127 **** /// <param name="disassembled">The disassembled Set.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); --- 133,137 ---- /// <param name="disassembled">The disassembled Set.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { BeforeInitialize( persister ); *************** *** 138,142 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { if( persister.HasOrdering ) --- 148,152 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { if( persister.HasOrdering ) *************** *** 379,383 **** /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, CollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); --- 389,393 ---- /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); *************** *** 391,395 **** /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); --- 401,405 ---- /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); *************** *** 436,440 **** /// </summary> /// <param name="persister"></param> ! public override object Disassemble( CollectionPersister persister ) { object[ ] result = new object[internalSet.Count]; --- 446,450 ---- /// </summary> /// <param name="persister"></param> ! public override object Disassemble( ICollectionPersister persister ) { object[ ] result = new object[internalSet.Count]; --- NEW FILE: AbstractCollectionPersister.cs --- using System; using System.Collections; using System.Data; using Iesi.Collections; using log4net; using NHibernate.Cache; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Engine; using NHibernate.Id; using NHibernate.Impl; using NHibernate.Loader; using NHibernate.Mapping; using NHibernate.Metadata; using NHibernate.Persister; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; using Array = NHibernate.Mapping.Array; [...1268 lines suppressed...] /// <param name="includeSubclasses"></param> /// <returns></returns> public abstract SqlString FromJoinFragment( string alias, bool innerJoin, bool includeSubclasses ); /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="innerJoin"></param> /// <param name="includeSubclasses"></param> /// <returns></returns> public abstract SqlString WhereJoinFragment( string alias, bool innerJoin, bool includeSubclasses ); /// <summary> /// /// </summary> /// <returns></returns> public abstract bool ConsumesAlias( ); } } --- NEW FILE: OneToManyPersister.cs --- using System; using System.Collections; using System.Data; using NHibernate.Cache; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Engine; using NHibernate.Id; using NHibernate.Impl; using NHibernate.Loader; using NHibernate.Mapping; using NHibernate.Metadata; using NHibernate.Persister; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Collection { /// <summary> /// Summary description for OneToManyPersister. /// </summary> public class OneToManyPersister : AbstractCollectionPersister { /// <summary> /// /// </summary> /// <param name="collection"></param> /// <param name="datastore"></param> /// <param name="factory"></param> public OneToManyPersister( Mapping.Collection collection, Configuration datastore, ISessionFactoryImplementor factory ) : base( collection, datastore, factory ) { } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateDeleteString( ) { SqlUpdateBuilder update = new SqlUpdateBuilder( factory ); update.SetTableName( QualifiedTableName ) .AddColumns( KeyColumnNames, "null" ) .SetIdentityColumn( KeyColumnNames, KeyType ); if( HasIndex ) { update.AddColumns( IndexColumnNames, "null" ); } if( HasWhere ) { update.AddWhereFragment( Where ); } return update.ToSqlString(); } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateInsertRowString( ) { SqlUpdateBuilder update = new SqlUpdateBuilder( factory ); update.SetTableName( QualifiedTableName ) .AddColumns( KeyColumnNames, KeyType ) .SetIdentityColumn( ElementColumnNames, ElementType ); if( HasIndex ) { update.AddColumns( IndexColumnNames, IndexType ); } return update.ToSqlString(); } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateUpdateRowString( ) { return null; } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateDeleteRowString( ) { SqlUpdateBuilder update = new SqlUpdateBuilder( factory ); update.SetTableName( QualifiedTableName ) .AddColumns( KeyColumnNames, "null" ); if( HasIndex ) { update.AddColumns( IndexColumnNames, "null" ); } if( HasIdentifier ) { update.AddWhereFragment( RowSelectColumnNames, RowSelectType, " = " ); } else { update.AddWhereFragment( KeyColumnNames, KeyType, " = " ); update.AddWhereFragment( RowSelectColumnNames, RowSelectType, " = " ); } return update.ToSqlString(); } /// <summary> /// /// </summary> /// <returns></returns> public override bool ConsumesAlias( ) { return true; } /// <summary> /// /// </summary> public override bool IsOneToMany { get { return true; } } /// <summary> /// /// </summary> public override bool IsManyToMany { get { return false; } } /// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="collection"></param> /// <param name="session"></param> /// <returns></returns> protected int DoUpdateRows( object id, PersistentCollection collection, ISessionImplementor session ) { // we finish all the "removes" first to take care of possible unique // constraints and so that we can take better advantage of batching IDbCommand st; ICollection entries; int i; int count; try { // update removed rows fks to null count = 0; try { st = null; i = 0; entries = collection.Entries(); foreach( object entry in entries ) { if( collection.NeedsUpdating( entry, i, ElementType ) ) // will still be issued when it used to be null { if( st == null ) { st = session.Batcher.PrepareBatchCommand( SqlDeleteRowString ); } WriteKey( st, id, false, session ); WriteIndex( st, collection.GetIndex( entry, i ), false, session ); session.Batcher.AddToBatch( -1 ); count++; } i++; } } catch( Exception e ) { //TODO: change to SqlException session.Batcher.AbortBatch( e ); throw; } // now update all changed or added rows fks count = 0; try { st = null; i = 0; entries = collection.Entries(); foreach( object entry in entries ) { if( collection.NeedsUpdating( entry, i, ElementType ) ) // will still be issued when it used to be null { if( st == null ) { st = session.Batcher.PrepareBatchCommand( SqlInsertRowString ); } WriteKey( st, id, false, session ); collection.WriteTo( st, this, entry, i, false ); session.Batcher.AddToBatch( 1 ); count++; } i++; } } catch( Exception e ) { //TODO: change to SqlException session.Batcher.AbortBatch( e ); throw; } return count; } catch ( Exception ) { //TODO: change to SqlException throw; } } /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="suffix"></param> /// <param name="includeCollectionColumns"></param> /// <returns></returns> public override SqlString SelectFragment( string alias, string suffix, bool includeCollectionColumns ) { IOuterJoinLoadable ojl = (IOuterJoinLoadable) ElementPersister; if ( includeCollectionColumns ) { // Super impl will ignore suffix for collection columns! return SelectFragment( alias ).Append( StringHelper.CommaSpace ); } else { // Use suffix for the entity columns. return ojl.SelectFragment( alias, suffix ); } } /// <summary> /// /// </summary> /// <param name="factory"></param> /// <returns></returns> protected override ICollectionInitializer CreateCollectionInitializer( ISessionFactoryImplementor factory ) { // Don't worry about batching for now // TODO: Uncomment when we implement OneToManyLoader /* Loader nonbatchLoader = new OneToManyLoader( this, factory ); if ( batchSize > 1 ) { Loader batchLoader = new OneToManyLoader( this, batchSize, factory ); int smallBatchSize = (int) Math.Round( Math.Sqrt( batchSize ) ); Loader smallBatchLoader = new OneToManyLoader( this, smallBatchSize, factory ); // the strategy for choosing batch or single load return new BatchingCollectionInitializer( this, batchSize, batchLoader, smallBatchSize, smallBatchLoader, nonbatchLoader ); } else { // don't to batch loading return (ICollectionInitializer) nonbatchLoader; } */ return null; } /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="innerJoin"></param> /// <param name="includeSubclasses"></param> /// <returns></returns> public override SqlString FromJoinFragment( string alias, bool innerJoin, bool includeSubclasses ) { return ( (IJoinable) ElementPersister).FromJoinFragment( alias, innerJoin, includeSubclasses ); } /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="innerJoin"></param> /// <param name="includeSubclasses"></param> /// <returns></returns> public override SqlString WhereJoinFragment( string alias, bool innerJoin, bool includeSubclasses ) { return ( (IJoinable) ElementPersister).WhereJoinFragment( alias, innerJoin, includeSubclasses ); } } } --- NEW FILE: ElementPropertyMapping.cs --- using NHibernate.Persister; using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Collection { /// <summary> /// Summary description for ElementPropertyMapping. /// </summary> public class ElementPropertyMapping : IPropertyMapping { private readonly string[] elementColumns; private readonly IType type; /// <summary> /// /// </summary> /// <param name="elementColumns"></param> /// <param name="type"></param> public ElementPropertyMapping( string[] elementColumns, IType type) { this.elementColumns = elementColumns; this.type = type; } #region IPropertyMapping Members /// <summary> /// /// </summary> /// <param name="propertyName"></param> /// <returns></returns> public IType ToType( string propertyName ) { if ( propertyName == null || "id".Equals( propertyName ) ) { return type; } else { throw new QueryException( string.Format( "cannot dereference scalar collection element: {0}", propertyName ) ); } } /// <summary> /// /// </summary> /// <param name="alias"></param> /// <param name="propertyName"></param> /// <returns></returns> public string[] ToColumns( string alias, string propertyName ) { if ( propertyName == null || "id".Equals( propertyName ) ) { return StringHelper.Qualify( alias, elementColumns ); } else { throw new QueryException( string.Format( "cannot dereference scalar collection element: {0}", propertyName ) ); } } /// <summary> /// /// </summary> public IType Type { get { return type; } } #endregion } } Index: Bag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Bag.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Bag.cs 14 Feb 2005 03:35:19 -0000 1.14 --- Bag.cs 1 Mar 2005 16:24:44 -0000 1.15 *************** *** 62,65 **** --- 62,76 ---- } + + /// <summary> + /// + /// </summary> + /// <param name="collection"></param> + /// <returns></returns> + public override bool IsWrapper( object collection ) + { + return bag == collection; + } + /// <summary> /// *************** *** 78,82 **** /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader reader, CollectionPersister persister, object owner ) { object element = persister.ReadElement( reader, owner, session ); --- 89,93 ---- /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader reader, ICollectionPersister persister, object owner ) { object element = persister.ReadElement( reader, owner, session ); *************** *** 93,97 **** /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, CollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); --- 104,108 ---- /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); *************** *** 102,106 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { this.bag = new ArrayList(); --- 113,117 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { this.bag = new ArrayList(); *************** *** 157,161 **** /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( CollectionPersister persister ) { ArrayList clonedList = new ArrayList( bag.Count ); --- 168,172 ---- /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( ICollectionPersister persister ) { ArrayList clonedList = new ArrayList( bag.Count ); *************** *** 186,190 **** /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( CollectionPersister persister ) { int length = bag.Count; --- 197,201 ---- /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( ICollectionPersister persister ) { int length = bag.Count; *************** *** 205,209 **** /// <param name="disassembled">The disassembled Bag.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); --- 216,220 ---- /// <param name="disassembled">The disassembled Bag.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { BeforeInitialize( persister ); *************** *** 228,232 **** /// <c>many-to-many</c> so it is just recreated. /// </returns> ! public override bool NeedsRecreate( CollectionPersister persister ) { return !persister.IsOneToMany; --- 239,243 ---- /// <c>many-to-many</c> so it is just recreated. /// </returns> ! public override bool NeedsRecreate( ICollectionPersister persister ) { return !persister.IsOneToMany; Index: ArrayHolder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/ArrayHolder.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** ArrayHolder.cs 14 Feb 2005 03:35:19 -0000 1.17 --- ArrayHolder.cs 1 Mar 2005 16:24:44 -0000 1.18 *************** *** 48,52 **** /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( CollectionPersister persister ) { int length = /*(array==null) ? temp.Count :*/ array.Length; --- 48,52 ---- /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( ICollectionPersister persister ) { int length = /*(array==null) ? temp.Count :*/ array.Length; *************** *** 95,99 **** /// <param name="session"></param> /// <param name="persister"></param> ! public ArrayHolder( ISessionImplementor session, CollectionPersister persister ) : base( session ) { --- 95,99 ---- /// <param name="session"></param> /// <param name="persister"></param> ! public ArrayHolder( ISessionImplementor session, ICollectionPersister persister ) : base( session ) { *************** *** 112,115 **** --- 112,125 ---- /// /// </summary> + /// <param name="collection"></param> + /// <returns></returns> + public override bool IsWrapper( object collection ) + { + return array == collection; + } + + /// <summary> + /// + /// </summary> /// <param name="elementType"></param> /// <returns></returns> *************** *** 165,169 **** /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, CollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); --- 175,179 ---- /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); *************** *** 178,182 **** /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); --- 188,192 ---- /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); *************** *** 235,239 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { } --- 245,249 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { } *************** *** 261,265 **** /// <param name="disassembled">The disassembled Array.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { object[] cached = ( object[] ) disassembled; --- 271,275 ---- /// <param name="disassembled">The disassembled Array.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { object[] cached = ( object[] ) disassembled; *************** *** 279,283 **** /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( CollectionPersister persister ) { int length = array.Length; --- 289,293 ---- /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( ICollectionPersister persister ) { int length = array.Length; Index: List.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/List.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** List.cs 14 Feb 2005 03:35:19 -0000 1.19 --- List.cs 1 Mar 2005 16:24:44 -0000 1.20 *************** *** 20,24 **** /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( CollectionPersister persister ) { ArrayList clonedList = new ArrayList( list.Count ); --- 20,24 ---- /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( ICollectionPersister persister ) { ArrayList clonedList = new ArrayList( list.Count ); *************** *** 69,72 **** --- 69,82 ---- /// /// </summary> + /// <param name="collection"></param> + /// <returns></returns> + public override bool IsWrapper( object collection ) + { + return list == collection; + } + + /// <summary> + /// + /// </summary> /// <param name="session"></param> internal List( ISessionImplementor session ) : base( session ) *************** *** 90,94 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { this.list = new ArrayList(); --- 100,104 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { this.list = new ArrayList(); *************** *** 289,293 **** /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, CollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); --- 299,303 ---- /// <param name="i"></param> /// <param name="writeOrder"></param> ! public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { persister.WriteElement( st, entry, writeOrder, session ); *************** *** 302,306 **** /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); --- 312,316 ---- /// <param name="owner"></param> /// <returns></returns> ! public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { object element = persister.ReadElement(rs, owner, session); *************** *** 328,332 **** /// <param name="disassembled">The disassembled List.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { BeforeInitialize( persister ); --- 338,342 ---- /// <param name="disassembled">The disassembled List.</param> /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { BeforeInitialize( persister ); *************** *** 344,348 **** /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( CollectionPersister persister ) { int length = list.Count; --- 354,358 ---- /// <param name="persister"></param> /// <returns></returns> ! public override object Disassemble( ICollectionPersister persister ) { int length = list.Count; --- NEW FILE: IQueryableCollection.cs --- using NHibernate.Loader; using NHibernate.Persister; using NHibernate.SqlCommand; namespace NHibernate.Collection { /// <summary> /// A collection role that may be queried or loaded by outer join. /// </summary> public interface IQueryableCollection : IPropertyMapping, IJoinable, ICollectionPersister { /// <summary> /// Get the names of the collection index columns if this is an indexed collection (optional operation) /// </summary> string[] IndexColumnNames { get; } /// <summary> /// Get the names of the collection element columns (or the primary key columns in the case of a one-to-many association) /// </summary> string[] ElementColumnNames { get; } /// <summary> /// Get the names of the collection key columns /// </summary> string[] KeyColumnNames { get; } /// <summary> /// Does this collection role have a where clause filter? /// </summary> bool HasWhere { get; } /// <summary> /// Get the persister of the element class, if this is a /// collection of entities (optional operation). Note that /// for a one-to-many association, the returned persister /// must be <tt>OuterJoinLoadable</tt>. /// </summary> IClassPersister ElementPersister { get; } /// <summary> /// Should we load this collection role by outer joining? /// </summary> OuterJoinFetchStrategy EnableJoinedFetch { get; } /// <summary> /// Generate a list of collection index and element columns /// </summary> /// <param name="alias"></param> /// <returns></returns> SqlString SelectFragment( string alias ); /// <summary> /// Get the extra where clause filter SQL /// </summary> /// <param name="alias"></param> /// <returns></returns> string GetSQLWhereString( string alias ); /// <summary> /// Get the order by SQL /// </summary> /// <param name="alias"></param> /// <returns></returns> string GetSQLOrderByString( string alias ); } } Index: SortedSet.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedSet.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** SortedSet.cs 14 Feb 2005 03:35:19 -0000 1.14 --- SortedSet.cs 1 Mar 2005 16:24:44 -0000 1.15 *************** *** 23,27 **** /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( CollectionPersister persister ) { SortedList clonedSet = new SortedList( comparer, internalSet.Count ); --- 23,27 ---- /// <param name="persister"></param> /// <returns></returns> ! protected override object Snapshot( ICollectionPersister persister ) { SortedList clonedSet = new SortedList( comparer, internalSet.Count ); *************** *** 45,49 **** /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( CollectionPersister persister ) { internalSet = new Iesi.Collections.SortedSet( Comparer ); --- 45,49 ---- /// </summary> /// <param name="persister"></param> ! public override void BeforeInitialize( ICollectionPersister persister ) { internalSet = new Iesi.Collections.SortedSet( Comparer ); --- NEW FILE: BasicCollectionPersister.cs --- using System; using System.Collections; using System.Data; using NHibernate.Cache; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Engine; using NHibernate.Id; using NHibernate.Impl; using NHibernate.Loader; using NHibernate.Mapping; using NHibernate.Metadata; using NHibernate.Persister; using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; namespace NHibernate.Collection { /// <summary> /// Collection persister for collections of values and many-to-many associations. /// </summary> public class BasicCollectionPersister : AbstractCollectionPersister { /// <summary> /// /// </summary> /// <param name="collection"></param> /// <param name="datastore"></param> /// <param name="factory"></param> public BasicCollectionPersister( Mapping.Collection collection, Configuration datastore, ISessionFactoryImplementor factory ) : base( collection, datastore, factory ) { } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateDeleteString( ) { SqlDeleteBuilder delete = new SqlDeleteBuilder( factory ); delete.SetTableName( QualifiedTableName ); if( HasIdentifier ) { delete.AddWhereFragment( RowSelectColumnNames, RowSelectType, " = " ); } else { delete.AddWhereFragment( KeyColumnNames, KeyType, " = " ) .AddWhereFragment( RowSelectColumnNames, RowSelectType, " = " ); } return delete.ToSqlString(); } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateInsertRowString( ) { SqlInsertBuilder insert = new SqlInsertBuilder( factory ); insert.SetTableName( QualifiedTableName ) .AddColumn( KeyColumnNames, KeyType ); if( HasIndex ) { insert.AddColumn( IndexColumnNames, IndexType ); } if( HasIdentifier ) { insert.AddColumn( new string[ ] { IdentifierColumnName }, IdentifierType ); } insert.AddColumn( ElementColumnNames, ElementType ); return insert.ToSqlString(); } /// <summary> /// /// </summary> /// <returns></returns> protected override SqlString GenerateUpdateRowString( ) { SqlUpdateBuilder update = new SqlUpdateBuilder( factory ); update.SetTableName( QualifiedTableName ) .AddColumns( ElementColumnNames, ElementType ); if( HasIdentifier ) { update.AddWhereFragment( RowSelectColumnNames, RowSelectType, " = " ); } else { update.AddWhereFragment( KeyColumn... [truncated message content] |