Commit 79eaf24

mokhan <mokhan@ce5e1baf-6525-42e4-a1b2-857ea38da20a>
2009-04-04 19:29:19
trimming the waste from the unit of work.
git-svn-id: https://svn.xp-dev.com/svn/mokhan-mo.money@137 ce5e1baf-6525-42e4-a1b2-857ea38da20a
1 parent dd9cd1d
trunk/product/MyMoney/Infrastructure/transactions2/ChangeTracker.cs
@@ -9,12 +9,14 @@ namespace MoMoney.Infrastructure.transactions2
         readonly ITrackerEntryMapper<T> mapper;
         readonly IStatementRegistry registry;
         readonly IList<ITrackerEntry<T>> items;
+        readonly IList<T> to_be_deleted;
 
         public ChangeTracker(ITrackerEntryMapper<T> mapper, IStatementRegistry registry)
         {
             this.mapper = mapper;
             this.registry = registry;
             items = new List<ITrackerEntry<T>>();
+            to_be_deleted = new List<T>();
         }
 
         public void register(T entity)
@@ -22,14 +24,20 @@ namespace MoMoney.Infrastructure.transactions2
             items.Add(mapper.map_from(entity));
         }
 
+        public void delete(T entity)
+        {
+            to_be_deleted.Add(entity);
+        }
+
         public void commit_to(IDatabase database)
         {
             items.each(x => commit(x, database));
+            to_be_deleted.each(x => database.apply(registry.prepare_command_for(x)));
         }
 
         public bool is_dirty()
         {
-            return items.Count(x => x.contains_changes()) > 0;
+            return items.Count(x => x.contains_changes()) > 0 || to_be_deleted.Count > 0;
         }
 
         public void Dispose()
trunk/product/MyMoney/Infrastructure/transactions2/IChangeTracker.cs
@@ -11,5 +11,6 @@ namespace MoMoney.Infrastructure.transactions2
     public interface IChangeTracker<T> : IChangeTracker, IDisposable
     {
         void register(T value);
+        void delete(T entity);
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/IdentityMapProxy.cs
@@ -40,9 +40,10 @@ namespace MoMoney.Infrastructure.transactions2
             return real_map.item_that_belongs_to(key);
         }
 
-        public void remove(Key key)
+        public void evict(Key key)
         {
-            real_map.remove(key);
+            change_tracker.delete(real_map.item_that_belongs_to(key));
+            real_map.evict(key);
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/IIdentityMap.cs
@@ -10,7 +10,7 @@ namespace MoMoney.Infrastructure.transactions2
         void update_the_item_for(TKey key, TValue new_value);
         bool contains_an_item_for(TKey key);
         TValue item_that_belongs_to(TKey key);
-        void remove(TKey key);
+        void evict(TKey key);
     }
 
     public class IdentityMap<TKey, TValue> : IIdentityMap<TKey, TValue>
@@ -52,9 +52,9 @@ namespace MoMoney.Infrastructure.transactions2
             return contains_an_item_for(key) ? items_in_map[key] : default(TValue);
         }
 
-        public void remove(TKey key)
+        public void evict(TKey key)
         {
-            throw new NotImplementedException();
+            if (contains_an_item_for(key)) items_in_map.Remove(key);
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/IStatementRegistry.cs
@@ -1,15 +1,7 @@
-using System;
-
 namespace MoMoney.Infrastructure.transactions2
 {
     public interface IStatementRegistry
     {
-        [Obsolete]
-        IStatement prepare_insert_statement_for<T>(T entity);
-
-        [Obsolete]
-        IStatement prepare_update_statement_for<T>(T entity);
-
         IStatement prepare_delete_statement_for<T>(T entity);
         IStatement prepare_command_for<T>(T entity);
     }
trunk/product/MyMoney/Infrastructure/transactions2/Session.cs
@@ -11,7 +11,6 @@ namespace MoMoney.Infrastructure.transactions2
         IEntity find<T>(Guid guid) where T : IEntity;
         IEnumerable<T> all<T>() where T : IEntity;
         void save<T>(T entity) where T : IEntity;
-        void update<T>(T entity) where T : IEntity;
         void delete<T>(T entity) where T : IEntity;
         void flush();
     }
@@ -53,19 +52,11 @@ namespace MoMoney.Infrastructure.transactions2
         public void save<T>(T entity) where T : IEntity
         {
             get_identity_map_for<T>().add(entity.Id, entity);
-            transaction.add_transient(entity);
-        }
-
-        public void update<T>(T entity) where T : IEntity
-        {
-            get_identity_map_for<T>().update_the_item_for(entity.Id, entity);
-            transaction.add_dirty(entity);
         }
 
         public void delete<T>(T entity) where T : IEntity
         {
-            transaction.mark_for_deletion(entity);
-            get_identity_map_for<T>().remove(entity.Id);
+            get_identity_map_for<T>().evict(entity.Id);
         }
 
         public void flush()
trunk/product/MyMoney/Infrastructure/transactions2/SessionFactory.cs
@@ -21,7 +21,7 @@ namespace MoMoney.Infrastructure.transactions2
 
         public ISession create()
         {
-            return new Session(new Transaction(registry, database, factory), database);
+            return new Session(new Transaction(database, factory), database);
         }
     }
 }
