Commit 79eaf24
Changed files (12)
trunk
product
MyMoney
Infrastructure
Presentation
Presenters
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");
}