From: Paul H. <pha...@us...> - 2005-03-14 18:53:25
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6750/nhibernate/src/NHibernate/Loader Modified Files: AbstractEntityLoader.cs CollectionLoader.cs CriteriaLoader.cs EntityLoader.cs ICollectionInitializer.cs Loader.cs OneToManyLoader.cs OuterJoinLoader.cs SimpleEntityLoader.cs SqlLoader.cs Log Message: Refactored as per 2.1 Index: ICollectionInitializer.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/ICollectionInitializer.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ICollectionInitializer.cs 6 Mar 2005 12:44:43 -0000 1.4 --- ICollectionInitializer.cs 14 Mar 2005 18:53:03 -0000 1.5 *************** *** 13,25 **** /// </summary> /// <param name="id"></param> - /// <param name="collection"></param> - /// <param name="owner"></param> - /// <param name="session"></param> - void Initialize( object id, PersistentCollection collection, object owner, ISessionImplementor session ); - - /// <summary> - /// - /// </summary> - /// <param name="id"></param> /// <param name="session"></param> void Initialize( object id, ISessionImplementor session); --- 13,16 ---- Index: EntityLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/EntityLoader.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** EntityLoader.cs 1 Mar 2005 16:24:48 -0000 1.9 --- EntityLoader.cs 14 Mar 2005 18:53:03 -0000 1.10 *************** *** 9,25 **** { /// <summary> ! /// Load an entity using outerjoin fetching to fetch associated entities /// </summary> public class EntityLoader : AbstractEntityLoader, IUniqueEntityLoader { ! private IType[ ] idType; /// <summary> /// ! /// </summary> /// <param name="persister"></param> /// <param name="batchSize"></param> /// <param name="factory"></param> ! public EntityLoader( ILoadable persister, int batchSize, ISessionFactoryImplementor factory ) : this( persister, persister.IdentifierColumnNames, persister.IdentifierType, batchSize, factory ) { } --- 9,30 ---- { /// <summary> ! /// Load an entity using outerjoin fetching to fetch associated entities. /// </summary> + /// <remarks> + /// The <tt>ClassPersister</tt> must implement <tt>Loadable</tt>. For other entities, + /// create a customized subclass of <tt>Loader</tt>. + /// </remarks> public class EntityLoader : AbstractEntityLoader, IUniqueEntityLoader { ! private readonly IType uniqueKeyType; ! private readonly bool batchLoader; /// <summary> /// ! /// </summary>C:\Devel\Sourceforge\NHibernate\nhibernate\src\NHibernate\Loader\EntityLoader.cs /// <param name="persister"></param> /// <param name="batchSize"></param> /// <param name="factory"></param> ! public EntityLoader( IOuterJoinLoadable persister, int batchSize, ISessionFactoryImplementor factory ) : this( persister, persister.IdentifierColumnNames, persister.IdentifierType, batchSize, factory ) { } *************** *** 33,47 **** /// <param name="batchSize"></param> /// <param name="factory"></param> ! public EntityLoader( ILoadable persister, string[] uniqueKey, IType uniqueKeyType, int batchSize, ISessionFactoryImplementor factory ) : base( persister, factory ) { ! idType = new IType[ ] {persister.IdentifierType}; ! ! SqlSelectBuilder selectBuilder = new SqlSelectBuilder( factory ); ! selectBuilder.SetWhereClause( Alias, persister.IdentifierColumnNames, persister.IdentifierType ); ! RenderStatement( selectBuilder, factory ); ! this.SqlString = selectBuilder.ToSqlString(); PostInstantiate(); } --- 38,53 ---- /// <param name="batchSize"></param> /// <param name="factory"></param> ! public EntityLoader( IOuterJoinLoadable persister, string[] uniqueKey, IType uniqueKeyType, int batchSize, ISessionFactoryImplementor factory ) : base( persister, factory ) { ! this.uniqueKeyType = uniqueKeyType; ! IList associations = WalkTree( persister, Alias, factory ); ! InitClassPersisters( associations ); ! SqlString whereString = WhereString( factory, Alias, uniqueKey, uniqueKeyType, batchSize ); ! RenderStatement( associations, whereString, factory ); PostInstantiate(); + + batchLoader = batchSize > 1; } *************** *** 51,58 **** /// <param name="session"></param> /// <param name="id"></param> /// <returns></returns> ! public object LoadByUniqueKey( ISessionImplementor session, object id ) { ! return Load( session, id, null, null ); } --- 57,65 ---- /// <param name="session"></param> /// <param name="id"></param> + /// <param name="optionalObject"></param> /// <returns></returns> ! public object Load( ISessionImplementor session, object id, object optionalObject ) { ! return Load( session, id, optionalObject, id ); } *************** *** 62,70 **** /// <param name="session"></param> /// <param name="id"></param> - /// <param name="obj"></param> /// <returns></returns> ! public object Load( ISessionImplementor session, object id, object obj ) { ! return Load( session, id, obj, id ); } --- 69,76 ---- /// <param name="session"></param> /// <param name="id"></param> /// <returns></returns> ! public object LoadByUniqueKey( ISessionImplementor session, object id ) { ! return Load( session, id, null, null ); } *************** *** 74,83 **** /// <param name="session"></param> /// <param name="id"></param> ! /// <param name="obj"></param> /// <param name="optionalId"></param> /// <returns></returns> ! public object Load( ISessionImplementor session, object id, object obj, object optionalId ) { ! IList list = LoadEntity( session, new object[ ] {id}, idType, obj, optionalId, false ); if( list.Count == 1 ) { --- 80,89 ---- /// <param name="session"></param> /// <param name="id"></param> ! /// <param name="optionalObject"></param> /// <param name="optionalId"></param> /// <returns></returns> ! public object Load( ISessionImplementor session, object id, object optionalObject, object optionalId ) { ! IList list = LoadEntity( session, id, uniqueKeyType, optionalObject, optionalId ); if( list.Count == 1 ) { *************** *** 116,119 **** --- 122,131 ---- return row[ row.Length - 1 ]; } + + /// <summary></summary> + protected override bool IsSingleRowLoader + { + get { return !batchLoader; } + } } } \ No newline at end of file Index: AbstractEntityLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/AbstractEntityLoader.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** AbstractEntityLoader.cs 6 Mar 2005 12:44:43 -0000 1.15 --- AbstractEntityLoader.cs 14 Mar 2005 18:53:03 -0000 1.16 *************** *** 5,8 **** --- 5,9 ---- using NHibernate.Persister; using NHibernate.SqlCommand; + using NHibernate.Type; using NHibernate.Util; *************** *** 12,16 **** public abstract class AbstractEntityLoader : OuterJoinLoader { ! private ILoadable persister; private ICollectionPersister collectionPersister; private int collectionOwner; --- 13,17 ---- public abstract class AbstractEntityLoader : OuterJoinLoader { ! private readonly IOuterJoinLoadable persister; private ICollectionPersister collectionPersister; private int collectionOwner; *************** *** 23,104 **** /// <param name="persister"></param> /// <param name="factory"></param> ! public AbstractEntityLoader( ILoadable persister, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { this.persister = persister; ! alias = ToAlias( persister.ClassName, 0 ); ! } ! ! /// <summary></summary> ! protected string Alias ! { ! get { return alias; } ! } ! ! /// <summary> ! /// Gets the <see cref="ILoadable"/> Persister. ! /// </summary> ! protected ILoadable Persister ! { ! get { return persister; } ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="selectBuilder"></param> ! /// <param name="factory"></param> ! protected void RenderStatement( SqlSelectBuilder selectBuilder, ISessionFactoryImplementor factory ) ! { ! RenderStatement( selectBuilder, String.Empty, factory ); ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="selectBuilder"></param> ! /// <param name="orderBy"></param> ! /// <param name="factory"></param> ! protected void RenderStatement( SqlSelectBuilder selectBuilder, string orderBy, ISessionFactoryImplementor factory ) ! { ! IList associations = WalkTree( persister, alias, factory ); ! ! int joins = associations.Count; ! Suffixes = new string[joins + 1]; ! for( int i = 0; i <= joins; i++ ) ! { ! Suffixes[ i ] = ( joins == 0 ) ? String.Empty : i.ToString() + StringHelper.Underscore; ! } ! ! JoinFragment ojf = OuterJoins( associations ); ! ! selectBuilder.SetSelectClause( ! ( joins == 0 ? String.Empty : SelectString( associations ) + "," ) + ! SelectString( persister, alias, Suffixes[ joins ] ) ! ) ! .SetFromClause ! ( ! persister.FromTableFragment( alias ).Append( ! persister.FromJoinFragment( alias, true, true ) ! ) ! ) ! .SetOuterJoins ! ( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString.Append( ! UseQueryWhereFragment ? ! ( ( IQueryable ) persister ).QueryWhereFragment( alias, true, true ) : ! persister.WhereJoinFragment( alias, true, true ) ! ) ! ) ! .SetOrderByClause( orderBy ); ! ! Persisters = new ILoadable[joins + 1]; ! // classPersisters = new ILoadable[joins+1]; ! LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); ! for( int i = 0; i < joins; i++ ) ! { ! Persisters[ i ] = ( ( OuterJoinableAssociation ) associations[ i ] ).Subpersister; ! } ! Persisters[ joins ] = persister; } --- 24,31 ---- /// <param name="persister"></param> /// <param name="factory"></param> ! public AbstractEntityLoader( IOuterJoinLoadable persister, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { this.persister = persister; ! alias = GenerateRootAlias( persister.ClassName ); } *************** *** 106,114 **** /// /// </summary> /// <param name="condition"></param> /// <param name="factory"></param> ! protected void RenderStatement( SqlString condition, ISessionFactoryImplementor factory ) { ! RenderStatement( condition, String.Empty, factory ); } --- 33,42 ---- /// /// </summary> + /// <param name="associations"></param> /// <param name="condition"></param> /// <param name="factory"></param> ! protected void RenderStatement( IList associations, SqlString condition, ISessionFactoryImplementor factory ) { ! InitStatementString( associations, condition, string.Empty, factory ); } *************** *** 116,179 **** /// /// </summary> ! /// <param name="condition"></param> ! /// <param name="orderBy"></param> ! /// <param name="factory"></param> ! protected void RenderStatement( SqlString condition, string orderBy, ISessionFactoryImplementor factory ) { ! SqlSelectBuilder sqlBuilder = new SqlSelectBuilder( factory ); ! ! IList associations = WalkTree( persister, alias, factory ); ! ! int joins = associations.Count; ! Suffixes = new string[joins + 1]; ! for( int i = 0; i <= joins; i++ ) ! { ! Suffixes[ i ] = ( joins == 0 ) ? String.Empty : i.ToString() + StringHelper.Underscore; ! } ! ! JoinFragment ojf = OuterJoins( associations ); ! sqlBuilder.SetSelectClause( ! ( joins == 0 ? String.Empty : SelectString( associations ) + "," ) + ! SelectString( persister, alias, Suffixes[ joins ] ) ! ); ! ! sqlBuilder.SetFromClause( ! persister.FromTableFragment( alias ).Append( ! persister.FromJoinFragment( alias, true, true ) ! ) ! ); ! ! sqlBuilder.AddWhereClause( condition ); ! ! sqlBuilder.SetOuterJoins( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString.Append ! ( ! UseQueryWhereFragment ? ! ( ( IQueryable ) persister ).QueryWhereFragment( alias, true, true ) : ! persister.WhereJoinFragment( alias, true, true ) ) ! ); ! ! sqlBuilder.SetOrderByClause( orderBy ); ! ! this.SqlString = sqlBuilder.ToSqlString(); ! ! Persisters = new ILoadable[joins + 1]; ! LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); ! for( int i = 0; i < joins; i++ ) { ! Persisters[ i ] = ( ( OuterJoinableAssociation ) associations[ i ] ).Subpersister; } - Persisters[ joins ] = persister; } /// <summary> ! /// Should we sue the discriminator, to narrow the select to ! /// instances of the queried subclass? /// </summary> ! /// <value>False, unless overridden</value> ! protected virtual bool UseQueryWhereFragment { ! get { return false; } } --- 44,63 ---- /// /// </summary> ! /// <param name="spaces"></param> ! protected void AddAllToPropertySpaces( object[] spaces ) { ! for ( int i = 0; i < spaces.Length; i++ ) { ! AddToPropertySpaces( spaces[ i ] ); } } /// <summary> ! /// /// </summary> ! /// <param name="space"></param> ! protected virtual void AddToPropertySpaces( object space ) { ! throw new NotSupportedException( "only criteria queries need to autoflush" ); } *************** *** 188,192 **** collectionOwner = -1; // if no collection found classPersisters = new ILoadable[ joins + 1 ]; ! owners = new int[ joins + 1 ]; aliases = new string[ joins + 1 ]; LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); --- 72,76 ---- collectionOwner = -1; // if no collection found classPersisters = new ILoadable[ joins + 1 ]; ! SetOwners( new int[ joins + 1 ] ); aliases = new string[ joins + 1 ]; LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); *************** *** 198,202 **** { classPersisters[ i ] = (ILoadable) subpersister; ! owners[ i ] = ToOwner( oj, joins, oj.IsOneToOne ); aliases[ i ] = oj.Subalias; if ( oj.JoinType == JoinType.InnerJoin ) --- 82,86 ---- { classPersisters[ i ] = (ILoadable) subpersister; ! Owners[ i ] = ToOwner( oj, joins, oj.IsOneToOne ); aliases[ i ] = oj.Subalias; if ( oj.JoinType == JoinType.InnerJoin ) *************** *** 229,238 **** } classPersisters[ joins ] = persister; ! owners[ joins ] = -1; aliases[ joins ] = alias; ! if ( ArrayHelper.IsAllNegative( owners ) ) { ! owners = null; } } --- 113,122 ---- } classPersisters[ joins ] = persister; ! Owners[ joins ] = -1; aliases[ joins ] = alias; ! if ( ArrayHelper.IsAllNegative( Owners ) ) { ! SetOwners( null ); } } *************** *** 241,251 **** /// /// </summary> ! /// <param name="spaces"></param> ! protected void AddAllToPropertySpaces( object[] spaces ) { ! for ( int i = 0; i < spaces.Length; i++ ) ! { ! AddToPropertySpaces( spaces[ i ] ); ! } } --- 125,199 ---- /// /// </summary> ! /// <param name="associations"></param> ! /// <param name="condition"></param> ! /// <param name="orderBy"></param> ! /// <param name="factory"></param> ! protected void InitStatementString( IList associations, SqlString condition, string orderBy, ISessionFactoryImplementor factory ) { ! int joins = CountClassPersisters( associations ); ! ! Suffixes = GenerateSuffixes( joins + 1 ); ! ! JoinFragment ojf = MergeOuterJoins( associations ); ! ! SqlString = new SqlSelectBuilder( factory ) ! .SetSelectClause( ! persister.SelectFragment( alias, Suffixes[ joins ] ) + ! SelectString( associations, factory ) ! ) ! .SetFromClause( ! persister.FromTableFragment( alias ).Append( ! persister.FromJoinFragment( alias, true, true ) ) ! ) ! .AddWhereClause( condition ) ! .SetOuterJoins( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString ! ) ! .AddWhereClause( GetWhereFragment() ) ! .SetOrderByClause( orderBy ) ! .ToSqlString(); ! } ! ! /// <summary> ! /// Don't bother with the discriminator, unless overridded by subclass ! /// </summary> ! /// <returns></returns> ! protected virtual SqlString GetWhereFragment( ) ! { ! return persister.WhereJoinFragment( alias, true, true ); ! } ! ! /// <summary> ! /// Gets the <see cref="ILoadable"/> Persister. ! /// </summary> ! protected ILoadable Persister ! { ! get { return persister; } ! } ! ! /// <summary></summary> ! protected string Alias ! { ! get { return alias; } ! set { Alias = value; } ! } ! ! /// <summary></summary> ! protected override ICollectionPersister CollectionPersister ! { ! get { return collectionPersister; } ! } ! ! /// <summary></summary> ! protected override int CollectionOwner ! { ! get { return collectionOwner; } ! } ! ! /// <summary></summary> ! protected string[] EntityAliases ! { ! get { return aliases; } } *************** *** 253,260 **** /// /// </summary> ! /// <param name="space"></param> ! protected void AddToPropertySpaces( object space ) { ! throw new NotSupportedException( "only criteria queries need to autoflush" ); } } --- 201,227 ---- /// /// </summary> ! /// <param name="type"></param> ! /// <param name="mappingDefault"></param> ! /// <param name="path"></param> ! /// <param name="table"></param> ! /// <param name="foreignKeyColumns"></param> ! /// <returns></returns> ! protected override bool IsJoinedFetchEnabled( ! IType type, ! bool mappingDefault, ! string path, ! string table, ! string[] foreignKeyColumns ) { ! return mappingDefault; ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <returns></returns> ! public override string ToString() ! { ! return this.GetType().Name + " for " + Persister.ClassName; } } Index: CollectionLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/CollectionLoader.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** CollectionLoader.cs 6 Mar 2005 12:44:43 -0000 1.14 --- CollectionLoader.cs 14 Mar 2005 18:53:03 -0000 1.15 *************** *** 1,4 **** --- 1,5 ---- using System; using System.Collections; + using System.Text; using NHibernate.Collection; using NHibernate.Engine; *************** *** 15,20 **** public class CollectionLoader : OuterJoinLoader, ICollectionInitializer { ! private IQueryableCollection collectionPersister; ! private IType keyType; /// <summary> --- 16,21 ---- public class CollectionLoader : OuterJoinLoader, ICollectionInitializer { ! private readonly IQueryableCollection collectionPersister; ! private readonly IType keyType; /// <summary> *************** *** 35,93 **** public CollectionLoader( IQueryableCollection persister, int batchSize, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { ! keyType = persister.KeyType; ! ! string alias = ToAlias( persister.TableName, 0 ); ! ! //TODO: H2.0.3 the whereString is appended with the " and " - I don't think ! // that is needed because we are building SqlStrings differently and the Builder ! // probably already takes this into account. ! SqlString whereSqlString = null; ! if( persister.HasWhere ) ! { ! whereSqlString = new SqlString( persister.GetSQLWhereString( alias ) ); ! } IList associations = WalkCollectionTree( persister, alias, factory ); ! int joins = associations.Count; ! Suffixes = new string[joins]; ! for( int i = 0; i < joins; i++ ) ! { ! Suffixes[ i ] = i.ToString() + StringHelper.Underscore; ! } ! ! JoinFragment ojf = OuterJoins( associations ); ! SqlSelectBuilder selectBuilder = new SqlSelectBuilder( factory ); ! selectBuilder.SetSelectClause( ! persister.SelectFragment( alias ).ToString() + ! ( joins == 0 ? String.Empty : ", " + SelectString( associations ) ) ! ) ! .SetFromClause( persister.TableName, alias ) ! .SetWhereClause( alias, persister.KeyColumnNames, persister.KeyType ) ! .SetOuterJoins( ojf.ToFromFragmentString, ojf.ToWhereFragmentString ); ! if( persister.HasWhere ) ! { ! selectBuilder.AddWhereClause( whereSqlString ); ! } ! if( persister.HasOrdering ) { ! selectBuilder.SetOrderByClause( persister.GetSQLOrderByString( alias ) ); } ! this.SqlString = selectBuilder.ToSqlString(); ! ! Persisters = new ILoadable[joins]; ! LockModeArray = CreateLockModeArray( joins, LockMode.None ); ! for( int i = 0; i < joins; i++ ) { ! Persisters[ i ] = ( ILoadable ) ( ( OuterJoinableAssociation ) associations[ i ] ).Subpersister; } - this.collectionPersister = persister; - - PostInstantiate(); - } --- 36,71 ---- public CollectionLoader( IQueryableCollection persister, int batchSize, ISessionFactoryImplementor factory ) : base( factory.Dialect ) { ! this.collectionPersister = persister; ! this.keyType = persister.KeyType; + string alias = GenerateRootAlias( persister.TableName ); IList associations = WalkCollectionTree( persister, alias, factory ); ! InitStatementString( persister, alias, associations, batchSize, factory ); ! InitClassPersisters( associations ); ! ! PostInstantiate(); ! } ! private void InitClassPersisters( IList associations ) ! { ! int joins = associations.Count; ! LockModeArray = CreateLockModeArray( joins, LockMode.None ); ! classPersisters = new ILoadable[ joins ]; ! SetOwners( new int[ joins ] ); ! int i = 0; ! foreach( OuterJoinableAssociation oj in associations ) { ! classPersisters[ i ] = (ILoadable) oj.Joinable; ! Owners[ i ] = ToOwner( oj, joins, oj.IsOneToOne ); ! i++; } ! if ( ArrayHelper.IsAllNegative( Owners ) ) { ! SetOwners( null ); } } *************** *** 102,111 **** /// </summary> /// <param name="id"></param> - /// <param name="collection"></param> - /// <param name="owner"></param> /// <param name="session"></param> ! public void Initialize( object id, PersistentCollection collection, object owner, ISessionImplementor session ) { ! LoadCollection( session, id, keyType, owner, collection ); } --- 80,117 ---- /// </summary> /// <param name="id"></param> /// <param name="session"></param> ! public void Initialize( object id, ISessionImplementor session ) { ! LoadCollection( session, id, keyType ); ! } ! ! private void InitStatementString( IQueryableCollection persister, string alias, IList associations, int batchSize, ISessionFactoryImplementor factory ) ! { ! Suffixes = GenerateSuffixes( associations.Count ); ! ! SqlString whereString = WhereString( factory, alias, persister.KeyColumnNames, persister.KeyType, batchSize ); ! if ( persister.HasWhere ) ! { ! whereString = whereString.Append( " and ").Append( persister.GetSQLWhereString( alias ) ); ! } ! ! JoinFragment ojf = MergeOuterJoins( associations ); ! SqlSelectBuilder select = new SqlSelectBuilder( factory ) ! .SetSelectClause( ! persister.SelectFragment( alias ).Append( ! SelectString( associations, factory ) ).ToString() ! ) ! .SetFromClause( persister.TableName, alias ) ! .AddWhereClause( whereString ) ! .SetOuterJoins( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString ! ); ! ! if ( persister.HasOrdering ) ! { ! select.SetOrderByClause( persister.GetSQLOrderByString( alias ) ); ! } ! SqlString = select.ToSqlString(); } *************** *** 113,121 **** /// /// </summary> ! /// <param name="id"></param> ! /// <param name="session"></param> ! public void Initialize( object id, ISessionImplementor session ) { ! LoadCollection( session, id, keyType ); } } --- 119,145 ---- /// /// </summary> ! /// <param name="type"></param> ! /// <param name="config"></param> ! /// <param name="path"></param> ! /// <param name="table"></param> ! /// <param name="foreignKeyColumns"></param> ! /// <param name="factory"></param> ! /// <returns></returns> ! protected override JoinType GetJoinType( ! IAssociationType type, ! OuterJoinFetchStrategy config, ! string path, ! string table, ! string[] foreignKeyColumns, ! ISessionFactoryImplementor factory ! ) { ! JoinType joinType = base.GetJoinType( type, config, path, table, foreignKeyColumns, factory ); ! // We can use an inner-join for the many-to-many ! if ( joinType == JoinType.LeftOuterJoin && path.Equals( string.Empty ) ) ! { ! joinType = JoinType.InnerJoin; ! } ! return joinType; } } Index: OneToManyLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/OneToManyLoader.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** OneToManyLoader.cs 6 Mar 2005 12:44:43 -0000 1.15 --- OneToManyLoader.cs 14 Mar 2005 18:53:03 -0000 1.16 *************** *** 13,16 **** --- 13,20 ---- /// Loads one-to-many associations /// </summary> + /// <remarks> + /// The collection persister must implement IQueryableCollection. For + /// other collections, create a customized subclass of Loader. + /// </remarks> public class OneToManyLoader : OuterJoinLoader, ICollectionInitializer { *************** *** 38,108 **** idType = collectionPersister.KeyType; ! //ILoadable persister = ( ILoadable ) factory.GetPersister( ( ( EntityType ) collPersister.ElementType ).AssociatedClass ); ! ILoadable persister = ( ILoadable ) collPersister.ElementPersister; ! ! string alias = ToAlias( collectionPersister.TableName, 0 ); ! ! SqlString whereSqlString = null; ! ! if( collectionPersister.HasWhere ) ! { ! whereSqlString = new SqlString( collectionPersister.GetSQLWhereString( alias ) ); ! } IList associations = WalkTree( persister, alias, factory ); ! int joins = associations.Count; ! Suffixes = new string[joins + 1]; ! for( int i = 0; i <= joins; i++ ) ! { ! Suffixes[ i ] = ( joins == 0 ) ? String.Empty : i.ToString() + StringHelper.Underscore; ! } ! ! JoinFragment ojf = OuterJoins( associations ); ! ! SqlSelectBuilder selectBuilder = new SqlSelectBuilder( factory ); ! ! selectBuilder.SetSelectClause( ! collectionPersister.SelectFragment( alias ).ToString() + ! ( joins == 0 ? String.Empty : "," + SelectString( associations ) ) + ! ", " + ! SelectString( persister, alias, Suffixes[ joins ] ) ! ); ! ! ! selectBuilder.SetFromClause( ! persister.FromTableFragment( alias ).Append( ! persister.FromJoinFragment( alias, true, true ) ! ) ! ); ! ! selectBuilder.SetWhereClause( alias, collectionPersister.KeyColumnNames, collectionPersister.KeyType ); ! if( collectionPersister.HasWhere ) ! { ! selectBuilder.AddWhereClause( whereSqlString ); ! } ! ! selectBuilder.SetOuterJoins( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString.Append( ! persister.WhereJoinFragment( alias, true, true ) ! ) ! ); ! ! if( collectionPersister.HasOrdering ) ! { ! selectBuilder.SetOrderByClause( collectionPersister.GetSQLOrderByString( alias ) ); ! } ! ! this.SqlString = selectBuilder.ToSqlString(); ! ! ! Persisters = new ILoadable[joins + 1]; ! LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); ! for( int i = 0; i < joins; i++ ) ! { ! Persisters[ i ] = ( ( OuterJoinableAssociation ) associations[ i ] ).Subpersister; ! } ! Persisters[ joins ] = persister; PostInstantiate(); --- 42,52 ---- idType = collectionPersister.KeyType; ! IOuterJoinLoadable persister = ( IOuterJoinLoadable ) collPersister.ElementPersister; + string alias = GenerateRootAlias( collPersister.Role ); IList associations = WalkTree( persister, alias, factory ); ! InitStatementString( collPersister, persister, alias, associations, batchSize, factory ); ! InitClassPersisters( persister, associations ); PostInstantiate(); *************** *** 110,115 **** /// <summary> ! /// /// </summary> /// <param name="mappingDefault"></param> /// <param name="path"></param> --- 54,60 ---- /// <summary> ! /// Disable a join back to this same association /// </summary> + /// <param name="type"></param> /// <param name="mappingDefault"></param> /// <param name="path"></param> *************** *** 117,125 **** /// <param name="foreignKeyColumns"></param> /// <returns></returns> ! protected override bool EnableJoinedFetch( bool mappingDefault, string path, string table, string[ ] foreignKeyColumns ) { ! return mappingDefault && ( ! !table.Equals( collectionPersister.TableName ) || ! !ArrayHelper.Equals( foreignKeyColumns, collectionPersister.KeyColumnNames ) ); } --- 62,70 ---- /// <param name="foreignKeyColumns"></param> /// <returns></returns> ! protected override bool IsJoinedFetchEnabled( IType type, bool mappingDefault, string path, string table, string[] foreignKeyColumns ) { ! return base.IsJoinedFetchEnabled( type, mappingDefault, path, table, foreignKeyColumns) && ( ! !table.Equals( collectionPersister.TableName ) || ! !ArrayHelper.Equals( foreignKeyColumns, collectionPersister.KeyColumnNames ) ); } *************** *** 135,154 **** /// </summary> /// <param name="id"></param> - /// <param name="collection"></param> - /// <param name="owner"></param> /// <param name="session"></param> ! public void Initialize( object id, PersistentCollection collection, object owner, ISessionImplementor session ) { ! LoadCollection( session, id, idType, owner, collection ); } ! /// <summary> ! /// ! /// </summary> ! /// <param name="id"></param> ! /// <param name="session"></param> ! public void Initialize( object id, ISessionImplementor session ) { ! LoadCollection( session, id, idType ); } } --- 80,157 ---- /// </summary> /// <param name="id"></param> /// <param name="session"></param> ! public void Initialize( object id, ISessionImplementor session ) { ! LoadCollection( session, id, idType ); } ! private void InitClassPersisters( IOuterJoinLoadable persister, IList associations ) { ! int joins = associations.Count; ! LockModeArray = CreateLockModeArray( joins + 1, LockMode.None ); ! ! Persisters = new ILoadable[joins + 1]; ! SetOwners( new int[ joins + 1 ] ); ! for( int i = 0; i < joins; i++ ) ! { ! OuterJoinableAssociation oj = ( OuterJoinableAssociation ) associations[ i ]; ! Persisters[ i ] = (ILoadable) oj.Joinable; ! Owners[ i ] = ToOwner( oj, joins, oj.IsOneToOne ); ! } ! Persisters[ joins ] = persister; ! Owners[ joins ] = -1; ! ! if ( ArrayHelper.IsAllNegative( Owners ) ) ! { ! SetOwners( null ); ! } ! } ! ! private void InitStatementString( ! IQueryableCollection collPersister, ! IOuterJoinLoadable persister, ! string alias, ! IList associations, ! int batchSize, ! ISessionFactoryImplementor factory ! ) ! { ! int joins = associations.Count; ! ! Suffixes = GenerateSuffixes( joins + 1 ); ! ! SqlString whereSqlString = WhereString( factory, alias, collPersister.KeyColumnNames, collPersister.KeyType, batchSize ); ! ! if( collectionPersister.HasWhere ) ! { ! whereSqlString.Append( " and " ).Append( collectionPersister.GetSQLWhereString( alias ) ); ! } ! ! JoinFragment ojf = MergeOuterJoins( associations ); ! ! SqlSelectBuilder selectBuilder = new SqlSelectBuilder( factory ) ! .SetSelectClause( ! collectionPersister.SelectFragment( alias, Suffixes[ joins ], true ).ToString() + ! SelectString( associations, factory ) ! ) ! .SetFromClause( ! persister.FromTableFragment( alias ).Append( ! persister.FromJoinFragment( alias, true, true ) ! ) ! ) ! .AddWhereClause( whereSqlString ) ! .SetOuterJoins( ! ojf.ToFromFragmentString, ! ojf.ToWhereFragmentString.Append( ! persister.WhereJoinFragment( alias, true, true ) ! ) ! ); ! ! if( collectionPersister.HasOrdering ) ! { ! selectBuilder.SetOrderByClause( collectionPersister.GetSQLOrderByString( alias ) ); ! } ! ! this.SqlString = selectBuilder.ToSqlString(); } } Index: CriteriaLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/CriteriaLoader.cs,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** CriteriaLoader.cs 31 Dec 2004 20:57:25 -0000 1.11 --- CriteriaLoader.cs 14 Mar 2005 18:53:03 -0000 1.12 *************** *** 2,8 **** --- 2,12 ---- using System.Data; using System.Text; + using Iesi.Collections; + using NHibernate.Dialect; using NHibernate.Engine; using NHibernate.Expression; + using NHibernate.Impl; using NHibernate.Persister; + using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; *************** *** 17,24 **** /// queries are more like multi-object <c>Load()</c>s than like HQL queries. /// </remarks> ! public class CriteriaLoader : AbstractEntityLoader { ! private ICriteria criteria; ! //private static readonly IType[] noTypes = new IType[0]; /// <summary> --- 21,29 ---- /// queries are more like multi-object <c>Load()</c>s than like HQL queries. /// </remarks> ! internal class CriteriaLoader : AbstractEntityLoader { ! private CriteriaImpl criteria; ! private ISet querySpaces = new HashedSet(); ! private IType[] resultTypes; /// <summary> *************** *** 28,42 **** /// <param name="factory"></param> /// <param name="criteria"></param> ! public CriteriaLoader( ILoadable persister, ISessionFactoryImplementor factory, ICriteria criteria ) : base( persister, factory ) { this.criteria = criteria; ! IEnumerator iter = criteria.IterateExpressions(); StringBuilder orderByBuilder = new StringBuilder( 60 ); bool commaNeeded = false; - iter = criteria.IterateOrderings(); while( iter.MoveNext() ) { --- 33,50 ---- /// <param name="factory"></param> /// <param name="criteria"></param> ! public CriteriaLoader( IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl criteria ) : base( persister, factory ) { this.criteria = criteria; ! AddAllToPropertySpaces( persister.PropertySpaces ); ! ! resultTypes = new IType[ 1 ]; ! resultTypes[ 0 ] = NHibernateUtil.Entity( persister.MappedClass ); StringBuilder orderByBuilder = new StringBuilder( 60 ); bool commaNeeded = false; + IEnumerator iter = criteria.IterateOrderings(); while( iter.MoveNext() ) { *************** *** 52,59 **** } ! RenderStatement( criteria.Expression.ToSqlString( factory, criteria.PersistentClass, Alias ), orderByBuilder.ToString(), factory ); PostInstantiate(); - } --- 60,68 ---- } ! IList associations = WalkTree( persister, Alias, factory ); ! InitClassPersisters( associations ); ! InitStatementString( associations, criteria.Expression.ToSqlString( factory, criteria.PersistentClass, Alias ), orderByBuilder.ToString(), factory ); PostInstantiate(); } *************** *** 82,87 **** IType[ ] typeArray = ( IType[ ] ) types.ToArray( typeof( IType ) ); ! QueryParameters qp = new QueryParameters( typeArray, valueArray, null, criteria.Selection ); ! return Find( session, qp, true ); } --- 91,110 ---- IType[ ] typeArray = ( IType[ ] ) types.ToArray( typeof( IType ) ); ! // TODO: 2.1 Uncomment once CriteriaImpl up to standard ! /* ! RowSelection selection = new RowSelection(); ! selection.FirstRow = criteria.FirstResult; ! selection.MaxRows = criteria.MaxResults; ! selection.Timeout = criteria.Timeout; ! selection.FetchSize = criteria.FetchSize; ! ! QueryParameters qp = new QueryParameters( typeArray, valueArray, criteria.LockModes, selection ); ! qp.Cacheable = criteria.Cacheable; ! qp.CacheRegion = criteria.CacheRegion; ! */ ! ! QueryParameters qp = new QueryParameters( typeArray, valueArray, criteria.LockModes, criteria.Selection ); ! ! return List( session, qp, querySpaces, resultTypes ); } *************** *** 95,110 **** protected override object GetResultColumnOrRow( object[ ] row, IDataReader rs, ISessionImplementor session ) { return row[ row.Length - 1 ]; } /// <summary> ! /// Navigate associations, returning the aliased columns. Adds extra table joins ! /// to this loader. /// </summary> ! /// <param name="pathExpression"></param> /// <returns></returns> ! public string[ ] ToColumns( string pathExpression ) { ! return null; } --- 118,160 ---- protected override object GetResultColumnOrRow( object[ ] row, IDataReader rs, ISessionImplementor session ) { + //return criteria.ResultTransformer.TransformTuple( row, EntityAliases ); return row[ row.Length - 1 ]; } /// <summary> ! /// /// </summary> ! /// <param name="type"></param> ! /// <param name="config"></param> ! /// <param name="path"></param> ! /// <param name="table"></param> ! /// <param name="foreignKeyColumns"></param> ! /// <param name="factory"></param> /// <returns></returns> ! protected override JoinType GetJoinType( ! IAssociationType type, ! OuterJoinFetchStrategy config, ! string path, ! string table, ! string[] foreignKeyColumns, ! ISessionFactoryImplementor factory ) { ! if ( criteria.IsJoin( path ) ) ! { ! return JoinType.InnerJoin; ! } ! else ! { ! FetchMode fm = criteria.GetFetchMode( path ); ! //fm==null || - an Enum can't be null ! if( fm == FetchMode.Default ) ! { ! return base.GetJoinType( type, config, path, table, foreignKeyColumns, factory ); ! } ! else ! { ! return fm == FetchMode.Eager ? JoinType.LeftOuterJoin : JoinType.None; ! } ! } } *************** *** 112,140 **** /// /// </summary> ! /// <param name="mappingDefault"></param> /// <param name="path"></param> ! /// <param name="table"></param> ! /// <param name="foreignKeyColumns"></param> /// <returns></returns> ! protected override bool EnableJoinedFetch( bool mappingDefault, string path, string table, string[ ] foreignKeyColumns ) { ! FetchMode fm = criteria.GetFetchMode( path ); ! //fm==null || - an Enum can't be null ! if( fm == FetchMode.Default ) { ! return mappingDefault; } else { ! return fm == FetchMode.Eager; } } ! /// <summary></summary> ! protected override bool UseQueryWhereFragment { ! get { return true; } } } } \ No newline at end of file --- 162,268 ---- /// /// </summary> ! /// <returns></returns> ! /// <remarks>Uses the discriminator, to narrow the select to instances of the queried subclass.</remarks> ! protected override SqlString GetWhereFragment( ) ! { ! return ( (IQueryable) Persister).QueryWhereFragment( Alias, true, true ); ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="className"></param> ! /// <param name="n"></param> /// <param name="path"></param> ! /// <param name="isLinkTable"></param> /// <returns></returns> ! protected override string GenerateTableAlias( string className, int n, string path, bool isLinkTable ) { ! if ( !isLinkTable ) { ! string userDefinedAlias = criteria.GetAlias( path ); ! if ( userDefinedAlias != null ) ! { ! return userDefinedAlias; ! } ! } ! return base.GenerateTableAlias( className, n, path, isLinkTable ); ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="tableName"></param> ! /// <returns></returns> ! protected override string GenerateRootAlias( string tableName ) ! { ! return CriteriaImpl.RootAlias; ! } ! ! /// <summary> ! /// ! /// </summary> ! public ISet QuerySpaces ! { ! get { return querySpaces; } ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="space"></param> ! protected override void AddToPropertySpaces( object space ) ! { ! querySpaces.Add( space ); ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="sqlSelectString"></param> ! /// <param name="lockModes"></param> ! /// <param name="dialect"></param> ! /// <returns></returns> ! protected string ApplyLocks( string sqlSelectString, IDictionary lockModes, Dialect.Dialect dialect ) ! { ! if ( lockModes == null || lockModes.Count == 0 ) ! { ! return sqlSelectString; } else { ! return sqlSelectString + new ForUpdateFragment( ).ToSqlStringFragment( dialect ); } } ! /// <summary> ! /// ! /// </summary> ! /// <param name="lockModes"></param> ! /// <returns></returns> ! protected override LockMode[] GetLockModes( IDictionary lockModes ) { ! string[] aliases = EntityAliases; ! int size = aliases.Length; ! LockMode[] lockModesArray = new LockMode[ size ]; ! for( int i = 0; i < size; i++ ) ! { ! LockMode lockMode = (LockMode) lockModes[ aliases[ i ] ]; ! lockModesArray[ i ] = lockMode == null ? LockMode.None : lockMode; ! } ! return lockModesArray; } + /// <summary> + /// + /// </summary> + /// <param name="results"></param> + /// <returns></returns> + protected override IList ResultList( IList results ) + { + // TODO: 2.1 Transform the results + //return criteria.ResultTransformer.TransformList( results ); + return results; + } } } \ No newline at end of file Index: OuterJoinLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/OuterJoinLoader.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** OuterJoinLoader.cs 6 Mar 2005 12:44:44 -0000 1.19 --- OuterJoinLoader.cs 14 Mar 2005 18:53:03 -0000 1.20 *************** *** 2,5 **** --- 2,6 ---- using System.Collections; using System.Text; + using Iesi.Collections; using NHibernate.Collection; using NHibernate.Dialect; *************** *** 42,52 **** private LockMode[ ] lockModeArray; [...1298 lines suppressed...] ! } ! else ! { ! // a many-to-one association ! return aliasedPropertyColumns; ! } ! } ! ! private static string[] GetForeignKeyColumns( IOuterJoinLoadable persister, IAssociationType associationType, string[] propertyColumns ) ! { ! if ( associationType.UsePrimaryKeyAsForeignKey ) ! { ! return persister.IdentifierColumnNames; ! } ! else ! { ! return propertyColumns; ! } } Index: SimpleEntityLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/SimpleEntityLoader.cs,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** SimpleEntityLoader.cs 1 Mar 2005 16:24:48 -0000 1.11 --- SimpleEntityLoader.cs 14 Mar 2005 18:53:03 -0000 1.12 *************** *** 15,22 **** public class SimpleEntityLoader : Loader, IUniqueEntityLoader { ! private ILoadable[ ] persister; ! private IType[ ] idType; private SqlString sqlString; ! private LockMode[ ] lockMode; /// <summary> --- 15,22 ---- public class SimpleEntityLoader : Loader, IUniqueEntityLoader { ! private readonly ILoadable[ ] persister; ! private readonly IType idType; private SqlString sqlString; ! private readonly LockMode[ ] lockMode; /// <summary> *************** *** 30,34 **** { this.persister = new ILoadable[ ] {persister}; ! this.idType = new IType[ ] {persister.IdentifierType}; this.sqlString = sqlString; this.lockMode = new LockMode[ ] {lockMode}; --- 30,34 ---- { this.persister = new ILoadable[ ] {persister}; ! this.idType = persister.IdentifierType; this.sqlString = sqlString; this.lockMode = new LockMode[ ] {lockMode}; *************** *** 44,51 **** /// <summary></summary> protected override ILoadable[ ] Persisters { get { return persister; } ! set { persister = value; } } --- 44,63 ---- /// <summary></summary> + protected override int[] Owners + { + get { return null; } + } + + /// <summary></summary> + protected override bool IsSingleRowLoader + { + get { return true; } + } + + /// <summary></summary> protected override ILoadable[ ] Persisters { get { return persister; } ! set { throw new NotSupportedException( "cannot assign to the Persisters property" ); } } *************** *** 72,80 **** public object Load( ISessionImplementor session, object id, object obj ) { ! IList list = LoadEntity( session, new object[ ] {id}, idType, obj, id, false ); if( list.Count == 1 ) { return list[ 0 ]; - //return ( (object[]) list[0] )[0]; } else if( list.Count == 0 ) --- 84,91 ---- public object Load( ISessionImplementor session, object id, object obj ) { ! IList list = LoadEntity( session, id, idType, obj, id ); if( list.Count == 1 ) { return list[ 0 ]; } else if( list.Count == 0 ) *************** *** 112,116 **** return row[ 0 ]; } - } } \ No newline at end of file --- 123,126 ---- Index: Loader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/Loader.cs,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** Loader.cs 6 Mar 2005 12:44:43 -0000 1.49 --- Loader.cs 14 Mar 2005 18:53:03 -0000 1.50 *************** *** 6,9 **** --- 6,10 ---- using NHibernate.Collection; using NHibernate.Engine; + using NHibernate.Impl; using NHibernate.Persister; using NHibernate.SqlCommand; *************** *** 19,32 **** /// This class implements useful common funtionality that concrete loaders would delegate to. /// It is not intended that this functionality would be directly accessed by client code (Hence, [...1116 lines suppressed...] { ! //return new Alias( 10, unique.ToString() + StringHelper.Underscore ) ! // .ToAliasString( StringHelper.Unqualify( description ).ToLower(), Dialect ); ! ! string alias = StringHelper.Unqualify( description ).ToLower().Replace( "$", "_" ); ! int len = Math.Min( 10, alias.Length ); ! ! return alias.Substring( 0, len ) + unique.ToString() + StringHelper.Underscore; } } --- 1187,1195 ---- /// <param name="unique"></param> /// <returns>an alias of the form <c>foo1_</c></returns> ! protected string GenerateAlias( string description, int unique ) { ! // NB Java has this as static but we need the Dialect to achieve correct quoting. ! return new Alias( 10, unique.ToString() + StringHelper.Underscore ) ! .ToAliasString( StringHelper.Unqualify( description ).ToLower().Replace( "$", "_" ), Dialect ); } } Index: SqlLoader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/SqlLoader.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** SqlLoader.cs 1 Mar 2005 16:24:48 -0000 1.1 --- SqlLoader.cs 14 Mar 2005 18:53:03 -0000 1.2 *************** *** 236,240 **** public IList List( ISessionImplementor session, QueryParameters queryParameters ) { ! // TODO: Uncomment once //return List( session, queryParameters, querySpaces, resultTypes ) ; return null ; --- 236,240 ---- public IList List( ISessionImplementor session, QueryParameters queryParameters ) { ! // TODO: 2.1 Uncomment once SQL Loading implemented //return List( session, queryParameters, querySpaces, resultTypes ) ; return null ; |