You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(248) |
May
(82) |
Jun
(90) |
Jul
(177) |
Aug
(253) |
Sep
(157) |
Oct
(151) |
Nov
(143) |
Dec
(278) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(152) |
Feb
(107) |
Mar
(177) |
Apr
(133) |
May
(259) |
Jun
(81) |
Jul
(119) |
Aug
(306) |
Sep
(416) |
Oct
(240) |
Nov
(329) |
Dec
(206) |
2006 |
Jan
(466) |
Feb
(382) |
Mar
(153) |
Apr
(162) |
May
(133) |
Jun
(21) |
Jul
(18) |
Aug
(37) |
Sep
(97) |
Oct
(114) |
Nov
(110) |
Dec
(28) |
2007 |
Jan
(74) |
Feb
(65) |
Mar
(49) |
Apr
(76) |
May
(43) |
Jun
(15) |
Jul
(68) |
Aug
(55) |
Sep
(63) |
Oct
(59) |
Nov
(70) |
Dec
(66) |
2008 |
Jan
(71) |
Feb
(60) |
Mar
(120) |
Apr
(31) |
May
(48) |
Jun
(81) |
Jul
(107) |
Aug
(51) |
Sep
(80) |
Oct
(83) |
Nov
(83) |
Dec
(79) |
2009 |
Jan
(83) |
Feb
(110) |
Mar
(97) |
Apr
(91) |
May
(291) |
Jun
(250) |
Jul
(197) |
Aug
(58) |
Sep
(54) |
Oct
(122) |
Nov
(68) |
Dec
(34) |
2010 |
Jan
(50) |
Feb
(17) |
Mar
(63) |
Apr
(61) |
May
(84) |
Jun
(81) |
Jul
(138) |
Aug
(144) |
Sep
(78) |
Oct
(26) |
Nov
(30) |
Dec
(61) |
2011 |
Jan
(33) |
Feb
(35) |
Mar
(166) |
Apr
(221) |
May
(109) |
Jun
(76) |
Jul
(27) |
Aug
(37) |
Sep
(1) |
Oct
(4) |
Nov
(2) |
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
(2) |
Apr
(2) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2013 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(2) |
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
(1) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Donald L M. Jr. <lu...@us...> - 2005-02-08 19:14:45
|
Update of /cvsroot/nhibernate/NHibernateContrib/src/Nullables In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17703/src/Nullables Modified Files: NullableBoolean.cs NullableByte.cs NullableDateTime.cs NullableDecimal.cs NullableDouble.cs NullableGuid.cs NullableInt16.cs NullableInt32.cs NullableInt64.cs NullableSByte.cs NullableSingle.cs Log Message: Changed the behavior of Nullables.Value (getter) to throw an InvalidOperationException when there is no value (null). This was intended (but forgotten). Index: NullableInt16.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableInt16.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableInt16.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableInt16.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public Int16 Value { ! get { return _value; } } --- 37,47 ---- public Int16 Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableInt32.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableInt32.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableInt32.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableInt32.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 38,42 **** public Int32 Value { ! get { return _value; } } --- 38,48 ---- public Int32 Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } *************** *** 158,162 **** #region IFormattable Members ! string System.IFormattable.ToString(string format, IFormatProvider formatProvider) { if (HasValue) --- 164,168 ---- #region IFormattable Members ! public string ToString(string format, IFormatProvider formatProvider) { if (HasValue) Index: NullableByte.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableByte.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableByte.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableByte.cs 8 Feb 2005 19:13:07 -0000 1.4 *************** *** 37,41 **** public Byte Value { ! get { return _value; } } --- 37,47 ---- public Byte Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableSByte.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableSByte.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NullableSByte.cs 10 Dec 2004 18:24:22 -0000 1.1 --- NullableSByte.cs 8 Feb 2005 19:13:11 -0000 1.2 *************** *** 39,43 **** public SByte Value { ! get { return _value; } } --- 39,49 ---- public SByte Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableDouble.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableDouble.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableDouble.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableDouble.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public Double Value { ! get { return _value; } } --- 37,47 ---- public Double Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableDateTime.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableDateTime.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableDateTime.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableDateTime.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public DateTime Value { ! get { return _value; } } --- 37,47 ---- public DateTime Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableDecimal.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableDecimal.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableDecimal.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableDecimal.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public Decimal Value { ! get { return _value; } } --- 37,47 ---- public Decimal Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableBoolean.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableBoolean.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NullableBoolean.cs 10 Dec 2004 18:24:21 -0000 1.2 --- NullableBoolean.cs 8 Feb 2005 19:12:56 -0000 1.3 *************** *** 37,41 **** public Boolean Value { ! get { return _value; } } --- 37,47 ---- public Boolean Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableSingle.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableSingle.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableSingle.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableSingle.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public Single Value { ! get { return _value; } } --- 37,47 ---- public Single Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableGuid.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableGuid.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableGuid.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableGuid.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 38,42 **** public Guid Value { ! get { return _value; } } --- 38,48 ---- public Guid Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } Index: NullableInt64.cs =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/src/Nullables/NullableInt64.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NullableInt64.cs 10 Dec 2004 18:24:22 -0000 1.3 --- NullableInt64.cs 8 Feb 2005 19:13:11 -0000 1.4 *************** *** 37,41 **** public Int64 Value { ! get { return _value; } } --- 37,47 ---- public Int64 Value { ! get ! { ! if (hasValue) ! return _value; ! else ! throw new InvalidOperationException("Nullable type must have a value."); ! } } |
From: Michael D. <mik...@us...> - 2005-02-07 01:34:52
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106/Impl Modified Files: AbstractVisitor.cs CollectionKey.cs FlushVisitor.cs OnLockVisitor.cs OnUpdateVisitor.cs ProxyVisitor.cs ReattachVisitor.cs SessionFactoryImpl.cs SessionImpl.cs WrapVisitor.cs Added Files: DirtyCollectionSearchVisitor.cs EvictVisitor.cs Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: SessionImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionImpl.cs,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** SessionImpl.cs 6 Feb 2005 01:59:02 -0000 1.64 --- SessionImpl.cs 7 Feb 2005 01:34:41 -0000 1.65 *************** *** 821,824 **** --- 821,826 ---- if ( persister.HasCollections ) { + // h2.1 has some extra code here for OnReplicateVisitor - is a new setting + // that is only in h2.1 because of the method Replicate(object, ReplicateMode) WrapVisitor visitor = new WrapVisitor(this); // substitutes into values by side-effect *************** *** 879,885 **** } internal bool ReassociateIfUninitializedProxy(object value) { ! if (!NHibernateUtil.IsInitialized(value)) { ReassociateProxy(value); --- 881,895 ---- } + /// <summary> + /// If the parameter <c>value</c> is an unitialized proxy then it will be reassociated + /// with the session. + /// </summary> + /// <param name="value">A persistable object, proxy, persistent collection or null</param> + /// <returns> + /// <c>true</c> when an uninitialized proxy was passed into this method, <c>false</c> otherwise. + /// </returns> internal bool ReassociateIfUninitializedProxy(object value) { ! if( !NHibernateUtil.IsInitialized(value) ) { ReassociateProxy(value); *************** *** 1110,1114 **** new OnUpdateVisitor(this, id).Process( obj, persister ); - //RemoveCollectionsFor( persister, id, obj ); AddEntity( new Key( id, persister ), obj ); --- 1120,1123 ---- *************** *** 1333,1339 **** } ! if( !NHibernateUtil.IsInitialized( obj ) ) { - ReassociateProxy( obj ); return; } --- 1342,1347 ---- } ! if( ReassociateIfUninitializedProxy( obj ) ) { return; } *************** *** 1376,1384 **** } ! if( !NHibernateUtil.IsInitialized( obj ) ) { - ReassociateProxy( obj ); return; } object theObj = UnproxyAndReassociate( obj ); --- 1384,1392 ---- } ! if( ReassociateIfUninitializedProxy( obj ) ) { return; } + object theObj = UnproxyAndReassociate( obj ); *************** *** 1472,1478 **** } ! if( !NHibernateUtil.IsInitialized( obj ) ) { - ReassociateProxy( obj ); return; } --- 1480,1485 ---- } ! if( ReassociateIfUninitializedProxy( obj ) ) { return; } *************** *** 2501,2507 **** } ! if( !NHibernateUtil.IsInitialized( obj ) ) { - ReassociateProxy( obj ); return; } --- 2508,2513 ---- } ! if( ReassociateIfUninitializedProxy( obj ) ) { return; } *************** *** 2509,2517 **** object theObj = UnproxyAndReassociate( obj ); EntityEntry e = RemoveEntry( theObj ); ! if( e == null ) { ! IClassPersister persister = GetPersister( theObj ); ! object id = persister.GetIdentifier( theObj ); if( log.IsDebugEnabled ) { --- 2515,2525 ---- object theObj = UnproxyAndReassociate( obj ); EntityEntry e = RemoveEntry( theObj ); + IClassPersister persister; + object id; ! if( e==null ) { ! persister = GetPersister( theObj ); ! id = persister.GetIdentifier( theObj ); if( log.IsDebugEnabled ) { *************** *** 2519,2522 **** --- 2527,2533 ---- } + // TODO: add another check here about refreshing transient instance when persisted + // instance already associated with the session. + DoLoadByObject( theObj, id, true, lockMode ); } *************** *** 2533,2540 **** } ! Key key = new Key( e.Id, e.Persister ); RemoveEntity( key ); ! EvictCollections( e.Persister.GetPropertyValues( obj ), e.Persister.PropertyTypes ); try { --- 2544,2565 ---- } ! persister = e.Persister; ! id = e.Id; ! Key key = new Key( id, persister ); RemoveEntity( key ); ! if( persister.HasCollections ) ! { ! new EvictVisitor( this ).Process( obj, persister ); ! } + // this is from h2.1 - the code around here has some more interaction with the factory + // and collection cache. + if( persister.HasCache ) + { + persister.Cache.Remove( id ); + } + EvictCachedCollections( persister, id ); + + // h2.1 has some differences with how it interacts with Load and errors thrown. try { *************** *** 2914,2923 **** // compare to cached state (ignoring nested collections) ! if( persister.IsMutable && ! ( cannotDirtyCheck || ! ( dirtyProperties != null && dirtyProperties.Length != 0 ) || ! ( status == Status.Loaded && persister.IsVersioned && persister.HasCollections && SearchForDirtyCollections( values, types ) ) ! ) ! ) { // its dirty! --- 2939,2943 ---- // compare to cached state (ignoring nested collections) ! if ( IsUpdateNecessary(persister, cannotDirtyCheck, status, dirtyProperties, values, types) ) { // its dirty! *************** *** 2995,2998 **** --- 3015,3038 ---- } + private bool IsUpdateNecessary( IClassPersister persister, bool cannotDirtyCheck, Status status, int[] dirtyProperties, + object[] values, IType[] types) + { + if( persister.IsMutable==false ) return false; + if( cannotDirtyCheck ) return true; + + if( dirtyProperties!=null && dirtyProperties.Length!=0 ) return true; + + if( status==Status.Loaded && persister.IsVersioned && persister.HasCollections ) + { + DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor( this ); + visitor.ProcessValues( values, types ); + return visitor.WasDirtyCollectionFound; + } + else + { + return false; + } + } + /// <summary> /// Process cascade save/update at the start of a flush to discover *************** *** 3412,3416 **** /// <param name="coll"></param> /// <returns></returns> ! private bool CollectionIsDirty( PersistentCollection coll ) { CollectionEntry entry = GetCollectionEntry( coll ); --- 3452,3456 ---- /// <param name="coll"></param> /// <returns></returns> ! internal bool CollectionIsDirty( PersistentCollection coll ) { CollectionEntry entry = GetCollectionEntry( coll ); *************** *** 3418,3489 **** } - /// <summary> - /// Given an array of fields, search recursively for dirty collections. - /// </summary> - /// <param name="fields"></param> - /// <param name="types"></param> - /// <returns>return true if we find one</returns> - private bool SearchForDirtyCollections( object[ ] fields, IType[ ] types ) - { - for( int i = 0; i < types.Length; i++ ) - { - if( SearchForDirtyCollections( fields[ i ], types[ i ] ) ) - { - return true; - } - } - return false; - } - - /// <summary> - /// Do we have a dirty collection here? - /// 1. if it is a new application-instantiated collection, return true (does not occur anymore!) - /// 2. if it is a component, recurse - /// 3. if it is a wrappered collection, ask the collection entry - /// </summary> - /// <param name="obj"></param> - /// <param name="type"></param> - /// <returns></returns> - private bool SearchForDirtyCollections( object obj, IType type ) - { - if( obj != null ) - { - if( type.IsPersistentCollectionType ) - { - if( obj.GetType().IsArray ) - { - PersistentCollection ah = GetArrayHolder( obj ); - // if no array holder we found an unwrappered array (this can't occur, - // because we now always call wrap() before getting to here) - //return (ah==null) ? true : SearchForDirtyCollections(ah, type); - return CollectionIsDirty( ah ); - } - else - { - // if not wrappered yet, its dirty (this can't occur, because - // we now always call wrap() before getting to here) - // return ( ! (obj is PersistentCollection) ) ? - // true : SearchForDirtyCollections( (PersistentCollection) obj, type ); - return CollectionIsDirty( ( PersistentCollection ) obj ); - } - } - - else if( type.IsComponentType ) - { - IAbstractComponentType componentType = ( IAbstractComponentType ) type; - object[ ] values = componentType.GetPropertyValues( obj, this ); - IType[ ] types = componentType.Subtypes; - for( int i = 0; i < values.Length; i++ ) - { - if( SearchForDirtyCollections( values[ i ], types[ i ] ) ) - { - return true; - } - } - } - } - return false; - } - private IDictionary loadingCollections = new Hashtable(); private string loadingRole; --- 3458,3461 ---- *************** *** 3502,3516 **** } - internal LoadingCollectionEntry( PersistentCollection collection, object id, object owner ) - { - _collection = collection; - _id = id; - _owner = owner; - } - public PersistentCollection Collection { get { return _collection; } - set { _collection = value; } } --- 3474,3480 ---- *************** *** 3518,3522 **** { get { return _id; } - set { _id = value; } } --- 3482,3485 ---- *************** *** 3542,3547 **** /// <param name="id"></param> /// <returns></returns> - // TODO: replace with owner version of this method... - [Obsolete( "Use the one with CollectionPersister, id, owner) instead" )] public PersistentCollection GetLoadingCollection( CollectionPersister persister, object id ) { --- 3505,3508 ---- *************** *** 3579,3583 **** lce.Collection.EndRead(); AddInitializedCollection( lce.Collection, persister, lce.Id ); ! persister.Cache( lce.Id, lce.Collection, this ); } } --- 3540,3548 ---- lce.Collection.EndRead(); AddInitializedCollection( lce.Collection, persister, lce.Id ); ! // h2.1 synch - added the IsCacheable to nh specifically ! if( persister.HasCache && lce.Collection.IsCacheable ) ! { ! persister.Cache.Put( lce.Id, lce.Collection.Disassemble( persister ), Timestamp ); ! } } } *************** *** 3809,3817 **** log.Debug( "checking second-level cache" ); ! // TODO: ! //bool foundInCache = InitializeCollectionFromCache(ce.loadedKey, GetCollectionOwner(ce), ! // ce.loadedPersister, collection); ! bool foundInCache = false; ! if (foundInCache) { --- 3774,3779 ---- log.Debug( "checking second-level cache" ); ! bool foundInCache = InitializeCollectionFromCache(ce.loadedKey, GetCollectionOwner(ce), ce.loadedPersister, collection); ! if (foundInCache) { *************** *** 3843,3847 **** // Collections are still written to the Cache in EndLoadingCollection and that // is probably the most appropriate place for that code anyway. ! // if (!writing) persister.Cache(id, collection, this); log.Debug("collection initialized"); } --- 3805,3816 ---- // Collections are still written to the Cache in EndLoadingCollection and that // is probably the most appropriate place for that code anyway. ! if (!writing) ! { ! // h2.1 synch - added the IsCacheable to nh specifically ! if( persister.HasCache && collection.IsCacheable ) ! { ! persister.Cache.Put( id, collection.Disassemble( persister ), Timestamp ); ! } ! } log.Debug("collection initialized"); } *************** *** 4400,4466 **** } ! //remove all collections for the entity ! EvictCollections( persister.GetPropertyValues( obj ), persister.PropertyTypes ); Cascades.Cascade( this, persister, obj, Cascades.CascadingAction.ActionEvict, CascadePoint.CascadeOnEvict, null ); } ! ! /// <summary> ! /// Evict any collections referenced by the object from the session cache. This will NOT ! /// pick up any collections that were dereferenced, so they will be deleted (suboptimal ! /// but not exactly incorrect). ! /// </summary> ! /// <param name="values"></param> ! /// <param name="types"></param> ! private void EvictCollections( Object[ ] values, IType[ ] types ) { ! for( int i = 0; i < types.Length; i++ ) { ! if( values[ i ] == null ) { ! // do nothing } ! else if( types[ i ].IsPersistentCollectionType ) ! { ! object pc = null; ! if( ( ( PersistentCollectionType ) types[ i ] ).IsArrayType ) ! { ! pc = arrayHolders[ values[ i ] ]; ! arrayHolders.Remove( values[ i ] ); ! } ! else if( values[ i ] is PersistentCollection ) ! { ! pc = values[ i ]; ! } ! if( pc != null ) ! { ! PersistentCollection coll = (PersistentCollection) pc; ! if( coll.UnsetSession( this ) ) ! { ! CollectionEntry ce = GetCollectionEntry(coll); ! collectionEntries.Remove(coll); ! if (log.IsDebugEnabled) ! { ! log.Debug( "evicting collection: " ! + MessageHelper.InfoString(ce.loadedPersister, ce.loadedKey) ); ! } ! if ( ce.loadedPersister != null && ce.loadedKey != null ) ! { ! collectionsByKey.Remove( ! new CollectionKey( ce.loadedPersister.Role, ce.loadedKey ) ); ! } ! } ! } } ! else if( types[ i ].IsComponentType ) { ! IAbstractComponentType actype = ( IAbstractComponentType ) types[ i ]; ! EvictCollections( ! actype.GetPropertyValues( values[ i ], this ), ! actype.Subtypes ! ); } } --- 4369,4440 ---- } ! //remove all collections for the entity from the session-level cache ! if( persister.HasCollections ) ! { ! new EvictVisitor(this).Process( obj, persister ); ! } ! Cascades.Cascade( this, persister, obj, Cascades.CascadingAction.ActionEvict, CascadePoint.CascadeOnEvict, null ); } ! internal void EvictCollection(object value, PersistentCollectionType type) { ! object pc; ! if( type.IsArrayType ) { ! pc = arrayHolders[ value ]; ! arrayHolders.Remove(value); ! } ! else ! { ! // the hibernate java coding style is a little different - but ! // doing the same thing ! pc = value as PersistentCollection; ! if( value==null ) { ! return; //EARLY EXIT! } ! } ! PersistentCollection collection = (PersistentCollection)pc; ! if( collection.UnsetSession( this) ) ! { ! EvictCollection( collection ); ! } ! } ! private void EvictCollection(PersistentCollection collection) ! { ! CollectionEntry ce = (CollectionEntry)collectionEntries[collection]; ! collectionEntries.Remove( collection ); ! if( log.IsDebugEnabled ) ! { ! log.Debug( "evicting collection: " + MessageHelper.InfoString( ce.loadedPersister, ce.loadedKey ) ); ! } ! if( ce.loadedPersister!=null && ce.loadedKey!=null ) ! { ! collectionsByKey.Remove( new CollectionKey( ce.loadedPersister.Role, ce.loadedKey ) ); ! } ! } ! ! ! private void EvictCachedCollections(IClassPersister persister, object id) ! { ! EvictCachedCollections( persister.PropertyTypes, id ); ! } ! ! private void EvictCachedCollections(IType[] types, object id) ! { ! foreach( IType type in types ) ! { ! if( type.IsPersistentCollectionType ) ! { ! factory.EvictCollection( ((PersistentCollectionType)type).Role, id ); } ! else if ( type.IsComponentType ) { ! IAbstractComponentType acType = (IAbstractComponentType)type; ! EvictCachedCollections( acType.Subtypes, id ); } } *************** *** 4495,4507 **** if (collection != null) { ! if ( log.IsDebugEnabled ) log.Debug( "returning loading collection:" + MessageHelper.InfoString(persister, id) ); return collection.GetValue(); } else { ! if ( log.IsDebugEnabled ) log.Debug( "creating collection wrapper:" + MessageHelper.InfoString(persister, id) ); collection = persister.CollectionType.Instantiate(this, persister); //TODO: suck into CollectionPersister.instantiate() AddUninitializedCollection(collection, persister, id); --- 4469,4485 ---- if (collection != null) { ! if ( log.IsDebugEnabled ) ! { log.Debug( "returning loading collection:" + MessageHelper.InfoString(persister, id) ); + } return collection.GetValue(); } else { ! if ( log.IsDebugEnabled ) ! { log.Debug( "creating collection wrapper:" + MessageHelper.InfoString(persister, id) ); + } collection = persister.CollectionType.Instantiate(this, persister); //TODO: suck into CollectionPersister.instantiate() AddUninitializedCollection(collection, persister, id); *************** *** 4518,4521 **** --- 4496,4527 ---- } } + + /// <summary> + /// Try to initialize a Collection from the cache. + /// </summary> + /// <param name="id"></param> + /// <param name="owner"></param> + /// <param name="persister"></param> + /// <param name="collection"></param> + /// <returns><c>true</c> if the collection was initialized from the cache, otherwise <c>false</c>.</returns> + private bool InitializeCollectionFromCache(object id, object owner, CollectionPersister persister, PersistentCollection collection) + { + if( persister.HasCache==false ) + { + return false; + } + + object cached = persister.Cache.Get( id, Timestamp ); + if( cached==null ) + { + return false; + } + + collection.InitializeFromCache( persister, cached, owner ); + GetCollectionEntry( collection ).PostInitialize( collection ); + //addInitializedCollection(collection, persister, id); h2.1 - commented out + return true; + + } } } \ No newline at end of file Index: ProxyVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ProxyVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ProxyVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- ProxyVisitor.cs 7 Feb 2005 01:34:41 -0000 1.2 *************** *** 1,12 **** using System; - using System.Collections; - using NHibernate.Type; namespace NHibernate.Impl { internal abstract class ProxyVisitor : AbstractVisitor { ! public ProxyVisitor(SessionImpl session) : base(session) { } --- 1,13 ---- using System; using NHibernate.Type; namespace NHibernate.Impl { + /// <summary> + /// Reassociates uninitialized Proxies with the Session. + /// </summary> internal abstract class ProxyVisitor : AbstractVisitor { ! public ProxyVisitor(SessionImpl session) : base( session ) { } *************** *** 14,20 **** protected override object ProcessEntity(object value, EntityType entityType) { ! if (value != null) { ! Session.ReassociateIfUninitializedProxy(value); // if it is an initialized proxy, let cascade // handle it later on --- 15,21 ---- protected override object ProcessEntity(object value, EntityType entityType) { ! if( value != null ) { ! Session.ReassociateIfUninitializedProxy( value ); // if it is an initialized proxy, let cascade // handle it later on *************** *** 24,26 **** } } ! } --- 25,27 ---- } } ! } \ No newline at end of file Index: WrapVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/WrapVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** WrapVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- WrapVisitor.cs 7 Feb 2005 01:34:41 -0000 1.2 *************** *** 1,32 **** using System; ! using System.Collections; ! using NHibernate.Collection; ! using NHibernate.Engine; using NHibernate.Type; - using log4net; - namespace NHibernate.Impl { internal class WrapVisitor : ProxyVisitor { ! private static readonly ILog log = LogManager.GetLogger(typeof(WrapVisitor)); ! private bool substitute = false; public bool IsSubstitutionRequired { ! get { return substitute; } } ! public WrapVisitor(SessionImpl session) : base (session) { } protected override object ProcessCollection(object collection, PersistentCollectionType collectionType) { ! if ( collection is PersistentCollection ) { ! PersistentCollection coll = (PersistentCollection) collection; ! if ( coll.SetCurrentSession(Session) ) { Session.ReattachCollection( coll, coll.CollectionSnapshot ); --- 1,34 ---- using System; ! using log4net; using NHibernate.Collection; ! using NHibernate.Persister; using NHibernate.Type; namespace NHibernate.Impl { + /// <summary> + /// Wrap collections in a NHibernate collection wrapper. + /// </summary> internal class WrapVisitor : ProxyVisitor { ! private static readonly ILog log = LogManager.GetLogger( typeof( WrapVisitor ) ); ! private bool _substitute = false; public bool IsSubstitutionRequired { ! get { return _substitute; } } ! public WrapVisitor(SessionImpl session) : base( session ) ! { ! } protected override object ProcessCollection(object collection, PersistentCollectionType collectionType) { ! if( collection is PersistentCollection ) { ! PersistentCollection coll = (PersistentCollection)collection; ! if( coll.SetCurrentSession( Session ) ) { Session.ReattachCollection( coll, coll.CollectionSnapshot ); *************** *** 35,41 **** } ! else { ! return ProcessArrayOrNewCollection(collection, collectionType); } } --- 37,43 ---- } ! else { ! return ProcessArrayOrNewCollection( collection, collectionType ); } } *************** *** 43,68 **** private object ProcessArrayOrNewCollection(object collection, PersistentCollectionType collectionType) { ! if (collection == null) return null; CollectionPersister persister = Session.GetCollectionPersister( collectionType.Role ); ! ! if ( collectionType.IsArrayType ) { ! ArrayHolder ah = Session.GetArrayHolder(collection); ! if (ah == null) { ! ah = new ArrayHolder(Session, collection); ! Session.AddNewCollection(ah, persister); ! Session.AddArrayHolder(ah); } return null; } ! else { ! PersistentCollection persistentCollection = collectionType.Wrap(Session, collection); ! Session.AddNewCollection(persistentCollection, persister); ! ! if ( log.IsDebugEnabled ) log.Debug( "Wrapped collection in role: " + collectionType.Role ); ! return persistentCollection; //Force a substitution! } --- 45,76 ---- private object ProcessArrayOrNewCollection(object collection, PersistentCollectionType collectionType) { ! if( collection == null ) ! { ! return null; ! } CollectionPersister persister = Session.GetCollectionPersister( collectionType.Role ); ! ! if( collectionType.IsArrayType ) { ! ArrayHolder ah = Session.GetArrayHolder( collection ); ! if( ah == null ) { ! ah = new ArrayHolder( Session, collection ); ! Session.AddNewCollection( ah, persister ); ! Session.AddArrayHolder( ah ); } return null; } ! else { ! PersistentCollection persistentCollection = collectionType.Wrap( Session, collection ); ! Session.AddNewCollection( persistentCollection, persister ); ! ! if( log.IsDebugEnabled ) ! { ! log.Debug( "Wrapped collection in role: " + collectionType.Role ); ! } ! return persistentCollection; //Force a substitution! } *************** *** 71,81 **** public override void ProcessValues(object[] values, IType[] types) { ! for (int i = 0; i < types.Length; i++) { ! object result = ProcessValue( values[i], types[i] ); ! if ( result != null ) { ! substitute = true; ! values[i] = result; } } --- 79,89 ---- public override void ProcessValues(object[] values, IType[] types) { ! for( int i = 0; i < types.Length; i++ ) { ! object result = ProcessValue( values[ i ], types[ i ] ); ! if( result != null ) { ! _substitute = true; ! values[ i ] = result; } } *************** *** 84,105 **** protected override object ProcessComponent(object component, IAbstractComponentType componentType) { ! if (component == null) return null; object[] values = componentType.GetPropertyValues( component, Session ); IType[] types = componentType.Subtypes; bool substituteComponent = false; ! for ( int i=0; i<types.Length; i++ ) { ! object result = ProcessValue( values[i], types[i] ); ! if (result != null) { substituteComponent = true; ! values[i] = result; } } ! if (substituteComponent) { ! componentType.SetPropertyValues(component, values); } --- 92,116 ---- protected override object ProcessComponent(object component, IAbstractComponentType componentType) { ! if( component == null ) ! { ! return null; ! } object[] values = componentType.GetPropertyValues( component, Session ); IType[] types = componentType.Subtypes; bool substituteComponent = false; ! for( int i = 0; i < types.Length; i++ ) { ! object result = ProcessValue( values[ i ], types[ i ] ); ! if( result != null ) { substituteComponent = true; ! values[ i ] = result; } } ! if( substituteComponent ) { ! componentType.SetPropertyValues( component, values ); } *************** *** 107,118 **** } ! public override void Process(object obj, NHibernate.Persister.IClassPersister persister) { ! object[] values = persister.GetPropertyValues(obj); IType[] types = persister.PropertyTypes; ! ProcessValues(values, types); ! if ( IsSubstitutionRequired ) persister.SetPropertyValues(obj, values); } } ! } --- 118,132 ---- } ! public override void Process(object obj, IClassPersister persister) { ! object[] values = persister.GetPropertyValues( obj ); IType[] types = persister.PropertyTypes; ! ProcessValues( values, types ); ! if( IsSubstitutionRequired ) ! { ! persister.SetPropertyValues( obj, values ); ! } } } ! } \ No newline at end of file Index: SessionFactoryImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionFactoryImpl.cs,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** SessionFactoryImpl.cs 30 Jan 2005 19:36:15 -0000 1.40 --- SessionFactoryImpl.cs 7 Feb 2005 01:34:41 -0000 1.41 *************** *** 784,788 **** if( p.HasCache ) { ! p.CacheConcurrencyStrategy.Destroy(); } } --- 784,788 ---- if( p.HasCache ) { ! p.Cache.Destroy(); } } *************** *** 835,839 **** if( p.HasCache ) { ! p.CacheConcurrencyStrategy.Remove( id ); } } --- 835,839 ---- if( p.HasCache ) { ! p.Cache.Remove( id ); } } *************** *** 848,852 **** if( p.HasCache ) { ! p.CacheConcurrencyStrategy.Clear(); } } --- 848,852 ---- if( p.HasCache ) { ! p.Cache.Clear(); } } --- NEW FILE: DirtyCollectionSearchVisitor.cs --- using System; using NHibernate.Collection; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// A Visitor that determines if a dirty collection was found. /// </summary> /// <remarks> /// <list type="number"> /// <listheader> /// <description>Reason for dirty collection</description> /// </listheader> /// <item> /// <description> /// If it is a new application-instantiated collection, return true (does not occur anymore!) /// </description> /// </item> /// <item> /// <description> /// If it is a component, recurse. /// </description> /// </item> /// <item> /// <description> /// If it is a wrapped collection, ask the collection entry. /// </description> /// </item> /// </list> /// </remarks> internal class DirtyCollectionSearchVisitor : AbstractVisitor { private bool _dirty; public DirtyCollectionSearchVisitor(SessionImpl session) : base( session ) { } /// <summary> /// Gets a <see cref="bool"/> indicating if a dirty collection was found. /// </summary> /// <value><c>true</c> if a dirty collection was found.</value> public bool WasDirtyCollectionFound { get { return _dirty; } } protected override object ProcessCollection(object collection, PersistentCollectionType type) { if( collection != null ) { SessionImpl session = Session; PersistentCollection coll; if( type.IsArrayType ) { coll = session.GetArrayHolder( collection ); // if no array holder we found an unwrappered array (this can't occur, // because we now always call wrap() before getting to here) // return (ah==null) ? true : searchForDirtyCollections(ah, type); } else { // if not wrappered yet, its dirty (this can't occur, because // we now always call wrap() before getting to here) // return ( ! (obj is PersistentCollection) ) ? // true : SearchForDirtyCollections( (PersistentCollection) obj, type ); coll = (PersistentCollection)collection; } if( session.CollectionIsDirty( coll ) ) { _dirty = true; return null; // NOTE: early exit } } return null; } } } --- NEW FILE: EvictVisitor.cs --- using System; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// Evict any collections referenced by the object from the ISession cache. /// </summary> /// <remarks> /// This will <b>NOT</b> pick up any collections that were dereferenced, so /// they will be deleted (suboptimal but not exactly incorrect). /// </remarks> internal class EvictVisitor : AbstractVisitor { public EvictVisitor(SessionImpl session) : base( session ) { } protected override object ProcessCollection(object collection, PersistentCollectionType type) { if( collection != null ) { Session.EvictCollection( collection, type ); } return null; } } } Index: ReattachVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/ReattachVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ReattachVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- ReattachVisitor.cs 7 Feb 2005 01:34:41 -0000 1.2 *************** *** 1,5 **** using System; - using System.Collections; - using NHibernate.Type; --- 1,3 ---- *************** *** 11,25 **** internal abstract class ReattachVisitor : ProxyVisitor { ! private readonly object key; protected object Key { ! get { return key; } } public ReattachVisitor(SessionImpl session, object key) ! : base(session) { ! this.key = key; } --- 9,23 ---- internal abstract class ReattachVisitor : ProxyVisitor { ! private readonly object _key; protected object Key { ! get { return _key; } } public ReattachVisitor(SessionImpl session, object key) ! : base( session ) { ! _key = key; } *************** *** 27,37 **** { IType[] types = componentType.Subtypes; ! if (component == null) { ! ProcessValues(new object[types.Length], types); } else { ! base.ProcessComponent(component, componentType); } --- 25,35 ---- { IType[] types = componentType.Subtypes; ! if( component == null ) { ! ProcessValues( new object[types.Length], types ); } else { ! base.ProcessComponent( component, componentType ); } *************** *** 39,41 **** } } ! } --- 37,39 ---- } } ! } \ No newline at end of file Index: AbstractVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/AbstractVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** AbstractVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- AbstractVisitor.cs 7 Feb 2005 01:34:40 -0000 1.2 *************** *** 1,7 **** using System; - using System.Collections; - - using NHibernate.Type; using NHibernate.Persister; namespace NHibernate.Impl --- 1,5 ---- using System; using NHibernate.Persister; + using NHibernate.Type; namespace NHibernate.Impl *************** *** 14,22 **** internal abstract class AbstractVisitor { ! private readonly SessionImpl session; protected AbstractVisitor(SessionImpl session) { ! this.session = session; } --- 12,20 ---- internal abstract class AbstractVisitor { ! private readonly SessionImpl _session; protected AbstractVisitor(SessionImpl session) { ! _session = session; } *************** *** 28,34 **** public virtual void ProcessValues(object[] values, IType[] types) { ! for (int i = 0; i < values.Length; i++) { ! ProcessValue(values[i], types[i]); } } --- 26,32 ---- public virtual void ProcessValues(object[] values, IType[] types) { ! for( int i = 0; i < values.Length; i++ ) { ! ProcessValue( values[ i ], types[ i ] ); } } *************** *** 36,43 **** protected virtual object ProcessComponent(object component, IAbstractComponentType componentType) { ! if (component != null) { ! ProcessValues(componentType.GetPropertyValues(component, session), ! componentType.Subtypes); } --- 34,41 ---- protected virtual object ProcessComponent(object component, IAbstractComponentType componentType) { ! if( component != null ) { ! ProcessValues( componentType.GetPropertyValues( component, _session ), ! componentType.Subtypes ); } *************** *** 54,71 **** protected object ProcessValue(object value, IType type) { ! if (type.IsPersistentCollectionType) { // Even process null collections ! return ProcessCollection(value, (PersistentCollectionType) type); } ! else if (type.IsEntityType) { ! return ProcessEntity(value, (EntityType) type); } ! else if (type.IsComponentType) { //TODO: what about a null component with a collection! // we also need to clean up that "null collection" ! return ProcessComponent(value, (IAbstractComponentType) type); } else --- 52,69 ---- protected object ProcessValue(object value, IType type) { ! if( type.IsPersistentCollectionType ) { // Even process null collections ! return ProcessCollection( value, (PersistentCollectionType)type ); } ! else if( type.IsEntityType ) { ! return ProcessEntity( value, (EntityType)type ); } ! else if( type.IsComponentType ) { //TODO: what about a null component with a collection! // we also need to clean up that "null collection" ! return ProcessComponent( value, (IAbstractComponentType)type ); } else *************** *** 83,88 **** { ProcessValues( ! persister.GetPropertyValues(obj), ! persister.PropertyTypes); } --- 81,86 ---- { ProcessValues( ! persister.GetPropertyValues( obj ), ! persister.PropertyTypes ); } *************** *** 112,117 **** protected SessionImpl Session { ! get { return session; } } } ! } --- 110,115 ---- protected SessionImpl Session { ! get { return _session; } } } ! } \ No newline at end of file Index: CollectionKey.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/CollectionKey.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CollectionKey.cs 6 Feb 2005 01:59:02 -0000 1.1 --- CollectionKey.cs 7 Feb 2005 01:34:40 -0000 1.2 *************** *** 1,4 **** using System; - using System.Collections; using NHibernate.Collection; --- 1,3 ---- *************** *** 33,38 **** { int result = 17; ! result = 37 * result + key.GetHashCode(); ! result = 37 * result + role.GetHashCode(); return result; } --- 32,40 ---- { int result = 17; ! unchecked ! { ! result = 37 * result + key.GetHashCode(); ! result = 37 * result + role.GetHashCode(); ! } return result; } Index: OnUpdateVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/OnUpdateVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** OnUpdateVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- OnUpdateVisitor.cs 7 Feb 2005 01:34:41 -0000 1.2 *************** *** 1,5 **** using System; - using System.Collections; - using NHibernate.Collection; using NHibernate.Engine; --- 1,3 ---- *************** *** 8,15 **** namespace NHibernate.Impl { internal class OnUpdateVisitor : ReattachVisitor { public OnUpdateVisitor(SessionImpl session, object key) ! : base (session, key) { } --- 6,36 ---- namespace NHibernate.Impl { + /// <summary> + /// When an entity is passed to <c>Update()</c>, all its collections must be + /// inspected and: + /// <list type="number"> + /// <item> + /// <description> + /// Associate any uninitialized PersistentCollections with this Session. + /// </description> + /// </item> + /// <item> + /// <description> + /// Associate any initialized PersistentCollections with this Session, using the + /// existing snapshot. + /// </description> + /// </item> + /// <item> + /// <description> + /// Execute a collection removal (SQL DELETE) for each null collection property + /// or "new" collection. + /// </description> + /// </item> + /// </list> + /// </summary> internal class OnUpdateVisitor : ReattachVisitor { public OnUpdateVisitor(SessionImpl session, object key) ! : base( session, key ) { } *************** *** 18,54 **** { CollectionPersister persister = Session.GetCollectionPersister( type.Role ); ! ! if ( collection is PersistentCollection ) { ! PersistentCollection wrapper = (PersistentCollection) collection; ! if ( wrapper.SetCurrentSession(Session) ) { //a "detached" collection! ICollectionSnapshot snapshot = wrapper.CollectionSnapshot; ! ! if ( !SessionImpl.IsOwnerUnchanged(snapshot, persister, Key) ) { // if the collection belonged to a different entity, // clean up the existing state of the collection ! Session.RemoveCollection(persister, Key); } ! ! Session.ReattachCollection(wrapper, snapshot); } ! else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() ! Session.RemoveCollection(persister, Key); } } ! else { // null or brand new collection // this will also (inefficiently) handle arrays, which have // no snapshot, so we can't do any better ! Session.RemoveCollection(persister, Key); //processArrayOrNewCollection(collection, type); } --- 39,75 ---- { CollectionPersister persister = Session.GetCollectionPersister( type.Role ); ! ! if( collection is PersistentCollection ) { ! PersistentCollection wrapper = (PersistentCollection)collection; ! if( wrapper.SetCurrentSession( Session ) ) { //a "detached" collection! ICollectionSnapshot snapshot = wrapper.CollectionSnapshot; ! ! if( !SessionImpl.IsOwnerUnchanged( snapshot, persister, Key ) ) { // if the collection belonged to a different entity, // clean up the existing state of the collection ! Session.RemoveCollection( persister, Key ); } ! ! Session.ReattachCollection( wrapper, snapshot ); } ! else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() ! Session.RemoveCollection( persister, Key ); } } ! else { // null or brand new collection // this will also (inefficiently) handle arrays, which have // no snapshot, so we can't do any better ! Session.RemoveCollection( persister, Key ); //processArrayOrNewCollection(collection, type); } *************** *** 57,59 **** } } ! } --- 78,80 ---- } } ! } \ No newline at end of file Index: FlushVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/FlushVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** FlushVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- FlushVisitor.cs 7 Feb 2005 01:34:40 -0000 1.2 *************** *** 1,5 **** using System; - using System.Collections; - using NHibernate.Collection; using NHibernate.Type; --- 1,3 ---- *************** *** 9,37 **** internal class FlushVisitor : AbstractVisitor { ! private object owner; ! public FlushVisitor( SessionImpl session, object owner ) : base( session ) { ! this.owner = owner; } protected override object ProcessCollection(object collection, PersistentCollectionType type) { ! if (collection!=null) { PersistentCollection coll; ! if ( type.IsArrayType ) { ! coll = Session.GetArrayHolder(collection); } ! else { ! coll = (PersistentCollection) collection; } ! Session.UpdateReachableCollection(coll, type, owner); } return null; } } ! } --- 7,35 ---- internal class FlushVisitor : AbstractVisitor { ! private object _owner; ! public FlushVisitor(SessionImpl session, object owner) : base( session ) { ! _owner = owner; } protected override object ProcessCollection(object collection, PersistentCollectionType type) { ! if( collection != null ) { PersistentCollection coll; ! if( type.IsArrayType ) { ! coll = Session.GetArrayHolder( collection ); } ! else { ! coll = (PersistentCollection)collection; } ! Session.UpdateReachableCollection( coll, type, _owner ); } return null; } } ! } \ No newline at end of file Index: OnLockVisitor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/OnLockVisitor.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** OnLockVisitor.cs 6 Feb 2005 01:59:02 -0000 1.1 --- OnLockVisitor.cs 7 Feb 2005 01:34:41 -0000 1.2 *************** *** 1,5 **** using System; - using System.Collections; - using NHibernate.Collection; using NHibernate.Engine; --- 1,3 ---- *************** *** 18,22 **** { public OnLockVisitor(SessionImpl session, object key) ! : base(session, key) { } --- 16,20 ---- { public OnLockVisitor(SessionImpl session, object key) ! : base( session, key ) { } *************** *** 24,68 **** protected override object ProcessCollection(object collection, PersistentCollectionType type) { ! CollectionPersister persister = Session.GetCollectionPersister(type.Role); ! if (collection == null) { // Do nothing } ! else if ( collection is PersistentCollection ) { ! PersistentCollection coll = (PersistentCollection) collection; ! if ( coll.SetCurrentSession(Session) ) { ICollectionSnapshot snapshot = coll.CollectionSnapshot; ! if (SessionImpl.IsOwnerUnchanged( snapshot, persister, this.Key )) { // a "detached" collection that originally belonged to the same entity ! if ( snapshot.Dirty ) { ! throw new HibernateException("reassociated object has dirty collection"); } ! Session.ReattachCollection(coll, snapshot); } ! else { // a "detached" collection that belonged to a different entity ! throw new HibernateException("reassociated object has dirty collection reference"); } } ! else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() ! throw new HibernateException("reassociated object has dirty collection reference"); } } ! else { // brand new collection //TODO: or an array!! we can't lock objects with arrays now?? ! throw new HibernateException("reassociated object has dirty collection reference"); } --- 22,66 ---- protected override object ProcessCollection(object collection, PersistentCollectionType type) { ! CollectionPersister persister = Session.GetCollectionPersister( type.Role ); ! if( collection == null ) { // Do nothing } ! else if( collection is PersistentCollection ) { ! PersistentCollection coll = (PersistentCollection)collection; ! if( coll.SetCurrentSession( Session ) ) { ICollectionSnapshot snapshot = coll.CollectionSnapshot; ! if( SessionImpl.IsOwnerUnchanged( snapshot, persister, this.Key ) ) { // a "detached" collection that originally belonged to the same entity ! if( snapshot.Dirty ) { ! throw new HibernateException( "reassociated object has dirty collection" ); } ! Session.ReattachCollection( coll, snapshot ); } ! else { // a "detached" collection that belonged to a different entity ! throw new HibernateException( "reassociated object has dirty collection reference" ); } } ! else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() ! throw new HibernateException( "reassociated object has dirty collection reference" ); } } ! else { // brand new collection //TODO: or an array!! we can't lock objects with arrays now?? ! throw new HibernateException( "reassociated object has dirty collection reference" ); } *************** *** 71,73 **** } ! } --- 69,71 ---- } ! } \ No newline at end of file |
From: Michael D. <mik...@us...> - 2005-02-07 01:34:52
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Type In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106/Type Modified Files: ArrayType.cs BagType.cs IdentifierBagType.cs ListType.cs MapType.cs PersistentCollectionType.cs SetType.cs SortedMapType.cs SortedSetType.cs Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: BagType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/BagType.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** BagType.cs 31 Dec 2004 23:50:57 -0000 1.4 --- BagType.cs 7 Feb 2005 01:34:41 -0000 1.5 *************** *** 44,61 **** } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) - { - return new Bag( session, persister, disassembled, owner ); - } - } } \ No newline at end of file --- 44,47 ---- Index: ListType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/ListType.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ListType.cs 31 Dec 2004 23:54:40 -0000 1.5 --- ListType.cs 7 Feb 2005 01:34:41 -0000 1.6 *************** *** 43,63 **** return new List( session, ( IList ) collection ); } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( - ISessionImplementor session, - CollectionPersister persister, - object disassembled, - object owner ) - { - return new List( session, persister, disassembled, owner ); - } } } \ No newline at end of file --- 43,46 ---- Index: IdentifierBagType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/IdentifierBagType.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** IdentifierBagType.cs 31 Dec 2004 23:52:52 -0000 1.2 --- IdentifierBagType.cs 7 Feb 2005 01:34:41 -0000 1.3 *************** *** 45,63 **** return new IdentifierBag( session, ( ICollection ) collection ); } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) - { - return new IdentifierBag( session, persister, disassembled, owner ); - } - - } } \ No newline at end of file --- 45,48 ---- Index: ArrayType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/ArrayType.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** ArrayType.cs 31 Dec 2004 23:50:57 -0000 1.7 --- ArrayType.cs 7 Feb 2005 01:34:41 -0000 1.8 *************** *** 93,112 **** get { return true; } } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, - CollectionPersister persister, - object disassembled, - object owner ) - { - return new ArrayHolder( session, persister, disassembled, owner ); - } } } \ No newline at end of file --- 93,96 ---- Index: MapType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/MapType.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MapType.cs 31 Dec 2004 23:54:40 -0000 1.5 --- MapType.cs 7 Feb 2005 01:34:41 -0000 1.6 *************** *** 53,73 **** return new Map( session, ( IDictionary ) collection ); } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( - ISessionImplementor session, - CollectionPersister persister, - object disassembled, - object owner ) - { - return new Map( session, persister, disassembled, owner ); - } } } \ No newline at end of file --- 53,56 ---- Index: SortedMapType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/SortedMapType.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SortedMapType.cs 31 Dec 2004 23:55:34 -0000 1.3 --- SortedMapType.cs 7 Feb 2005 01:34:41 -0000 1.4 *************** *** 48,64 **** return new SortedMap( session, ( IDictionary ) collection, comparer ); } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) - { - return new SortedMap( session, persister, comparer, disassembled, owner ); - } } } \ No newline at end of file --- 48,51 ---- Index: SetType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/SetType.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** SetType.cs 31 Dec 2004 23:55:34 -0000 1.5 --- SetType.cs 7 Feb 2005 01:34:41 -0000 1.6 *************** *** 49,65 **** /// <summary> - /// <see cref="PersistentCollectionType.AssembleCachedCollection"/> - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) - { - return new Set( session, persister, disassembled, owner ); - } - - /// <summary> /// /// </summary> --- 49,52 ---- Index: PersistentCollectionType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/PersistentCollectionType.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** PersistentCollectionType.cs 6 Feb 2005 01:59:02 -0000 1.19 --- PersistentCollectionType.cs 7 Feb 2005 01:34:41 -0000 1.20 *************** *** 93,130 **** } - /* - /// <summary> - /// - /// </summary> - /// <param name="id"></param> - /// <param name="owner"></param> - /// <param name="session"></param> - /// <returns></returns> - public virtual object GetCollection( object id, object owner, ISessionImplementor session ) - { - // added the owner - PersistentCollection collection = session.GetLoadingCollection( role, id ); - if( collection != null ) - { - return collection.GetCachedValue(); - } //TODO: yuck... call another method - H2.0.3comment - - CollectionPersister persister = session.Factory.GetCollectionPersister( role ); - collection = persister.GetCachedCollection( id, owner, session ); - if( collection != null ) - { - session.AddInitializedCollection( collection, persister, id ); - return collection.GetCachedValue(); - } - else - { - collection = Instantiate( session, persister ); - session.AddUninitializedCollection( collection, persister, id ); - return collection.GetInitialValue( persister.IsLazy ); - } - - } - */ - /// <summary> /// --- 93,96 ---- *************** *** 321,334 **** get { return false; } } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public abstract PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ); } } \ No newline at end of file --- 287,290 ---- Index: SortedSetType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/SortedSetType.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** SortedSetType.cs 31 Dec 2004 23:55:53 -0000 1.6 --- SortedSetType.cs 7 Feb 2005 01:34:41 -0000 1.7 *************** *** 51,68 **** } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - /// <returns></returns> - public override PersistentCollection AssembleCachedCollection( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) - { - return new SortedSet( session, persister, comparer, disassembled, owner ); - } - } } \ No newline at end of file --- 51,54 ---- |
From: Michael D. <mik...@us...> - 2005-02-07 01:34:50
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106/Collection Modified Files: ArrayHolder.cs Bag.cs CollectionPersister.cs IdentifierBag.cs List.cs Map.cs PersistentCollection.cs Set.cs SortedMap.cs SortedSet.cs Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: Bag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Bag.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Bag.cs 6 Feb 2005 01:58:56 -0000 1.12 --- Bag.cs 7 Feb 2005 01:34:40 -0000 1.13 *************** *** 41,45 **** } ! initialized = true; directlyAccessible = true; } --- 41,45 ---- } ! SetInitialized(); directlyAccessible = true; } *************** *** 48,69 **** /// /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - public Bag( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i++ ) - { - bag.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); - } - initialized = true; - } - - /// <summary> - /// - /// </summary> /// <returns></returns> public override ICollection Elements() --- 48,51 ---- *************** *** 218,221 **** --- 200,221 ---- /// <summary> + /// Initializes this Bag from the cached values. + /// </summary> + /// <param name="persister">The CollectionPersister to use to reassemble the Bag.</param> + /// <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 ); + object[] array = ( object[] ) disassembled; + for( int i = 0; i < array.Length; i++ ) + { + bag.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); + } + SetInitialized(); + } + + + /// <summary> /// Gets a <see cref="Boolean"/> indicating if this Bag needs to be recreated /// in the database. Index: Map.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Map.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** Map.cs 6 Feb 2005 01:58:56 -0000 1.18 --- Map.cs 7 Feb 2005 01:34:40 -0000 1.19 *************** *** 78,100 **** /// <summary> - /// Construct an initialized Map from its disassembled state. - /// </summary> - /// <param name="session">The ISession the Map should be a part of.</param> - /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> - /// <param name="disassembled">The disassembled Map.</param> - /// <param name="owner">The owner object.</param> - public Map( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i += 2 ) - { - map[ persister.IndexType.Assemble( array[ i ], session, owner ) ] = - persister.ElementType.Assemble( array[ i + 1 ], session, owner ); - } - initialized = true; - } - - /// <summary> /// Construct an initialized Map based off the values from the existing IDictionary. /// </summary> --- 78,81 ---- *************** *** 104,108 **** { this.map = map; ! initialized = true; directlyAccessible = true; } --- 85,89 ---- { this.map = map; ! SetInitialized(); directlyAccessible = true; } *************** *** 332,335 **** --- 313,334 ---- /// <summary> + /// Initializes this Map from the cached values. + /// </summary> + /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> + /// <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 ); + object[ ] array = ( object[ ] ) disassembled; + for( int i = 0; i < array.Length; i += 2 ) + { + map[ persister.IndexType.Assemble( array[ i ], session, owner ) ] = + persister.ElementType.Assemble( array[ i + 1 ], session, owner ); + } + SetInitialized(); + } + + /// <summary> /// /// </summary> Index: PersistentCollection.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/PersistentCollection.cs,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** PersistentCollection.cs 6 Feb 2005 01:58:56 -0000 1.19 --- PersistentCollection.cs 7 Feb 2005 01:34:40 -0000 1.20 *************** *** 197,201 **** /// Return the user-visible collection (or array) instance /// </summary> ! /// <returns></returns> public virtual object GetValue() { --- 197,206 ---- /// Return the user-visible collection (or array) instance /// </summary> ! /// <returns> ! /// By default, the NHibernate wrapper is an acceptable collection for ! /// the end user code to work with because it is interface compatible. ! /// An NHibernate List is an IList, an NHibernate Map is an IDictionary ! /// and those are the types user code is expecting. ! /// </returns> public virtual object GetValue() { *************** *** 221,226 **** /// <summary> ! /// Override on some subclasses. /// </summary> public virtual void EndRead() { --- 226,243 ---- /// <summary> ! /// Called when the reading the Collection from the database is finished. /// </summary> + /// <remarks> + /// <p> + /// This should be overridden by sub collections that use temporary collections + /// to store values read from the db. + /// </p> + /// <p> + /// This is also responsible for determining if the collection is cacheable by + /// setting the property <see cref="IsCacheable"/>. When NH is synched with h2.1 + /// this method will be changed to return that bool instead of setting the property, + /// but this accomplishes the same thing until then. + /// </p> + /// </remarks> public virtual void EndRead() { *************** *** 232,243 **** --- 249,288 ---- DelayedAddAll(additions); additions=null; + // can't cache the collection because it contains additions that are + // not in the database - those additions can't be put in the cache + // because they might throw TransientObjectExceptions when attempting + // to get their database identifier. + IsCacheable = false; //return false; } else { + // nothing happened that would prevent this collection from being safe + // to cache. + IsCacheable = true; //return true; } } + private bool _isCacheable; + + /// <summary> + /// Gets or sets a boolean indicating if this collection can be put into the + /// cache. + /// </summary> + /// <remarks> + /// This is a method new to NHibernate and is in here until the Loader design + /// can get synched up with h2.1's loader design. In h2.1 the <c>EndRead()</c> + /// method returns a bool that is used by the ISession to determine wether or + /// not the Collection can go in cache. Right now, the only thing that can keep + /// a collection from being cached is if Delayed Adds are supported - ie, adding + /// items to the collection without fully initializing it. + /// </remarks> + internal bool IsCacheable + { + get { return _isCacheable; } + set { _isCacheable = value; } + } + /// <summary> /// *************** *** 352,355 **** --- 397,409 ---- /// <summary> + /// Read the state of the collection from a disassembled cached value. + /// </summary> + /// <param name="persister"></param> + /// <param name="disassembled"></param> + /// <param name="owner"></param> + public abstract void InitializeFromCache(CollectionPersister persister, object disassembled, object owner); + + + /// <summary> /// Reads the elements Identifier from the reader. /// </summary> *************** *** 573,576 **** --- 627,633 ---- } + /// <summary> + /// Mark the collection as initialized. + /// </summary> protected void SetInitialized() { Index: List.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/List.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** List.cs 6 Feb 2005 01:58:56 -0000 1.17 --- List.cs 7 Feb 2005 01:34:40 -0000 1.18 *************** *** 82,86 **** { this.list = list; ! initialized = true; directlyAccessible = true; } --- 82,86 ---- { this.list = list; ! SetInitialized(); directlyAccessible = true; } *************** *** 323,333 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public List( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) { BeforeInitialize( persister ); --- 323,332 ---- /// <summary> ! /// Initializes this List from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the List.</param> ! /// <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 ); *************** *** 337,341 **** list.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! initialized = true; } --- 336,340 ---- list.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! SetInitialized(); } Index: CollectionPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/CollectionPersister.cs,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** CollectionPersister.cs 31 Dec 2004 16:36:46 -0000 1.31 --- CollectionPersister.cs 7 Feb 2005 01:34:40 -0000 1.32 *************** *** 282,304 **** /// /// </summary> ! /// <param name="id"></param> ! /// <param name="coll"></param> ! /// <param name="s"></param> ! public void Cache( object id, PersistentCollection coll, ISessionImplementor s ) ! { ! if( cache != null ) ! { ! if( log.IsDebugEnabled ) ! { ! log.Debug( "Caching collection: " + role + "#" + id ); ! } ! cache.Put( id, coll.Disassemble( this ), s.Timestamp ); ! } ! } ! ! /// <summary> ! /// ! /// </summary> ! public ICacheConcurrencyStrategy CacheConcurrencyStrategy { get { return cache; } --- 282,286 ---- /// /// </summary> ! public ICacheConcurrencyStrategy Cache { get { return cache; } *************** *** 317,351 **** /// </summary> /// <param name="id"></param> - /// <param name="owner"></param> - /// <param name="s"></param> - /// <returns></returns> - public PersistentCollection GetCachedCollection( object id, object owner, ISessionImplementor s ) - { - if( cache == null ) - { - return null; - } - else - { - if( log.IsDebugEnabled ) - { - log.Debug( "Searching for collection in cache: " + role + "#" + id ); - } - object cached = cache.Get( id, s.Timestamp ); - if( cached == null ) - { - return null; - } - else - { - return collectionType.AssembleCachedCollection( s, this, cached, owner ); - } - } - } - - /// <summary> - /// - /// </summary> - /// <param name="id"></param> public void Softlock( object id ) { --- 299,302 ---- Index: ArrayHolder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/ArrayHolder.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** ArrayHolder.cs 6 Feb 2005 01:58:56 -0000 1.15 --- ArrayHolder.cs 7 Feb 2005 01:34:40 -0000 1.16 *************** *** 16,19 **** --- 16,22 ---- private static readonly ILog log = LogManager.GetLogger( typeof( PersistentCollection ) ); + /// <summary> + /// The <see cref="Array"/> that NHibernate is wrapping. + /// </summary> private Array array; *************** *** 21,24 **** --- 24,31 ---- private System.Type elementClass; + /// <summary> + /// A temporary list that holds the objects while the ArrayHolder is being + /// populated from the database. + /// </summary> [NonSerialized] private ArrayList tempList; *************** *** 33,37 **** { this.array = (Array) array; ! initialized = true; } --- 40,44 ---- { this.array = (Array) array; ! SetInitialized(); } *************** *** 192,196 **** /// <summary> ! /// /// </summary> public override void BeginRead() --- 199,204 ---- /// <summary> ! /// Before the <c>ReadFrom()</c> is called the ArrayHolder needs to setup ! /// a temporary list to hold the objects. /// </summary> public override void BeginRead() *************** *** 200,203 **** --- 208,216 ---- } + /// <summary> + /// Takes the contents stored in the temporary list created during <c>BeginRead()</c> + /// that was populated during <c>ReadFrom()</c> and write it to the underlying + /// array. + /// </summary> public override void EndRead() { *************** *** 211,214 **** --- 224,230 ---- } tempList = null; + + // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) + IsCacheable = true; //return true; } *************** *** 239,252 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public ArrayHolder( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) ! : base( session ) { ! object[ ] cached = ( object[ ] ) disassembled; array = System.Array.CreateInstance( persister.ElementClass, cached.Length ); --- 255,266 ---- /// <summary> ! /// Initializes this array holder from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the Array.</param> ! /// <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; array = System.Array.CreateInstance( persister.ElementClass, cached.Length ); *************** *** 254,260 **** for( int i = 0; i < cached.Length; i++ ) { ! ( ( Array ) array ).SetValue( persister.ElementType.Assemble( cached[ i ], session, owner ), i ); } ! initialized = true; } --- 268,274 ---- for( int i = 0; i < cached.Length; i++ ) { ! array.SetValue( persister.ElementType.Assemble( cached[ i ], session, owner ), i ); } ! SetInitialized(); } *************** *** 275,278 **** --- 289,298 ---- } + /// <summary> + /// Returns the user-visible portion of the NHibernate ArrayHolder. + /// </summary> + /// <returns> + /// The array that contains the data, not the NHibernate wrapper. + /// </returns> public override object GetValue() { Index: SortedSet.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedSet.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** SortedSet.cs 6 Feb 2005 01:58:56 -0000 1.12 --- SortedSet.cs 7 Feb 2005 01:34:40 -0000 1.13 *************** *** 71,95 **** this.comparer = comparer; } - - /// <summary> - /// - /// </summary> - /// <param name="session"></param> - /// <param name="persister"></param> - /// <param name="comparer"></param> - /// <param name="disassembled"></param> - /// <param name="owner"></param> - public SortedSet( ISessionImplementor session, CollectionPersister persister, IComparer comparer, object disassembled, object owner ) : this( session, comparer ) - { - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - for( int i = 0; i < array.Length; i++ ) - { - object newObject = persister.ElementType.Assemble( array[ i ], session, owner ); - internalSet.Add( newObject ); - } - - initialized = true; - } } } \ No newline at end of file --- 71,74 ---- Index: SortedMap.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedMap.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** SortedMap.cs 6 Feb 2005 01:58:56 -0000 1.7 --- SortedMap.cs 7 Feb 2005 01:34:40 -0000 1.8 *************** *** 54,84 **** /// <summary> - /// Create an Initialized SortedMap from its disassembled state. - /// </summary> - /// <param name="session">The ISession the Map should be a part of.</param> - /// <param name="persister">The CollectionPersister to use to reassemble the Map.</param> - /// <param name="comparer">The IComparer to perform the sorting.</param> - /// <param name="disassembled">The disassembled Map.</param> - /// <param name="owner">The owner object.</param> - public SortedMap( ISessionImplementor session, CollectionPersister persister, IComparer comparer, object disassembled, object owner ) - : base( session ) - { - this.comparer = comparer; - BeforeInitialize( persister ); - object[ ] array = ( object[ ] ) disassembled; - - for( int i = 0; i < array.Length; i += 2 ) - { - object key = persister.IndexType.Assemble( array[ i ], session, owner ); - object val = persister.ElementType.Assemble( array[ i + 1 ], session, owner ); - - map[ key ] = val; - } - - initialized = true; - - } - - /// <summary> /// Constuct an uninitialized SortedMap that uses an IComparer to perform the sorting. /// </summary> --- 54,57 ---- Index: Set.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Set.cs,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** Set.cs 6 Feb 2005 01:58:56 -0000 1.22 --- Set.cs 7 Feb 2005 01:34:40 -0000 1.23 *************** *** 20,27 **** public class Set : PersistentCollection, ISet { ! /// <summary></summary> protected ISet internalSet; ! /// <summary></summary> [NonSerialized] protected IList tempList; --- 20,37 ---- public class Set : PersistentCollection, ISet { ! /// <summary> ! /// The <see cref="ISet"/> that NHibernate is wrapping. ! /// </summary> protected ISet internalSet; ! /// <summary> ! /// A temporary list that holds the objects while the Set is being ! /// populated from the database. ! /// </summary> ! /// <remarks> ! /// This is necessary to ensure that the object being added to the Set doesn't ! /// have its' <c>GetHashCode()</c> and <c>Equals()</c> methods called during the load ! /// process. ! /// </remarks> [NonSerialized] protected IList tempList; *************** *** 103,119 **** { internalSet = collection; ! initialized = true; directlyAccessible = true; } /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public Set( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) ! : base( session ) { BeforeInitialize( persister ); --- 113,127 ---- { internalSet = collection; ! SetInitialized(); directlyAccessible = true; } /// <summary> ! /// Initializes this Set from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the Set.</param> ! /// <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 ); *************** *** 123,127 **** internalSet.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! initialized = true; } --- 131,135 ---- internalSet.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } ! SetInitialized(); } *************** *** 391,397 **** /// <summary> ! /// Set up the temporary Identifier List that will be used in the EndRead() ! /// to resolve the Identifier to an Entity. ! /// <see cref="PersistentCollection.BeginRead"/> /// </summary> public override void BeginRead() --- 399,404 ---- /// <summary> ! /// Set up the temporary List that will be used in the EndRead() ! /// to fully create the set. /// </summary> public override void BeginRead() *************** *** 400,403 **** --- 407,415 ---- } + /// <summary> + /// Takes the contents stored in the temporary list created during <c>BeginRead()</c> + /// that was populated during <c>ReadFrom()</c> and write it to the underlying + /// Set. + /// </summary> public override void EndRead() { *************** *** 405,408 **** --- 417,422 ---- tempList = null; SetInitialized(); + // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) + IsCacheable = true; // return true; } Index: IdentifierBag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/IdentifierBag.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** IdentifierBag.cs 6 Feb 2005 01:58:56 -0000 1.7 --- IdentifierBag.cs 7 Feb 2005 01:34:40 -0000 1.8 *************** *** 28,32 **** private IList values; ! private IDictionary identifiers; //element -> id /// <summary> --- 28,33 ---- private IList values; ! // TODO: h2.1 changed this to index->id, haven't made that change in nh yet. ! private IDictionary identifiers; //element -> id /// <summary> *************** *** 58,62 **** } ! initialized = true; directlyAccessible = true; identifiers = new Hashtable(); --- 59,63 ---- } ! SetInitialized(); directlyAccessible = true; identifiers = new Hashtable(); *************** *** 64,75 **** /// <summary> ! /// /// </summary> ! /// <param name="session"></param> ! /// <param name="persister"></param> ! /// <param name="disassembled"></param> ! /// <param name="owner"></param> ! public IdentifierBag( ISessionImplementor session, CollectionPersister persister, object disassembled, object owner ) : base( session ) { BeforeInitialize( persister ); object[ ] array = ( object[ ] ) disassembled; --- 65,76 ---- /// <summary> ! /// Initializes this Bag from the cached values. /// </summary> ! /// <param name="persister">The CollectionPersister to use to reassemble the IdentifierBag.</param> ! /// <param name="disassembled">The disassembled IdentifierBag.</param> ! /// <param name="owner">The owner object.</param> ! public override void InitializeFromCache(CollectionPersister persister, object disassembled, object owner) { + BeforeInitialize( persister ); object[ ] array = ( object[ ] ) disassembled; *************** *** 82,88 **** } ! initialized = true; } #region IList Members --- 83,90 ---- } ! SetInitialized(); } + #region IList Members |
From: Michael D. <mik...@us...> - 2005-02-07 01:34:49
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106/Engine Modified Files: ISessionImplementor.cs Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: ISessionImplementor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** ISessionImplementor.cs 6 Feb 2005 01:58:57 -0000 1.27 --- ISessionImplementor.cs 7 Feb 2005 01:34:40 -0000 1.28 *************** *** 78,81 **** --- 78,90 ---- void EndLoadingCollections(); + /// <summary> + /// Gets the NHibernate collection wrapper from the ISession. + /// </summary> + /// <param name="role"></param> + /// <param name="id"></param> + /// <param name="owner"></param> + /// <returns> + /// A NHibernate wrapped collection. + /// </returns> object GetCollection( string role, object id, object owner ); |
From: Michael D. <mik...@us...> - 2005-02-07 01:34:49
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10106 Modified Files: NHibernate-1.1.csproj Log Message: modifications to Collections and their Types for caching related code. Formatting of the Visitor classes and added in two missing Visitors. Index: NHibernate-1.1.csproj =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/NHibernate-1.1.csproj,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** NHibernate-1.1.csproj 6 Feb 2005 01:58:56 -0000 1.71 --- NHibernate-1.1.csproj 7 Feb 2005 01:34:39 -0000 1.72 *************** *** 985,988 **** --- 985,993 ---- /> <File + RelPath = "Impl\DirtyCollectionSearchVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\EntityEntry.cs" SubType = "Code" *************** *** 995,998 **** --- 1000,1008 ---- /> <File + RelPath = "Impl\EvictVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\FilterImpl.cs" SubType = "Code" |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:47
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787/Collection Modified Files: ArrayHolder.cs Bag.cs IdentifierBag.cs List.cs Map.cs PersistentCollection.cs Set.cs SortedMap.cs SortedSet.cs Log Message: sergey's patch for the visitor pattern from h2.1. Index: Map.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Map.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** Map.cs 31 Dec 2004 16:36:46 -0000 1.17 --- Map.cs 6 Feb 2005 01:58:56 -0000 1.18 *************** *** 17,22 **** /// <summary></summary> protected IDictionary map; - /// <summary></summary> - protected IDictionary mapIdentifiers; /// <summary> --- 17,20 ---- *************** *** 122,131 **** // added. this.map = new ListDictionary(); - this.mapIdentifiers = new ListDictionary(); } else { this.map = new Hashtable(); - this.mapIdentifiers = new Hashtable(); } } --- 120,127 ---- *************** *** 274,295 **** } - /// <summary> - /// - /// </summary> - /// <param name="persister"></param> - /// <param name="owner"></param> - public override void EndRead( CollectionPersister persister, object owner ) - { - foreach( DictionaryEntry entry in mapIdentifiers ) - { - object index = entry.Key; - object elementIdentifier = entry.Value; - - object element = persister.ElementType.ResolveIdentifier( elementIdentifier, session, owner ); - - map[ index ] = element; - } - } - /// <summary></summary> public override ICollection Elements() --- 270,273 ---- *************** *** 335,345 **** public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! //object element = persister.ReadElement(rs, owner, session); ! object elementIdentifier = persister.ReadElementIdentifier( rs, owner, session ); ! object index = persister.ReadIndex( rs, session ); ! map[ index ] = null; ! mapIdentifiers[ index ] = elementIdentifier; ! return elementIdentifier; } --- 313,321 ---- public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); object index = persister.ReadIndex( rs, session ); ! ! map[ index ] = element; ! return element; } Index: PersistentCollection.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/PersistentCollection.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** PersistentCollection.cs 31 Dec 2004 16:36:46 -0000 1.18 --- PersistentCollection.cs 6 Feb 2005 01:58:56 -0000 1.19 *************** *** 45,48 **** --- 45,49 ---- /// <summary></summary> protected bool initialized; + private bool initializing; [NonSerialized] *************** *** 194,212 **** /// <summary> ! /// As far as every client is concerned, the collection is loaded after this call! ! /// (Actually is done lazily /// </summary> - /// <param name="lazy"></param> /// <returns></returns> ! public virtual object GetInitialValue( bool lazy ) { - if( !lazy ) - { - session.Initialize( this, false ); - initialized = true; - } return this; } /// <summary></summary> public virtual object GetCachedValue() --- 195,207 ---- /// <summary> ! /// Return the user-visible collection (or array) instance /// </summary> /// <returns></returns> ! public virtual object GetValue() { return this; } + /* /// <summary></summary> public virtual object GetCachedValue() *************** *** 215,218 **** --- 210,214 ---- return this; } + */ /// <summary> *************** *** 221,271 **** public virtual void BeginRead() { ! // override on some subclasses } /// <summary> ! /// It is my thoughts to have this be the portion that takes care of ! /// converting the Identifier to the element... /// </summary> - [Obsolete( "Should be replaced with EndRead(CollectionPersister, object) - need to verify" )] public virtual void EndRead() { ! // override on some subclasses } /// <summary> - /// Called when there are no other open IDataReaders so this PersistentCollection - /// is free to resolve all of the Identifiers to their Entities (which potentially - /// involves issuing a new query and opening a new IDataReader. - /// </summary> - /// <param name="persister"></param> - /// <param name="owner"></param> - public abstract void EndRead( CollectionPersister persister, object owner ); - - /// <summary> /// /// </summary> /// <param name="writing"></param> ! public void Initialize( bool writing ) { if( !initialized ) { if( IsConnectedToSession ) { ! try { ! session.Initialize( this, writing ); ! initialized = true; ! // do this after setting initialized to true or it will recurse ! if( additions != null ) { ! DelayedAddAll( additions ); ! additions = null; } } ! catch( Exception e ) { ! log.Error( "Failed to lazily initialize a collection", e ); ! throw new LazyInitializationException( "Failed to lazily initialize a collection", e ); } } --- 217,269 ---- public virtual void BeginRead() { ! initializing = true; } /// <summary> ! /// Override on some subclasses. /// </summary> public virtual void EndRead() { ! // TODO:SYNCH:hib2.1 has this return a bool ! SetInitialized(); ! //do this bit after setting initialized to true or it will recurse ! if (additions!=null) ! { ! DelayedAddAll(additions); ! additions=null; ! //return false; ! } ! else ! { ! //return true; ! } } /// <summary> /// /// </summary> /// <param name="writing"></param> ! protected void Initialize( bool writing ) { if( !initialized ) { + if( initializing ) throw new LazyInitializationException("cannot access loading collection"); if( IsConnectedToSession ) { ! if( session.IsConnected ) { ! try { ! session.InitializeCollection( this, writing ); ! } ! catch( Exception e ) ! { ! log.Error( "Failed to lazily initialize a collection", e ); ! throw new LazyInitializationException( "Failed to lazily initialize a collection", e ); } } ! else { ! throw new LazyInitializationException( "Failed to lazily initialize a collection - session is disconnected" ); } } *************** *** 300,304 **** /// <param name="session"></param> /// <returns></returns> ! public bool SetSession( ISessionImplementor session ) { if( session == this.session ) --- 298,302 ---- /// <param name="session"></param> /// <returns></returns> ! public bool SetCurrentSession( ISessionImplementor session ) { if( session == this.session ) *************** *** 575,578 **** --- 573,582 ---- } + protected void SetInitialized() + { + initializing = false; + initialized = true; + } + #region - Hibernate Collection Proxy Classes Index: List.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/List.cs,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** List.cs 31 Dec 2004 16:36:46 -0000 1.16 --- List.cs 6 Feb 2005 01:58:56 -0000 1.17 *************** *** 15,22 **** private IList list; - // used to hold the Identifiers of the Elements that will later - // be moved to the list field. - private IList listIdentifiers; - /// <summary> /// --- 15,18 ---- *************** *** 97,101 **** { this.list = new ArrayList(); - this.listIdentifiers = new ArrayList(); } --- 93,96 ---- *************** *** 267,290 **** } - /// <summary> - /// - /// </summary> - /// <param name="persister"></param> - /// <param name="owner"></param> - public override void EndRead( CollectionPersister persister, object owner ) - { - for( int i = 0; i < listIdentifiers.Count; i++ ) - { - object element = persister.ElementType.ResolveIdentifier( listIdentifiers[ i ], session, owner ); - list[ i ] = element; - } - - if( Additions != null ) - { - DelayedAddAll( Additions ); - Additions = null; - } - } - /// <summary></summary> public override ICollection Elements() --- 262,265 ---- *************** *** 329,343 **** public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! //object element = persister.ReadElement(rs, owner, session); ! object elementIdentifier = persister.ReadElementIdentifier( rs, owner, session ); ! int index = ( int ) persister.ReadIndex( rs, session ); ! for( int i = list.Count; i <= index; i++ ) { list.Insert( i, null ); - listIdentifiers.Insert( i, null ); } ! listIdentifiers[ index ] = elementIdentifier; ! //list[index] = element; ! return elementIdentifier; } --- 304,317 ---- public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); ! int index = (int)persister.ReadIndex( rs, session ); ! ! for( int i=list.Count; i<=index; i++ ) { list.Insert( i, null ); } ! ! list[ index ] = element; ! return element; } Index: Bag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Bag.cs,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** Bag.cs 31 Dec 2004 16:36:46 -0000 1.11 --- Bag.cs 6 Feb 2005 01:58:56 -0000 1.12 *************** *** 17,23 **** { private IList bag; - // used to hold the Identifiers of the Elements that will later - // be moved to the bag field. - private IList bagIdentifiers; /// <summary> --- 17,20 ---- *************** *** 95,119 **** /// /// </summary> - /// <param name="persister"></param> - /// <param name="owner"></param> - public override void EndRead( CollectionPersister persister, object owner ) - { - for( int i = 0; i < bagIdentifiers.Count; i++ ) - { - object element = persister.ElementType.ResolveIdentifier( bagIdentifiers[ i ], session, owner ); - bag.Add( element ); - } - - if( Additions != null ) - { - DelayedAddAll( Additions ); - Additions = null; - } - } - - - /// <summary> - /// - /// </summary> /// <param name="reader"></param> /// <param name="persister"></param> --- 92,95 ---- *************** *** 122,129 **** public override object ReadFrom( IDataReader reader, CollectionPersister persister, object owner ) { ! object elementIdentifier = persister.ReadElementIdentifier( reader, owner, session ); ! bagIdentifiers.Add( elementIdentifier ); ! ! return elementIdentifier; } --- 98,104 ---- public override object ReadFrom( IDataReader reader, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, session ); ! bag.Add( element ); ! return element; } *************** *** 148,152 **** { this.bag = new ArrayList(); - this.bagIdentifiers = new ArrayList(); } --- 123,126 ---- Index: ArrayHolder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/ArrayHolder.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** ArrayHolder.cs 31 Dec 2004 16:36:46 -0000 1.14 --- ArrayHolder.cs 6 Feb 2005 01:58:56 -0000 1.15 *************** *** 16,20 **** private static readonly ILog log = LogManager.GetLogger( typeof( PersistentCollection ) ); ! private object array; [NonSerialized] --- 16,20 ---- private static readonly ILog log = LogManager.GetLogger( typeof( PersistentCollection ) ); ! private Array array; [NonSerialized] *************** *** 22,29 **** [NonSerialized] ! private IList tempList; - [NonSerialized] - private IList tempListIdentifier; /// <summary> --- 22,27 ---- [NonSerialized] ! private ArrayList tempList; /// <summary> *************** *** 34,38 **** public ArrayHolder( ISessionImplementor session, object array ) : base( session ) { ! this.array = array; initialized = true; } --- 32,36 ---- public ArrayHolder( ISessionImplementor session, object array ) : base( session ) { ! this.array = (Array) array; initialized = true; } *************** *** 45,56 **** protected override object Snapshot( CollectionPersister persister ) { ! int length = /*(array==null) ? temp.Count :*/ ( ( Array ) array ).Length; ! object result = System.Array.CreateInstance( persister.ElementClass, length ); for( int i = 0; i < length; i++ ) { ! object elt = /*(array==null) ? temp[i] :*/ ( ( Array ) array ).GetValue( i ); try { ! ( ( Array ) result ).SetValue( persister.ElementType.DeepCopy( elt ), i ); } catch( Exception e ) --- 43,54 ---- protected override object Snapshot( CollectionPersister persister ) { ! int length = /*(array==null) ? temp.Count :*/ array.Length; ! Array result = System.Array.CreateInstance( persister.ElementClass, length ); for( int i = 0; i < length; i++ ) { ! object elt = /*(array==null) ? temp[i] :*/ array.GetValue( i ); try { ! result.SetValue( persister.ElementType.DeepCopy( elt ), i ); } catch( Exception e ) *************** *** 174,188 **** public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! //object element = persister.ReadElement(rs, owner, session); ! object elementIdentifier = persister.ReadElementIdentifier( rs, owner, session ); int index = ( int ) persister.ReadIndex( rs, session ); for( int i = tempList.Count; i <= index; i++ ) { tempList.Insert( i, null ); - tempListIdentifier.Insert( i, null ); } ! //tempList[index] = element; ! tempListIdentifier[ index ] = elementIdentifier; ! return elementIdentifier; } --- 172,183 ---- public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); int index = ( int ) persister.ReadIndex( rs, session ); for( int i = tempList.Count; i <= index; i++ ) { tempList.Insert( i, null ); } ! tempList[index] = element; ! return element; } *************** *** 201,249 **** public override void BeginRead() { tempList = new ArrayList(); - tempListIdentifier = new ArrayList(); } - /// <summary> - /// - /// </summary> - [Obsolete( "See PersistentCollection.EndRead for reason." )] public override void EndRead() { ! array = ( ( ArrayList ) tempList ).ToArray( elementClass ); ! tempList = null; ! } ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="persister"></param> ! /// <param name="owner"></param> ! public override void EndRead( CollectionPersister persister, object owner ) ! { ! array = System.Array.CreateInstance( elementClass, tempListIdentifier.Count ); ! ! for( int i = 0; i < tempListIdentifier.Count; i++ ) { ! object element = persister.ElementType.ResolveIdentifier( tempListIdentifier[ i ], session, owner ); ! ( ( Array ) array ).SetValue( element, i ); ! tempList[ i ] = element; } ! ! //tempList = null; ! //tempListIdentifier = null; ! } ! ! ! /// <summary> ! /// ! /// </summary> ! /// <param name="lazy"></param> ! /// <returns></returns> ! public override object GetInitialValue( bool lazy ) ! { ! base.GetInitialValue( false ); ! session.AddArrayHolder( this ); ! return array; } --- 196,215 ---- public override void BeginRead() { + base.BeginRead(); tempList = new ArrayList(); } public override void EndRead() { ! SetInitialized(); ! array = System.Array.CreateInstance( elementClass, tempList.Count ); ! int index = 0; ! foreach( object element in tempList ) { ! array.SetValue( element, index ); ! index++; } ! tempList = null; ! //return true; } *************** *** 309,319 **** } ! /// <summary> ! /// ! /// </summary> ! /// <returns></returns> ! public override object GetCachedValue() { - session.AddArrayHolder( this ); return array; } --- 275,280 ---- } ! public override object GetValue() { return array; } Index: SortedSet.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedSet.cs,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** SortedSet.cs 31 Dec 2004 16:36:46 -0000 1.11 --- SortedSet.cs 6 Feb 2005 01:58:56 -0000 1.12 *************** *** 48,54 **** { internalSet = new Iesi.Collections.SortedSet( Comparer ); - // an ArrayList of the identifiers is what Set uses because there is not - // both a Key & Value to worry about - just the Key. - this.tempIdentifierList = new ArrayList(); } --- 48,51 ---- Index: SortedMap.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/SortedMap.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** SortedMap.cs 31 Dec 2004 16:36:46 -0000 1.6 --- SortedMap.cs 6 Feb 2005 01:58:56 -0000 1.7 *************** *** 111,118 **** { this.map = new SortedList( comparer ); - // it should be okay to use just a hashtable to store the MapIdentifier because - // when the Identifiers are converted to actual entries then the Comparer should - // take care of putting them in the correct order... - this.mapIdentifiers = new Hashtable(); } --- 111,114 ---- Index: Set.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Set.cs,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Set.cs 31 Dec 2004 16:36:46 -0000 1.21 --- Set.cs 6 Feb 2005 01:58:56 -0000 1.22 *************** *** 25,29 **** /// <summary></summary> [NonSerialized] ! protected IList tempIdentifierList; /// <summary> --- 25,29 ---- /// <summary></summary> [NonSerialized] ! protected IList tempList; /// <summary> *************** *** 385,393 **** public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! //object elementIdentifier = persister.ReadElement(rs, owner, session); ! object elementIdentifier = persister.ReadElementIdentifier( rs, owner, session ); ! ! tempIdentifierList.Add( elementIdentifier ); ! return elementIdentifier; } --- 385,391 ---- public override object ReadFrom( IDataReader rs, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); ! tempList.Add( element ); ! return element; } *************** *** 399,419 **** public override void BeginRead() { ! tempIdentifierList = new ArrayList(); } ! /// <summary> ! /// Resolves all of the Identifiers to an Entity. ! /// <see cref="PersistentCollection.BeginRead"/> ! /// </summary> ! /// <param name="owner"></param> ! /// <param name="persister"></param> ! public override void EndRead( CollectionPersister persister, object owner ) { ! foreach( object identifier in tempIdentifierList ) ! { ! object element = persister.ElementType.ResolveIdentifier( identifier, session, owner ); ! internalSet.Add( element ); ! } ! } --- 397,409 ---- public override void BeginRead() { ! tempList = new ArrayList(); } ! public override void EndRead() { ! internalSet.AddAll( tempList ); ! tempList = null; ! SetInitialized(); ! // return true; } Index: IdentifierBag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/IdentifierBag.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** IdentifierBag.cs 31 Dec 2004 16:36:46 -0000 1.6 --- IdentifierBag.cs 6 Feb 2005 01:58:56 -0000 1.7 *************** *** 27,31 **** { private IList values; - private IList valuesIdentifiers; private IDictionary identifiers; //element -> id --- 27,30 ---- *************** *** 245,249 **** identifiers = new Hashtable(); values = new ArrayList(); - valuesIdentifiers = new ArrayList(); } --- 244,247 ---- *************** *** 279,296 **** } - /// <summary> - /// - /// </summary> - /// <param name="persister"></param> - /// <param name="owner"></param> - public override void EndRead( CollectionPersister persister, object owner ) - { - for( int i = 0; i < valuesIdentifiers.Count; i++ ) - { - object element = persister.ElementType.ResolveIdentifier( valuesIdentifiers[ i ], session, owner ); - values[ i ] = element; - } - } - /// <summary></summary> public override ICollection Entries() --- 277,280 ---- *************** *** 425,435 **** public override object ReadFrom( IDataReader reader, CollectionPersister persister, object owner ) { ! object elementIdentifier = persister.ReadElementIdentifier( reader, owner, session ); ! values.Add( null ); ! valuesIdentifiers.Add( elementIdentifier ); ! identifiers[ values.Count - 1 ] = persister.ReadIdentifier( reader, session ); ! ! return elementIdentifier; } --- 409,416 ---- public override object ReadFrom( IDataReader reader, CollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, session ); ! values.Add( element ); identifiers[ values.Count - 1 ] = persister.ReadIdentifier( reader, session ); ! return element; } |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:46
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787/Engine Modified Files: Cascades.cs ICollectionSnapshot.cs ISessionImplementor.cs Log Message: sergey's patch for the visitor pattern from h2.1. Index: ISessionImplementor.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine/ISessionImplementor.cs,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** ISessionImplementor.cs 31 Dec 2004 17:36:22 -0000 1.26 --- ISessionImplementor.cs 6 Feb 2005 01:58:57 -0000 1.27 *************** *** 38,57 **** /// <summary> - /// Register an uninitialized <c>PersistentColleciton</c> that will be lazily initialized - /// </summary> - /// <param name="collection"></param> - /// <param name="persister"></param> - /// <param name="id"></param> - void AddUninitializedCollection( PersistentCollection collection, CollectionPersister persister, object id ); - - /// <summary> - /// Register an initialized <c>PersistentCollection</c> - /// </summary> - /// <param name="collection"></param> - /// <param name="persister"></param> - /// <param name="id"></param> - void AddInitializedCollection( PersistentCollection collection, CollectionPersister persister, object id ); - - /// <summary> /// Set the "shallow dirty" status of the collection. Called when the collection detects /// that the client is modifying it --- 38,41 ---- *************** *** 64,68 **** /// <param name="coolection"></param> /// <param name="writing"></param> ! void Initialize( PersistentCollection coolection, bool writing ); /// <summary> --- 48,52 ---- /// <param name="coolection"></param> /// <param name="writing"></param> ! void InitializeCollection( PersistentCollection coolection, bool writing ); /// <summary> *************** *** 83,97 **** /// <summary> /// new in h2.0.3 and no javadoc - /// - /// MikeD added to help with EndRead of Collections... - /// </summary> - /// <param name="persister"></param> - /// <param name="id"></param> - /// <param name="owner"></param> - /// <returns></returns> - PersistentCollection GetLoadingCollection( CollectionPersister persister, object id, object owner ); - - /// <summary> - /// new in h2.0.3 and no javadoc /// </summary> /// <param name="role"></param> --- 67,70 ---- *************** *** 105,108 **** --- 78,82 ---- void EndLoadingCollections(); + object GetCollection( string role, object id, object owner ); /// <summary> *************** *** 161,165 **** /// <summary> ! /// After actually inserting a row, record the fact taht the instance exists on the database /// (needed for identity-column key generation) /// </summary> --- 135,139 ---- /// <summary> ! /// After actually inserting a row, record the fact that the instance exists on the database /// (needed for identity-column key generation) /// </summary> *************** *** 175,179 **** /// <summary> ! /// After actually updating a row, record the fact that the database state has been update. /// </summary> /// <param name="obj">The <see cref="object"/> instance that was saved.</param> --- 149,153 ---- /// <summary> ! /// After actually updating a row, record the fact that the database state has been updated. /// </summary> /// <param name="obj">The <see cref="object"/> instance that was saved.</param> Index: Cascades.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine/Cascades.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Cascades.cs 23 Jan 2005 15:54:23 -0000 1.12 --- Cascades.cs 6 Feb 2005 01:58:56 -0000 1.13 *************** *** 35,39 **** /// session cache /// </summary> ! CascadeOnEvict = 0 //-1 } --- 35,44 ---- /// session cache /// </summary> ! CascadeOnEvict = 0, //-1 ! ! /// <summary> ! /// A cascade point that occurs just after locking the parent entity ! /// </summary> ! CascadeOnLock = 0 } *************** *** 58,62 **** /// Cascade the action to the child object /// </summary> ! public abstract void Cascade( ISessionImplementor session, object child ); /// <summary> --- 63,67 ---- /// Cascade the action to the child object /// </summary> ! public abstract void Cascade( ISessionImplementor session, object child, object anything ); /// <summary> *************** *** 73,77 **** private class ActionDeleteClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child ) { log.Debug( "cascading to delete()" ); --- 78,82 ---- private class ActionDeleteClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child, object anything ) { log.Debug( "cascading to delete()" ); *************** *** 99,103 **** private class ActionEvictClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child ) { log.Debug( "cascading to evict()" ); --- 104,108 ---- private class ActionEvictClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child, object anything ) { log.Debug( "cascading to evict()" ); *************** *** 118,126 **** /// <summary></summary> public static CascadingAction ActionSaveUpdate = new ActionSaveUpdateClass(); private class ActionSaveUpdateClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child ) { log.Debug( "cascading to SaveOrUpdate()" ); --- 123,153 ---- /// <summary></summary> + public static CascadingAction ActionLock = new ActionLockClass(); + + private class ActionLockClass : CascadingAction + { + public override void Cascade( ISessionImplementor session, object child, object anything ) + { + log.Debug( "cascading to lock()" ); + session.Lock( child, (LockMode) anything ); + } + + public override bool ShouldCascadeCollection( object collection ) + { + return CollectionIsInitialized( collection ); + } + + public override bool DeleteOrphans() + { + return false; + } + } + + /// <summary></summary> public static CascadingAction ActionSaveUpdate = new ActionSaveUpdateClass(); private class ActionSaveUpdateClass : CascadingAction { ! public override void Cascade( ISessionImplementor session, object child, object anything ) { log.Debug( "cascading to SaveOrUpdate()" ); *************** *** 323,327 **** /// <param name="cascadeTo"></param> /// <param name="deleteOrphans"></param> ! private static void Cascade( ISessionImplementor session, object child, IType type, CascadingAction action, CascadePoint cascadeTo, bool deleteOrphans ) { if( child != null ) --- 350,355 ---- /// <param name="cascadeTo"></param> /// <param name="deleteOrphans"></param> ! /// <param name="anything"></param> ! private static void Cascade( ISessionImplementor session, object child, IType type, CascadingAction action, CascadePoint cascadeTo, bool deleteOrphans, object anything ) { if( child != null ) *************** *** 333,337 **** if( type.IsEntityType || type.IsObjectType ) { ! action.Cascade( session, child ); } else if( type.IsPersistentCollectionType ) --- 361,365 ---- if( type.IsEntityType || type.IsObjectType ) { ! action.Cascade( session, child, anything ); } else if( type.IsPersistentCollectionType ) *************** *** 388,392 **** foreach( object obj in iter ) { ! Cascade( session, obj, elemType, action, cascadeVia, false ); } } --- 416,420 ---- foreach( object obj in iter ) { ! Cascade( session, obj, elemType, action, cascadeVia, false, anything ); } } *************** *** 417,421 **** if( ctype.Cascade( i ).DoCascade( action ) ) { ! Cascade( session, children[ i ], types[ i ], action, cascadeTo, deleteOrphans ); } } --- 445,449 ---- if( ctype.Cascade( i ).DoCascade( action ) ) { ! Cascade( session, children[ i ], types[ i ], action, cascadeTo, deleteOrphans, anything ); } } *************** *** 432,436 **** /// <param name="action"></param> /// <param name="cascadeTo"></param> ! public static void Cascade( ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo ) { if( persister.HasCascades ) --- 460,465 ---- /// <param name="action"></param> /// <param name="cascadeTo"></param> ! /// <param name="anything"></param> ! public static void Cascade( ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo, object anything ) { if( persister.HasCascades ) *************** *** 446,450 **** if( cascadeStyles[ i ].DoCascade( action ) ) { ! Cascade( session, persister.GetPropertyValue( parent, i ), types[ i ], action, cascadeTo, cascadeStyles[ i ] == CascadeStyle.StyleAllGC ); } } --- 475,479 ---- if( cascadeStyles[ i ].DoCascade( action ) ) { ! Cascade( session, persister.GetPropertyValue( parent, i ), types[ i ], action, cascadeTo, cascadeStyles[ i ] == CascadeStyle.StyleAllGC, anything ); } } Index: ICollectionSnapshot.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine/ICollectionSnapshot.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ICollectionSnapshot.cs 31 Dec 2004 17:36:22 -0000 1.5 --- ICollectionSnapshot.cs 6 Feb 2005 01:58:57 -0000 1.6 *************** *** 37,44 **** /// <summary> ! /// Gets a <see cref="bool"/> indicating if the underlying collection has been ! /// initialized yet. /// </summary> ! bool IsInitialized { get; } } } \ No newline at end of file --- 37,44 ---- /// <summary> ! /// Gets a <see cref="bool"/> indicating if the collection was at one time ! /// associated with an Entity and then later dereferenced during a Flush(). /// </summary> ! bool WasDereferenced { get; } } } \ No newline at end of file |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:46
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787 Modified Files: NHibernate-1.1.csproj Log Message: sergey's patch for the visitor pattern from h2.1. Index: NHibernate-1.1.csproj =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/NHibernate-1.1.csproj,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** NHibernate-1.1.csproj 25 Jan 2005 13:37:08 -0000 1.70 --- NHibernate-1.1.csproj 6 Feb 2005 01:58:56 -0000 1.71 *************** *** 955,958 **** --- 955,963 ---- /> <File + RelPath = "Impl\AbstractVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\BatcherImpl.cs" SubType = "Code" *************** *** 970,973 **** --- 975,983 ---- /> <File + RelPath = "Impl\CollectionKey.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\CriteriaImpl.cs" SubType = "Code" *************** *** 990,993 **** --- 1000,1008 ---- /> <File + RelPath = "Impl\FlushVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\IExecutable.cs" SubType = "Code" *************** *** 1005,1008 **** --- 1020,1038 ---- /> <File + RelPath = "Impl\OnLockVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Impl\OnUpdateVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "Impl\ProxyVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\QueryImpl.cs" SubType = "Code" *************** *** 1010,1013 **** --- 1040,1048 ---- /> <File + RelPath = "Impl\ReattachVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Impl\ScheduledCollectionAction.cs" SubType = "Code" *************** *** 1070,1073 **** --- 1105,1113 ---- /> <File + RelPath = "Impl\WrapVisitor.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "Loader\AbstractEntityLoader.cs" SubType = "Code" |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:14
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Type In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787/Type Modified Files: PersistentCollectionType.cs Log Message: sergey's patch for the visitor pattern from h2.1. Index: PersistentCollectionType.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Type/PersistentCollectionType.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** PersistentCollectionType.cs 1 Jan 2005 03:37:34 -0000 1.18 --- PersistentCollectionType.cs 6 Feb 2005 01:59:02 -0000 1.19 *************** *** 93,96 **** --- 93,97 ---- } + /* /// <summary> /// *************** *** 124,127 **** --- 125,129 ---- } + */ /// <summary> *************** *** 310,316 **** else { ! // h2.1 changed this to use sesion.GetCollection( role, value, owner ) and ! // move the impl of GetCollection from this class to the ISession. ! return GetCollection( value, owner, session ); } } --- 312,316 ---- else { ! return session.GetCollection( role, value, owner ); } } |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:13
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787/Loader Modified Files: Loader.cs Log Message: sergey's patch for the visitor pattern from h2.1. Index: Loader.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Loader/Loader.cs,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** Loader.cs 31 Dec 2004 20:57:56 -0000 1.45 --- Loader.cs 6 Feb 2005 01:59:02 -0000 1.46 *************** *** 229,233 **** if( ownerKey != null ) { ! PersistentCollection rowCollection = session.GetLoadingCollection( collectionPersister, ownerKey.Identifier, row[ collectionOwner ] ); object collectionRowKey = collectionPersister.ReadKey( rs, session ); if( collectionRowKey != null ) --- 229,233 ---- if( ownerKey != null ) { ! PersistentCollection rowCollection = session.GetLoadingCollection( collectionPersister, ownerKey.Identifier ); object collectionRowKey = collectionPersister.ReadKey( rs, session ); if( collectionRowKey != null ) *************** *** 288,292 **** if( singleCollection ) { ! optionalCollection.EndRead( CollectionPersister, optionalCollectionOwner ); } --- 288,292 ---- if( singleCollection ) { ! optionalCollection.EndRead(); } |
From: Michael D. <mik...@us...> - 2005-02-06 01:59:13
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26787/Impl Modified Files: CollectionEntry.cs SessionImpl.cs Added Files: AbstractVisitor.cs CollectionKey.cs FlushVisitor.cs OnLockVisitor.cs OnUpdateVisitor.cs ProxyVisitor.cs ReattachVisitor.cs WrapVisitor.cs Log Message: sergey's patch for the visitor pattern from h2.1. Index: SessionImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionImpl.cs,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** SessionImpl.cs 31 Jan 2005 03:25:39 -0000 1.63 --- SessionImpl.cs 6 Feb 2005 01:59:02 -0000 1.64 *************** *** 97,101 **** /// and an <see cref="CollectionEntry"/> as the value. /// </summary> ! private IdentityMap collections; /// <summary> --- 97,107 ---- /// and an <see cref="CollectionEntry"/> as the value. /// </summary> ! private IdentityMap collectionEntries; ! [...1666 lines suppressed...] + { + if ( log.IsDebugEnabled ) + log.Debug( "creating collection wrapper:" + MessageHelper.InfoString(persister, id) ); + collection = persister.CollectionType.Instantiate(this, persister); //TODO: suck into CollectionPersister.instantiate() + AddUninitializedCollection(collection, persister, id); + if ( persister.IsArray ) + { + InitializeCollection(collection, false); + AddArrayHolder( (ArrayHolder) collection ); + } + else if ( !persister.IsLazy ) + { + //nonlazyCollections.Add(collection); + } + return collection.GetValue(); + } + } } } \ No newline at end of file --- NEW FILE: ProxyVisitor.cs --- using System; using System.Collections; using NHibernate.Type; namespace NHibernate.Impl { internal abstract class ProxyVisitor : AbstractVisitor { public ProxyVisitor(SessionImpl session) : base(session) { } protected override object ProcessEntity(object value, EntityType entityType) { if (value != null) { Session.ReassociateIfUninitializedProxy(value); // if it is an initialized proxy, let cascade // handle it later on } return null; } } } --- NEW FILE: ReattachVisitor.cs --- using System; using System.Collections; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// Abstract superclass of visitors that reattach collections /// </summary> internal abstract class ReattachVisitor : ProxyVisitor { private readonly object key; protected object Key { get { return key; } } public ReattachVisitor(SessionImpl session, object key) : base(session) { this.key = key; } protected override object ProcessComponent(object component, IAbstractComponentType componentType) { IType[] types = componentType.Subtypes; if (component == null) { ProcessValues(new object[types.Length], types); } else { base.ProcessComponent(component, componentType); } return null; } } } --- NEW FILE: AbstractVisitor.cs --- using System; using System.Collections; using NHibernate.Type; using NHibernate.Persister; namespace NHibernate.Impl { /// <summary> /// Abstract superclass of algorithms that walk a tree of property values /// of an entity, and perform specific functionality for collections, /// components and associated entities. /// </summary> internal abstract class AbstractVisitor { private readonly SessionImpl session; protected AbstractVisitor(SessionImpl session) { this.session = session; } /// <summary> /// Dispatch each property value to <see cref="ProcessValue" />. /// </summary> /// <param name="values"></param> /// <param name="types"></param> public virtual void ProcessValues(object[] values, IType[] types) { for (int i = 0; i < values.Length; i++) { ProcessValue(values[i], types[i]); } } protected virtual object ProcessComponent(object component, IAbstractComponentType componentType) { if (component != null) { ProcessValues(componentType.GetPropertyValues(component, session), componentType.Subtypes); } return null; } /// <summary> /// Visit a property value. Dispatch to the correct handler /// for the property type. /// </summary> /// <param name="value"></param> /// <param name="type"></param> /// <returns></returns> protected object ProcessValue(object value, IType type) { if (type.IsPersistentCollectionType) { // Even process null collections return ProcessCollection(value, (PersistentCollectionType) type); } else if (type.IsEntityType) { return ProcessEntity(value, (EntityType) type); } else if (type.IsComponentType) { //TODO: what about a null component with a collection! // we also need to clean up that "null collection" return ProcessComponent(value, (IAbstractComponentType) type); } else { return null; } } /// <summary> /// Walk the tree starting from the given entity. /// </summary> /// <param name="obj"></param> /// <param name="persister"></param> public virtual void Process(object obj, IClassPersister persister) { ProcessValues( persister.GetPropertyValues(obj), persister.PropertyTypes); } /// <summary> /// Visit a collection. Default superclass implementation is a no-op. /// </summary> /// <param name="collection"></param> /// <param name="type"></param> /// <returns></returns> protected virtual object ProcessCollection(object collection, PersistentCollectionType type) { return null; } /// <summary> /// Visit a many-to-one or one-to-one associated entity. Default /// superclass implementation is a no-op. /// </summary> /// <param name="value"></param> /// <param name="entityType"></param> /// <returns></returns> protected virtual object ProcessEntity(object value, EntityType entityType) { return null; } protected SessionImpl Session { get { return session; } } } } --- NEW FILE: CollectionKey.cs --- using System; using System.Collections; using NHibernate.Collection; namespace NHibernate.Impl { [Serializable] internal sealed class CollectionKey { private string role; private object key; public CollectionKey(string role, object key) { this.role = role; this.key = key; } public CollectionKey(CollectionPersister persister, object key) : this(persister.Role, key) { } public override bool Equals(object obj) { CollectionKey that = (CollectionKey) obj; return Equals (key, that.key) && Equals (role, that.role); } public override int GetHashCode() { int result = 17; result = 37 * result + key.GetHashCode(); result = 37 * result + role.GetHashCode(); return result; } } } --- NEW FILE: WrapVisitor.cs --- using System; using System.Collections; using NHibernate.Collection; using NHibernate.Engine; using NHibernate.Type; using log4net; namespace NHibernate.Impl { internal class WrapVisitor : ProxyVisitor { private static readonly ILog log = LogManager.GetLogger(typeof(WrapVisitor)); private bool substitute = false; public bool IsSubstitutionRequired { get { return substitute; } } public WrapVisitor(SessionImpl session) : base (session) { } protected override object ProcessCollection(object collection, PersistentCollectionType collectionType) { if ( collection is PersistentCollection ) { PersistentCollection coll = (PersistentCollection) collection; if ( coll.SetCurrentSession(Session) ) { Session.ReattachCollection( coll, coll.CollectionSnapshot ); } return null; } else { return ProcessArrayOrNewCollection(collection, collectionType); } } private object ProcessArrayOrNewCollection(object collection, PersistentCollectionType collectionType) { if (collection == null) return null; CollectionPersister persister = Session.GetCollectionPersister( collectionType.Role ); if ( collectionType.IsArrayType ) { ArrayHolder ah = Session.GetArrayHolder(collection); if (ah == null) { ah = new ArrayHolder(Session, collection); Session.AddNewCollection(ah, persister); Session.AddArrayHolder(ah); } return null; } else { PersistentCollection persistentCollection = collectionType.Wrap(Session, collection); Session.AddNewCollection(persistentCollection, persister); if ( log.IsDebugEnabled ) log.Debug( "Wrapped collection in role: " + collectionType.Role ); return persistentCollection; //Force a substitution! } } public override void ProcessValues(object[] values, IType[] types) { for (int i = 0; i < types.Length; i++) { object result = ProcessValue( values[i], types[i] ); if ( result != null ) { substitute = true; values[i] = result; } } } protected override object ProcessComponent(object component, IAbstractComponentType componentType) { if (component == null) return null; object[] values = componentType.GetPropertyValues( component, Session ); IType[] types = componentType.Subtypes; bool substituteComponent = false; for ( int i=0; i<types.Length; i++ ) { object result = ProcessValue( values[i], types[i] ); if (result != null) { substituteComponent = true; values[i] = result; } } if (substituteComponent) { componentType.SetPropertyValues(component, values); } return null; } public override void Process(object obj, NHibernate.Persister.IClassPersister persister) { object[] values = persister.GetPropertyValues(obj); IType[] types = persister.PropertyTypes; ProcessValues(values, types); if ( IsSubstitutionRequired ) persister.SetPropertyValues(obj, values); } } } Index: CollectionEntry.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/CollectionEntry.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CollectionEntry.cs 23 Jan 2005 15:52:07 -0000 1.4 --- CollectionEntry.cs 6 Feb 2005 01:59:02 -0000 1.5 *************** *** 16,22 **** private static readonly ILog log = LogManager.GetLogger( typeof( CollectionEntry ) ); ! /// <summary></summary> ! // false by default ! internal bool dirty; /// <summary> --- 16,24 ---- private static readonly ILog log = LogManager.GetLogger( typeof( CollectionEntry ) ); ! /// <summary> ! /// Collections detect changes made via their public interface ! /// and mark themselves as dirty. False by default. ! /// </summary> ! private bool dirty; /// <summary> *************** *** 69,72 **** --- 71,81 ---- /// <summary> + /// If we instantiate a collection during the <see cref="ISession.Flush" /> + /// process, we must ignore it for the rest of the flush. + /// </summary> + [NonSerialized] + internal bool ignore; + + /// <summary> /// Indicates that the Collection has been fully initialized. /// </summary> *************** *** 98,102 **** internal object currentKey; ! /// <summary></summary> internal object loadedKey; --- 107,114 ---- internal object currentKey; ! /// <summary> ! /// The identifier of the Entity that is the owner of this Collection ! /// during the load or post flush. ! /// </summary> internal object loadedKey; *************** *** 116,122 **** public CollectionEntry() { ! // dirty is initialized to false by runtime //this.dirty = false; this.initialized = true; } --- 128,144 ---- public CollectionEntry() { ! // A newly wrapped collection is NOT dirty (or we get unnecessary version updates) //this.dirty = false; this.initialized = true; + + // New collections that get found and wrapped during flush shouldn't be ignored + //this.ignore = false; + } + + public CollectionEntry( CollectionPersister loadedPersister, object loadedID ) + // Detached collection wrappers that get found and reattached + // during flush shouldn't be ignored + : this( loadedPersister, loadedID, false ) + { } *************** *** 126,137 **** /// <param name="loadedPersister">The <see cref="CollectionPersister"/> that persists this Collection type.</param> /// <param name="loadedID">The identifier of the Entity that is the owner of this Collection.</param> ! /// <param name="initialized">A boolean indicating if the collection has been initialized.</param> ! public CollectionEntry( CollectionPersister loadedPersister, object loadedID, bool initialized ) { // dirty is initialized to false by runtime //this.dirty = false; ! this.initialized = initialized; this.loadedKey = loadedID; SetLoadedPersister( loadedPersister ); } --- 148,160 ---- /// <param name="loadedPersister">The <see cref="CollectionPersister"/> that persists this Collection type.</param> /// <param name="loadedID">The identifier of the Entity that is the owner of this Collection.</param> ! /// <param name="ignore">A boolean indicating whether to ignore the collection during current (or next) flush.</param> ! public CollectionEntry( CollectionPersister loadedPersister, object loadedID, bool ignore ) { // dirty is initialized to false by runtime //this.dirty = false; ! this.initialized = false; this.loadedKey = loadedID; SetLoadedPersister( loadedPersister ); + this.ignore = ignore; } *************** *** 151,156 **** this.snapshot = cs.Snapshot; this.loadedKey = cs.Key; - SetLoadedPersister( factory.GetCollectionPersister( cs.Role ) ); this.initialized = true; } --- 174,182 ---- this.snapshot = cs.Snapshot; this.loadedKey = cs.Key; this.initialized = true; + // Detached collections that get found and reattached during flush + // shouldn't be ignored + //this.ignore = false; + SetLoadedPersister( factory.GetCollectionPersister( cs.Role ) ); } *************** *** 226,252 **** public void PostFlush( PersistentCollection collection ) { ! // the CollectionEntry should be processed if we are in the PostFlush() ! if( !processed ) { ! throw new AssertionFailure( "Hibernate has a bug processing collections" ); } ! // now that the flush has gone through move everything that is the current ! // over to the loaded fields and set dirty to false since the db & collection ! // are in synch. ! loadedKey = currentKey; ! SetLoadedPersister( currentPersister ); ! dirty = false; ! // collection needs to know its' representation in memory and with ! // the db is now in synch - esp important for collections like a bag ! // that can add without initializing the collection. ! collection.PostFlush(); ! // if it was initialized or any of the scheduled actions were performed then ! // need to resnpashot the contents of the collection. ! if( initialized && ( doremove || dorecreate || doupdate ) ) ! { ! snapshot = collection.GetSnapshot( loadedPersister ); //re-snapshot } } --- 252,285 ---- public void PostFlush( PersistentCollection collection ) { ! if( ignore ) { ! ignore = false; } + else + { + // the CollectionEntry should be processed if we are in the PostFlush() + if( !processed ) + { + throw new AssertionFailure( "collection was not processed by Flush()" ); + } ! // now that the flush has gone through move everything that is the current ! // over to the loaded fields and set dirty to false since the db & collection ! // are in synch. ! loadedKey = currentKey; ! SetLoadedPersister( currentPersister ); ! dirty = false; ! // collection needs to know its' representation in memory and with ! // the db is now in synch - esp important for collections like a bag ! // that can add without initializing the collection. ! collection.PostFlush(); ! // if it was initialized or any of the scheduled actions were performed then ! // need to resnpashot the contents of the collection. ! if( initialized && ( doremove || dorecreate || doupdate ) ) ! { ! InitSnapshot(collection, loadedPersister); ! } } } *************** *** 254,257 **** --- 287,295 ---- #region Engine.ICollectionSnapshot Members + internal void InitSnapshot(PersistentCollection collection, CollectionPersister persister) + { + snapshot = collection.GetSnapshot( persister ); + } + /// <summary></summary> public object Key *************** *** 278,282 **** } - /// <summary></summary> public void SetDirty() { --- 316,319 ---- *************** *** 284,291 **** } ! /// <summary></summary> ! public bool IsInitialized { ! get { return initialized; } } --- 321,330 ---- } ! /// <summary> ! /// ! /// </summary> ! public bool WasDereferenced { ! get { return loadedKey == null; } } *************** *** 300,304 **** /// responsible for the Collection. /// </param> ! private void SetLoadedPersister( CollectionPersister persister ) { loadedPersister = persister; --- 339,343 ---- /// responsible for the Collection. /// </param> ! internal void SetLoadedPersister( CollectionPersister persister ) { loadedPersister = persister; --- NEW FILE: FlushVisitor.cs --- using System; using System.Collections; using NHibernate.Collection; using NHibernate.Type; namespace NHibernate.Impl { internal class FlushVisitor : AbstractVisitor { private object owner; public FlushVisitor( SessionImpl session, object owner ) : base( session ) { this.owner = owner; } protected override object ProcessCollection(object collection, PersistentCollectionType type) { if (collection!=null) { PersistentCollection coll; if ( type.IsArrayType ) { coll = Session.GetArrayHolder(collection); } else { coll = (PersistentCollection) collection; } Session.UpdateReachableCollection(coll, type, owner); } return null; } } } --- NEW FILE: OnUpdateVisitor.cs --- using System; using System.Collections; using NHibernate.Collection; using NHibernate.Engine; using NHibernate.Type; namespace NHibernate.Impl { internal class OnUpdateVisitor : ReattachVisitor { public OnUpdateVisitor(SessionImpl session, object key) : base (session, key) { } protected override object ProcessCollection(object collection, PersistentCollectionType type) { CollectionPersister persister = Session.GetCollectionPersister( type.Role ); if ( collection is PersistentCollection ) { PersistentCollection wrapper = (PersistentCollection) collection; if ( wrapper.SetCurrentSession(Session) ) { //a "detached" collection! ICollectionSnapshot snapshot = wrapper.CollectionSnapshot; if ( !SessionImpl.IsOwnerUnchanged(snapshot, persister, Key) ) { // if the collection belonged to a different entity, // clean up the existing state of the collection Session.RemoveCollection(persister, Key); } Session.ReattachCollection(wrapper, snapshot); } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() Session.RemoveCollection(persister, Key); } } else { // null or brand new collection // this will also (inefficiently) handle arrays, which have // no snapshot, so we can't do any better Session.RemoveCollection(persister, Key); //processArrayOrNewCollection(collection, type); } return null; } } } --- NEW FILE: OnLockVisitor.cs --- using System; using System.Collections; using NHibernate.Collection; using NHibernate.Engine; using NHibernate.Type; namespace NHibernate.Impl { /// <summary> /// When a transient entity is passed to <see cref="ISession.Lock" />, 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. throw an exception for each "new" collection /// </summary> internal class OnLockVisitor : ReattachVisitor { public OnLockVisitor(SessionImpl session, object key) : base(session, key) { } protected override object ProcessCollection(object collection, PersistentCollectionType type) { CollectionPersister persister = Session.GetCollectionPersister(type.Role); if (collection == null) { // Do nothing } else if ( collection is PersistentCollection ) { PersistentCollection coll = (PersistentCollection) collection; if ( coll.SetCurrentSession(Session) ) { ICollectionSnapshot snapshot = coll.CollectionSnapshot; if (SessionImpl.IsOwnerUnchanged( snapshot, persister, this.Key )) { // a "detached" collection that originally belonged to the same entity if ( snapshot.Dirty ) { throw new HibernateException("reassociated object has dirty collection"); } Session.ReattachCollection(coll, snapshot); } else { // a "detached" collection that belonged to a different entity throw new HibernateException("reassociated object has dirty collection reference"); } } else { // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() throw new HibernateException("reassociated object has dirty collection reference"); } } else { // brand new collection //TODO: or an array!! we can't lock objects with arrays now?? throw new HibernateException("reassociated object has dirty collection reference"); } return null; } } } |
From: Michael D. <mik...@us...> - 2005-02-05 14:43:56
|
Update of /cvsroot/nhibernate/CVSROOT In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15188 Modified Files: avail Log Message: Added Sergey Koshcheyev (justme84) as a developer Index: avail =================================================================== RCS file: /cvsroot/nhibernate/CVSROOT/avail,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** avail 30 Jan 2005 14:03:05 -0000 1.3 --- avail 5 Feb 2005 14:43:46 -0000 1.4 *************** *** 1,4 **** unavail ! avail|luggage, kevinwilliams, johntmorris|NHibernateContrib ! avail|kevinwilliams|nhibernate avail|mikedoerfler, szoke --- 1,4 ---- unavail ! avail|luggage, kevinwilliams, johntmorris, justme84|NHibernateContrib ! avail|kevinwilliams, justme84|nhibernate avail|mikedoerfler, szoke |
From: Kevin W. <kev...@us...> - 2005-01-31 19:11:50
|
Update of /cvsroot/nhibernate/NHibernateContrib/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25391 Modified Files: Bamboo.Prevalence.dll Log Message: update Bamboo.Prevalence with strongly-named version 1.4.4.3 Index: Bamboo.Prevalence.dll =================================================================== RCS file: /cvsroot/nhibernate/NHibernateContrib/lib/Bamboo.Prevalence.dll,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 Binary files /tmp/cvspEB6Tg and /tmp/cvs9G9T3S differ |
From: Michael D. <mik...@us...> - 2005-01-31 03:29:45
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate.Test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11789/NHibernate.Test Modified Files: PerformanceTest.cs Log Message: changed to use the keyword "using" for session. Index: PerformanceTest.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/PerformanceTest.cs,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PerformanceTest.cs 30 Jan 2005 20:04:43 -0000 1.10 --- PerformanceTest.cs 31 Jan 2005 03:29:34 -0000 1.11 *************** *** 117,123 **** for(int i = 0; i < loops; i++) { ! s = sessions.OpenSession(); ! Hibernate(s, simples, ids, n, "h" + runIndex.ToString()); ! s.Close(); } hiber += DateTime.Now.Ticks - time; --- 117,124 ---- for(int i = 0; i < loops; i++) { ! using( s = sessions.OpenSession() ) ! { ! Hibernate(s, simples, ids, n, "h" + runIndex.ToString()); ! } } hiber += DateTime.Now.Ticks - time; |
From: Michael D. <mik...@us...> - 2005-01-31 03:25:48
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11156/NHibernate/Impl Modified Files: BatcherImpl.cs NonBatchingBatcher.cs SessionImpl.cs Log Message: implemented IDisposable on IBatcher. Index: SessionImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/SessionImpl.cs,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** SessionImpl.cs 30 Jan 2005 19:36:16 -0000 1.62 --- SessionImpl.cs 31 Jan 2005 03:25:39 -0000 1.63 *************** *** 4105,4109 **** if( batcher!=null ) { ! // TODO: add batcher.Dispose() when IDisposable implemented by IBatcher } --- 4105,4109 ---- if( batcher!=null ) { ! batcher.Dispose(); } Index: BatcherImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/BatcherImpl.cs,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** BatcherImpl.cs 30 Jan 2005 19:39:12 -0000 1.16 --- BatcherImpl.cs 31 Jan 2005 03:25:39 -0000 1.17 *************** *** 20,28 **** private static int openReaderCount; ! /// <summary></summary> ! protected readonly ISessionImplementor session; ! /// <summary></summary> ! protected readonly ISessionFactoryImplementor factory; // batchCommand used to be called batchUpdate - that name to me implied that updates --- 20,26 ---- private static int openReaderCount; ! private readonly ISessionImplementor session; ! private readonly ISessionFactoryImplementor factory; // batchCommand used to be called batchUpdate - that name to me implied that updates *************** *** 35,46 **** private ISet readersToClose = new HashedSet(); ! // key = SqlString ! // value = IDbCommand private IDictionary commands; /// <summary> ! /// /// </summary> ! /// <param name="session"></param> public BatcherImpl( ISessionImplementor session ) { --- 33,46 ---- private ISet readersToClose = new HashedSet(); ! /// <summary> ! /// An IDictionary with a key of a SqlString and ! /// a value of an IDbCommand. ! /// </summary> private IDictionary commands; /// <summary> ! /// Initializes a new instance of the <see cref="BatcherImpl"/> class. /// </summary> ! /// <param name="session">The <see cref="ISessionImplementor"/> this Batcher is executing in.</param> public BatcherImpl( ISessionImplementor session ) { *************** *** 51,59 **** /// <summary> ! /// Gets the current Command that is contained for this Batch /// </summary> ! protected IDbCommand GetCommand() { ! return batchCommand; } --- 51,61 ---- /// <summary> ! /// Gets the current <see cref="IDbCommand"/> that is contained for this Batch /// </summary> ! /// <value>The current <see cref="IDbCommand"/>.</value> ! protected IDbCommand CurrentCommand { ! // in h2.0.3 this was a method GetCommand ! get { return batchCommand; } } *************** *** 161,166 **** public IDbCommand PrepareCommand( SqlString sql ) { ExecuteBatch(); ! LogOpenPreparedCommands(); // do not actually prepare the Command here - instead just generate it because --- 163,171 ---- public IDbCommand PrepareCommand( SqlString sql ) { + // a new IDbCommand is being prepared and a new (potential) batch + // started - so execute the current batch of commands. ExecuteBatch(); ! ! LogOpenPreparedCommand(); // do not actually prepare the Command here - instead just generate it because *************** *** 181,185 **** //TODO: figure out what to do with scrollable - don't think it applies // to ado.net since DataReader is forward only ! LogOpenPreparedCommands(); // do not actually prepare the Command here - instead just generate it because --- 186,190 ---- //TODO: figure out what to do with scrollable - don't think it applies // to ado.net since DataReader is forward only ! LogOpenPreparedCommand(); // do not actually prepare the Command here - instead just generate it because *************** *** 204,207 **** --- 209,213 ---- batchCommand = null; batchCommandSql = null; + CloseCommand( cmd, null ); // close the statement closeStatement(cmd) } *************** *** 247,251 **** readersToClose.Add( reader ); ! LogOpenReaders(); return reader; } --- 253,257 ---- readersToClose.Add( reader ); ! LogOpenReader(); return reader; } *************** *** 293,297 **** try { ! LogCloseReaders(); reader.Close(); } --- 299,303 ---- try { ! LogCloseReader(); reader.Close(); } *************** *** 312,316 **** { // no big deal ! log.Warn( "Could not close a JDBC statement", e ); } } --- 318,322 ---- { // no big deal ! log.Warn( "Could not close ADO.NET Command", e ); } } *************** *** 331,335 **** } ! LogClosePreparedCommands(); } --- 337,341 ---- } ! LogClosePreparedCommand(); } *************** *** 351,355 **** if( reader != null ) { ! LogCloseReaders(); reader.Close(); } --- 357,361 ---- if( reader != null ) { ! LogCloseReader(); reader.Close(); } *************** *** 364,367 **** --- 370,375 ---- public void ExecuteBatch() { + // if there is currently a command that a batch is + // being built for then execute it if( batchCommand != null ) { *************** *** 387,396 **** /// <summary> ! /// /// </summary> ! /// <param name="expectedRowCount"></param> public abstract void AddToBatch( int expectedRowCount ); ! /// <summary></summary> protected ISessionFactoryImplementor Factory { --- 395,415 ---- /// <summary> ! /// Adds the expected row count into the batch. /// </summary> ! /// <param name="expectedRowCount">The number of rows expected to be affected by the query.</param> ! /// <remarks> ! /// If Batching is not supported, then this is when the Command should be executed. If Batching ! /// is supported then it should hold of on executing the batch until explicitly told to. ! /// </remarks> public abstract void AddToBatch( int expectedRowCount ); ! /// <summary> ! /// Gets the <see cref="ISessionFactoryImplementor"/> the Batcher was ! /// created in. ! /// </summary> ! /// <value> ! /// The <see cref="ISessionFactoryImplementor"/> the Batcher was ! /// created in. ! /// </value> protected ISessionFactoryImplementor Factory { *************** *** 398,402 **** } ! /// <summary></summary> protected ISessionImplementor Session { --- 417,428 ---- } ! /// <summary> ! /// Gets the <see cref="ISessionImplementor"/> the Batcher is handling the ! /// sql actions for. ! /// </summary> ! /// <value> ! /// The <see cref="ISessionImplementor"/> the Batcher is handling the ! /// sql actions for. ! /// </value> protected ISessionImplementor Session { *************** *** 404,408 **** } ! private static void LogOpenPreparedCommands() { if( log.IsDebugEnabled ) --- 430,434 ---- } ! private static void LogOpenPreparedCommand() { if( log.IsDebugEnabled ) *************** *** 413,417 **** } ! private static void LogClosePreparedCommands() { if( log.IsDebugEnabled ) --- 439,443 ---- } ! private static void LogClosePreparedCommand() { if( log.IsDebugEnabled ) *************** *** 422,426 **** } ! private static void LogOpenReaders() { if( log.IsDebugEnabled ) --- 448,452 ---- } ! private static void LogOpenReader() { if( log.IsDebugEnabled ) *************** *** 430,434 **** } ! private static void LogCloseReaders() { if( log.IsDebugEnabled ) --- 456,460 ---- } ! private static void LogCloseReader() { if( log.IsDebugEnabled ) *************** *** 438,441 **** --- 464,553 ---- } + #region IDisposable Members + + /// <summary> + /// A flag to indicate if <c>Disose()</c> has been called. + /// </summary> + private bool _isAlreadyDisposed; + + /// <summary> + /// Finalizer that ensures the object is correctly disposed of. + /// </summary> + ~BatcherImpl() + { + Dispose( false ); + } + + /// <summary> + /// Takes care of freeing the managed and unmanaged resources that + /// this class is responsible for. + /// </summary> + public void Dispose() + { + log.Debug( "running BatcherImpl.Dispose()" ); + Dispose( true ); + } + + /// <summary> + /// Takes care of freeing the managed and unmanaged resources that + /// this class is responsible for. + /// </summary> + /// <param name="isDisposing">Indicates if this BatcherImpl is being Disposed of or Finalized.</param> + /// <remarks> + /// If this BatcherImpl is being Finalized (<c>isDisposing==false</c>) then make sure not + /// to call any methods that could potentially bring this BatcherImpl back to life. + /// </remarks> + protected virtual void Dispose(bool isDisposing) + { + if( _isAlreadyDisposed ) + { + // don't dispose of multiple times. + return; + } + + // free managed resources that are being managed by the AdoTransaction if we + // know this call came through Dispose() + if( isDisposing ) + { + foreach( IDataReader reader in readersToClose ) + { + try + { + LogCloseReader(); + reader.Dispose(); + } + catch( Exception e ) + { + log.Warn( "Could not dispose IDataReader", e ); + } + } + readersToClose.Clear(); + + foreach( IDbCommand cmd in commandsToClose ) + { + try + { + LogClosePreparedCommand(); + cmd.Dispose(); + } + catch( Exception e ) + { + // no big deal + log.Warn( "Could not dispose of ADO.NET Command", e ); + } + } + commandsToClose.Clear(); + } + + // free unmanaged resources here + + _isAlreadyDisposed = true; + // nothing for Finalizer to do - so tell the GC to ignore it + GC.SuppressFinalize( this ); + + } + + #endregion + } Index: NonBatchingBatcher.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/NonBatchingBatcher.cs,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** NonBatchingBatcher.cs 31 Dec 2004 19:52:14 -0000 1.7 --- NonBatchingBatcher.cs 31 Jan 2005 03:25:39 -0000 1.8 *************** *** 5,16 **** { /// <summary> ! /// An implementation of the <c>IBatcher</c> inteface that does no batching /// </summary> internal class NonBatchingBatcher : BatcherImpl { /// <summary> ! /// /// </summary> ! /// <param name="session"></param> public NonBatchingBatcher( ISessionImplementor session ) : base( session ) { --- 5,17 ---- { /// <summary> ! /// An implementation of the <see cref="IBatcher" /> ! /// interface that does no batching. /// </summary> internal class NonBatchingBatcher : BatcherImpl { /// <summary> ! /// Initializes a new instance of the <see cref="NonBatchingBatcher"/> class. /// </summary> ! /// <param name="session">The <see cref="ISessionImplementor"/> the Batcher is in.</param> public NonBatchingBatcher( ISessionImplementor session ) : base( session ) { *************** *** 18,27 **** /// <summary> ! /// /// </summary> ! /// <param name="expectedRowCount"></param> public override void AddToBatch( int expectedRowCount ) { ! int rowCount = this.ExecuteNonQuery( this.GetCommand() ); //negative expected row count means we don't know how many rows to expect --- 19,36 ---- /// <summary> ! /// Executes the current <see cref="IDbCommand"/> and compares the row Count ! /// to the <c>expectedRowCount</c>. /// </summary> ! /// <param name="expectedRowCount"> ! /// The expected number of rows affected by the query. A value of less than <c>0</c> ! /// indicates that the number of rows to expect is unknown or should not be a factor. ! /// </param> ! /// <exception cref="HibernateException"> ! /// Thrown when there is an expected number of rows to be affected and the ! /// actual number of rows is different. ! /// </exception> public override void AddToBatch( int expectedRowCount ) { ! int rowCount = this.ExecuteNonQuery( this.CurrentCommand ); //negative expected row count means we don't know how many rows to expect *************** *** 33,37 **** /// <summary> ! /// /// </summary> /// <param name="ps"></param> --- 42,48 ---- /// <summary> ! /// This Batcher implementation does not support batching so this is a no-op call. The ! /// actual execution of the <see cref="IDbCommand"/> is run in the <c>AddToBatch</c> ! /// method. /// </summary> /// <param name="ps"></param> |
From: Michael D. <mik...@us...> - 2005-01-31 03:25:48
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11156/NHibernate/Engine Modified Files: IBatcher.cs Log Message: implemented IDisposable on IBatcher. Index: IBatcher.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Engine/IBatcher.cs,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** IBatcher.cs 24 Jan 2005 03:33:30 -0000 1.6 --- IBatcher.cs 31 Jan 2005 03:25:39 -0000 1.7 *************** *** 6,37 **** { /// <summary> ! /// Manages <see cref="IDbCommand">IDbCommands</see> and <see cref="IDataReader">IDataReaders</see> for a session. /// </summary> /// <remarks> ! /// <para> /// Abstracts ADO.NET batching to maintain the illusion that a single logical batch /// exists for the whole session, even when batching is disabled. /// Provides transparent <c>IDbCommand</c> caching. ! /// </para> ! /// <para> /// This will be useful once ADO.NET gets support for batching. Until that point /// no code exists that will do batching, but this will provide a good point to do /// error checking and making sure the correct number of rows were affected. ! /// </para> /// </remarks> ! //TODO: add IDisposable ! public interface IBatcher { /// <summary> ! /// Get a prepared statement for using in loading / querying. /// </summary> ! /// <param name="sql"></param> /// <param name="scrollable">TODO: not sure how to use this yet</param> /// <remarks> /// If not explicitly released by <c>CloseQueryStatement()</c>, it will be /// released when the session is closed or disconnected. ! /// /// This does NOT add anything to the batch - it only creates the IDbCommand and /// does NOT cause the batch to execute... /// </remarks> IDbCommand PrepareQueryCommand( SqlString sql, bool scrollable ); --- 6,43 ---- { /// <summary> ! /// Manages <see cref="IDbCommand"/>s and <see cref="IDataReader"/>s ! /// for an <see cref="ISession"/>. /// </summary> /// <remarks> ! /// <p> /// Abstracts ADO.NET batching to maintain the illusion that a single logical batch /// exists for the whole session, even when batching is disabled. /// Provides transparent <c>IDbCommand</c> caching. ! /// </p> ! /// <p> /// This will be useful once ADO.NET gets support for batching. Until that point /// no code exists that will do batching, but this will provide a good point to do /// error checking and making sure the correct number of rows were affected. ! /// </p> /// </remarks> ! public interface IBatcher : IDisposable { /// <summary> ! /// Get an <see cref="IDbCommand"/> for using in loading / querying. /// </summary> ! /// <param name="sql">The <see cref="SqlString"/> to convert to an <see cref="IDbCommand"/>.</param> /// <param name="scrollable">TODO: not sure how to use this yet</param> + /// <returns> + /// An <see cref="IDbCommand"/> that is ready to be executed. + /// </returns> /// <remarks> + /// <p> /// If not explicitly released by <c>CloseQueryStatement()</c>, it will be /// released when the session is closed or disconnected. ! /// </p> ! /// <p> /// This does NOT add anything to the batch - it only creates the IDbCommand and /// does NOT cause the batch to execute... + /// </p> /// </remarks> IDbCommand PrepareQueryCommand( SqlString sql, bool scrollable ); *************** *** 39,43 **** /// <summary> /// Closes the <see cref="IDbCommand"/> & the <see cref="IDataReader"/> that was ! /// opened with <c>PrepareQueryCommand</c>. /// </summary> /// <param name="cmd">The <see cref="IDbCommand"/> to close.</param> --- 45,49 ---- /// <summary> /// Closes the <see cref="IDbCommand"/> & the <see cref="IDataReader"/> that was ! /// opened with the method <c>PrepareQueryCommand</c>. /// </summary> /// <param name="cmd">The <see cref="IDbCommand"/> to close.</param> *************** *** 46,72 **** /// <summary> ! /// Get a non-batchable prepared statement to use for inserting / deleting / updating. ! /// Must be explicitly released by <c>CloseStatement()</c> /// </summary> ! /// <param name="sql">The SqlString to convert to an IDbCommand.</param> ! /// <returns></returns> IDbCommand PrepareCommand( SqlString sql ); /// <summary> ! /// Close a IDbCommand opened using <c>PrepareStatement()</c> /// </summary> ! /// <param name="cm">The <see cref="IDbCommand"/> to ensure is closed.</param> /// <param name="reader">The <see cref="IDataReader"/> to ensure is closed.</param> ! void CloseCommand( IDbCommand cm, IDataReader reader ); /// <summary> ! /// Get a batchable prepared statement to use for inserting / deleting / updating /// (might be called many times before a single call to <c>ExecuteBatch()</c> /// </summary> /// <remarks> /// After setting parameters, call <c>AddToBatch()</c> - do not execute the statement ! /// explicitly /// </remarks> ! /// <param name="sql"></param> /// <returns></returns> IDbCommand PrepareBatchCommand( SqlString sql ); --- 52,81 ---- /// <summary> ! /// Get a non-batchable an <see cref="IDbCommand"/> to use for inserting / deleting / updating. ! /// Must be explicitly released by <c>CloseCommand()</c> /// </summary> ! /// <param name="sql">The <see cref="SqlString"/> to convert to an <see cref="IDbCommand"/>.</param> ! /// <returns> ! /// An <see cref="IDbCommand"/> that is ready to have the parameter values set ! /// and then executed. ! /// </returns> IDbCommand PrepareCommand( SqlString sql ); /// <summary> ! /// Close a <see cref="IDbCommand"/> opened using <c>PrepareCommand()</c> /// </summary> ! /// <param name="cmd">The <see cref="IDbCommand"/> to ensure is closed.</param> /// <param name="reader">The <see cref="IDataReader"/> to ensure is closed.</param> ! void CloseCommand( IDbCommand cmd, IDataReader reader ); /// <summary> ! /// Get a batchable <see cref="IDbCommand"/> to use for inserting / deleting / updating /// (might be called many times before a single call to <c>ExecuteBatch()</c> /// </summary> /// <remarks> /// After setting parameters, call <c>AddToBatch()</c> - do not execute the statement ! /// explicitly. /// </remarks> ! /// <param name="sql">The <see cref="SqlString"/> to convert to an <see cref="IDbCommand"/>.</param> /// <returns></returns> IDbCommand PrepareBatchCommand( SqlString sql ); *************** *** 76,80 **** /// for a single <c>PrepareBatchStatement()</c>) /// </summary> ! /// <param name="expectedRowCount"></param> /// <remarks> /// A negative number in expectedRowCount means that you don't know how many rows to --- 85,89 ---- /// for a single <c>PrepareBatchStatement()</c>) /// </summary> ! /// <param name="expectedRowCount">The number of rows that should be affected when the query is run.</param> /// <remarks> /// A negative number in expectedRowCount means that you don't know how many rows to *************** *** 88,95 **** void ExecuteBatch(); - // TODO: how applicable is this??? /// <summary> /// Close any query statements that were left lying around /// </summary> void CloseCommands(); --- 97,107 ---- void ExecuteBatch(); /// <summary> /// Close any query statements that were left lying around /// </summary> + /// <remarks> + /// Use this method instead of <c>Dispose</c> if the <see cref="IBatcher"/> + /// can be used again. + /// </remarks> void CloseCommands(); |
From: Michael D. <mik...@us...> - 2005-01-31 03:24:54
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Dialect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11018/NHibernate/Dialect Modified Files: Dialect.cs Log Message: Fixed typo in xml doc. Index: Dialect.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Dialect/Dialect.cs,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** Dialect.cs 17 Jan 2005 03:40:55 -0000 1.42 --- Dialect.cs 31 Jan 2005 03:24:43 -0000 1.43 *************** *** 16,20 **** /// <summary> /// Represents a dialect of SQL implemented by a particular RDBMS. Sublcasses ! /// implement Hibernate compatibility with differen systems /// </summary> /// <remarks> --- 16,20 ---- /// <summary> /// Represents a dialect of SQL implemented by a particular RDBMS. Sublcasses ! /// implement NHibernate compatibility with different systems. /// </summary> /// <remarks> |
From: Michael D. <mik...@us...> - 2005-01-30 20:04:52
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate.Test In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6778/NHibernate.Test Modified Files: PerformanceTest.cs Log Message: manual ado.net uses same value of prepare_sql as config file has. Dispose of connection provider. Index: PerformanceTest.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/PerformanceTest.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PerformanceTest.cs 1 Sep 2004 00:10:28 -0000 1.9 --- PerformanceTest.cs 30 Jan 2005 20:04:43 -0000 1.10 *************** *** 1,7 **** using System; - using System.Collections; using System.Data; - using NHibernate.Cfg; using NHibernate.Connection; using NHibernate.Driver; --- 1,5 ---- *************** *** 46,49 **** --- 44,48 ---- string driverClass = null; IDriver driver = null; + bool prepareSql; [SetUp] *************** *** 59,62 **** --- 58,68 ---- driver = (IDriver)Activator.CreateInstance(System.Type.GetType(driverClass)); + + string prepare = (string)cfg.Properties[ Cfg.Environment.PrepareSql ] as string; + if( prepare=="true" ) + { + prepareSql = true; + } + } *************** *** 131,135 **** System.Console.Out.Write("NHibernate: " + hiber + "ms / Direct ADO.NET: " + adonet + "ms = Ratio: " + (((float)hiber/adonet)).ToString() ); ! cp.Close(); System.GC.Collect(); } --- 137,141 ---- System.Console.Out.Write("NHibernate: " + hiber + "ms / Direct ADO.NET: " + adonet + "ms = Ratio: " + (((float)hiber/adonet)).ToString() ); ! cp.Dispose(); System.GC.Collect(); } *************** *** 205,212 **** update.Transaction = t; ! insert.Prepare(); ! delete.Prepare(); ! select.Prepare(); ! update.Prepare(); for(int i = 0; i < N; i++) --- 211,221 ---- update.Transaction = t; ! if( prepareSql ) ! { ! insert.Prepare(); ! delete.Prepare(); ! select.Prepare(); ! update.Prepare(); ! } for(int i = 0; i < N; i++) |
From: Michael D. <mik...@us...> - 2005-01-30 20:03:57
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Dialect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6418/NHibernate/Dialect Modified Files: MsSql2000Dialect.cs Log Message: defaults prepare_sql to false - best perf with sql server. Index: MsSql2000Dialect.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** MsSql2000Dialect.cs 17 Jan 2005 22:31:48 -0000 1.23 --- MsSql2000Dialect.cs 30 Jan 2005 20:03:33 -0000 1.24 *************** *** 23,26 **** --- 23,30 ---- /// <description><see cref="NHibernate.Driver.SqlClientDriver" /></description> /// </item> + /// <item> + /// <term>hibernate.prepare_sql</term> + /// <description><c>false</c></description> + /// </item> /// </list> /// </remarks> *************** *** 67,70 **** --- 71,75 ---- DefaultProperties[ Environment.OuterJoin ] = "true"; DefaultProperties[ Environment.ConnectionDriver ] = "NHibernate.Driver.SqlClientDriver"; + DefaultProperties[ Environment.PrepareSql ] = "false"; } |
From: Michael D. <mik...@us...> - 2005-01-30 19:40:45
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv536/NHibernate.Test/SqlCommandTest Modified Files: SqlDeleteBuilderFixture.cs SqlInsertBuilderFixture.cs SqlSelectBuilderFixture.cs SqlSimpleSelectBuilderFixture.cs SqlStringFixture.cs SqlStringParameterFixture.cs SqlUpdateBuilderFixture.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Added some test for Equals method of Parameter. Index: SqlStringFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** SqlStringFixture.cs 13 Sep 2004 07:11:05 -0000 1.5 --- SqlStringFixture.cs 30 Jan 2005 19:39:52 -0000 1.6 *************** *** 48,54 **** { SqlStringBuilder builder = new SqlStringBuilder(); ! Parameter param = new Parameter(); ! param.Name = "id"; ! param.SqlType = new SqlTypes.Int32SqlType(); builder.Add("select from table "); --- 48,52 ---- { SqlStringBuilder builder = new SqlStringBuilder(); ! Parameter param = new Parameter( "id", new SqlTypes.Int32SqlType() ); builder.Add("select from table "); *************** *** 70,77 **** public void CompactWithNoString() { ! Parameter p1 = new Parameter(); ! Parameter p2 = new Parameter(); ! p1.Name = "p1"; ! p2.Name = "p2"; SqlString sql = new SqlString( new object[] {p1, p2} ); --- 68,73 ---- public void CompactWithNoString() { ! Parameter p1 = new Parameter( "p1" ); ! Parameter p2 = new Parameter( "p2" ); SqlString sql = new SqlString( new object[] {p1, p2} ); *************** *** 93,100 **** public void ContainsUntypedParameterWithParam() { ! Parameter p1 = new Parameter(); ! p1.SqlType = new SqlTypes.Int32SqlType(); ! p1.Name = "p1"; ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", p1} ); Assert.IsFalse( sql.ContainsUntypedParameter ); --- 89,94 ---- public void ContainsUntypedParameterWithParam() { ! Parameter p1 = new Parameter( "p1", new SqlTypes.Int32SqlType() ); ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", p1} ); Assert.IsFalse( sql.ContainsUntypedParameter ); *************** *** 105,109 **** { ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter()} ); Assert.IsTrue( sql.ContainsUntypedParameter ); } --- 99,103 ---- { ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter( "p1" )} ); Assert.IsTrue( sql.ContainsUntypedParameter ); } *************** *** 112,120 **** public void ContainsUntypedParameterWithMixedUntypedParam() { ! Parameter p1 = new Parameter(); ! p1.SqlType = new SqlTypes.Int32SqlType(); ! p1.Name = "p1"; ! ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter(), " and b = " , p1} ); Assert.IsTrue( sql.ContainsUntypedParameter ); } --- 106,112 ---- public void ContainsUntypedParameterWithMixedUntypedParam() { ! Parameter p1 = new Parameter( "p1", new SqlTypes.Int32SqlType() ); ! ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter( "p2" ), " and b = " , p1} ); Assert.IsTrue( sql.ContainsUntypedParameter ); } *************** *** 123,127 **** public void Count() { ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter(), " and b = " , new Parameter() } ); Assert.AreEqual( 5, sql.Count, "Count with no nesting failed." ); --- 115,119 ---- public void Count() { ! SqlString sql = new SqlString( new object[] {"select", " from table where a = ", new Parameter( "p1" ), " and b = " , new Parameter( "p2" ) } ); Assert.AreEqual( 5, sql.Count, "Count with no nesting failed." ); *************** *** 155,159 **** public void EndsWithParameter() { ! SqlString sql = new SqlString( new object[] { "", "select", " from table where id = ", new Parameter() } ); Assert.IsFalse( sql.EndsWith("'") ); Assert.IsFalse( sql.EndsWith("") ); --- 147,151 ---- public void EndsWithParameter() { ! SqlString sql = new SqlString( new object[] { "", "select", " from table where id = ", new Parameter( "p1" ) } ); Assert.IsFalse( sql.EndsWith("'") ); Assert.IsFalse( sql.EndsWith("") ); *************** *** 171,178 **** public void ParameterIndexOneParam() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter() } ); Assert.AreEqual( 1, sql.ParameterIndexes.Length ); ! Assert.AreEqual( 3, sql.ParameterIndexes[0] ); } --- 163,170 ---- public void ParameterIndexOneParam() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter( "p1" ) } ); Assert.AreEqual( 1, sql.ParameterIndexes.Length ); ! Assert.AreEqual( 3, sql.ParameterIndexes[0], "the first param should be at index 3" ); } *************** *** 181,189 **** public void ParameterIndexManyParam() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter(), " and c = ", new Parameter() } ); Assert.AreEqual( 2, sql.ParameterIndexes.Length ); ! Assert.AreEqual( 3, sql.ParameterIndexes[0] ); ! Assert.AreEqual( 5, sql.ParameterIndexes[1] ); } --- 173,181 ---- public void ParameterIndexManyParam() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter( "p1" ), " and c = ", new Parameter( "p2" ) } ); Assert.AreEqual( 2, sql.ParameterIndexes.Length ); ! Assert.AreEqual( 3, sql.ParameterIndexes[0], "the first param should be at index 3" ); ! Assert.AreEqual( 5, sql.ParameterIndexes[1], "the second param should be at index 5" ); } *************** *** 191,195 **** public void Replace() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter(), " and c = ", new Parameter() } ); SqlString replacedSql = sql.Replace( "table", "replacedTable" ); --- 183,187 ---- public void Replace() { ! SqlString sql = new SqlString( new object[] {"select ", "from table ", "where a = ", new Parameter( "p1" ), " and c = ", new Parameter( "p2" ) } ); SqlString replacedSql = sql.Replace( "table", "replacedTable" ); *************** *** 227,233 **** { SqlStringBuilder builder = new SqlStringBuilder(); ! Parameter p = new Parameter(); ! p.Name = "p1"; ! builder.Add(" select from table"); builder.Add(" where p = "); --- 219,224 ---- { SqlStringBuilder builder = new SqlStringBuilder(); ! Parameter p = new Parameter( "p1" ); ! builder.Add(" select from table"); builder.Add(" where p = "); *************** *** 255,261 **** public void TrimBeginParamEndString() { ! Parameter p1 = new Parameter(); ! p1.Name = "p1"; ! SqlString sql = new SqlString( new object[] {p1, " extra space "} ); sql = sql.Trim(); --- 246,251 ---- public void TrimBeginParamEndString() { ! Parameter p1 = new Parameter( "p1" ); ! SqlString sql = new SqlString( new object[] {p1, " extra space "} ); sql = sql.Trim(); *************** *** 267,273 **** public void TrimBeginStringEndParam() { ! Parameter p1 = new Parameter(); ! p1.Name = "p1"; ! SqlString sql = new SqlString( new object[] { " extra space ", p1 } ); sql = sql.Trim(); --- 257,262 ---- public void TrimBeginStringEndParam() { ! Parameter p1 = new Parameter( "p1" ); ! SqlString sql = new SqlString( new object[] { " extra space ", p1 } ); sql = sql.Trim(); *************** *** 279,286 **** public void TrimAllParam() { ! Parameter p1 = new Parameter(); ! p1.Name = "p1"; ! Parameter p2 = new Parameter(); ! p2.Name = "p2"; SqlString sql = new SqlString( new object[] { p1, p2 } ); --- 268,273 ---- public void TrimAllParam() { ! Parameter p1 = new Parameter( "p1" ); ! Parameter p2 = new Parameter( "p2" ); SqlString sql = new SqlString( new object[] { p1, p2 } ); Index: SqlDeleteBuilderFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlDeleteBuilderFixture.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** SqlDeleteBuilderFixture.cs 17 Jan 2005 03:40:53 -0000 1.5 --- SqlDeleteBuilderFixture.cs 30 Jan 2005 19:39:52 -0000 1.6 *************** *** 51,62 **** ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.DecimalSqlType(); ! firstParam.Name = "decimalColumn"; ! ! Parameter secondParam = new Parameter(); ! secondParam.SqlType = new SqlTypes.Int32SqlType(); ! secondParam.Name = "versionColumn"; ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "firstParam Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "firstParam Name"); --- 51,58 ---- ! Parameter firstParam = new Parameter( "decimalColumn", new SqlTypes.DecimalSqlType() ); ! ! Parameter secondParam = new Parameter( "versionColumn", new SqlTypes.Int32SqlType()); ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "firstParam Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "firstParam Name"); Index: SqlSimpleSelectBuilderFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlSimpleSelectBuilderFixture.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SqlSimpleSelectBuilderFixture.cs 17 Jan 2005 03:40:53 -0000 1.4 --- SqlSimpleSelectBuilderFixture.cs 30 Jan 2005 19:39:52 -0000 1.5 *************** *** 70,85 **** Assert.AreEqual(3, numOfParameters, "3 parameters"); ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.Int64SqlType(); ! firstParam.Name = "identity_column"; ! ! Parameter secondParam = new Parameter(); ! secondParam.SqlType = new SqlTypes.Int32SqlType(); ! secondParam.Name = "version_column"; ! ! Parameter thirdParam = new Parameter(); ! thirdParam.SqlType = new SqlTypes.Int32SqlType(); ! thirdParam.Name = "where_frag_column"; ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "First Parameter Name"); --- 70,79 ---- Assert.AreEqual(3, numOfParameters, "3 parameters"); ! Parameter firstParam = new Parameter( "identity_column", new SqlTypes.Int64SqlType() ); ! ! Parameter secondParam = new Parameter( "version_column", new SqlTypes.Int32SqlType() ); ! ! Parameter thirdParam = new Parameter( "where_frag_column", new SqlTypes.Int32SqlType() ); ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "First Parameter Name"); Index: SqlUpdateBuilderFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlUpdateBuilderFixture.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** SqlUpdateBuilderFixture.cs 17 Jan 2005 03:40:53 -0000 1.5 --- SqlUpdateBuilderFixture.cs 30 Jan 2005 19:39:52 -0000 1.6 *************** *** 58,77 **** ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.Int32SqlType(); ! firstParam.Name = "intColumn"; ! ! Parameter secondParam = new Parameter(); ! secondParam.SqlType = new SqlTypes.Int64SqlType(); ! secondParam.Name = "longColumn"; ! ! Parameter thirdParam = new Parameter(); ! thirdParam.SqlType = new SqlTypes.DecimalSqlType(); ! thirdParam.Name = "decimalColumn"; ! ! Parameter fourthParam = new Parameter(); ! fourthParam.SqlType = new SqlTypes.Int32SqlType(); ! fourthParam.Name = "versionColumn"; ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "firstParam Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "firstParam Name"); --- 58,69 ---- ! Parameter firstParam = new Parameter( "intColumn", new SqlTypes.Int32SqlType() ); ! ! Parameter secondParam = new Parameter( "longColumn", new SqlTypes.Int64SqlType() ); ! ! Parameter thirdParam = new Parameter( "decimalColumn", new SqlTypes.DecimalSqlType() ); ! ! Parameter fourthParam = new Parameter( "versionColumn", new SqlTypes.Int32SqlType() ); ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "firstParam Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "firstParam Name"); Index: SqlStringParameterFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringParameterFixture.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** SqlStringParameterFixture.cs 20 Sep 2004 17:46:01 -0000 1.3 --- SqlStringParameterFixture.cs 30 Jan 2005 19:39:52 -0000 1.4 *************** *** 16,44 **** public class SqlStringParameterFixture { ! [Test] ! public void TestParameterClone() { ! Parameter original = new Parameter(); ! Parameter cloned = null; ! original.SqlType = new SqlTypes.Int32SqlType(); ! original.Name = "originalName"; ! cloned = (Parameter)original.Clone(); ! Assert.IsTrue((original==cloned)==false, "Not the same object by =="); ! Assert.AreEqual(original.SqlType.DbType, cloned.SqlType.DbType, "Same DbType"); ! Assert.AreEqual(original.Name, cloned.Name, "Same Name"); ! // change some of the values of the clone to ensure the original doesn't change ! cloned.SqlType = new SqlTypes.StringSqlType(); ! cloned.Name = "Cloned name"; ! Assert.IsTrue(cloned.SqlType.DbType!=original.SqlType.DbType, "Should not the same db type anymore"); ! Assert.IsTrue(cloned.Name!=original.Name, "Should not the same name anymore"); } --- 16,126 ---- public class SqlStringParameterFixture { ! /* ! * "The equals() method implements an equivalence relation: ! - It is reflexive: For any reference value x, x.equals(x) should return true ! - It is symmetric: For any reference values x and y, x.equals(y) should return ! true if and only if y.equals(x) returns true ! - It is transitive: For any reference values x, y, and z, if x.equals(y) returns ! true and y.equals(z) returns true, then x.equals(z) should return true ! - It is consistent: For any reference values x and y, multiple invocations of ! x.equals(y) consistently return true or consistently return false, provided no ! information used in equals comparisons on the object is modified ! - For any non-null reference value x, x.equals(null) should return false" ! */ ! [Test] ! public void EqualsSameType() { ! Parameter x = new Parameter( "name", "alias", new SqlTypes.Int32SqlType() ); ! Parameter y = new Parameter( "name", "alias", new SqlTypes.Int32SqlType() ); ! Parameter z = new Parameter( "name", "alias", new SqlTypes.Int32SqlType() ); ! ! Assert.IsTrue( x.Equals(y) ); ! Assert.IsTrue( y.Equals(x) ); ! Assert.IsTrue( y.Equals(z) ); ! Assert.IsTrue( x.Equals(z) ); ! Assert.IsFalse( x.Equals(null) ); ! y = new Parameter( "name2", "alias", new SqlTypes.Int32SqlType() ); ! ! Assert.IsFalse( x.Equals(y) ); ! Assert.IsFalse( y.Equals(x) ); ! } ! ! [Test] ! public void EqualsLengthType() ! { ! ParameterLength x = new ParameterLength( "name", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! ParameterLength y = new ParameterLength( "name", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! ParameterLength z = new ParameterLength( "name", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! Assert.IsTrue( x.Equals(y) ); ! Assert.IsTrue( y.Equals(x) ); ! Assert.IsTrue( y.Equals(z) ); ! Assert.IsTrue( x.Equals(z) ); ! Assert.IsFalse( x.Equals(null) ); ! y = new ParameterLength( "name2", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! ! Assert.IsFalse( x.Equals(y) ); ! Assert.IsFalse( y.Equals(x) ); ! } ! ! [Test] ! public void EqualsLengthDiffType() ! { ! Parameter x = new Parameter( "name", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! ParameterLength y = new ParameterLength( "name", "alias", new SqlTypes.AnsiStringSqlType(5) ); ! // even though these contain the exact same values - they should not be ! // equal because they are different types ! Assert.IsFalse( x.Equals(y) ); ! Assert.IsFalse( y.Equals(x) ); ! } ! [Test] ! public void EqualsPrecisionDiffType() ! { ! Parameter x = new Parameter( "name", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); ! ParameterPrecisionScale y = new ParameterPrecisionScale( "name", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); ! ! // even though these contain the exact same values - they should not be ! // equal because they are different types ! Assert.IsFalse( x.Equals(y) ); ! Assert.IsFalse( y.Equals(x) ); ! } ! [Test] ! public void EqualsPrecisionType() ! { ! ParameterPrecisionScale x = new ParameterPrecisionScale( "name", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); ! ParameterPrecisionScale y = new ParameterPrecisionScale( "name", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); ! ParameterPrecisionScale z = new ParameterPrecisionScale( "name", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); + Assert.IsTrue( x.Equals(y) ); + Assert.IsTrue( y.Equals(x) ); + Assert.IsTrue( y.Equals(z) ); + Assert.IsTrue( x.Equals(z) ); + Assert.IsFalse( x.Equals(null) ); + y = new ParameterPrecisionScale( "name2", "alias", new SqlTypes.DecimalSqlType( 20, 4 ) ); + + Assert.IsFalse( x.Equals(y) ); + Assert.IsFalse( y.Equals(x) ); + } + + + + [Test] + public void TestParameterClone() + { + Parameter original = new Parameter( "originalName", new SqlTypes.Int32SqlType() ); + Parameter cloned = null; + + cloned = (Parameter)original.Clone(); + + Assert.IsTrue((original==cloned)==false, "Not the same object by =="); + Assert.AreEqual(original.SqlType.DbType, cloned.SqlType.DbType, "Same DbType"); + Assert.AreEqual(original.Name, cloned.Name, "Same Name"); } *************** *** 46,56 **** public void TestParameterLengthClone() { ! ParameterLength original = new ParameterLength(); ParameterLength cloned = null; - original.SqlType = new SqlTypes.StringSqlType(275); - original.Name = "originalName"; - original.Length = 275; - cloned = (ParameterLength)original.Clone(); --- 128,134 ---- public void TestParameterLengthClone() { ! ParameterLength original = new ParameterLength( "originalName", new SqlTypes.StringSqlType(275) ); ParameterLength cloned = null; cloned = (ParameterLength)original.Clone(); *************** *** 59,73 **** Assert.AreEqual(original.Name, cloned.Name, "Same Name"); Assert.AreEqual(original.Length, cloned.Length, "Same Length"); - - // change some of the values of the clone to ensure the original doesn't change - - cloned.SqlType = new SqlTypes.AnsiStringSqlType(175); - cloned.Name = "Cloned name"; - cloned.Length = 175; - - Assert.IsTrue(cloned.SqlType.DbType!=original.SqlType.DbType, "Should not the same db type anymore"); - Assert.IsTrue(cloned.Name!=original.Name, "Should not the same name anymore"); - Assert.IsTrue(cloned.Length!=original.Length, "Should not the same length anymore"); - } --- 137,140 ---- *************** *** 75,86 **** public void TestParameterPrecisionClone() { ! ParameterPrecisionScale original = new ParameterPrecisionScale(); ParameterPrecisionScale cloned = null; - original.SqlType = new SqlTypes.DecimalSqlType(19, 5); - original.Name = "originalName"; - original.Precision = 19; - original.Scale = 5; - cloned = (ParameterPrecisionScale)original.Clone(); --- 142,148 ---- public void TestParameterPrecisionClone() { ! ParameterPrecisionScale original = new ParameterPrecisionScale( "originalName", new SqlTypes.DecimalSqlType(19, 5) ); ParameterPrecisionScale cloned = null; cloned = (ParameterPrecisionScale)original.Clone(); *************** *** 91,108 **** Assert.AreEqual(original.Scale, cloned.Scale, "Same Scale"); - // change some of the values of the clone to ensure the original doesn't change - - // I know AnsiString is not a precision based but for this example we just need - // to make sure the clonging is working... - cloned.SqlType = new SqlTypes.AnsiStringSqlType(); - cloned.Name = "Cloned name"; - cloned.Precision = 15; - cloned.Scale = 4; - - Assert.IsTrue(cloned.SqlType.DbType!=original.SqlType.DbType, "Should not the same db type anymore"); - Assert.IsTrue(cloned.Name!=original.Name, "Should not the same name anymore"); - Assert.IsTrue(cloned.Precision!=original.Precision, "Should not the same Precision anymore"); - Assert.IsTrue(cloned.Scale!=original.Scale, "Should not the same Scale anymore"); - } --- 153,156 ---- *************** *** 118,129 **** Parameter[] origParams = new Parameter[2]; ! origParams[0] = new Parameter(); ! origParams[0].SqlType = new SqlTypes.Int32SqlType(); ! origParams[0].Name = "OP1"; - origParams[1] = new Parameter(); - origParams[1].SqlType = new SqlTypes.Int64SqlType(); - origParams[1].Name = "OP2"; - sqlBuilder.Add("UPDATE tablename set param0 = ") .Add(origParams[0]) --- 166,173 ---- Parameter[] origParams = new Parameter[2]; ! origParams[0] = new Parameter( "OP1", new SqlTypes.Int32SqlType() ); ! ! origParams[1] = new Parameter( "OP2", new SqlTypes.Int64SqlType() ); sqlBuilder.Add("UPDATE tablename set param0 = ") .Add(origParams[0]) *************** *** 145,150 **** // modify the first parameter of the clone to ensure they are not the same cloned.SqlParts[0] = "UPDATE changedtablename set param0 = "; ! Parameter lastParamPart = (Parameter)cloned.SqlParts[3]; ! lastParamPart.Name = "modifiedOP2"; Assert.IsTrue(cloned.ToString()!=original.ToString(), "Should not be the same ToString()"); --- 189,193 ---- // modify the first parameter of the clone to ensure they are not the same cloned.SqlParts[0] = "UPDATE changedtablename set param0 = "; ! cloned.SqlParts[3] = new Parameter( "modifiedOP2" ); Assert.IsTrue(cloned.ToString()!=original.ToString(), "Should not be the same ToString()"); Index: SqlSelectBuilderFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlSelectBuilderFixture.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** SqlSelectBuilderFixture.cs 17 Jan 2005 03:40:53 -0000 1.5 --- SqlSelectBuilderFixture.cs 30 Jan 2005 19:39:52 -0000 1.6 *************** *** 65,73 **** Assert.AreEqual(1, numOfParams, "One parameter"); ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.Int64SqlType(); ! firstParam.TableAlias = "select_test_alias"; ! firstParam.Name = "identity_column"; ! Assert.AreEqual(firstParam.SqlType.DbType, expectedParam.SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.TableAlias, expectedParam.TableAlias, "First Parameter TableAlias"); --- 65,69 ---- Assert.AreEqual(1, numOfParams, "One parameter"); ! Parameter firstParam = new Parameter( "identity_column", "select_test_alias", new SqlTypes.Int64SqlType() ); Assert.AreEqual(firstParam.SqlType.DbType, expectedParam.SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.TableAlias, expectedParam.TableAlias, "First Parameter TableAlias"); Index: SqlInsertBuilderFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlInsertBuilderFixture.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SqlInsertBuilderFixture.cs 17 Jan 2005 03:40:53 -0000 1.4 --- SqlInsertBuilderFixture.cs 30 Jan 2005 19:39:52 -0000 1.5 *************** *** 52,63 **** Assert.AreEqual(2, numOfParameters, "Two parameters"); ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.Int32SqlType(); ! firstParam.Name = "intColumn"; ! ! Parameter secondParam = new Parameter(); ! secondParam.SqlType = new SqlTypes.Int64SqlType(); ! secondParam.Name = "longColumn"; ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "First Parameter Name"); --- 52,59 ---- Assert.AreEqual(2, numOfParameters, "Two parameters"); ! Parameter firstParam = new Parameter( "intColumn", new SqlTypes.Int32SqlType() ); ! ! Parameter secondParam = new Parameter( "longColumn", new SqlTypes.Int64SqlType() ); ! Assert.AreEqual(firstParam.SqlType.DbType, actualParams[0].SqlType.DbType, "First Parameter Type"); Assert.AreEqual(firstParam.Name, actualParams[0].Name, "First Parameter Name"); |
From: Michael D. <mik...@us...> - 2005-01-30 19:40:05
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv536/NHibernate.Test/ExpressionTest Modified Files: BetweenExpressionFixture.cs InExpressionFixture.cs InsensitiveLikeExpressionFixture.cs NotExpressionFixture.cs SimpleExpressionFixture.cs SQLExpressionFixture.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Added some test for Equals method of Parameter. Index: BetweenExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/BetweenExpressionFixture.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** BetweenExpressionFixture.cs 19 Jul 2004 03:25:25 -0000 1.2 --- BetweenExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.3 *************** *** 31,44 **** Parameter[] expectedParams = new Parameter[2]; ! Parameter firstBetweenParam = new Parameter(); ! firstBetweenParam.SqlType = new SqlTypes.Int32SqlType(); ! firstBetweenParam.TableAlias = "simple_alias"; ! firstBetweenParam.Name = "count__lo"; expectedParams[0] = firstBetweenParam; ! Parameter secondBetweenParam = new Parameter(); ! secondBetweenParam.SqlType = new SqlTypes.Int32SqlType(); ! secondBetweenParam.TableAlias = "simple_alias"; ! secondBetweenParam.Name = "count__hi"; expectedParams[1] = secondBetweenParam; --- 31,38 ---- Parameter[] expectedParams = new Parameter[2]; ! Parameter firstBetweenParam = new Parameter( "count__lo", "simple_alias", new SqlTypes.Int32SqlType() ); expectedParams[0] = firstBetweenParam; ! Parameter secondBetweenParam = new Parameter( "count__hi", "simple_alias", new SqlTypes.Int32SqlType() ); expectedParams[1] = secondBetweenParam; Index: InExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/InExpressionFixture.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** InExpressionFixture.cs 19 Jul 2004 03:25:25 -0000 1.2 --- InExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.3 *************** *** 35,42 **** for(int i = 0 ; i < expectedParams.Length; i++) { ! Parameter param = new Parameter(); ! param.SqlType = new SqlTypes.Int32SqlType(); ! param.TableAlias = "simple_alias"; ! param.Name = "count_" + "_" + i; expectedParams[i] = param; } --- 35,39 ---- for(int i = 0 ; i < expectedParams.Length; i++) { ! Parameter param = new Parameter( "count_" + "_" + i, "simple_alias", new SqlTypes.Int32SqlType() ); expectedParams[i] = param; } Index: InsensitiveLikeExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/InsensitiveLikeExpressionFixture.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** InsensitiveLikeExpressionFixture.cs 19 Jul 2004 03:25:25 -0000 1.2 --- InsensitiveLikeExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.3 *************** *** 32,40 **** Parameter[] expectedParams = new Parameter[1]; ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.StringSqlType(); ! firstParam.TableAlias = "simple_alias"; ! firstParam.Name = "address"; ! expectedParams[0] = firstParam; --- 32,36 ---- Parameter[] expectedParams = new Parameter[1]; ! Parameter firstParam = new Parameter( "address", "simple_alias", new SqlTypes.StringSqlType() ); expectedParams[0] = firstParam; Index: SQLExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/SQLExpressionFixture.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SQLExpressionFixture.cs 17 Jan 2005 03:40:51 -0000 1.2 --- SQLExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.3 *************** *** 57,63 **** Parameter[] expectedParams = new Parameter[1]; ! Parameter firstAndParam = new Parameter(); ! firstAndParam.SqlType = new SqlTypes.StringSqlType(); ! firstAndParam.Name = "address"; expectedParams[0] = firstAndParam; --- 57,61 ---- Parameter[] expectedParams = new Parameter[1]; ! Parameter firstAndParam = new Parameter( "address", new SqlTypes.StringSqlType() ); expectedParams[0] = firstAndParam; Index: SimpleExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/SimpleExpressionFixture.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** SimpleExpressionFixture.cs 18 Nov 2004 02:47:00 -0000 1.4 --- SimpleExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.5 *************** *** 42,50 **** // type="String(200)" -> in the mapping file it is now defined as // type="String" length="200" ! Parameter firstAndParam = new Parameter(); ! firstAndParam.SqlType = new SqlTypes.StringSqlType(); ! firstAndParam.TableAlias = "simple_alias"; ! firstAndParam.Name = "address"; ! expectedParams[0] = firstAndParam; --- 42,46 ---- // type="String(200)" -> in the mapping file it is now defined as // type="String" length="200" ! Parameter firstAndParam = new Parameter( "address", "simple_alias", new SqlTypes.StringSqlType() ); expectedParams[0] = firstAndParam; *************** *** 83,91 **** Parameter[] expectedParams = new Parameter[1]; ! Parameter firstAndParam = new Parameter(); ! firstAndParam.SqlType = new SqlTypes.DateTimeSqlType(); ! firstAndParam.TableAlias = "simple_alias"; ! firstAndParam.Name = "date_"; ! expectedParams[0] = firstAndParam; --- 79,83 ---- Parameter[] expectedParams = new Parameter[1]; ! Parameter firstAndParam = new Parameter( "date_", "simple_alias", new SqlTypes.DateTimeSqlType() ); expectedParams[0] = firstAndParam; Index: NotExpressionFixture.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate.Test/ExpressionTest/NotExpressionFixture.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NotExpressionFixture.cs 19 Jul 2004 03:25:25 -0000 1.2 --- NotExpressionFixture.cs 30 Jan 2005 19:39:52 -0000 1.3 *************** *** 30,38 **** string expectedSql = "not simple_alias.address = :simple_alias.address"; ! Parameter firstParam = new Parameter(); ! firstParam.SqlType = new SqlTypes.StringSqlType(); ! firstParam.TableAlias = "simple_alias"; ! firstParam.Name = "address"; ! CompareSqlStrings(sqlString, expectedSql, new Parameter[] {firstParam}); --- 30,34 ---- string expectedSql = "not simple_alias.address = :simple_alias.address"; ! Parameter firstParam = new Parameter( "address", "simple_alias", new SqlTypes.StringSqlType() ); CompareSqlStrings(sqlString, expectedSql, new Parameter[] {firstParam}); |
From: Michael D. <mik...@us...> - 2005-01-30 19:39:25
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv308/NHibernate/SqlCommand Modified Files: Parameter.cs ParameterLength.cs ParameterPrecisionScale.cs QuerySelect.cs SqlString.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Index: Parameter.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/Parameter.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Parameter.cs 31 Dec 2004 22:25:00 -0000 1.12 --- Parameter.cs 30 Jan 2005 19:39:13 -0000 1.13 *************** *** 9,13 **** { /// <summary> ! /// A lightweight object to hold what later will be converted into an IDbParameter /// for an IDbCommand. /// </summary> --- 9,13 ---- { /// <summary> ! /// An immutable Parameter that later will be converted into an IDbParameter /// for an IDbCommand. /// </summary> *************** *** 15,41 **** public class Parameter : ICloneable { ! private string tableAlias; ! private string name; private SqlType _sqlType; ! /// <summary></summary> public string Name { ! get { return name; } ! set { this.name = value; } } ! /// <summary></summary> public string TableAlias { ! get { return tableAlias; } ! set { this.tableAlias = value; } } ! /// <summary></summary> public SqlType SqlType { get { return _sqlType; } - set { _sqlType = value; } } --- 15,89 ---- public class Parameter : ICloneable { ! private string _tableAlias; ! private string _name; private SqlType _sqlType; ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! public Parameter(string name) ! : this( name, null, null ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType">The <see cref="SqlType"/> to create the parameter for.</param> ! public Parameter(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="Parameter"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType">The <see cref="SqlType"/> to create the parameter for.</param> ! public Parameter(string name, string tableAlias, SqlType sqlType) ! { ! _name = name; ! _tableAlias = tableAlias; ! _sqlType = sqlType; ! } ! ! /// <summary> ! /// Gets the name of the Parameter. ! /// </summary> ! /// <value>The name of the Parameter.</value> public string Name { ! get { return _name; } } ! /// <summary> ! /// Gets the alias for the table in the Sql statement. ! /// </summary> ! /// <value> ! /// The alias for the table in the Sql statement. ! /// </value> ! /// <remarks> ! /// TODO: Determine if this is even needed - it is not used anywhere ! /// and is just extra junk. ! /// </remarks> public string TableAlias { ! get { return _tableAlias; } } ! /// <summary> ! /// Gets the <see cref="SqlType"/> that defines the specifics of ! /// the IDbDataParameter. ! /// </summary> ! /// <value> ! /// The <see cref="SqlType"/> that defines the specifics of ! /// the IDbDataParameter. ! /// </value> public SqlType SqlType { get { return _sqlType; } } *************** *** 47,51 **** /// <param name="type">The IType to turn into Parameters</param> /// <param name="factory"></param> ! /// <returns>An Array of IParameter objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string[ ] columnNames, IType type ) { --- 95,99 ---- /// <param name="type">The IType to turn into Parameters</param> /// <param name="factory"></param> ! /// <returns>An Array of <see cref="Parameter"/> objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string[ ] columnNames, IType type ) { *************** *** 61,65 **** /// <param name="columnNames">The names of the Columns that compose the IType</param> /// <param name="type">The IType to turn into Parameters</param> ! /// <returns>An Array of IParameter objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string tableAlias, string[ ] columnNames, IType type ) { --- 109,113 ---- /// <param name="columnNames">The names of the Columns that compose the IType</param> /// <param name="type">The IType to turn into Parameters</param> ! /// <returns>An Array of <see cref="Parameter"/> objects</returns> public static Parameter[ ] GenerateParameters( ISessionFactoryImplementor factory, string tableAlias, string[ ] columnNames, IType type ) { *************** *** 72,98 **** if( sqlTypes[ i ].LengthDefined ) { ! ParameterLength param = new ParameterLength(); ! param.Length = sqlTypes[ i ].Length; parameters[ i ] = param; } else if( sqlTypes[ i ].PrecisionDefined ) { ! ParameterPrecisionScale param = new ParameterPrecisionScale(); ! param.Precision = sqlTypes[ i ].Precision; ! param.Scale = sqlTypes[ i ].Scale; parameters[ i ] = param; } else { ! parameters[ i ] = new Parameter(); } - - parameters[ i ].Name = columnNames[ i ]; - parameters[ i ].TableAlias = tableAlias; - parameters[ i ].SqlType = sqlTypes[ i ]; - } - return parameters; } --- 120,137 ---- if( sqlTypes[ i ].LengthDefined ) { ! ParameterLength param = new ParameterLength( columnNames[i], tableAlias, sqlTypes[i] ); parameters[ i ] = param; } else if( sqlTypes[ i ].PrecisionDefined ) { ! ParameterPrecisionScale param = new ParameterPrecisionScale( columnNames[i], tableAlias, sqlTypes[i] ); parameters[ i ] = param; } else { ! parameters[ i ] = new Parameter( columnNames[i], tableAlias, sqlTypes[i] ); } } return parameters; } *************** *** 101,108 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { --- 140,154 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a Parameter (not a subclass) and has the ! /// same values. ! /// </returns> ! /// <remarks> ! /// Each subclass needs to implement their own <c>Equals</c>. ! /// </remarks> public override bool Equals( object obj ) { *************** *** 121,127 **** return false; } ! //Step 3: Check each important field // these 2 fields will not be null so compare them... if( this.SqlType.Equals( rhs.SqlType ) == false || this.Name.Equals( rhs.Name ) == false ) --- 167,202 ---- return false; } ! //Step 3: Check each important field + // verify the Parameter is actually a Parameter, and not a ParameterLength + // or ParameterPrecisionScale - this ensures that rhs.Equals(lhs) and + // lhs.Equals(rhs) always returns the same result. + return this.Equals( rhs, true ); + } + + /// <summary> + /// Determines if this instance and the specified object have the + /// same values. If <c>isTypeSensitive==true</c> then <c>rhs</c> + /// has to be a <see cref="Parameter"/> and can not be a subclass. + /// </summary> + /// <param name="rhs">The <see cref="Parameter"/> to compare to this instance.</param> + /// <param name="isTypeSensitive"> + /// <c>true</c> if <c>rhs</c> has to be a <see cref="Parameter"/> and not a subclass, + /// <c>false</c> if <c>rhs</c> can be a subclass of <see cref="Parameter"/>.</param> + /// <returns> + /// <c>true</c> if the properties in <see cref="Parameter"/> are all the same. + /// </returns> + protected bool Equals(Parameter rhs, bool isTypeSensitive) + { + if( isTypeSensitive ) + { + if( typeof(Parameter)!=rhs.GetType() ) + { + return false; + } + } + + // these 2 fields will not be null so compare them... if( this.SqlType.Equals( rhs.SqlType ) == false || this.Name.Equals( rhs.Name ) == false ) *************** *** 146,152 **** /// <summary> ! /// /// </summary> ! /// <returns></returns> public override int GetHashCode() { --- 221,229 ---- /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> public override int GetHashCode() { *************** *** 159,169 **** hashCode += _sqlType.GetHashCode(); } ! if( name != null ) { ! hashCode += name.GetHashCode(); } ! if( tableAlias != null ) { ! hashCode += tableAlias.GetHashCode(); } --- 236,246 ---- hashCode += _sqlType.GetHashCode(); } ! if( _name != null ) { ! hashCode += _name.GetHashCode(); } ! if( _tableAlias != null ) { ! hashCode += _tableAlias.GetHashCode(); } *************** *** 175,179 **** public override string ToString() { ! return ( tableAlias == null || tableAlias.Length == 0 ) ? ":" + name : ":" + tableAlias + "." + name; } --- 252,256 ---- public override string ToString() { ! return ( _tableAlias == null || _tableAlias.Length == 0 ) ? ":" + _name : ":" + _tableAlias + "." + _name; } Index: SqlString.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/SqlString.cs,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** SqlString.cs 31 Dec 2004 22:25:44 -0000 1.17 --- SqlString.cs 30 Jan 2005 19:39:13 -0000 1.18 *************** *** 36,39 **** --- 36,46 ---- /// <summary></summary> + /// <remarks> + /// TODO: modify this from object[] to an ICollection so that we can + /// safely say that SqlString truly is immutable. Right now someone + /// can change the contents of the array - hence changing the SqlString + /// and throwing any place this is used as a key in a hashtable into + /// an unfindable instance. + /// </remarks> public object[ ] SqlParts { *************** *** 211,215 **** /// <summary> ! /// Gets the indexes of the Parameters in the SqlParts /// </summary> /// <value> --- 218,222 ---- /// <summary> ! /// Gets the indexes of the Parameters in the SqlParts array. /// </summary> /// <value> *************** *** 408,411 **** --- 415,428 ---- //Step 3: Check each important field + + // if they don't contain the same number of parts then we + // can exit early because they are different + if( sqlParts.Length!=rhs.SqlParts.Length ) + { + return false; + } + + // they have the same number of parts - so compare each + // part for equallity. for( int i = 0; i < sqlParts.Length; i++ ) { *************** *** 416,419 **** --- 433,437 ---- } + // nothing has been found that is different - so they are equal. return true; } Index: QuerySelect.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** QuerySelect.cs 23 Jan 2005 15:48:00 -0000 1.5 --- QuerySelect.cs 30 Jan 2005 19:39:13 -0000 1.6 *************** *** 353,358 **** if( token.Equals( StringHelper.SqlParameter ) ) { ! Parameter param = new Parameter(); ! param.Name = "placholder"; builder.Add( param ); } --- 353,357 ---- if( token.Equals( StringHelper.SqlParameter ) ) { ! Parameter param = new Parameter( "placeholder" ); builder.Add( param ); } Index: ParameterLength.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/ParameterLength.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ParameterLength.cs 31 Dec 2004 22:25:19 -0000 1.8 --- ParameterLength.cs 30 Jan 2005 19:39:13 -0000 1.9 *************** *** 1,3 **** --- 1,4 ---- using System; + using NHibernate.SqlTypes; namespace NHibernate.SqlCommand *************** *** 13,25 **** /// </remarks> [Serializable] ! public class ParameterLength : Parameter { ! private int length; ! /// <summary></summary> public int Length { ! get { return length; } ! set { length = value; } } --- 14,56 ---- /// </remarks> [Serializable] ! public sealed class ParameterLength : Parameter { ! private int _length; ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterLength"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Length ! /// to create the parameter for. ! /// </param> ! public ParameterLength(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterLength"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Length ! /// to create the parameter for. ! /// </param> ! public ParameterLength(string name, string tableAlias, SqlType sqlType) ! : base( name, tableAlias, sqlType ) ! { ! _length = sqlType.Length; ! } ! ! /// <summary> ! /// Gets the length of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The length of data the IDbDataParameter should hold.</value> public int Length { ! get { return _length; } } *************** *** 27,63 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { ! if( base.Equals( obj ) ) ! { ! ParameterLength rhs; ! // Step 2: Instance of check ! rhs = obj as ParameterLength; ! if( rhs == null ) ! { ! return false; ! } ! //Step 3: Check each important field ! return this.Length.Equals( rhs.Length ); } ! else { return false; } } ! /// <summary></summary> public override int GetHashCode() { ! unchecked ! { ! return base.GetHashCode() + length.GetHashCode(); ! } } --- 58,115 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a <see cref="ParameterLength" /> and has the ! /// same values. ! /// </returns> public override bool Equals( object obj ) { ! ParameterLength rhs = null; ! // Step1: Perform an equals test ! if( obj == this ) ! { ! return true; ! } ! // Step 2: Instance of check - don't need to worry about subclasses ! // getting in here because this class is sealed. ! rhs = obj as ParameterLength; ! if( rhs == null ) ! { ! return false; } ! ! //Step 3: Check each important field ! ! // isTypeSensitive is false because we want to check the values ! // of the fields - we know the rhs is a subclass of Parameter. ! if( this.Equals( rhs, false )==false ) { return false; } + + + return this.Length==rhs.Length; } ! /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. ! /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> ! /// <remarks> ! /// This just uses the <see cref="Parameter"/>'s <c>GetHashCode()</c> method. The ! /// compiler complains if Equals is implemented without a GetHashCode. ! /// </remarks> public override int GetHashCode() { ! // base should be sufficient enough because SqlType uses the ! // precision and scale to get the hash code ! return base.GetHashCode(); } Index: ParameterPrecisionScale.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/SqlCommand/ParameterPrecisionScale.cs,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** ParameterPrecisionScale.cs 31 Dec 2004 22:25:19 -0000 1.8 --- ParameterPrecisionScale.cs 30 Jan 2005 19:39:13 -0000 1.9 *************** *** 1,9 **** using System; namespace NHibernate.SqlCommand { /// <summary> ! /// Extension to the Parameter class that supports Parameters with ! /// a Precision and a Scale /// </summary> /// <remarks> --- 1,9 ---- using System; + using NHibernate.SqlTypes; namespace NHibernate.SqlCommand { /// <summary> ! /// An immutable Parameter that supports a Precision and a Scale /// </summary> /// <remarks> *************** *** 13,33 **** /// </remarks> [Serializable] ! public class ParameterPrecisionScale : Parameter { ! private byte precision; ! private byte scale; ! /// <summary></summary> public byte Precision { ! get { return precision; } ! set { precision = value; } } ! /// <summary></summary> public byte Scale { ! get { return scale; } ! set { scale = value; } } --- 13,66 ---- /// </remarks> [Serializable] ! public sealed class ParameterPrecisionScale : Parameter { ! private byte _precision; ! private byte _scale; ! ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterPrecisionScale"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Precision & Scale ! /// to create the parameter for. ! /// </param> ! public ParameterPrecisionScale(string name, SqlType sqlType) ! : this( name, null, sqlType ) ! { ! } ! /// <summary> ! /// Initializes a new instance of <see cref="ParameterPrecisionScale"/> class. ! /// </summary> ! /// <param name="name">The name of the parameter.</param> ! /// <param name="tableAlias">The Alias to use for the table.</param> ! /// <param name="sqlType"> ! /// The <see cref="SqlType"/> that contains a Precision & Scale ! /// to create the parameter for. ! /// </param> ! public ParameterPrecisionScale(string name, string tableAlias, SqlType sqlType ) ! : base( name, tableAlias, sqlType ) ! { ! _precision = sqlType.Precision; ! _scale = sqlType.Scale; ! } ! ! /// <summary> ! /// Gets the precision of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The precision of data the IDbDataParameter should hold.</value> public byte Precision { ! get { return _precision; } } ! /// <summary> ! /// Gets the scale of data the IDbDataParameter should hold. ! /// </summary> ! /// <value>The scale of data the IDbDataParameter should hold.</value> public byte Scale { ! get { return _scale; } } *************** *** 35,72 **** /// <summary> ! /// /// </summary> ! /// <param name="obj"></param> ! /// <returns></returns> public override bool Equals( object obj ) { ! if( base.Equals( obj ) ) ! { ! ParameterPrecisionScale rhs; ! // Step 2: Instance of check ! rhs = obj as ParameterPrecisionScale; ! if( rhs == null ) ! { ! return false; ! } ! //Step 3: Check each important field ! return this.Precision == rhs.Precision ! && this.Scale == rhs.Scale; } ! else { return false; } } ! /// <summary></summary> public override int GetHashCode() { ! unchecked ! { ! return base.GetHashCode() + precision.GetHashCode() + scale.GetHashCode(); ! } } --- 68,125 ---- /// <summary> ! /// Determines wether this instance and the specified object ! /// are the same Type and have the same values. /// </summary> ! /// <param name="obj">An object to compare to this instance.</param> ! /// <returns> ! /// <c>true</c> if the object is a <see cref="ParameterPrecisionScale" /> and has the ! /// same values. ! /// </returns> public override bool Equals( object obj ) { ! ParameterPrecisionScale rhs = null; ! // Step1: Perform an equals test ! if( obj == this ) ! { ! return true; ! } ! // Step 2: Instance of check - don't need to worry about subclasses ! // getting in here because this class is sealed. ! rhs = obj as ParameterPrecisionScale; ! if( rhs == null ) ! { ! return false; } ! ! //Step 3: Check each important field ! ! // isTypeSensitive is false because we want to check the values ! // of the fields - we know the rhs is a subclass of Parameter. ! if( this.Equals( rhs, false )==false ) { return false; } + + return this.Precision == rhs.Precision + && this.Scale == rhs.Scale; } ! /// <summary> ! /// Gets a hash code based on the SqlType, Name, and TableAlias properties. ! /// </summary> ! /// <returns> ! /// An <see cref="Int32"/> value for the hash code. ! /// </returns> ! /// <remarks> ! /// This just uses the <see cref="Parameter"/>'s <c>GetHashCode()</c> method. The ! /// compiler complains if Equals is implemented without a GetHashCode. ! /// </remarks> public override int GetHashCode() { ! // base should be sufficient enough because SqlType factors ! // in the Precision and Scale to the hash code. ! return base.GetHashCode(); } |
From: Michael D. <mik...@us...> - 2005-01-30 19:39:23
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Id In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv308/NHibernate/Id Modified Files: CounterGenerator.cs TableGenerator.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Index: TableGenerator.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Id/TableGenerator.cs,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** TableGenerator.cs 16 Jan 2005 14:43:00 -0000 1.14 --- TableGenerator.cs 30 Jan 2005 19:39:12 -0000 1.15 *************** *** 82,92 **** // build the sql string for the Update since it uses parameters ! Parameter setParam = new Parameter(); ! setParam.Name = columnName; ! setParam.SqlType = new Int32SqlType(); ! ! Parameter whereParam = new Parameter(); ! whereParam.Name = columnName; ! whereParam.SqlType = new Int32SqlType(); SqlStringBuilder builder = new SqlStringBuilder(); --- 82,87 ---- // build the sql string for the Update since it uses parameters ! Parameter setParam = new Parameter( columnName, new Int32SqlType() ); ! Parameter whereParam = new Parameter( columnName, new Int32SqlType() ); SqlStringBuilder builder = new SqlStringBuilder(); Index: CounterGenerator.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Id/CounterGenerator.cs,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** CounterGenerator.cs 15 Jan 2005 21:16:12 -0000 1.4 --- CounterGenerator.cs 30 Jan 2005 19:39:12 -0000 1.5 *************** *** 10,14 **** public class CounterGenerator : IIdentifierGenerator { ! private static short counter = ( short ) 0; /// <summary></summary> --- 10,15 ---- public class CounterGenerator : IIdentifierGenerator { ! // (short)0 by default ! private static short counter; /// <summary></summary> |
From: Michael D. <mik...@us...> - 2005-01-30 19:39:23
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv308/NHibernate/Impl Modified Files: BatcherImpl.cs Log Message: Parameter classes are now immutable. All values must be set in the ctor. Index: BatcherImpl.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Impl/BatcherImpl.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** BatcherImpl.cs 23 Jan 2005 15:53:52 -0000 1.15 --- BatcherImpl.cs 30 Jan 2005 19:39:12 -0000 1.16 *************** *** 234,238 **** Prepare( cmd ); ! ; IDataReader reader; --- 234,238 ---- Prepare( cmd ); ! IDataReader reader; |