main
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using Gorilla.Commons.Infrastructure.Logging;
5using gorilla.commons.utility;
6
7namespace momoney.database.transactions
8{
9 public interface ISession : IDisposable
10 {
11 T find<T>(Guid guid) where T : Identifiable<Guid>;
12 IEnumerable<T> all<T>() where T : Identifiable<Guid>;
13 void save<T>(T entity) where T : Identifiable<Guid>;
14 void delete<T>(T entity) where T : Identifiable<Guid>;
15 void flush();
16 bool is_dirty();
17 }
18
19 public class Session : ISession
20 {
21 ITransaction transaction;
22 readonly IDatabase database;
23 readonly IDictionary<Type, object> identity_maps;
24 long id;
25
26 public Session(ITransaction transaction, IDatabase database)
27 {
28 this.database = database;
29 this.transaction = transaction;
30 identity_maps = new Dictionary<Type, object>();
31 id = DateTime.Now.Ticks;
32 }
33
34 public T find<T>(Guid id) where T : Identifiable<Guid>
35 {
36 if (get_identity_map_for<T>().contains_an_item_for(id))
37 {
38 return get_identity_map_for<T>().item_that_belongs_to(id);
39 }
40
41 var entity = database.fetch_all<T>().Single(x => x.id.Equals(id));
42 get_identity_map_for<T>().add(id, entity);
43 return entity;
44 }
45
46 public IEnumerable<T> all<T>() where T : Identifiable<Guid>
47 {
48 database
49 .fetch_all<T>()
50 .where(x => !get_identity_map_for<T>().contains_an_item_for(x.id))
51 .each(x => get_identity_map_for<T>().add(x.id, x));
52 return get_identity_map_for<T>().all();
53 }
54
55 public void save<T>(T entity) where T : Identifiable<Guid>
56 {
57 this.log().debug("saving {0}: {1}", id, entity);
58 get_identity_map_for<T>().add(entity.id, entity);
59 }
60
61 public void delete<T>(T entity) where T : Identifiable<Guid>
62 {
63 get_identity_map_for<T>().evict(entity.id);
64 }
65
66 public void flush()
67 {
68 this.log().debug("flushing session {0}", id);
69 transaction.commit_changes();
70 transaction = null;
71 }
72
73 public bool is_dirty()
74 {
75 this.log().debug("is dirty? {0}", id);
76 return null != transaction && transaction.is_dirty();
77 }
78
79 public void Dispose()
80 {
81 if (null != transaction) transaction.rollback_changes();
82 }
83
84 IIdentityMap<Guid, T> get_identity_map_for<T>() where T : Identifiable<Guid>
85 {
86 return identity_maps.ContainsKey(typeof (T))
87 ? identity_maps[typeof (T)].downcast_to<IIdentityMap<Guid, T>>()
88 : create_map_for<T>();
89 }
90
91 IIdentityMap<Guid, T> create_map_for<T>() where T : Identifiable<Guid>
92 {
93 var identity_map = transaction.create_for<T>();
94 identity_maps.Add(typeof (T), identity_map);
95 return identity_map;
96 }
97
98 public override string ToString()
99 {
100 return "session: {0}".formatted_using(id);
101 }
102 }
103}