main
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using gorilla.commons.utility;
 5
 6namespace momoney.database.transactions
 7{
 8    public interface ITransaction
 9    {
10        IIdentityMap<Guid, T> create_for<T>() where T : Identifiable<Guid>;
11        void commit_changes();
12        void rollback_changes();
13        bool is_dirty();
14    }
15
16    public class Transaction : ITransaction
17    {
18        readonly IDatabase database;
19        readonly IChangeTrackerFactory factory;
20        readonly IDictionary<Type, IChangeTracker> change_trackers;
21
22        public Transaction(IDatabase database, IChangeTrackerFactory factory)
23        {
24            this.factory = factory;
25            this.database = database;
26            change_trackers = new Dictionary<Type, IChangeTracker>();
27        }
28
29        public IIdentityMap<Guid, T> create_for<T>() where T : Identifiable<Guid>
30        {
31            return new IdentityMapProxy<Guid, T>(get_change_tracker_for<T>(), new IdentityMap<Guid, T>());
32        }
33
34        public void commit_changes()
35        {
36            change_trackers.Values.where(x => x.is_dirty()).each(x => x.commit_to(database));
37        }
38
39        public void rollback_changes()
40        {
41            change_trackers.each(x => x.Value.Dispose());
42            change_trackers.Clear();
43        }
44
45        public bool is_dirty()
46        {
47            return change_trackers.Values.Count(x => x.is_dirty()) > 0;
48        }
49
50        IChangeTracker<T> get_change_tracker_for<T>() where T : Identifiable<Guid>
51        {
52            if (!change_trackers.ContainsKey(typeof (T))) change_trackers.Add(typeof (T), factory.create_for<T>());
53            return change_trackers[typeof (T)].downcast_to<IChangeTracker<T>>();
54        }
55    }
56}