DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
ViewManager.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 
22 using Deveel.Data.Sql.Objects;
23 using Deveel.Data.Sql.Tables;
25 using Deveel.Data.Types;
26 
27 namespace Deveel.Data.Sql.Views {
28  public sealed class ViewManager : IObjectManager {
29  private Dictionary<long, ViewInfo> viewCache;
30  private bool viewTableChanged;
31 
32  public ViewManager(ITransaction transaction) {
33  if (transaction == null)
34  throw new ArgumentNullException("transaction");
35 
36  Transaction = transaction;
37  viewCache = new Dictionary<long, ViewInfo>();
38 
39  transaction.RegisterOnCommit(OnCommit);
40  }
41 
42  private void OnCommit(TableCommitInfo obj) {
43  if (!obj.TableName.Equals(SystemSchema.ViewTableName))
44  return;
45 
46  // If there were changed then invalidate the cache
47  if (viewTableChanged) {
48  InvalidateViewCache();
49  viewTableChanged = false;
50  } else if ((obj.AddedRows != null && obj.AddedRows.Any()) ||
51  (obj.RemovedRows != null && obj.RemovedRows.Any())) {
52  // Otherwise, if there were committed added or removed changes also
53  // invalidate the cache,
54  InvalidateViewCache();
55  }
56  }
57 
58  private void InvalidateViewCache() {
59  viewCache.Clear();
60  }
61 
62  public ITransaction Transaction { get; private set; }
63 
64  public void Dispose() {
65  Dispose(true);
66  GC.SuppressFinalize(this);
67  }
68 
69  private void Dispose(bool disposing) {
70  Transaction = null;
71  }
72 
74  get { return DbObjectType.View; }
75  }
76 
77  private ITable FindViewEntry(ObjectName viewName) {
78  var table = Transaction.GetTable(SystemSchema.ViewTableName);
79 
80  var schemav = table.GetResolvedColumnName(0);
81  var namev = table.GetResolvedColumnName(1);
82 
83  using (var session = new SystemSession(Transaction, SystemSchema.Name)) {
84  using (var query =session.CreateQuery()) {
85  var t = table.SimpleSelect(query, namev, SqlExpressionType.Equal,
87  t = t.ExhaustiveSelect(query,
89 
90  // This should be at most 1 row in size
91  if (t.RowCount > 1)
92  throw new ArgumentException(String.Format("Multiple view entries for name '{0}' in the system.", viewName));
93 
94  // Return the entries found.
95  return t;
96  }
97  }
98  }
99 
100  public void Create() {
101  var tableInfo = new TableInfo(SystemSchema.ViewTableName);
102  tableInfo.AddColumn("schema", PrimitiveTypes.String());
103  tableInfo.AddColumn("name", PrimitiveTypes.String());
104  tableInfo.AddColumn("query", PrimitiveTypes.String());
105  tableInfo.AddColumn("plan", PrimitiveTypes.Binary());
106 
107  // TODO: Columns...
108 
109  Transaction.CreateTable(tableInfo);
110  }
111 
113  var viewInfo = objInfo as ViewInfo;
114  if (viewInfo == null)
115  throw new ArgumentException();
116 
117  DefineView(viewInfo);
118  }
119 
121  return ViewExists(objName);
122  }
123 
125  return ViewExists(objName);
126  }
127 
129  return GetView(objName);
130  }
131 
133  throw new NotSupportedException();
134  }
135 
137  return DropView(objName);
138  }
139 
140  public ObjectName ResolveName(ObjectName objName, bool ignoreCase) {
141  throw new NotImplementedException();
142  }
143 
144  public void DefineView(ViewInfo viewInfo) {
145  if (viewInfo == null)
146  throw new ArgumentNullException("viewInfo");
147 
148  var dataTableInfo = viewInfo.TableInfo;
149  var viewTable = Transaction.GetMutableTable(SystemSchema.ViewTableName);
150 
151  var viewName = dataTableInfo.TableName;
152  var query = viewInfo.QueryExpression;
153  var viewInfoData = viewInfo.AsBinary();
154 
155  // Create the view record
156  var rdat = viewTable.NewRow();
157  rdat.SetValue(0, dataTableInfo.SchemaName.Name);
158  rdat.SetValue(1, dataTableInfo.Name);
159  rdat.SetValue(2, query.ToString());
160  rdat.SetValue(3, DataObject.Binary(viewInfoData));
161 
162  // Find the entry from the view that equals this name
163  var t = FindViewEntry(viewName);
164 
165  // Delete the entry if it already exists.
166  if (t.RowCount == 1) {
167  viewTable.Delete(t);
168  }
169 
170  // Insert the new view entry in the system view table
171  viewTable.AddRow(rdat);
172 
173  // Notify that this database object has been successfully created.
175 
176  // Change to the view table
177  viewTableChanged = true;
178  }
179 
180  public View GetView(ObjectName viewName) {
181  var viewTable = Transaction.GetTable(SystemSchema.ViewTableName);
182  var e = viewTable.GetEnumerator();
183  while (e.MoveNext()) {
184  int row = e.Current.RowId.RowNumber;
185 
186  var cSchema = viewTable.GetValue(row, 0).Value.ToString();
187  var cName = viewTable.GetValue(row, 1).Value.ToString();
188 
189  if (viewName.ParentName.Equals(cSchema) &&
190  viewName.Name.Equals(cName)) {
191 
192  ViewInfo viewInfo;
193  if (!viewCache.TryGetValue(row, out viewInfo)) {
194  var blob = (SqlBinary)viewTable.GetValue(row, 3).Value;
195  using (var session = new SystemSession(Transaction, SystemSchema.Name)) {
196  using (var context = session.CreateQuery()) {
197 
198  viewInfo = ViewInfo.Deserialize(blob.GetInput());
199  }
200  }
201 
202  viewCache[row] = viewInfo;
203 
204  }
205 
206  return new View(viewInfo);
207  }
208 
209  }
210 
211  return null;
212  }
213 
214  public bool ViewExists(ObjectName viewName) {
215  return FindViewEntry(viewName).RowCount > 0;
216  }
217 
218  public bool DropView(ObjectName viewName) {
219  var table = Transaction.GetMutableTable(SystemSchema.ViewTableName);
220 
221  var t = FindViewEntry(viewName);
222 
223  if (t.RowCount == 0)
224  return false;
225 
226  table.Delete(t);
227 
228  // Notify that this database object has been successfully dropped.
230 
231  viewTableChanged = true;
232 
233  return true;
234  }
235 
237  return new ViewTableContainer(this);
238  }
239 
240  private View GetViewAt(int offset) {
241  var table = Transaction.GetTable(SystemSchema.ViewTableName);
242  if (table == null)
243  throw new DatabaseSystemException(String.Format("System table '{0}' was not defined.", SystemSchema.ViewTableName));
244 
245  var e = table.GetEnumerator();
246  int i = 0;
247  while (e.MoveNext()) {
248  var row = e.Current.RowId.RowNumber;
249 
250  if (i == offset) {
251  ViewInfo viewInfo;
252  if (!viewCache.TryGetValue(row, out viewInfo)) {
253  var binary = (ISqlBinary)table.GetValue(row, 3).Value;
254 
255  using (var session = new SystemSession(Transaction, SystemSchema.Name)) {
256  using (var context = session.CreateQuery()) {
257  viewInfo = ViewInfo.Deserialize(binary.GetInput());
258  }
259  }
260 
261  viewCache[row] = viewInfo;
262  }
263 
264  return new View(viewInfo);
265  }
266 
267  ++i;
268  }
269 
270  throw new ArgumentOutOfRangeException("offset");
271  }
272 
273  #region ViewTableContainer
274 
276  private readonly ViewManager viewManager;
277 
278  public ViewTableContainer(ViewManager viewManager)
279  : base(viewManager.Transaction, SystemSchema.ViewTableName) {
280  this.viewManager = viewManager;
281  }
282 
283  public override TableInfo GetTableInfo(int offset) {
284  var view = viewManager.GetViewAt(offset);
285  if (view == null)
286  return null;
287 
288  return view.ViewInfo.TableInfo;
289  }
290 
291  public override string GetTableType(int offset) {
292  return TableTypes.View;
293  }
294 
295  public override ITable GetTable(int offset) {
296  throw new NotSupportedException();
297  }
298  }
299 
300  #endregion
301  }
302 }
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
View GetView(ObjectName viewName)
Definition: ViewManager.cs:180
bool AlterObject(IObjectInfo objInfo)
Modifies an existing object managed, identified by IObjectInfo.FullName component of the given specif...
bool DropObject(ObjectName objName)
Deletes a database object handled by this manager from the system.
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
static DataObject Binary(SqlBinary binary)
Definition: DataObject.cs:638
override ITable GetTable(int offset)
Gets the table contained at the given offset within the context.
Definition: ViewManager.cs:295
const string View
Definition: TableTypes.cs:27
override string GetTableType(int offset)
Gets the type of the table at the given offset.
Definition: ViewManager.cs:291
A long string in the system.
TableInfo(ObjectName tableName)
Constructs the object with the given table name.
Definition: TableInfo.cs:54
The system implementation of a transaction model that handles isolated operations within a database c...
Definition: Transaction.cs:35
bool RealObjectExists(ObjectName objName)
Checks if an object really exists in the system.
void Dispose(bool disposing)
Definition: ViewManager.cs:69
void Create()
Initializes the manager into the underlying system.
Definition: ViewManager.cs:100
Implements a BINARY object that handles a limited number of bytes, not exceding MaxLength.
Definition: SqlBinary.cs:27
Represents a database object, such as a table, a trigger, a type or a column.
Definition: IDbObject.cs:24
An event fired when a database object of the given type is created during the lifetime of a transacti...
void OnCommit(TableCommitInfo obj)
Definition: ViewManager.cs:42
static BinaryType Binary(int maxSize)
static ViewInfo Deserialize(Stream stream)
Definition: ViewInfo.cs:77
static SqlBinaryExpression Equal(SqlExpression left, SqlExpression right)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
Exception thrown where various problems occur within the database.
static DataObject String(string s)
Definition: DataObject.cs:592
ITableContainer CreateInternalTableInfo()
Definition: ViewManager.cs:236
SqlExpressionType
All the possible type of SqlExpression supported
override TableInfo GetTableInfo(int offset)
Gets the information of the table at the given offset in this container.
Definition: ViewManager.cs:283
ObjectName ResolveName(ObjectName objName, bool ignoreCase)
Normalizes the input object name using the case sensitivity specified.
Definition: ViewManager.cs:140
ViewManager(ITransaction transaction)
Definition: ViewManager.cs:32
void CreateObject(IObjectInfo objInfo)
Create a new object of the ObjectType given the specifications given.
static readonly ObjectName ViewTableName
Provides the constant names of the types of tables in a database system.
Definition: TableTypes.cs:24
void RegisterOnCommit(Action< TableCommitInfo > action)
bool ViewExists(ObjectName viewName)
Definition: ViewManager.cs:214
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
A container for any system tables that are generated from information inside the database engine...
bool DropView(ObjectName viewName)
Definition: ViewManager.cs:218
Provides utilities and properties for handling the SYSTEN schema of a database.
Definition: SystemSchema.cs:37
DbObjectType ObjectType
Gets the type of objects managed by this instance.
string Name
Gets the name of the object being referenced.
Definition: ObjectName.cs:108
static SqlReferenceExpression Reference(ObjectName objectName)
ITable FindViewEntry(ObjectName viewName)
Definition: ViewManager.cs:77
void DefineView(ViewInfo viewInfo)
Definition: ViewManager.cs:144
IDbObject GetObject(ObjectName objName)
Gets a database object managed by this manager.
bool ObjectExists(ObjectName objName)
Checks if an object identified by the given name is managed by this instance.
Defines the base class for instances that represent SQL expression tree nodes.
Defines the contract for the business managers of database objects of a given type.
const string Name
The name of the system schema that contains tables referring to system information.
static SqlConstantExpression Constant(object value)
The simplest implementation of a transaction.
Definition: ITransaction.cs:30
DbObjectType
The kind of objects that can be handled by a database system and its managers
Definition: DbObjectType.cs:27
Defines the required contract of a SQL BINARY object
Definition: ISqlBinary.cs:25
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
Dictionary< long, ViewInfo > viewCache
Definition: ViewManager.cs:29
SqlQueryExpression QueryExpression
Definition: ViewInfo.cs:54