DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
TransactionRegistry.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 
21 using Deveel.Data;
22 using Deveel.Data.Sql;
23 
24 namespace Deveel.Data.Transactions {
25  public sealed class TransactionRegistry : IDisposable {
26  private List<ITransactionEvent> events;
27  private List<ObjectName> objectsCreated;
28  private List<ObjectName> objectsDropped;
29  private List<int> touchedTables;
30 
31  public TransactionRegistry(ITransaction transaction) {
32  Transaction = transaction;
33 
34  events = new List<ITransactionEvent>();
35  }
36 
38  Dispose(false);
39  }
40 
41  public ITransaction Transaction { get; private set; }
42 
43  public IEnumerable<ObjectName> ObjectsCreated {
44  get {
45  lock (this) {
46  return objectsCreated == null ? new ObjectName[0] : objectsCreated.ToArray();
47  }
48  }
49  }
50 
51  public IEnumerable<ObjectName> ObjectsDropped {
52  get {
53  lock (this) {
54  return objectsDropped == null ? new ObjectName[0] : objectsDropped.ToArray();
55  }
56  }
57  }
58 
59  public IEnumerable<int> TouchedTables {
60  get {
61  lock (this) {
62  return touchedTables == null ? new int[0] : touchedTables.ToArray();
63  }
64  }
65  }
66 
67  public IEnumerable<int> TablesCreated {
68  get {
69  lock (this) {
70  return events.OfType<TableCreatedEvent>().Select(x => x.TableId);
71  }
72  }
73  }
74 
75  //public IEnumerable<int> TablesChanged {
76  // get {
77  // lock (this) {
78  // return events.OfType<ITableEvent>()
79  // .Select(x => new {
80  // id = x.TableId,
81  // table = Transaction.GetTableManager().AccessedTables.First(y => y.TableInfo.Id == x.TableId)
82  // })
83  // .Where(x => x.table.EventRegistry.EventCount > 0)
84  // .Select(x => x.id);
85  // }
86  // }
87  //}
88 
89  public IEnumerable<int> TablesDropped {
90  get {
91  lock (this) {
92  return events.OfType<TableDroppedEvent>().Select(x => x.TableId);
93  }
94  }
95  }
96 
97  public IEnumerable<int> TablesConstraintAltered {
98  get {
99  lock (this) {
100  return events.OfType<TableConstraintAlteredEvent>().Select(x => x.TableId);
101  }
102  }
103  }
104 
105  private void RegisterObjectDropped(ObjectName objName) {
106  bool created = false;
107 
108  if (objectsCreated != null)
109  created = objectsCreated.Remove(objName);
110 
111  // If the above operation didn't remove a table name then add to the
112  // dropped database objects list.
113  if (!created) {
114  if (objectsDropped == null)
115  objectsDropped = new List<ObjectName>();
116 
117  objectsDropped.Add(objName);
118  }
119  }
120 
121  private void RegisterObjectCreated(ObjectName objName) {
122  // If this table name was dropped, then remove from the drop list
123  bool dropped = false;
124  if (objectsDropped != null)
125  dropped = objectsDropped.Remove(objName);
126 
127  // If the above operation didn't remove a table name then add to the
128  // created database objects list.
129  if (!dropped) {
130  if (objectsCreated == null)
131  objectsCreated = new List<ObjectName>();
132 
133  objectsCreated.Add(objName);
134  }
135  }
136 
138  lock (this) {
139  if (e == null)
140  throw new ArgumentNullException("e");
141 
142  //if (Transaction.ReadOnly())
143  // throw new InvalidOperationException("Transaction is read-only.");
144 
145  if (e is ObjectCreatedEvent) {
146  var createdEvent = (ObjectCreatedEvent) e;
147  RegisterObjectCreated(createdEvent.ObjectName);
148  } else if (e is ObjectDroppedEvent) {
149  var droppedEvent = (ObjectDroppedEvent) e;
150  RegisterObjectDropped(droppedEvent.ObjectName);
151  }
152 
153  if (e is ITableEvent) {
154  var tableEvent = (ITableEvent) e;
155  TouchTable(tableEvent.TableId);
156  }
157 
158  events.Add(e);
159  }
160  }
161 
162  private void TouchTable(int tableId) {
163  lock (this) {
164  if (touchedTables == null)
165  touchedTables = new List<int>();
166 
167  var index = touchedTables.LastIndexOf(tableId);
168  if (index > 0 && touchedTables[index] == tableId)
169  return;
170 
171  if (index < 0) {
172  touchedTables.Add(tableId);
173  } else {
174  touchedTables.Insert(index, tableId);
175  }
176  }
177  }
178 
179  public IEnumerable<ITransactionEvent> GetEvents() {
180  lock (this) {
181  return events.ToArray();
182  }
183  }
184 
185  public void Dispose() {
186  Dispose(true);
187  GC.SuppressFinalize(this);
188  }
189 
190  private void Dispose(bool disposing) {
191  if (disposing) {
192  if (objectsCreated != null)
193  objectsCreated.Clear();
194 
195  if (objectsDropped != null)
196  objectsDropped.Clear();
197 
198  events.Clear();
199  }
200 
201  objectsDropped = null;
202  objectsCreated = null;
203  events = null;
204  }
205  }
206 }
The system implementation of a transaction model that handles isolated operations within a database c...
Definition: Transaction.cs:35
An event fired when a database object of the given type is created during the lifetime of a transacti...
Describes the name of an object within a database.
Definition: ObjectName.cs:44
A new table was created during a transaction.
An event that happens within a ITransaction life-cycle.
Defines a transaction event whose object is a database table identified.
Definition: ITableEvent.cs:26
The simplest implementation of a transaction.
Definition: ITransaction.cs:30
A transaction event that caused the alteration of a constraints in the table given.
IEnumerable< ITransactionEvent > GetEvents()