\ No newline at end of file
trunk/product/MyMoney/Infrastructure/transactions2/SessionSpecs.cs
@@ -27,7 +27,7 @@ namespace MoMoney.Infrastructure.transactions2
     {
         it should_add_the_entity_to_the_identity_map = () => map.was_told_to(x => x.add(guid, entity));
 
-        it should_add_the_item_to_the_current_transaction = () => transaction.was_told_to(x => x.add_transient(entity));
+        //it should_add_the_item_to_the_current_transaction = () => transaction.was_told_to(x => x.add_transient(entity));
 
         context c = () =>
                         {
@@ -69,40 +69,6 @@ namespace MoMoney.Infrastructure.transactions2
         because b = () => sut.Dispose();
     }
 
-
-    public class when_updating_a_persistent_entity : behaves_like_session
-    {
-        it should_update_the_item_in_the_map = () => map.was_told_to(x => x.update_the_item_for(guid, modified));
-
-        it should_mark_the_item_as_changed_with_the_transaction =
-            () => transaction.was_told_to(x => x.add_dirty(modified));
-
-        context c = () =>
-                        {
-                            guid = Guid.NewGuid();
-                            original = an<ITestEntity>();
-                            modified = an<ITestEntity>();
-
-                            map = an<IIdentityMap<Guid, ITestEntity>>();
-                            when_the(original).is_told_to(x => x.Id).it_will_return(guid);
-                            when_the(modified).is_told_to(x => x.Id).it_will_return(guid);
-                            when_the(transaction).is_told_to(x => x.create_for<ITestEntity>()).it_will_return(map);
-                            when_the(database).is_told_to(x => x.fetch_all<ITestEntity>()).it_will_return(original);
-                            when_the(map).is_told_to(x => x.all()).it_will_return_nothing();
-                        };
-
-        because b = () =>
-                        {
-                            sut.all<ITestEntity>();
-                            sut.update(modified);
-                        };
-
-        static Guid guid;
-        static ITestEntity original;
-        static ITestEntity modified;
-        static IIdentityMap<Guid, ITestEntity> map;
-    }
-
     public class when_loading_all_instances_of_a_certain_type_and_some_have_already_been_loaded : behaves_like_session
     {
         it should_return_the_items_from_the_cache = () => results.should_contain(cached_item);
@@ -180,10 +146,9 @@ namespace MoMoney.Infrastructure.transactions2
 
     public class when_deleting_an_item_from_the_database : behaves_like_session
     {
-        it should_remove_that_item_from_the_cache = () => map.was_told_to(x => x.remove(id));
+        it should_remove_that_item_from_the_cache = () => map.was_told_to(x => x.evict(id));
 
-        it should_mark_the_item_for_deletion_when_the_transaction_is_committed =
-            () => transaction.was_told_to(x => x.mark_for_deletion(entity));
+        //it should_mark_the_item_for_deletion_when_the_transaction_is_committed = () => transaction.was_told_to(x => x.mark_for_deletion(entity));
 
         context c = () =>
                         {
trunk/product/MyMoney/Infrastructure/transactions2/StatementRegistry.cs
@@ -4,16 +4,6 @@ namespace MoMoney.Infrastructure.transactions2
 {
     public class StatementRegistry : IStatementRegistry
     {
-        public IStatement prepare_insert_statement_for<T>(T entity)
-        {
-            throw new NotImplementedException();
-        }
-
-        public IStatement prepare_update_statement_for<T>(T entity)
-        {
-            throw new NotImplementedException();
-        }
-
         public IStatement prepare_delete_statement_for<T>(T entity)
         {
             throw new NotImplementedException();
trunk/product/MyMoney/Infrastructure/transactions2/Transaction.cs
@@ -8,32 +8,22 @@ namespace MoMoney.Infrastructure.transactions2
     public interface ITransaction
     {
         IIdentityMap<Guid, T> create_for<T>() where T : IEntity;
-        void add_transient<T>(T entity) where T : IEntity;
-        void add_dirty<T>(T modified) where T : IEntity;
-        void mark_for_deletion<T>(T entity) where T : IEntity;
+        //void mark_for_deletion<T>(T entity) where T : IEntity;
         void commit_changes();
         void rollback_changes();
     }
 
     public class Transaction : ITransaction
     {
-        readonly IStatementRegistry registry;
         readonly IDatabase database;
         readonly IChangeTrackerFactory factory;
-        readonly List<IEntity> transients;
-        readonly List<IEntity> dirty;
-        readonly List<IEntity> to_be_deleted;
         readonly IDictionary<Type, IChangeTracker> change_trackers;
 
-        public Transaction(IStatementRegistry registry, IDatabase database, IChangeTrackerFactory factory)
+        public Transaction(IDatabase database, IChangeTrackerFactory factory)
         {
-            this.registry = registry;
             this.factory = factory;
             this.database = database;
             change_trackers = new Dictionary<Type, IChangeTracker>();
-            transients = new List<IEntity>();
-            dirty = new List<IEntity>();
-            to_be_deleted = new List<IEntity>();
         }
 
         public IIdentityMap<Guid, T> create_for<T>() where T : IEntity
@@ -41,30 +31,9 @@ namespace MoMoney.Infrastructure.transactions2
             return new IdentityMapProxy<Guid, T>(get_change_tracker_for<T>(), new IdentityMap<Guid, T>());
         }
 
-        public void add_transient<T>(T entity) where T : IEntity
-        {
-            transients.Add(entity);
-        }
-
-        public void add_dirty<T>(T modified) where T : IEntity
-        {
-            dirty.Add(modified);
-        }
-
-        public void mark_for_deletion<T>(T entity) where T : IEntity
-        {
-            to_be_deleted.Add(entity);
-        }
-
         public void commit_changes()
         {
-            change_trackers.Values
-                .where(x => x.is_dirty())
-                .each(x => x.commit_to(database));
-
-            transients.each(x => database.apply(registry.prepare_insert_statement_for(x)));
-            dirty.each(x => database.apply(registry.prepare_update_statement_for(x)));
-            to_be_deleted.each(x => database.apply(registry.prepare_delete_statement_for(x)));
+            change_trackers.Values.where(x => x.is_dirty()).each(x => x.commit_to(database));
         }
 
         public void rollback_changes()
trunk/product/MyMoney/Infrastructure/transactions2/TransactionSpecs.cs
@@ -1,7 +1,6 @@
 using System;
 using developwithpassion.bdd.contexts;
 using MoMoney.Domain.Core;
-using MoMoney.Infrastructure.Logging;
 using MoMoney.Testing.spechelpers.contexts;
 using MoMoney.Testing.spechelpers.core;
 
@@ -34,63 +33,6 @@ namespace MoMoney.Infrastructure.transactions2
         static IIdentityMap<Guid, IEntity> result;
     }
 
-    public class when_commiting_a_set_of_transient_instances_to_the_database : behaves_like_transaction
-    {
-        it should_prepare_an_insert_command_for_each_transient_instance =
-            () => registry.was_told_to(x => x.prepare_insert_statement_for(entity));
-
-        it should_apply_the_insert_statement_against_the_database_for_each_entity =
-            () => database.was_told_to(x => x.apply(insert_statement));
-
-        context c = () =>
-                        {
-                            entity = an<IEntity>();
-                            insert_statement = an<IStatement>();
-                            when_the(registry)
-                                .is_told_to(x => x.prepare_insert_statement_for(entity))
-                                .it_will_return(insert_statement);
-                        };
-
-        because b = () =>
-                        {
-                            sut.add_transient(entity);
-                            sut.commit_changes();
-                        };
-
-        static IEntity entity;
-        static IStatement insert_statement;
-    }
-
-    public class when_commiting_a_set_of_dirty_instances_to_The_database : behaves_like_transaction
-    {
-        it should_prepare_an_update_command_for_each_transient_instance =
-            () => registry.was_told_to(x => x.prepare_update_statement_for(entity)).only_once();
-
-        it should_apply_the_update_statement_against_the_database_for_each_entity =
-            () => database.was_told_to(x => x.apply(update_statement)).only_once();
-
-        it should_not_throw_an_exception = () => exception_thrown_while_the_sut_performed_its_work.should_be_null();
-
-        context c =
-            () =>
-                {
-                    entity = an<IEntity>();
-                    update_statement = an<IStatement>();
-
-                    when_the(registry).is_told_to(x => x.prepare_update_statement_for(entity)).it_will_return( update_statement).Repeat.Any();
-                };
-
-        because b =
-            () =>
-                {
-                    sut.add_dirty(entity);
-                    sut.commit_changes();
-                };
-
-        static IEntity entity;
-        static IStatement update_statement;
-    }
-
     public class when_committing_a_transaction_and_an_item_in_the_identity_map_has_changed : behaves_like_transaction
     {
         it should_commit_the_changes_to_that_item = () => tracker.was_told_to(x => x.commit_to(database));
@@ -98,12 +40,8 @@ namespace MoMoney.Infrastructure.transactions2
         context c = () =>
                         {
                             movie = new Movie("Goldeneye");
-                            update_statement = an<IStatement>();
                             tracker = an<IChangeTracker<IMovie>>();
 
-                            when_the(registry)
-                                .is_told_to(x => x.prepare_update_statement_for(movie))
-                                .it_will_return(update_statement);
                             when_the(factory).is_told_to(x => x.create_for<IMovie>()).it_will_return(tracker);
                             when_the(tracker).is_told_to(x => x.is_dirty()).it_will_return(true);
                         };
@@ -116,31 +54,35 @@ namespace MoMoney.Infrastructure.transactions2
                             sut.commit_changes();
                         };
 
-        static IStatement update_statement;
         static IMovie movie;
         static IChangeTracker<IMovie> tracker;
     }
 
     public class when_deleting_a_set_of_entities_from_the_database : behaves_like_transaction
     {
-        it should_apply_a_deletion_statement_for_each_entity =
-            () => database.was_told_to(x => x.apply(deletion_statement));
+        it should_prepare_to_delete_that_item_form_the_database = () => tracker.was_told_to(x => x.delete(movie));
+
+        it should_delete_all_items_marked_for_deletion = () => tracker.was_told_to(x => x.commit_to(database));
 
         context c = () =>
                         {
-                            entity = an<IEntity>();
-                            deletion_statement = an<IStatement>();
-                            when_the(registry)
-                                .is_told_to(x => x.prepare_delete_statement_for(entity))
-                                .it_will_return(deletion_statement);
-                        };
+                            movie = new Movie("Goldeneye");
+                            tracker = an<IChangeTracker<IMovie>>();
 
-        after_the_sut_has_been_created after_sut = () => sut.mark_for_deletion(entity);
+                            when_the(factory).is_told_to(x => x.create_for<IMovie>()).it_will_return(tracker);
+                            when_the(tracker).is_told_to(x => x.is_dirty()).it_will_return(true);
+                        };
 
-        because b = () => sut.commit_changes();
+        because b = () =>
+                        {
+                            var map = sut.create_for<IMovie>();
+                            map.add(movie.Id, movie);
+                            map.evict(movie.Id);
+                            sut.commit_changes();
+                        };
 
-        static IEntity entity;
-        static IStatement deletion_statement;
+        static IMovie movie;
+        static IChangeTracker<IMovie> tracker;
     }
 
     public interface IMovie : IEntity
trunk/product/MyMoney/Presentation/Presenters/Shell/NotificationIconPresenter.cs
@@ -1,3 +1,4 @@
+using System.Net.NetworkInformation;
 using MoMoney.Infrastructure.eventing;
 using MoMoney.Presentation.Core;
 using MoMoney.Presentation.Model.messages;
@@ -27,6 +28,7 @@ namespace MoMoney.Presentation.Presenters.Shell
         {
             broker.subscribe_to<ClosingTheApplication>(this);
             broker.subscribe_to<NewProjectOpened>(this);
+            NetworkChange.NetworkAvailabilityChanged += (sender, args) => view.display(ApplicationIcons.Application, args.IsAvailable ? "Connected To A Network" : "Disconnected From Network");
             view.display(ApplicationIcons.Application, "mokhan.ca");
         }