From: Paul H. <pha...@us...> - 2005-03-14 18:52:10
|
Update of /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6406/nhibernate/src/NHibernate/Collection Modified Files: AbstractCollectionPersister.cs ArrayHolder.cs Bag.cs BasicCollectionPersister.cs IdentifierBag.cs List.cs Map.cs OneToManyPersister.cs PersistentCollection.cs Set.cs Log Message: Refactored as per 2.1 Index: OneToManyPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/OneToManyPersister.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** OneToManyPersister.cs 8 Mar 2005 16:26:12 -0000 1.2 --- OneToManyPersister.cs 14 Mar 2005 18:51:48 -0000 1.3 *************** *** 142,146 **** /// <param name="session"></param> /// <returns></returns> ! protected int DoUpdateRows( object id, PersistentCollection collection, ISessionImplementor session ) { // we finish all the "removes" first to take care of possible unique --- 142,146 ---- /// <param name="session"></param> /// <returns></returns> ! protected override int DoUpdateRows( object id, PersistentCollection collection, ISessionImplementor session ) { // we finish all the "removes" first to take care of possible unique *************** *** 236,241 **** { // Super impl will ignore suffix for collection columns! ! //return SelectFragment( alias ).Append( StringHelper.CommaSpace ); ! return SelectFragment( alias ); } else --- 236,240 ---- { // Super impl will ignore suffix for collection columns! ! return SelectFragment( alias ).Append( StringHelper.CommaSpace ).Append( ojl.SelectFragment( alias, suffix ) ); } else Index: Map.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Map.cs,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** Map.cs 1 Mar 2005 16:24:44 -0000 1.21 --- Map.cs 14 Mar 2005 18:51:48 -0000 1.22 *************** *** 43,47 **** ArrayList result = new ArrayList( sn.Values.Count ); result.AddRange( sn.Values ); ! PersistentCollection.IdentityRemoveAll( result, map.Values, session ); return result; } --- 43,47 ---- ArrayList result = new ArrayList( sn.Values.Count ); result.AddRange( sn.Values ); ! PersistentCollection.IdentityRemoveAll( result, map.Values, Session ); return result; } *************** *** 61,65 **** foreach( DictionaryEntry entry in map ) { ! if( elementType.IsDirty( entry.Value, xmap[ entry.Key ], session ) ) { return false; --- 61,65 ---- foreach( DictionaryEntry entry in map ) { ! if( elementType.IsDirty( entry.Value, xmap[ entry.Key ], Session ) ) { return false; *************** *** 96,100 **** this.map = map; SetInitialized(); ! directlyAccessible = true; } --- 96,100 ---- this.map = map; SetInitialized(); ! DirectlyAccessible = true; } *************** *** 291,296 **** { DictionaryEntry e = ( DictionaryEntry ) entry; ! persister.WriteElement( st, e.Value, writeOrder, session ); ! persister.WriteIndex( st, e.Key, writeOrder, session ); } --- 291,296 ---- { DictionaryEntry e = ( DictionaryEntry ) entry; ! persister.WriteElement( st, e.Value, writeOrder, Session ); ! persister.WriteIndex( st, e.Key, writeOrder, Session ); } *************** *** 304,309 **** public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); ! object index = persister.ReadIndex( rs, session ); map[ index ] = element; --- 304,309 ---- public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, Session); ! object index = persister.ReadIndex( rs, Session ); map[ index ] = element; *************** *** 334,339 **** 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(); --- 334,339 ---- 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(); *************** *** 351,356 **** foreach( DictionaryEntry e in map ) { ! result[ i++ ] = persister.IndexType.Disassemble( e.Key, session ); ! result[ i++ ] = persister.ElementType.Disassemble( e.Value, session ); } return result; --- 351,356 ---- foreach( DictionaryEntry e in map ) { ! result[ i++ ] = persister.IndexType.Disassemble( e.Key, Session ); ! result[ i++ ] = persister.ElementType.Disassemble( e.Value, Session ); } return result; *************** *** 402,406 **** DictionaryEntry e = ( DictionaryEntry ) entry; object snValue = sn[ e.Key ]; ! return ( e.Value != null && snValue != null && elemType.IsDirty( snValue, e.Value, session ) ); } --- 402,406 ---- DictionaryEntry e = ( DictionaryEntry ) entry; object snValue = sn[ e.Key ]; ! return ( e.Value != null && snValue != null && elemType.IsDirty( snValue, e.Value, Session ) ); } Index: Set.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Set.cs,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** Set.cs 1 Mar 2005 16:24:44 -0000 1.26 --- Set.cs 14 Mar 2005 18:51:49 -0000 1.27 *************** *** 61,69 **** public override ICollection GetOrphans( object snapshot ) { IDictionary sn = ( IDictionary ) snapshot; ArrayList result = new ArrayList( sn.Keys.Count ); result.AddRange( sn.Keys ); ! PersistentCollection.IdentityRemoveAll( result, internalSet, session ); return result; } --- 61,73 ---- public override ICollection GetOrphans( object snapshot ) { + /* IDictionary sn = ( IDictionary ) snapshot; ArrayList result = new ArrayList( sn.Keys.Count ); result.AddRange( sn.Keys ); ! PersistentCollection.IdentityRemoveAll( result, internalSet, Session ); return result; + */ + IDictionary sn = ( IDictionary ) snapshot; + return PersistentCollection.GetOrphans( sn.Keys, internalSet, Session ); } *************** *** 84,88 **** { object oldValue = snapshot[ obj ]; ! if( oldValue == null || elementType.IsDirty( oldValue, obj, session ) ) { return false; --- 88,92 ---- { object oldValue = snapshot[ obj ]; ! if( oldValue == null || elementType.IsDirty( oldValue, obj, Session ) ) { return false; *************** *** 124,128 **** internalSet = collection; SetInitialized(); ! directlyAccessible = true; } --- 128,132 ---- internalSet = collection; SetInitialized(); ! DirectlyAccessible = true; } *************** *** 139,143 **** for( int i = 0; i < array.Length; i += 2 ) { ! internalSet.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } SetInitialized(); --- 143,147 ---- for( int i = 0; i < array.Length; i += 2 ) { ! internalSet.Add( persister.ElementType.Assemble( array[ i ], Session, owner ) ); } SetInitialized(); *************** *** 391,395 **** public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, session ); } --- 395,399 ---- public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, Session ); } *************** *** 403,407 **** public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, session); tempList.Add( element ); return element; --- 407,411 ---- public override object ReadFrom( IDataReader rs, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement(rs, owner, Session); tempList.Add( element ); return element; *************** *** 423,434 **** /// Set. /// </summary> ! public override void EndRead() { internalSet.AddAll( tempList ); tempList = null; SetInitialized(); ! // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) ! IsCacheable = true; ! // return true; } --- 427,436 ---- /// Set. /// </summary> ! public override bool EndRead() { internalSet.AddAll( tempList ); tempList = null; SetInitialized(); ! return true; } *************** *** 453,457 **** foreach( object obj in internalSet ) { ! result[ i++ ] = persister.ElementType.Disassemble( obj, session ); } return result; --- 455,459 ---- foreach( object obj in internalSet ) { ! result[ i++ ] = persister.ElementType.Disassemble( obj, Session ); } return result; *************** *** 483,487 **** object oldKey = snapshot[ obj ]; ! if( oldKey != null && elemType.IsDirty( obj, oldKey, session ) ) { deletes.Add( obj ); --- 485,489 ---- object oldKey = snapshot[ obj ]; ! if( oldKey != null && elemType.IsDirty( obj, oldKey, Session ) ) { deletes.Add( obj ); *************** *** 507,511 **** // assuming the user implements equals() properly, as required by the Set // contract! ! return oldKey == null || elemType.IsDirty( oldKey, entry, session ); } --- 509,513 ---- // assuming the user implements equals() properly, as required by the Set // contract! ! return oldKey == null || elemType.IsDirty( oldKey, entry, Session ); } *************** *** 544,549 **** return true; } - - } } \ No newline at end of file --- 546,549 ---- Index: List.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/List.cs,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** List.cs 1 Mar 2005 16:24:44 -0000 1.20 --- List.cs 14 Mar 2005 18:51:48 -0000 1.21 *************** *** 40,44 **** ArrayList result = new ArrayList( sn.Count ); result.AddRange( sn ); ! PersistentCollection.IdentityRemoveAll( result, list, session ); return result; } --- 40,44 ---- ArrayList result = new ArrayList( sn.Count ); result.AddRange( sn ); ! PersistentCollection.IdentityRemoveAll( result, list, Session ); return result; } *************** *** 58,62 **** for( int i = 0; i < list.Count; i++ ) { ! if( elementType.IsDirty( list[ i ], sn[ i ], session ) ) { return false; --- 58,62 ---- for( int i = 0; i < list.Count; i++ ) { ! if( elementType.IsDirty( list[ i ], sn[ i ], Session ) ) { return false; *************** *** 93,97 **** this.list = list; SetInitialized(); ! directlyAccessible = true; } --- 93,97 ---- this.list = list; SetInitialized(); ! DirectlyAccessible = true; } *************** *** 301,306 **** public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, session ); ! persister.WriteIndex( st, i, writeOrder, session ); } --- 301,306 ---- public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, Session ); ! persister.WriteIndex( st, i, writeOrder, Session ); } *************** *** 314,319 **** public override object ReadFrom( IDataReader rs, ICollectionPersister 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++ ) --- 314,319 ---- public override object ReadFrom( IDataReader rs, ICollectionPersister 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++ ) *************** *** 344,348 **** for( int i = 0; i < array.Length; i++ ) { ! list.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } SetInitialized(); --- 344,348 ---- for( int i = 0; i < array.Length; i++ ) { ! list.Add( persister.ElementType.Assemble( array[ i ], Session, owner ) ); } SetInitialized(); *************** *** 360,364 **** for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( list[ i ], session ); } return result; --- 360,364 ---- for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( list[ i ], Session ); } return result; *************** *** 420,424 **** { IList sn = ( IList ) GetSnapshot(); ! return i < sn.Count && sn[ i ] != null && list[ i ] != null && elemType.IsDirty( list[ i ], sn[ i ], session ); } --- 420,424 ---- { IList sn = ( IList ) GetSnapshot(); ! return i < sn.Count && sn[ i ] != null && list[ i ] != null && elemType.IsDirty( list[ i ], sn[ i ], Session ); } Index: ArrayHolder.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/ArrayHolder.cs,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** ArrayHolder.cs 1 Mar 2005 16:24:44 -0000 1.18 --- ArrayHolder.cs 14 Mar 2005 18:51:48 -0000 1.19 *************** *** 84,88 **** for( int i = 0; i < sn.Length; i++ ) { ! PersistentCollection.IdentityRemove( result, arr[ i ], session ); } return result; --- 84,88 ---- for( int i = 0; i < sn.Length; i++ ) { ! PersistentCollection.IdentityRemove( result, arr[ i ], Session ); } return result; *************** *** 135,139 **** for( int i = 0; i < xlen; i++ ) { ! if( elementType.IsDirty( snapshot.GetValue( i ), array.GetValue( i ), session ) ) { return false; --- 135,139 ---- for( int i = 0; i < xlen; i++ ) { ! if( elementType.IsDirty( snapshot.GetValue( i ), array.GetValue( i ), Session ) ) { return false; *************** *** 177,182 **** public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, session ); ! persister.WriteIndex( st, i, writeOrder, session ); } --- 177,182 ---- public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, Session ); ! persister.WriteIndex( st, i, writeOrder, Session ); } *************** *** 190,195 **** public override object ReadFrom( IDataReader rs, ICollectionPersister 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++ ) { --- 190,195 ---- public override object ReadFrom( IDataReader rs, ICollectionPersister 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++ ) { *************** *** 224,228 **** /// array. /// </summary> ! public override void EndRead() { SetInitialized(); --- 224,228 ---- /// array. /// </summary> ! public override bool EndRead() { SetInitialized(); *************** *** 236,242 **** tempList = null; ! // TODO: h2.1 synch to return bool instead of IsCacheable (NH specific code) ! IsCacheable = true; ! //return true; } --- 236,240 ---- tempList = null; ! return true; } *************** *** 279,283 **** for( int i = 0; i < cached.Length; i++ ) { ! array.SetValue( persister.ElementType.Assemble( cached[ i ], session, owner ), i ); } SetInitialized(); --- 277,281 ---- for( int i = 0; i < cached.Length; i++ ) { ! array.SetValue( persister.ElementType.Assemble( cached[ i ], Session, owner ), i ); } SetInitialized(); *************** *** 295,299 **** for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( array.GetValue( i ), session ); } return result; --- 293,297 ---- for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( array.GetValue( i ), Session ); } return result; *************** *** 371,375 **** sn.GetValue( i ) != null && array.GetValue( i ) != null && ! elemType.IsDirty( array.GetValue( i ), sn.GetValue( i ), session ); } --- 369,373 ---- sn.GetValue( i ) != null && array.GetValue( i ) != null && ! elemType.IsDirty( array.GetValue( i ), sn.GetValue( i ), Session ); } Index: Bag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/Bag.cs,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Bag.cs 1 Mar 2005 16:24:44 -0000 1.15 --- Bag.cs 14 Mar 2005 18:51:48 -0000 1.16 *************** *** 42,46 **** SetInitialized(); ! directlyAccessible = true; } --- 42,46 ---- SetInitialized(); ! DirectlyAccessible = true; } *************** *** 91,95 **** public override object ReadFrom( IDataReader reader, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, session ); bag.Add( element ); return element; --- 91,95 ---- public override object ReadFrom( IDataReader reader, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, Session ); bag.Add( element ); return element; *************** *** 106,110 **** public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, session ); } --- 106,110 ---- public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, Session ); } *************** *** 188,192 **** ArrayList result = new ArrayList(); result.AddRange( sn ); ! PersistentCollection.IdentityRemoveAll( result, bag, session ); return result; } --- 188,192 ---- ArrayList result = new ArrayList(); result.AddRange( sn ); ! PersistentCollection.IdentityRemoveAll( result, bag, Session ); return result; } *************** *** 204,208 **** for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( bag[ i ], session ); } --- 204,208 ---- for( int i = 0; i < length; i++ ) { ! result[ i ] = persister.ElementType.Disassemble( bag[ i ], Session ); } *************** *** 222,226 **** for( int i = 0; i < array.Length; i++ ) { ! bag.Add( persister.ElementType.Assemble( array[ i ], session, owner ) ); } SetInitialized(); --- 222,226 ---- for( int i = 0; i < array.Length; i++ ) { ! bag.Add( persister.ElementType.Assemble( array[ i ], Session, owner ) ); } SetInitialized(); *************** *** 545,550 **** return entry != null; } - - } } \ No newline at end of file --- 545,548 ---- Index: BasicCollectionPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/BasicCollectionPersister.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** BasicCollectionPersister.cs 8 Mar 2005 16:26:12 -0000 1.2 --- BasicCollectionPersister.cs 14 Mar 2005 18:51:48 -0000 1.3 *************** *** 146,150 **** /// <param name="session"></param> /// <returns></returns> ! protected int DoUpdateRows( object id, PersistentCollection collection, ISessionImplementor session ) { try --- 146,150 ---- /// <param name="session"></param> /// <returns></returns> ! protected override int DoUpdateRows( object id, PersistentCollection collection, ISessionImplementor session ) { try *************** *** 164,173 **** st = session.Batcher.PrepareBatchCommand( SqlUpdateRowString ); } - WriteKey( st, id, false, session ); if ( !HasIdentifier ) { WriteKey( st, id, true, session ); } ! collection.WriteTo( st, this, entry, i, false ); session.Batcher.AddToBatch( 1 ); count++; --- 164,172 ---- st = session.Batcher.PrepareBatchCommand( SqlUpdateRowString ); } if ( !HasIdentifier ) { WriteKey( st, id, true, session ); } ! collection.WriteTo( st, this, entry, i, true ); session.Batcher.AddToBatch( 1 ); count++; *************** *** 235,240 **** public override SqlString SelectFragment( string alias, string suffix, bool includeCollectionColumns ) { ! // TODO: Changed from Null to SqlString( string.Empty ) as per Java ! return includeCollectionColumns ? SelectFragment( alias ) : new SqlString( string.Empty ) ; } } --- 234,238 ---- public override SqlString SelectFragment( string alias, string suffix, bool includeCollectionColumns ) { ! return includeCollectionColumns ? SelectFragment( alias ) : null ; } } Index: AbstractCollectionPersister.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/AbstractCollectionPersister.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** AbstractCollectionPersister.cs 8 Mar 2005 16:26:12 -0000 1.2 --- AbstractCollectionPersister.cs 14 Mar 2005 18:51:45 -0000 1.3 *************** *** 382,386 **** public string GetSQLWhereString( string alias ) { ! if( sqlWhereStringTemplate != null ) { return StringHelper.Replace( sqlWhereStringTemplate, Template.Placeholder, alias ); --- 382,386 ---- public string GetSQLWhereString( string alias ) { ! if( hasWhere ) { return StringHelper.Replace( sqlWhereStringTemplate, Template.Placeholder, alias ); *************** *** 929,1036 **** /// /// </summary> - /// <param name="id"></param> - /// <param name="collection"></param> - /// <param name="session"></param> - public void Update( object id, PersistentCollection collection, ISessionImplementor session ) - { - IDbCommand st = null; - ICollection entries = collection.Entries(); - int i = 0; - try - { - foreach( object entry in entries ) - { - if( collection.NeedsUpdating( entry, i, elementType ) ) - { - if( st == null ) - { - st = session.Batcher.PrepareBatchCommand( SqlUpdateRowString ); - } - if( !hasIdentifier ) - { - WriteKey( st, id, true, session ); - } - collection.WriteTo( st, this, entry, i, true ); - session.Batcher.AddToBatch( 1 ); - } - i++; - } - } - // TODO: change to SqlException - catch( Exception e ) - { - session.Batcher.AbortBatch( e ); - throw; - } - } - - /// <summary> - /// - /// </summary> - /// <param name="id"></param> - /// <param name="collection"></param> - /// <param name="session"></param> - public void UpdateOneToMany( object id, PersistentCollection collection, ISessionImplementor session ) - { - IDbCommand rmvst = null; - int i = 0; - ICollection entries = collection.Entries(); - try - { - foreach( object entry in entries ) - { - if( collection.NeedsUpdating( entry, i, elementType ) ) - { - if( rmvst == null ) - { - rmvst = session.Batcher.PrepareBatchCommand( SqlDeleteRowString ); - } - WriteKey( rmvst, id, false, session ); - WriteIndex( rmvst, collection.GetIndex( entry, i ), false, session ); - session.Batcher.AddToBatch( -1 ); - } - i++; - } - } - // TODO: change to SqlException - catch( Exception e ) - { - session.Batcher.AbortBatch( e ); - throw; - } - - // finish all the removes first to take care of possible unique constraints - // and so that we can take advantage of batching - IDbCommand insst = null; - i = 0; - entries = collection.Entries(); - try - { - foreach( object entry in entries ) - { - if( collection.NeedsUpdating( entry, i, elementType ) ) - { - if( insst == null ) - { - insst = session.Batcher.PrepareBatchCommand( SqlInsertRowString ); - } - WriteKey( insst, id, false, session ); - collection.WriteTo( insst, this, entry, i, false ); - session.Batcher.AddToBatch( 1 ); - } - i++; - } - } - //TODO: change to SqlException - catch( Exception e ) - { - session.Batcher.AbortBatch( e ); - throw; - } - } - - /// <summary> - /// - /// </summary> /// <param name="collection"></param> /// <param name="id"></param> --- 929,932 ---- *************** *** 1042,1061 **** if( log.IsDebugEnabled ) { ! log.Debug( "Updating rows of collection: " + role + "#" + id ); } // update all the modified entries ! if( IsOneToMany ) ! { ! UpdateOneToMany( id, collection, session ); ! } ! else ! { ! Update( id, collection, session ); ! } if( log.IsDebugEnabled ) { ! log.Debug( "done updating rows" ); } } --- 938,950 ---- if( log.IsDebugEnabled ) { ! log.Debug( string.Format( "Updating rows of collection: {0}#{1}", role, id ) ); } // update all the modified entries ! int count = DoUpdateRows( id, collection, session ); if( log.IsDebugEnabled ) { ! log.Debug( string.Format( "done updating rows: {0} updated", count ) ); } } *************** *** 1065,1068 **** --- 954,966 ---- /// /// </summary> + /// <param name="key"></param> + /// <param name="collection"></param> + /// <param name="session"></param> + /// <returns></returns> + protected abstract int DoUpdateRows( object key, PersistentCollection collection, ISessionImplementor session ); + + /// <summary> + /// + /// </summary> /// <param name="collection"></param> /// <param name="id"></param> *************** *** 1085,1095 **** try { foreach( object entry in entries ) { - // This is as per the java, don't get the logic of this, it will be reinitialised each time round the loop anyway - IDbCommand st = null; if( collection.NeedsInserting( entry, i, elementType ) ) { - // This is as per the java, don't get the logic of this, it will be reinitialised each time round the loop anyway if( st == null ) { --- 983,992 ---- try { + // Moved the IDbCommand outside the loop otherwise, don't get the logic of this, it will be reinitialised each time round + IDbCommand st = null; foreach( object entry in entries ) { if( collection.NeedsInserting( entry, i, elementType ) ) { if( st == null ) { *************** *** 1258,1262 **** { SelectFragment frag = new SelectFragment( factory.Dialect ) ! .SetSuffix( String.Empty ) .AddColumns( alias, keyColumnNames, keyColumnAliases ) .AddColumns( alias, elementColumnNames, elementColumnAliases ); --- 1155,1159 ---- { SelectFragment frag = new SelectFragment( factory.Dialect ) ! .SetSuffix( String.Empty ) //always ignore suffix for collection columns .AddColumns( alias, keyColumnNames, keyColumnAliases ) .AddColumns( alias, elementColumnNames, elementColumnAliases ); Index: PersistentCollection.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/PersistentCollection.cs,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** PersistentCollection.cs 1 Mar 2005 16:24:44 -0000 1.22 --- PersistentCollection.cs 14 Mar 2005 18:51:49 -0000 1.23 *************** *** 2,5 **** --- 2,6 ---- using System.Collections; using System.Data; + using Iesi.Collections; using log4net; using NHibernate.Engine; *************** *** 10,14 **** /// <summary> /// Persistent collections are treated as value objects by Hibernate. ! /// ie. they have no independent existence beyond the object holding /// a reference to them. Unlike instances of entity classes, they are /// automatically deleted when unreferenced and automatically become --- 11,15 ---- /// <summary> /// Persistent collections are treated as value objects by Hibernate. ! /// i.e. they have no independent existence beyond the object holding /// a reference to them. Unlike instances of entity classes, they are /// automatically deleted when unreferenced and automatically become *************** *** 41,49 **** /// <summary></summary> [NonSerialized] ! protected ISessionImplementor session; ! /// <summary></summary> ! protected bool initialized; ! private bool initializing; [NonSerialized] --- 42,48 ---- /// <summary></summary> [NonSerialized] ! private ISessionImplementor session; ! private bool initialized; [NonSerialized] *************** *** 54,58 **** /// <summary></summary> [NonSerialized] ! protected bool directlyAccessible; //careful: these methods do not initialize the collection --- 53,60 ---- /// <summary></summary> [NonSerialized] ! private bool directlyAccessible; ! ! [NonSerialized] ! private bool initializing; //careful: these methods do not initialize the collection *************** *** 64,68 **** public abstract bool Empty { get; } ! /// <summary></summary> public void Read() { --- 66,72 ---- public abstract bool Empty { get; } ! /// <summary> ! /// Called by any read-only method of the collection interface ! /// </summary> public void Read() { *************** *** 70,73 **** --- 74,86 ---- } + /// <summary></summary> + protected ISessionImplementor Session + { + get { return session; } + } + + /// <summary> + /// Is the collection currently connected to an open session? + /// </summary> private bool IsConnectedToSession { *************** *** 76,107 **** /// <summary></summary> protected void Write() { Initialize( true ); ! if( IsConnectedToSession ) ! { ! session.Dirty( this ); ! } ! else ! { ! collectionSnapshot.SetDirty(); ! } } ! private bool MayQueueAdd { ! get { ! return ! !initialized && ! IsConnectedToSession && ! session.IsInverseCollection( this ); } } ! /// <summary></summary> protected bool QueueAdd( object element ) { ! if( MayQueueAdd ) { if( additions == null ) --- 89,125 ---- /// <summary></summary> + protected bool DirectlyAccessible + { + set { directlyAccessible = value; } + } + + /// <summary> + /// Called by any writer method of the collection interface + /// </summary> protected void Write() { Initialize( true ); ! collectionSnapshot.SetDirty(); } ! /// <summary> ! /// Is this collection in a state that would allow us to "queue" additions? ! /// </summary> ! private bool IsQueueAdditionEnabled { ! get { ! return !initialized && ! IsConnectedToSession && ! session.IsInverseCollection( this ); } } ! /// <summary> ! /// Queue an addition ! /// </summary> protected bool QueueAdd( object element ) { ! if( IsQueueAdditionEnabled ) { if( additions == null ) *************** *** 110,114 **** } additions.Add( element ); ! session.Dirty( this ); //needed so that we remove this collection from the JCS cache return true; } --- 128,132 ---- } additions.Add( element ); ! collectionSnapshot.SetDirty(); //needed so that we remove this collection from the JCS cache return true; } *************** *** 119,126 **** } ! /// <summary></summary> protected bool QueueAddAll( ICollection coll ) { ! if( MayQueueAdd ) { if( additions == null ) --- 137,146 ---- } ! /// <summary> ! /// Queue additions ! /// </summary> protected bool QueueAddAll( ICollection coll ) { ! if( IsQueueAdditionEnabled ) { if( additions == null ) *************** *** 137,143 **** } - //TODO: H2.0.3 new method /// <summary> ! /// /// </summary> /// <param name="coll"></param> --- 157,163 ---- } /// <summary> ! /// After reading all existing elements from the database, ! /// add the queued elements to the underlying collection. /// </summary> /// <param name="coll"></param> *************** *** 148,151 **** --- 168,172 ---- // TODO: h2.0.3 synhc - I don't see AddAll in the H code... + // NB This is needed by Set/SortedSet to fulfil ISet contract /// <summary> /// *************** *** 166,170 **** { get { return additions; } - set { additions = value; } } --- 187,190 ---- *************** *** 186,190 **** /// <summary> ! /// /// </summary> /// <param name="session"></param> --- 206,217 ---- /// <summary> ! /// Not called by Hibernate, but used by non-NET serialization, eg. SOAP libraries. ! /// </summary> ! public PersistentCollection() ! { ! } ! ! /// <summary> ! /// Not called by Hibernate, but used by non-NET serialization, eg. SOAP libraries. /// </summary> /// <param name="session"></param> *************** *** 208,220 **** } - /* - /// <summary></summary> - public virtual object GetCachedValue() - { - initialized = true; //TODO: only needed for query FETCH so should move out of here - return this; - } - */ - /// <summary> /// Override on some subclasses --- 235,238 ---- *************** *** 233,288 **** /// 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() { - // 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; ! // 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> /// Initialize the collection, if possible, wrapping any exceptions in a runtime exception --- 251,271 ---- /// to store values read from the db. /// </p> /// </remarks> ! public virtual bool EndRead() { 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> /// Initialize the collection, if possible, wrapping any exceptions in a runtime exception *************** *** 321,324 **** --- 304,316 ---- /// <summary> + /// Mark the collection as initialized. + /// </summary> + protected void SetInitialized() + { + initializing = false; + initialized = true; + } + + /// <summary> /// /// </summary> *************** *** 414,418 **** public abstract object ReadFrom( IDataReader reader, ICollectionPersister role, object owner ); - /* /// <summary> /// --- 406,409 ---- *************** *** 424,441 **** /// <param name="writeOrder"></param> public abstract void WriteTo( IDbCommand st, ICollectionPersister role, object entry, int i, bool writeOrder ); - */ - - /// <summary> - /// - /// </summary> - /// <param name="st"></param> - /// <param name="role"></param> - /// <param name="entry"></param> - /// <param name="i"></param> - /// <param name="writeOrder"></param> - /// <remarks>This is the 2.1 version, should be abstract, but trying to avoid lots of cascading changes</remarks> - public virtual void WriteTo( IDbCommand st, ICollectionPersister role, object entry, int i, bool writeOrder ) - { - } /// <summary> --- 415,418 ---- *************** *** 518,522 **** if( session == null ) throw new HibernateException("collection is not associated with any session"); if( !session.IsConnected ) throw new HibernateException("disconnected session"); ! if( !initialized ) session.InitializeCollection(this, false); } --- 495,499 ---- if( session == null ) throw new HibernateException("collection is not associated with any session"); if( !session.IsConnected ) throw new HibernateException("disconnected session"); ! if( !initialized ) session.InitializeCollection( this, false ); } *************** *** 576,580 **** public ICollection QueuedAddsCollection { ! get { return additions; } } --- 553,567 ---- public ICollection QueuedAddsCollection { ! get ! { ! if ( HasQueuedAdds ) ! { ! return additions; ! } ! else ! { ! return new ArrayList(); ! } ! } } *************** *** 586,604 **** } - // looks like it is used by IdentifierBag - /// <summary> - /// By default, no operation is performed. This provides a hook to get an identifer of the - /// collection row for <see cref="IdentifierBag"/>. - /// </summary> - /// <param name="persister">The <see cref="ICollectionPersister"/> for this Collection.</param> - /// <param name="entry"> - /// The entry to preInsert. If this is a Map this will be a DictionaryEntry. If this is - /// a List then it will be the object at that index. - /// </param> - /// <param name="i">The index of the Entry while enumerating through the Collection.</param> - public virtual void PreInsert( ICollectionPersister persister, object entry, int i ) - { - } - /// <summary> /// Called before inserting rows, to ensure that any surrogate keys are fully generated --- 573,576 ---- *************** *** 620,624 **** /// <summary> ! /// /// </summary> /// <param name="snapshot"></param> --- 592,596 ---- /// <summary> ! /// Get all "orphaned" elements /// </summary> /// <param name="snapshot"></param> *************** *** 644,647 **** --- 616,666 ---- /// /// </summary> + /// <param name="oldElements"></param> + /// <param name="currentElements"></param> + /// <param name="session"></param> + /// <returns></returns> + protected static ICollection GetOrphans( ICollection oldElements, ICollection currentElements, ISessionImplementor session ) + { + // short-circuit(s) + if ( currentElements.Count == 0 ) + { + // no new elements, the old list contains only Orphans + return oldElements; + } + if ( oldElements.Count == 0 ) + { + // no old elements, so no Orphans neither + return oldElements; + } + + // create the collection holding the orphans + IList res = new ArrayList(); + + // collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access + ISet currentIds = new HashedSet(); + foreach ( object current in currentElements ) + { + if ( session.IsSaved( current ) ) + { + currentIds.Add( session.GetEntityIdentifierIfNotUnsaved( current ) ); + } + } + + // iterate over the *old* list + foreach ( object old in oldElements ) + { + object id = session.GetEntityIdentifierIfNotUnsaved( old ); + if ( !currentIds.Contains( id ) ) + { + res.Add( old ); + } + } + + return res; + } + + /// <summary> + /// + /// </summary> /// <param name="list"></param> /// <param name="obj"></param> *************** *** 673,685 **** } - /// <summary> - /// Mark the collection as initialized. - /// </summary> - protected void SetInitialized() - { - initializing = false; - initialized = true; - } - #region - Hibernate Collection Proxy Classes --- 692,695 ---- Index: IdentifierBag.cs =================================================================== RCS file: /cvsroot/nhibernate/nhibernate/src/NHibernate/Collection/IdentifierBag.cs,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** IdentifierBag.cs 1 Mar 2005 16:24:44 -0000 1.10 --- IdentifierBag.cs 14 Mar 2005 18:51:48 -0000 1.11 *************** *** 26,33 **** public class IdentifierBag : PersistentCollection, IList { ! 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> --- 26,31 ---- public class IdentifierBag : PersistentCollection, IList { ! private IList values; //element ! private IDictionary identifiers; //index -> id /// <summary> *************** *** 48,52 **** IList list = coll as IList; ! if( list!=null ) { values = list; --- 46,50 ---- IList list = coll as IList; ! if( list != null ) { values = list; *************** *** 62,66 **** SetInitialized(); ! directlyAccessible = true; identifiers = new Hashtable(); } --- 60,64 ---- SetInitialized(); ! DirectlyAccessible = true; identifiers = new Hashtable(); } *************** *** 74,78 **** public override void InitializeFromCache( ICollectionPersister persister, object disassembled, object owner ) { - BeforeInitialize( persister ); object[ ] array = ( object[ ] ) disassembled; --- 72,75 ---- *************** *** 80,86 **** for( int i = 0; i < array.Length; i += 2 ) { ! object obj = persister.ElementType.Assemble( array[ i + 1 ], session, owner ); ! identifiers[ obj ] = persister.IdentifierType.Assemble( array[ i ], session, owner ); ! values.Add( obj ); } --- 77,84 ---- for( int i = 0; i < array.Length; i += 2 ) { ! //object obj = persister.ElementType.Assemble( array[ i + 1 ], session, owner ); ! //identifiers[ obj ] = persister.IdentifierType.Assemble( array[ i ], session, owner ); ! identifiers[ i / 2 ] = persister.IdentifierType.Assemble( array[ i ], Session, owner ); ! values.Add( persister.ElementType.Assemble( array[ i + 1 ], Session, owner ) ); } *************** *** 266,276 **** public override object Disassemble( ICollectionPersister persister ) { ! object[ ] result = new object[values.Count*2]; int i = 0; ! foreach( object obj in values ) { ! result[ i++ ] = persister.IdentifierType.Disassemble( identifiers[ obj ], session ); ! result[ i++ ] = persister.ElementType.Disassemble( obj, session ); } --- 264,275 ---- public override object Disassemble( ICollectionPersister persister ) { ! object[ ] result = new object[ values.Count * 2 ]; int i = 0; ! for( int j = 0; j < values.Count; j++ ) { ! object val = values[ j ]; ! result[ i++ ] = persister.IdentifierType.Disassemble( identifiers[ j ], Session ); ! result[ i++ ] = persister.ElementType.Disassemble( val, Session ); } *************** *** 320,327 **** } ! int i = 0; ! foreach( object obj in values ) { ! object id = identifiers[ i++ ]; if( id == null ) { --- 319,326 ---- } ! for( int i = 0; i < values.Count; i++ ) { ! object val = values[ i ]; ! object id = identifiers[ i ]; if( id == null ) { *************** *** 330,334 **** object old = snap[ id ]; ! if( elementType.IsDirty( old, obj, session ) ) { return false; --- 329,333 ---- object old = snap[ id ]; ! if( elementType.IsDirty( old, val, Session ) ) { return false; *************** *** 337,341 **** return true; - } --- 336,339 ---- *************** *** 350,359 **** IList deletes = new ArrayList( snap.Keys ); ! int i = 0; ! foreach( object obj in values ) { ! if( obj != null ) { ! deletes.Remove( identifiers[ i++ ] ); } } --- 348,356 ---- IList deletes = new ArrayList( snap.Keys ); ! for( int i = 0; i < values.Count; i++ ) { ! if( values[ i ] != null ) { ! deletes.Remove( identifiers[ i ] ); } } *************** *** 410,414 **** object old = snap[ id ]; ! return entry != null && old != null && elemType.IsDirty( old, entry, session ); } --- 407,411 ---- object old = snap[ id ]; ! return old != null && elemType.IsDirty( old, entry, Session ); } *************** *** 422,428 **** public override object ReadFrom( IDataReader reader, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, session ); values.Add( element ); ! identifiers[ values.Count - 1 ] = persister.ReadIdentifier( reader, session ); return element; } --- 419,425 ---- public override object ReadFrom( IDataReader reader, ICollectionPersister persister, object owner ) { ! object element = persister.ReadElement( reader, owner, Session ); values.Add( element ); ! identifiers[ values.Count - 1 ] = persister.ReadIdentifier( reader, Session ); return element; } *************** *** 454,457 **** --- 451,455 ---- public override ICollection GetOrphans( object snapshot ) { + /* IDictionary sn = ( IDictionary ) GetSnapshot(); ArrayList result = new ArrayList(); *************** *** 459,462 **** --- 457,463 ---- PersistentCollection.IdentityRemoveAll( result, values, session ); return result; + */ + + return PersistentCollection.GetOrphans( ( ( IDictionary ) snapshot).Values, values, Session ); } *************** *** 465,481 **** /// </summary> /// <param name="persister"></param> ! /// <param name="entry"></param> ! /// <param name="i"></param> ! public override void PreInsert( ICollectionPersister persister, object entry, int i ) { try { ! object id = persister.IdentifierGenerator.Generate( session, entry ); ! // TODO: native ids ! identifiers[ i ] = id; } catch( Exception sqle ) { ! throw new ADOException( "Could not generate collection row id.", sqle ); } } --- 466,487 ---- /// </summary> /// <param name="persister"></param> ! public override void PreInsert( ICollectionPersister persister ) { try { ! int i = 0; ! foreach( object entry in values ) ! { ! int loc = i++; ! if( !identifiers.Contains( loc ) ) // TODO: native ids ! { ! object id = persister.IdentifierGenerator.Generate( Session, entry ); ! identifiers[ loc ] = id; ! } ! } } catch( Exception sqle ) { ! throw new ADOException( "Could not generate idbag row id.", sqle ); } } *************** *** 491,499 **** public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, session ); ! persister.WriteIdentifier( st, identifiers[ i ], writeOrder, session ); } - - } } \ No newline at end of file --- 497,504 ---- public override void WriteTo( IDbCommand st, ICollectionPersister persister, object entry, int i, bool writeOrder ) { ! persister.WriteElement( st, entry, writeOrder, Session ); ! // TODO: if not using identity columns: ! persister.WriteIdentifier( st, identifiers[ i ], writeOrder, Session ); } } } \ No newline at end of file |