DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
TableEventRegistry.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;
19 using System.Collections.Generic;
20 using System.Linq;
21 
22 using Deveel.Data.Sql;
23 using Deveel.Data.Sql.Tables;
25 
26 namespace Deveel.Data {
27  public sealed class TableEventRegistry : IEnumerable<ITableEvent> {
28  private readonly List<ITableEvent> events;
29 
30  internal TableEventRegistry(TableSource tableSource) {
31  if (tableSource == null)
32  throw new ArgumentNullException("tableSource");
33 
34  TableSource = tableSource;
35  CommitId = -1;
36 
37  events = new List<ITableEvent>();
38  }
39 
40  internal TableSource TableSource { get; private set; }
41 
42  public int TableId {
43  get { return TableSource.TableId; }
44  }
45 
46  public long CommitId { get; internal set; }
47 
48  public IEnumerable<int> AddedRows {
49  get {
50  lock (this) {
51  var list = new List<int>();
52 
53  foreach (var tableEvent in events.OfType<TableRowEvent>()) {
54  var eventType = tableEvent.EventType;
55  if (eventType == TableRowEventType.Add ||
56  eventType == TableRowEventType.UpdateAdd) {
57  list.Add(tableEvent.RowNumber);
58  } else if (eventType == TableRowEventType.Remove ||
59  eventType == TableRowEventType.UpdateRemove) {
60  var index = list.IndexOf(tableEvent.RowNumber);
61  if (index != -1)
62  list.RemoveAt(index);
63  }
64  }
65 
66  return list.ToArray();
67  }
68  }
69  }
70 
71  public IEnumerable<int> RemovedRows {
72  get {
73  lock (this) {
74  var list = new List<int>();
75 
76  foreach (var tableEvent in events.OfType<TableRowEvent>()) {
77  if (tableEvent.EventType == TableRowEventType.Remove ||
78  tableEvent.EventType == TableRowEventType.UpdateRemove)
79  list.Add(tableEvent.RowNumber);
80  }
81 
82  return list.ToArray();
83  }
84  }
85  }
86 
87  public int EventCount {
88  get {
89  lock (this) {
90  return events.Count;
91  }
92  }
93  }
94 
95  internal void Rollback(int count) {
96  lock (this) {
97  if (count > events.Count)
98  throw new Exception("Trying to rollback more events than are in the registry.");
99 
100  List<int> toAdd = new List<int>();
101 
102  // Find all entries and added new rows to the table
103  foreach (var tableEvent in events.OfType<TableRowEvent>()) {
104  if (tableEvent.EventType == TableRowEventType.Add ||
105  tableEvent.EventType == TableRowEventType.UpdateAdd)
106  toAdd.Add(tableEvent.RowNumber);
107  }
108 
109  events.RemoveRange(0, count);
110 
111  // Mark all added entries to deleted.
112  for (int i = 0; i < toAdd.Count; ++i) {
113  events.Add(new TableRowEvent(TableId, toAdd[i], TableRowEventType.Add));
114  events.Add(new TableRowEvent(TableId, toAdd[i], TableRowEventType.Remove));
115  }
116 
117  }
118  }
119 
120  internal void Register(ITableEvent tableEvent) {
121  lock (this) {
122  events.Add(tableEvent);
123  }
124  }
125 
126  internal void TestCommitClash(TableInfo tableInfo, TableEventRegistry journal) {
127  lock (this) {
128  // Very nasty search here...
129  foreach (var rowEvent in events.OfType<TableRowEvent>()) {
130  if (rowEvent.EventType == TableRowEventType.Remove) {
131  var rowNum = rowEvent.RowNumber;
132  foreach (var otherRowEvent in journal.events.OfType<TableRowEvent>()) {
133  if (otherRowEvent.RowNumber == rowNum &&
134  otherRowEvent.EventType == TableRowEventType.Remove) {
136  String.Format("Concurrent Serializable Transaction Conflict(1): " +
137  "Current row remove clash ( row: {0}, table: {1})", rowNum, tableInfo.TableName));
138  }
139  }
140  }
141  }
142  }
143  }
144 
145  public IEnumerator<ITableEvent> GetEnumerator() {
146  lock (this) {
147  return events.GetEnumerator();
148  }
149  }
150 
151  IEnumerator IEnumerable.GetEnumerator() {
152  return GetEnumerator();
153  }
154 
155  public ITableEvent GetEvent(int index) {
156  lock (this) {
157  if (index < 0 || index >= events.Count)
158  throw new ArgumentOutOfRangeException("index");
159 
160  return events[index];
161  }
162  }
163  }
164 }
IEnumerator< ITableEvent > GetEnumerator()
ObjectName TableName
Gets the fully qualified name of the table that is ensured to be unique within the system...
Definition: TableInfo.cs:97
void TestCommitClash(TableInfo tableInfo, TableEventRegistry journal)
Defines a transaction event whose object is a database table identified.
Definition: ITableEvent.cs:26
ITableEvent GetEvent(int index)
void Register(ITableEvent tableEvent)
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
TableRowEventType
The kind of events that can happen on a table row during the life-time of a transaction.
readonly List< ITableEvent > events
TableEventRegistry(TableSource tableSource)