Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21577/nhibernate/src/NHibernate/Impl Modified Files: AbstractQueryImpl.cs BatcherImpl.cs EntityEntry.cs IExecutable.cs ScheduledCollectionAction.cs ScheduledCollectionRemove.cs ScheduledDeletion.cs ScheduledEntityAction.cs ScheduledInsertion.cs ScheduledUpdate.cs SessionFactoryImpl.cs SessionImpl.cs Added Files: BatchingBatcher.cs OnReplicateVisitor.cs ScheduledIdentityInsertion.cs SqlQueryImpl.cs Log Message: Refactored SessionImpl as per 2.1 for Save/Update Index: SessionImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionImpl.cs,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** SessionImpl.cs 1 Mar 2005 16:24:47 -0000 1.68 --- SessionImpl.cs 6 Mar 2005 12:44:42 -0000 1.69 *************** *** 34,39 **** private SessionFactoryImpl factory; ! private bool autoClose; ! private long timestamp; /// <summary> --- 34,39 ---- private SessionFactoryImpl factory; ! private readonly bool autoClose; [...1642 lines suppressed...] + { + return null; + } + + if ( obj is IHibenateProxy ) + { + ILazyInitializer li = HibernateProxyHelper. + } + + if ( copiedAlready.Contains( obj ) + { + return obj; // EARLY EXIT! + } + */ + + return null; + } } } \ No newline at end of file Index: BatcherImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/BatcherImpl.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** BatcherImpl.cs 31 Jan 2005 03:25:39 -0000 1.17 --- BatcherImpl.cs 6 Mar 2005 12:44:42 -0000 1.18 *************** *** 15,19 **** internal abstract class BatcherImpl : IBatcher { ! private static readonly ILog log = LogManager.GetLogger( typeof( BatcherImpl ) ); private static int openCommandCount; --- 15,19 ---- internal abstract class BatcherImpl : IBatcher { ! protected static readonly ILog log = LogManager.GetLogger( typeof( BatcherImpl ) ); private static int openCommandCount; Index: AbstractQueryImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AbstractQueryImpl.cs 1 Mar 2005 16:24:47 -0000 1.1 --- AbstractQueryImpl.cs 6 Mar 2005 12:44:42 -0000 1.2 *************** *** 662,666 **** /// <summary></summary> ! public IType[ ] ReturnTypes { get { return session.Factory.GetReturnTypes( queryString ); } --- 662,666 ---- /// <summary></summary> ! public virtual IType[ ] ReturnTypes { get { return session.Factory.GetReturnTypes( queryString ); } Index: SessionFactoryImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionFactoryImpl.cs,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** SessionFactoryImpl.cs 1 Mar 2005 16:24:46 -0000 1.42 --- SessionFactoryImpl.cs 6 Mar 2005 12:44:42 -0000 1.43 *************** *** 18,21 **** --- 18,22 ---- using NHibernate.Transaction; using NHibernate.Type; + using NHibernate.Tool.hbm2ddl; using HibernateDialect = NHibernate.Dialect.Dialect; *************** *** 56,92 **** internal class SessionFactoryImpl : ISessionFactory, ISessionFactoryImplementor, IObjectReference { ! private static readonly ILog log = LogManager.GetLogger( typeof( SessionFactoryImpl ) ); [NonSerialized] ! private Settings settings; ! private string name; ! private string uuid; [NonSerialized] ! private IDictionary classPersisters; [NonSerialized] ! private IDictionary classPersistersByName; [NonSerialized] ! private IDictionary collectionPersisters; [NonSerialized] ! private IDictionary namedQueries; [NonSerialized] ! private IDictionary imports; [NonSerialized] ! private IDictionary properties; // templates are related to XmlDatabinder - nothing like that yet // in NHibernate. //[NonSerialized] private Templates templates; [NonSerialized] ! private IInterceptor interceptor; ! private static IIdentifierGenerator uuidgen = new UUIDHexGenerator(); /// <summary> --- 57,106 ---- internal class SessionFactoryImpl : ISessionFactory, ISessionFactoryImplementor, IObjectReference { ! private readonly string name; ! private readonly string uuid; [NonSerialized] ! private readonly IDictionary classPersisters; ! [NonSerialized] ! private readonly IDictionary classPersistersByName; [NonSerialized] ! private readonly IDictionary classMetadata; [NonSerialized] ! private readonly IDictionary collectionPersisters; [NonSerialized] ! private readonly IDictionary collectionMetadata; [NonSerialized] ! private readonly IDictionary namedQueries; [NonSerialized] ! private readonly IDictionary namedSqlQueries; [NonSerialized] ! private readonly IDictionary imports; // templates are related to XmlDatabinder - nothing like that yet // in NHibernate. //[NonSerialized] private Templates templates; + [NonSerialized] ! private readonly IInterceptor interceptor; ! [NonSerialized] ! private readonly Settings settings; ! ! [NonSerialized] ! private readonly IDictionary properties; ! ! [NonSerialized] ! private SchemaExport schemaExport; ! ! private static readonly IIdentifierGenerator uuidgen = new UUIDHexGenerator(); ! ! private static readonly ILog log = LogManager.GetLogger( typeof( SessionFactoryImpl ) ); /// <summary> *************** *** 94,103 **** /// </summary> /// <param name="cfg"></param> - /// <param name="properties"></param> - /// <param name="interceptor"></param> /// <param name="settings"></param> ! public SessionFactoryImpl( Configuration cfg, IDictionary properties, IInterceptor interceptor, Settings settings ) { log.Info( "building session factory" ); if( log.IsDebugEnabled ) { --- 108,120 ---- /// </summary> /// <param name="cfg"></param> /// <param name="settings"></param> ! public SessionFactoryImpl( Configuration cfg, Settings settings ) { log.Info( "building session factory" ); + + this.properties = cfg.Properties; + this.interceptor = cfg.Interceptor; + this.settings = settings; + if( log.IsDebugEnabled ) { *************** *** 110,121 **** } - this.interceptor = interceptor; - this.properties = properties; - this.settings = settings; - // Persisters: classPersisters = new Hashtable(); classPersistersByName = new Hashtable(); foreach( PersistentClass model in cfg.ClassMappings ) --- 127,135 ---- } // Persisters: classPersisters = new Hashtable(); classPersistersByName = new Hashtable(); + IDictionary classMeta = new Hashtable(); foreach( PersistentClass model in cfg.ClassMappings ) *************** *** 136,148 **** // Imports provide the ability to jump from the Classname to the AssemblyQualifiedName. classPersistersByName[ model.MappedClass.AssemblyQualifiedName ] = cp; } collectionPersisters = new Hashtable(); foreach( Mapping.Collection map in cfg.CollectionMappings ) { - //collectionPersisters[ map.Role ] = new CollectionPersister( map, cfg, this ); collectionPersisters[ map.Role ] = PersisterFactory.CreateCollectionPersister( cfg, map, this ); } foreach( IClassPersister persister in classPersisters.Values ) { --- 150,166 ---- // Imports provide the ability to jump from the Classname to the AssemblyQualifiedName. classPersistersByName[ model.MappedClass.AssemblyQualifiedName ] = cp; + + classMeta[ model.MappedClass ] = cp.ClassMetadata; } + classMetadata = new Hashtable( classMeta ); collectionPersisters = new Hashtable(); foreach( Mapping.Collection map in cfg.CollectionMappings ) { collectionPersisters[ map.Role ] = PersisterFactory.CreateCollectionPersister( cfg, map, this ); } + collectionMetadata = new Hashtable( collectionPersisters ); + // after *all* persisters are registered foreach( IClassPersister persister in classPersisters.Values ) { *************** *** 166,174 **** SessionFactoryObjectFactory.AddInstance( uuid, name, this, properties ); ! namedQueries = cfg.NamedQueries; imports = new Hashtable( cfg.Imports ); log.Debug( "Instantiated session factory" ); } --- 184,217 ---- SessionFactoryObjectFactory.AddInstance( uuid, name, this, properties ); ! // Named queries: ! // TODO: precompile and cache named queries ! namedQueries = new Hashtable( cfg.NamedQueries ); ! namedSqlQueries = new Hashtable( cfg.NamedSQLQueries.Count ); ! foreach ( NamedSQLQuery nsq in cfg.NamedSQLQueries ) ! { ! namedSqlQueries[ nsq.QueryString ] = new InternalNamedSQLQuery( nsq.QueryString, nsq.ReturnAliases, nsq.ReturnClasses, nsq.SynchronizedTables ); ! } ! ! imports = new Hashtable( cfg.Imports ); log.Debug( "Instantiated session factory" ); + if ( settings.IsAutoCreateSchema ) + { + new SchemaExport( cfg ).Create( false, true ); + } + + /* + if ( settings.IsAutoUpdateSchema ) + { + new SchemaUpdate( cfg ).Execute( false, true ); + } + */ + + if ( settings.IsAutoDropSchema ) + { + schemaExport = new SchemaExport( cfg ); + } } *************** *** 328,331 **** --- 371,392 ---- /// <summary></summary> + public int MaximumFetchDepth + { + get { return settings.MaximumFetchDepth; } + } + + /// <summary></summary> + public bool IsShowSqlEnabled + { + get { return settings.IsShowSqlEnabled; } + } + + /// <summary></summary> + public int FetchSize + { + get { return settings.StatementFetchSize; } + } + + /// <summary></summary> public IConnectionProvider ConnectionProvider { *************** *** 570,574 **** /// <summary></summary> ! public bool EnableJoinedFetch { get { return settings.IsOuterJoinFetchEnabled; } --- 631,659 ---- /// <summary></summary> ! public bool IsBatchUpdateEnabled ! { ! get { return settings.BatchSize > 0; } ! } ! ! /// <summary></summary> ! public int BatchSize ! { ! get { return settings.BatchSize; } ! } ! ! /// <summary></summary> ! public bool IsScrollableResultSetsEnabled ! { ! get { return settings.IsScrollableResultSetsEnabled; } ! } ! ! /// <summary></summary> ! public bool IsGetGeneratedKeysEnabled ! { ! get { return settings.IsGetGeneratedKeysEnabled; } ! } ! ! /// <summary></summary> ! public bool IsOuterJoinedFetchEnabled { get { return settings.IsOuterJoinFetchEnabled; } *************** *** 593,596 **** --- 678,691 ---- /// /// </summary> + /// <param name="queryName"></param> + /// <returns></returns> + public InternalNamedSQLQuery GetNamedSQLQuery( string queryName ) + { + return namedSqlQueries[ queryName ] as InternalNamedSQLQuery; + } + + /// <summary> + /// + /// </summary> /// <param name="objectClass"></param> /// <returns></returns> *************** *** 864,867 **** --- 959,977 ---- /// /// </summary> + public void EvictQueries( ) + { + } + + /// <summary> + /// + /// </summary> + /// <param name="cacheRegion"></param> + public void EvictQueries( string cacheRegion ) + { + } + + /// <summary> + /// + /// </summary> /// <param name="roleName"></param> public void EvictCollection( string roleName ) *************** *** 874,877 **** --- 984,1023 ---- } + // TODO: a better way to normalised the NamedSQLQUery aspect + internal class InternalNamedSQLQuery + { + private readonly string queryString; + private readonly string[] returnAliases; + private readonly System.Type[] returnClasses; + private readonly IList querySpaces; + + public InternalNamedSQLQuery( string query, string[] aliases, System.Type[] clazz, IList querySpaces ) + { + this.returnClasses = clazz; + this.returnAliases = aliases; + this.queryString = query; + this.querySpaces = querySpaces; + } + + public string[] ReturnAliases + { + get { return returnAliases; } + } + + public System.Type[] ReturnClasses + { + get { return returnClasses; } + } + + public string QueryString + { + get { return queryString; } + } + + public ICollection QuerySpaces + { + get { return querySpaces; } + } + } } } \ No newline at end of file --- NEW FILE: ScheduledIdentityInsertion.cs --- using NHibernate.Engine; using NHibernate.Persister; namespace NHibernate.Impl { /// <summary> /// Summary description for ScheduledIdentityInsertion. /// </summary> internal sealed class ScheduledIdentityInsertion : ScheduledEntityAction, IExecutable { private readonly object[] state; private CacheEntry cacheEntry; private object generatedId; /// <summary> /// /// </summary> /// <param name="state"></param> /// <param name="instance"></param> /// <param name="persister"></param> /// <param name="session"></param> public ScheduledIdentityInsertion( object[] state, object instance, IClassPersister persister, ISessionImplementor session ) : base( session, null, instance, persister ) { this.state = state; } public override void Execute() { IClassPersister persister = Persister; ISessionImplementor session = Session; object obj = Instance; // Don't need to lock the cache here, since if someone // else inserted the same pk first, the insert would fail. generatedId = persister.Insert( state, obj, session ); // TODO: This bit has to be called after all the cascades /* if ( persister.HasCache && !persister.IsCacheInvalidationRequired ) { cacheEntry = new CacheEntry( obj, persister, session ); persister.Cache.Put( generatedId, cacheEntry, 0 ); } */ } public override void AfterTransactionCompletion( ) { // TODO: renable /* IClassPersister persister = Persister; if ( success && persister.HasCache && !persister.IsCacheInvalidationRequired ) { persister.Cache.AfterInsert( GeneratedId, cacheEntry ); } */ } /// <summary> /// /// </summary> // TODO: Remove once AfterTransactionCompletion is active public override bool HasAfterTransactionCompletion { get { return false; } } public object GeneratedId { get { return generatedId; } } } } Index: ScheduledDeletion.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledDeletion.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ScheduledDeletion.cs 1 Mar 2005 16:24:46 -0000 1.6 --- ScheduledDeletion.cs 6 Mar 2005 12:44:42 -0000 1.7 *************** *** 10,15 **** internal class ScheduledDeletion : ScheduledEntityAction { ! private object _version; ! private ISoftLock _lock; /// <summary> --- 10,15 ---- internal class ScheduledDeletion : ScheduledEntityAction { ! private object version; ! private ISoftLock lck; /// <summary> *************** *** 24,28 **** : base( session, id, instance, persister ) { ! _version = version; } --- 24,28 ---- : base( session, id, instance, persister ) { ! this.version = version; } *************** *** 32,38 **** if( Persister.HasCache ) { ! _lock = Persister.Cache.Lock( Id ); } ! Persister.Delete( Id, _version, Instance, Session ); Session.PostDelete( Instance ); } --- 32,38 ---- if( Persister.HasCache ) { ! lck = Persister.Cache.Lock( Id, version ); } ! Persister.Delete( Id, version, Instance, Session ); Session.PostDelete( Instance ); } *************** *** 43,47 **** if( Persister.HasCache ) { ! Persister.Cache.Release( Id, _lock ); } } --- 43,47 ---- if( Persister.HasCache ) { ! Persister.Cache.Release( Id, lck ); } } Index: ScheduledInsertion.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledInsertion.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ScheduledInsertion.cs 31 Dec 2004 19:53:54 -0000 1.5 --- ScheduledInsertion.cs 6 Mar 2005 12:44:42 -0000 1.6 *************** *** 9,13 **** internal class ScheduledInsertion : ScheduledEntityAction { ! private readonly object[ ] _state; /// <summary> --- 9,15 ---- internal class ScheduledInsertion : ScheduledEntityAction { ! private readonly object[ ] state; ! private CacheEntry entry; ! private readonly object version; /// <summary> *************** *** 17,26 **** /// <param name="state">An object array that contains the state of the object being inserted.</param> /// <param name="instance">The actual object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> ! public ScheduledInsertion( object id, object[ ] state, object instance, IClassPersister persister, ISessionImplementor session ) : base( session, id, instance, persister ) { ! _state = state; } --- 19,30 ---- /// <param name="state">An object array that contains the state of the object being inserted.</param> /// <param name="instance">The actual object instance.</param> + /// <param name="version">The version of the object instance.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for the persisting the object.</param> /// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param> ! public ScheduledInsertion( object id, object[ ] state, object instance, object version, IClassPersister persister, ISessionImplementor session ) : base( session, id, instance, persister ) { ! this.state = state; ! this.version = version; } *************** *** 28,33 **** public override void Execute() { ! Persister.Insert( Id, _state, Instance, Session ); Session.PostInsert( Instance ); } --- 32,45 ---- public override void Execute() { ! Persister.Insert( Id, state, Instance, Session ); Session.PostInsert( Instance ); + + /* + if ( Persister.HasCache && Persister.IsCacheInvalidationRequired ) + { + cacheEntry = new CacheEntry( Instance, Persister, Session ); + Persister.Cache.Put( Id, cacheEntry ); + } + */ } *************** *** 35,39 **** public override void AfterTransactionCompletion() { ! // do nothing } } --- 47,58 ---- public override void AfterTransactionCompletion() { ! // Make 100% certain that this is called before any subsequent ScheduledUpdate.AfterTransactionCompletion()!! ! /* ! if ( Persister.HasCache && Persister.IsCacheInvalidationRequired ) ! { ! cacheEntry = new CacheEntry( Instance, Persister, Session ); ! Persister.Cache.AfterInsert( Id, cacheEntry, version ); ! } ! */ } } Index: EntityEntry.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/EntityEntry.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** EntityEntry.cs 1 Jan 2005 02:35:07 -0000 1.2 --- EntityEntry.cs 6 Mar 2005 12:44:42 -0000 1.3 *************** *** 14,27 **** private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(EntityEntry) ); ! private LockMode _lockMode; ! private Status _status; ! private object _id; ! private object[] _loadedState; ! private object[] _deletedState; ! private bool _existsInDatabase; ! private object _version; // for convenience to save some lookups ! [NonSerialized] private IClassPersister _persister; ! private string _className; /// <summary> --- 14,28 ---- private static readonly log4net.ILog log = log4net.LogManager.GetLogger( typeof(EntityEntry) ); ! private LockMode lockMode; ! private Status status; ! private object id; ! private object[] loadedState; ! private object[] deletedState; ! private bool existsInDatabase; ! private object version; // for convenience to save some lookups ! [NonSerialized] private IClassPersister persister; ! private string className; ! private bool isBeingReplicated; /// <summary> *************** *** 35,48 **** /// <param name="existsInDatabase">A boolean indicating if the Entity exists in the database.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for this Entity.</param> ! public EntityEntry(Status status, object[] loadedState, object id, object version, LockMode lockMode, bool existsInDatabase, IClassPersister persister) { ! _status = status; ! _loadedState = loadedState; ! _id = id; ! _existsInDatabase = existsInDatabase; ! _version = version; ! _lockMode = lockMode; ! _persister = persister; ! if (_persister!=null) _className = _persister.ClassName; } --- 36,54 ---- /// <param name="existsInDatabase">A boolean indicating if the Entity exists in the database.</param> /// <param name="persister">The <see cref="IClassPersister"/> that is responsible for this Entity.</param> ! /// <param name="disableVersionIncrement"></param> ! public EntityEntry(Status status, object[] loadedState, object id, object version, LockMode lockMode, bool existsInDatabase, IClassPersister persister, bool disableVersionIncrement ) { ! this.status = status; ! this.loadedState = loadedState; ! this.id = id; ! this.existsInDatabase = existsInDatabase; ! this.version = version; ! this.lockMode = lockMode; ! this.isBeingReplicated = disableVersionIncrement; ! this.persister = persister; ! if ( persister != null ) ! { ! className = persister.ClassName; ! } } *************** *** 53,58 **** public LockMode LockMode { ! get { return _lockMode; } ! set { _lockMode = value; } } --- 59,64 ---- public LockMode LockMode { ! get { return lockMode; } ! set { lockMode = value; } } *************** *** 64,69 **** public Status Status { ! get { return _status; } ! set { _status = value; } } --- 70,75 ---- public Status Status { ! get { return status; } ! set { status = value; } } *************** *** 76,81 **** public object Id { ! get { return _id; } ! set { _id = value; } } --- 82,87 ---- public object Id { ! get { return id; } ! set { id = value; } } *************** *** 89,94 **** public object[] LoadedState { ! get { return _loadedState; } ! set { _loadedState = value; } } --- 95,100 ---- public object[] LoadedState { ! get { return loadedState; } ! set { loadedState = value; } } *************** *** 100,105 **** public object[] DeletedState { ! get { return _deletedState; } ! set { _deletedState = value; } } --- 106,111 ---- public object[] DeletedState { ! get { return deletedState; } ! set { deletedState = value; } } *************** *** 114,119 **** public bool ExistsInDatabase { ! get { return _existsInDatabase; } ! set { _existsInDatabase = value; } } --- 120,125 ---- public bool ExistsInDatabase { ! get { return existsInDatabase; } ! set { existsInDatabase = value; } } *************** *** 124,129 **** public object Version { ! get { return _version; } ! set { _version = value; } } --- 130,135 ---- public object Version { ! get { return version; } ! set { version = value; } } *************** *** 134,139 **** public IClassPersister Persister { ! get { return _persister; } ! set { _persister = value; } } --- 140,145 ---- public IClassPersister Persister { ! get { return persister; } ! set { persister = value; } } *************** *** 144,151 **** public string ClassName { ! get { return _className; } } } - } --- 150,163 ---- public string ClassName { ! get { return className; } } + /// <summary> + /// + /// </summary> + public bool IsBeingReplicated + { + get { return isBeingReplicated; } + } } } --- NEW FILE: SqlQueryImpl.cs --- using System; using System.Collections; using NHibernate.Engine; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// Implements SQL query passthrough /// <pre> /// <sql-query-name name="mySqlQuery"> /// <return alias="person" class="eg.Person" /> /// SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex} /// FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%' /// </sql-query-name> /// </pre> /// </summary> internal class SqlQueryImpl : AbstractQueryImpl { private readonly System.Type[] returnClasses; private readonly string[] returnAliases; private readonly ICollection querySpaces; /// <summary> /// /// </summary> /// <param name="sql"></param> /// <param name="returnAliases"></param> /// <param name="returnClasses"></param> /// <param name="session"></param> /// <param name="querySpaces"></param> public SqlQueryImpl( string sql, string[] returnAliases, System.Type[] returnClasses, ISessionImplementor session, ICollection querySpaces) : base( sql, session ) { this.returnClasses = returnClasses; this.returnAliases = returnAliases; this.querySpaces = querySpaces; } /// <summary> /// /// </summary> public string[] ReturnAliases { get { return returnAliases; } } /// <summary> /// /// </summary> public System.Type[] ReturnClasses { get { return returnClasses; } } /// <summary> /// /// </summary> public override IType[] ReturnTypes { get { IType[] types = new IType[ returnClasses.Length ]; for ( int i = 0; i < returnClasses.Length; i++ ) { types[ i ] = NHibernateUtil.Entity( returnClasses[ i ] ); } return types; } } /// <summary> /// /// </summary> /// <returns></returns> public override IList List() { VerifyParameters(); IDictionary namedParams = NamedParams; return Session.FindBySQL( BindParameterLists( namedParams ), returnAliases, returnClasses, QueryParams( namedParams ), querySpaces ); } /// <summary></summary> public override IEnumerable Enumerable() { throw new NotSupportedException( "SQL queries do not currently support enumeration" ); } } } --- NEW FILE: BatchingBatcher.cs --- using System; using System.Data; using NHibernate.Engine; namespace NHibernate.Impl { /// <summary> /// Summary description for BatchingBatcher. /// </summary> internal class BatchingBatcher : BatcherImpl { private int batchSize; private int[] expectedRowCounts; /// <summary> /// /// </summary> /// <param name="session"></param> public BatchingBatcher( ISessionImplementor session ) : base( session ) { expectedRowCounts = new int[ Factory.BatchSize ]; } /// <summary> /// /// </summary> /// <param name="expectedRowCount"></param> public override void AddToBatch( int expectedRowCount ) { throw new NotImplementedException( "Batching not implemented yet" ); /* log.Info( "Adding to batch" ); IDbCommand batchUpdate = CurrentStatment; */ } /// <summary> /// /// </summary> /// <param name="ps"></param> protected override void DoExecuteBatch( IDbCommand ps ) { throw new NotImplementedException( "Batching not implemented yet" ); } } } Index: ScheduledCollectionAction.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledCollectionAction.cs,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** ScheduledCollectionAction.cs 1 Mar 2005 16:24:46 -0000 1.10 --- ScheduledCollectionAction.cs 6 Mar 2005 12:44:42 -0000 1.11 *************** *** 11,18 **** internal abstract class ScheduledCollectionAction : IExecutable { ! private ICollectionPersister _persister; ! private object _id; ! private ISessionImplementor _session; ! private ISoftLock _lock = null; /// <summary> --- 11,19 ---- internal abstract class ScheduledCollectionAction : IExecutable { ! private ICollectionPersister persister; ! private object id; ! private ISessionImplementor session; ! private ISoftLock lck = null; ! private string collectionRole; /// <summary> *************** *** 24,30 **** public ScheduledCollectionAction( ICollectionPersister persister, object id, ISessionImplementor session ) { ! _persister = persister; ! _session = session; ! _id = id; } --- 25,32 ---- public ScheduledCollectionAction( ICollectionPersister persister, object id, ISessionImplementor session ) { ! this.persister = persister; ! this.session = session; ! this.id = id; ! this.collectionRole = persister.Role; } *************** *** 34,38 **** public ICollectionPersister Persister { ! get { return _persister; } } --- 36,40 ---- public ICollectionPersister Persister { ! get { return persister; } } *************** *** 42,46 **** public object Id { ! get { return _id; } } --- 44,48 ---- public object Id { ! get { return id; } } *************** *** 50,54 **** public ISessionImplementor Session { ! get { return _session; } } --- 52,56 ---- public ISessionImplementor Session { ! get { return session; } } *************** *** 58,73 **** public void AfterTransactionCompletion() { ! if ( _persister.HasCache ) { ! _persister.Cache.Release( _id, _lock ); } } public abstract void Execute(); /// <summary></summary> public object[ ] PropertySpaces { ! get { return new object[ ] {_persister.CollectionSpace}; } //TODO: cache the array on the persister } --- 60,97 ---- public void AfterTransactionCompletion() { ! if ( persister.HasCache ) { ! persister.Cache.Release( id, lck ); } } + public bool HasAfterTransactionCompletion + { + get { return persister.HasCache; } + } + public abstract void Execute(); + /// <summary> + /// + /// </summary> + public void BeforeExecutions( ) + { + // we need to obtain the lock before any actions are + // executed, since this may be an inverse="true" + // bidirectional association and it is one of the + // earlier entity actions which actually updates + // the database (this action is resposible for + // second-level cache invalidation only) + if ( persister.HasCache ) + { + lck = persister.Cache.Lock( id, null ); //collections don't have version numbers :-( + } + } + /// <summary></summary> public object[ ] PropertySpaces { ! get { return new object[ ] { persister.CollectionSpace }; } //TODO: cache the array on the persister } Index: IExecutable.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/IExecutable.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** IExecutable.cs 31 Dec 2004 19:51:46 -0000 1.2 --- IExecutable.cs 6 Mar 2005 12:44:42 -0000 1.3 *************** *** 8,11 **** --- 8,16 ---- { /// <summary> + /// + /// </summary> + void BeforeExecutions(); + + /// <summary> /// Execute the action required to write changes to the database. /// </summary> *************** *** 13,16 **** --- 18,26 ---- /// <summary> + /// Does the executable have an AfterTransactionCompletion process + /// </summary> + bool HasAfterTransactionCompletion { get; } + + /// <summary> /// Called after the Transaction has been completed. /// </summary> Index: ScheduledEntityAction.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledEntityAction.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ScheduledEntityAction.cs 31 Dec 2004 19:53:44 -0000 1.8 --- ScheduledEntityAction.cs 6 Mar 2005 12:44:42 -0000 1.9 *************** *** 1,2 **** --- 1,3 ---- + using System; using NHibernate.Engine; using NHibernate.Persister; *************** *** 10,17 **** internal abstract class ScheduledEntityAction : IExecutable { ! private readonly ISessionImplementor _session; ! private readonly object _id; ! private readonly IClassPersister _persister; ! private readonly object _instance; /// <summary> --- 11,18 ---- internal abstract class ScheduledEntityAction : IExecutable { ! private readonly ISessionImplementor session; ! private readonly object id; ! private readonly IClassPersister persister; ! private readonly object instance; /// <summary> *************** *** 24,31 **** protected ScheduledEntityAction( ISessionImplementor session, object id, object instance, IClassPersister persister ) { ! _session = session; ! _id = id; ! _persister = persister; ! _instance = instance; } --- 25,32 ---- protected ScheduledEntityAction( ISessionImplementor session, object id, object instance, IClassPersister persister ) { ! this.session = session; ! this.id = id; ! this.persister = persister; ! this.instance = instance; } *************** *** 36,40 **** protected ISessionImplementor Session { ! get { return _session; } } --- 37,41 ---- protected ISessionImplementor Session { ! get { return session; } } *************** *** 44,48 **** protected object Id { ! get { return _id; } } --- 45,49 ---- protected object Id { ! get { return id; } } *************** *** 52,56 **** protected IClassPersister Persister { ! get { return _persister; } } --- 53,57 ---- protected IClassPersister Persister { ! get { return persister; } } *************** *** 60,64 **** protected object Instance { ! get { return _instance; } } --- 61,65 ---- protected object Instance { ! get { return instance; } } *************** *** 66,69 **** --- 67,87 ---- /// <summary> + /// + /// </summary> + /// <remarks>Not supported for a non-collection entity</remarks> + public void BeforeExecutions( ) + { + throw new NotSupportedException( "BeforeExecutions() called for non-collection method" ); + } + + /// <summary> + /// + /// </summary> + public virtual bool HasAfterTransactionCompletion + { + get { return persister.HasCache; } + } + + /// <summary> /// Called when the Transaction this action occurred in has completed. /// </summary> *************** *** 78,82 **** public object[ ] PropertySpaces { ! get { return _persister.PropertySpaces; } } --- 96,100 ---- public object[ ] PropertySpaces { ! get { return persister.PropertySpaces; } } --- NEW FILE: OnReplicateVisitor.cs --- using NHibernate.Collection; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// When an entity is passed to Update(), we must inspect all its collections and /// 1. associate any uninitialized PersistentCollections with this session /// 2. associate any initialized PersistentCollections with this session, using the existing snapshot /// 3. execute a collection removal (SQL DELETE) for each null collection property or "new" collection /// </summary> internal class OnReplicateVisitor : ReattachVisitor { public OnReplicateVisitor( SessionImpl session, object key ) : base( session, key ) { } protected override object ProcessCollection( object collection, PersistentCollectionType type ) { SessionImpl session = Session; object key = Key; ICollectionPersister persister = session.GetCollectionPersister( type.Role ); session.RemoveCollection( persister, key ); if ( collection != null && ( collection is PersistentCollection ) ) { PersistentCollection wrapper = collection as PersistentCollection; wrapper.SetCurrentSession( session ); if ( wrapper.WasInitialized ) { session.AddNewCollection( wrapper, persister ); } else { session.ReattachCollection( wrapper, wrapper.CollectionSnapshot ) ; } } else { // otherwise a null or brand new collection // this will also (inefficiently) handle arrays, which // have no snapshot, so we can't do any better //processArrayOrNewCollection(collection, type); } return null; } } } Index: ScheduledUpdate.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledUpdate.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ScheduledUpdate.cs 1 Mar 2005 16:24:46 -0000 1.9 --- ScheduledUpdate.cs 6 Mar 2005 12:44:42 -0000 1.10 *************** *** 44,48 **** if( Persister.HasCache ) { ! _lock = Persister.Cache.Lock( Id ); } Persister.Update( Id, _fields, _dirtyFields, _lastVersion, Instance, Session ); --- 44,48 ---- if( Persister.HasCache ) { ! _lock = Persister.Cache.Lock( Id, _lastVersion ); } Persister.Update( Id, _fields, _dirtyFields, _lastVersion, Instance, Session ); Index: ScheduledCollectionRemove.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ScheduledCollectionRemove.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ScheduledCollectionRemove.cs 1 Mar 2005 16:24:46 -0000 1.7 --- ScheduledCollectionRemove.cs 6 Mar 2005 12:44:42 -0000 1.8 *************** *** 30,36 **** public override void Execute() { if ( Persister.HasCache ) { ! Persister.Cache.Lock( Id ); } --- 30,37 ---- public override void Execute() { + // TODO: 2.1 Remove this clause if ( Persister.HasCache ) { ! Persister.Cache.Lock( Id, null ); } |