DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
TransactionExtensions.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.Globalization;
20 using System.Linq;
21 
22 using Deveel.Data.Index;
23 using Deveel.Data.Services;
24 using Deveel.Data.Sql;
25 using Deveel.Data.Sql.Objects;
26 using Deveel.Data.Sql.Schemas;
27 using Deveel.Data.Sql.Sequences;
29 using Deveel.Data.Sql.Tables;
30 using Deveel.Data.Sql.Triggers;
31 using Deveel.Data.Sql.Variables;
32 using Deveel.Data.Sql.Views;
33 using Deveel.Data.Types;
34 
35 namespace Deveel.Data.Transactions {
39  public static class TransactionExtensions {
40  private static void AssertNotReadOnly(this ITransaction transaction) {
41  if (transaction.ReadOnly())
42  throw new TransactionException(TransactionErrorCodes.ReadOnly, "The transaction is in read-only mode.");
43  }
44 
45  #region Managers
46 
47  public static void CreateSystem(this ITransaction transaction) {
48  var managers = transaction.Context.ResolveAllServices<IObjectManager>();
49  foreach (var manager in managers) {
50  manager.Create();
51  }
52  }
53 
54  public static TableManager GetTableManager(this ITransaction transaction) {
55  return (TableManager) transaction.Context.ResolveService<IObjectManager>(DbObjectType.Table);
56  }
57 
58  public static TriggerManager GetTriggerManager(this ITransaction transaction) {
59  return transaction.Context.ResolveService<IObjectManager>(DbObjectType.Trigger) as TriggerManager;
60  }
61 
62  #endregion
63 
64  #region Objects
65 
66  internal static IObjectManager GetObjectManager(this ITransaction transaction, DbObjectType objectType) {
67  return transaction.Context.ResolveService<IObjectManager>(objectType);
68  }
69 
70  private static IEnumerable<IObjectManager> GetObjectManagers(this ITransaction transaction) {
71  return transaction.Context.ResolveAllServices<IObjectManager>();
72  }
73 
74  public static IDbObject FindObject(this ITransaction transaction, ObjectName objName) {
75  return transaction.GetObjectManagers()
76  .Select(manager => manager.GetObject(objName))
77  .FirstOrDefault(obj => obj != null);
78  }
79 
80  public static IDbObject GetObject(this ITransaction transaction, DbObjectType objType, ObjectName objName) {
81  var manager = transaction.GetObjectManager(objType);
82  if (manager == null)
83  return null;
84 
85  return manager.GetObject(objName);
86  }
87 
88  public static bool ObjectExists(this ITransaction transaction, ObjectName objName) {
89  return transaction.GetObjectManagers()
90  .Any(manager => manager.ObjectExists(objName));
91  }
92 
93  public static bool ObjectExists(this ITransaction transaction, DbObjectType objType, ObjectName objName) {
94  var manager = transaction.GetObjectManager(objType);
95  if (manager == null)
96  return false;
97 
98  return manager.ObjectExists(objName);
99  }
100 
101  public static bool RealObjectExists(this ITransaction transaction, DbObjectType objType, ObjectName objName) {
102  var manager = transaction.GetObjectManager(objType);
103  if (manager == null)
104  return false;
105 
106  return manager.RealObjectExists(objName);
107  }
108 
109  public static void CreateObject(this ITransaction transaction, IObjectInfo objInfo) {
110  if (objInfo == null)
111  throw new ArgumentNullException("objInfo");
112 
113  var manager = transaction.GetObjectManager(objInfo.ObjectType);
114  if (manager == null)
115  throw new InvalidOperationException(String.Format("Could not find any manager for object type '{0}' configured for the system.", objInfo.ObjectType));
116 
117  if (manager.ObjectType != objInfo.ObjectType)
118  throw new ArgumentException(
119  String.Format("Could not create an object of type '{0}' with the manager '{1}' (supported '{2}' type)",
120  objInfo.ObjectType, manager.GetType().FullName, manager.ObjectType));
121 
122  manager.CreateObject(objInfo);
123  }
124 
125  public static bool AlterObject(this ITransaction transaction, IObjectInfo objInfo) {
126  if (objInfo == null)
127  throw new ArgumentNullException("objInfo");
128 
129  var manager = transaction.GetObjectManager(objInfo.ObjectType);
130  if (manager == null)
131  throw new InvalidOperationException();
132 
133  if (manager.ObjectType != objInfo.ObjectType)
134  throw new ArgumentException();
135 
136  return manager.AlterObject(objInfo);
137  }
138 
139  public static bool DropObject(this ITransaction transaction, DbObjectType objType, ObjectName objName) {
140  var manager = transaction.GetObjectManager(objType);
141  if (manager == null)
142  return false;
143 
144  return manager.DropObject(objName);
145  }
146 
147  public static ObjectName ResolveObjectName(this ITransaction transaction, string schemaName, string objectName) {
148  if (String.IsNullOrEmpty(objectName))
149  throw new ArgumentNullException("objectName");
150 
151  if (String.IsNullOrEmpty(schemaName))
152  schemaName = transaction.CurrentSchema();
153 
154  var objName = new ObjectName(new ObjectName(schemaName), objectName);
155 
156  // Special case for OLD and NEW tables
157  if (String.Compare(objectName, "OLD", StringComparison.OrdinalIgnoreCase) == 0)
159  if (String.Compare(objectName, "NEW", StringComparison.OrdinalIgnoreCase) == 0)
161 
162  bool found = false;
163 
164  foreach (var manager in transaction.GetObjectManagers()) {
165  if (manager.ObjectExists(objName)) {
166  if (found)
167  throw new ArgumentException(String.Format("The name '{0}' is an ambiguous match.", objectName));
168 
169  found = true;
170  }
171  }
172 
173  if (!found)
174  throw new ObjectNotFoundException(objectName);
175 
176  return objName;
177  }
178 
179  public static ObjectName ResolveObjectName(this ITransaction transaction, string objectName) {
180  return transaction.ResolveObjectName(transaction.CurrentSchema(), objectName);
181  }
182 
183  public static ObjectName ResolveObjectName(this ITransaction transaction, DbObjectType objectType, ObjectName objectName) {
184  var manager = transaction.GetObjectManager(objectType);
185  if (manager == null)
186  return objectName;
187 
188  return manager.ResolveName(objectName, transaction.IgnoreIdentifiersCase());
189  }
190 
191  public static ObjectName ResolveObjectName(this ITransaction transaction, ObjectName objectName) {
192  var ignoreCase = transaction.IgnoreIdentifiersCase();
193 
194  return transaction.GetObjectManagers()
195  .Select(manager => manager.ResolveName(objectName, ignoreCase))
196  .FirstOrDefault(resolved => resolved != null);
197  }
198 
199  #endregion
200 
201  #region Schema
202 
203  public static void CreateSchema(this ITransaction transaction, SchemaInfo schemaInfo) {
204  transaction.CreateObject(schemaInfo);
205  }
206 
207  // TODO: move this elsewhere
208  public static void CreateSystemSchema(this ITransaction transaction) {
209  transaction.CreateSystem();
210 
211  // TODO: get the configured default culture...
212  var culture = CultureInfo.CurrentCulture.Name;
213  var schemaInfo = new SchemaInfo(SystemSchema.Name, SchemaTypes.System);
214  schemaInfo.Culture = culture;
215 
216  transaction.CreateSchema(schemaInfo);
217  }
218 
219  #endregion
220 
221  #region Tables
222 
223  private static ObjectName ResolveReservedTableName(ObjectName tableName) {
224  // We do not allow tables to be created with a reserved name
225  var name = tableName.Name;
226 
227  if (String.Compare(name, "OLD", StringComparison.OrdinalIgnoreCase) == 0)
229  if (String.Compare(name, "NEW", StringComparison.OrdinalIgnoreCase) == 0)
231 
232  return tableName;
233  }
234 
235  public static ObjectName ResolveTableName(this ITransaction transaction, ObjectName tableName) {
236  if (tableName == null)
237  return null;
238 
239  if (tableName.Parent == null)
240  tableName = new ObjectName(new ObjectName(transaction.CurrentSchema()), tableName.Name);
241 
242  // We do not allow tables to be created with a reserved name
243  var name = tableName.Name;
244 
245  if (String.Compare(name, "OLD", StringComparison.OrdinalIgnoreCase) == 0)
247  if (String.Compare(name, "NEW", StringComparison.OrdinalIgnoreCase) == 0)
249 
250  return transaction.ResolveObjectName(DbObjectType.Table, tableName);
251  }
252 
253  public static bool TableExists(this ITransaction transaction, ObjectName tableName) {
254  return transaction.ObjectExists(DbObjectType.Table, ResolveReservedTableName(tableName));
255  }
256 
257  public static bool RealTableExists(this ITransaction transaction, ObjectName objName) {
258  return transaction.RealObjectExists(DbObjectType.Table, objName);
259  }
260 
271  public static ITable GetTable(this ITransaction transaction, ObjectName tableName) {
272  tableName = ResolveReservedTableName(tableName);
273 
274  var tableStateHandler = transaction as ITableStateHandler;
275  if (tableStateHandler != null) {
276  if (tableName.Equals(SystemSchema.OldTriggerTableName, transaction.IgnoreIdentifiersCase()))
277  return tableStateHandler.TableState.OldDataTable;
278  if (tableName.Equals(SystemSchema.NewTriggerTableName, transaction.IgnoreIdentifiersCase()))
279  return tableStateHandler.TableState.NewDataTable;
280  }
281 
282  return (ITable) transaction.GetObject(DbObjectType.Table, tableName);
283  }
284 
285  internal static IEnumerable<ITableSource> GetVisibleTables(this ITransaction transaction) {
286  return transaction.GetTableManager().GetVisibleTables();
287  }
288 
289  internal static void RemoveVisibleTable(this ITransaction transaction, TableSource table) {
290  transaction.GetTableManager().RemoveVisibleTable(table);
291  }
292 
293  internal static void UpdateVisibleTable(this ITransaction transaction, TableSource tableSource, IIndexSet indexSet) {
294  transaction.GetTableManager().UpdateVisibleTable(tableSource, indexSet);
295  }
296 
297  internal static IIndexSet GetIndexSetForTable(this ITransaction transaction, TableSource tableSource) {
298  return transaction.GetTableManager().GetIndexSetForTable(tableSource);
299  }
300 
301  public static IMutableTable GetMutableTable(this ITransaction transaction, ObjectName tableName) {
302  return transaction.GetTable(tableName) as IMutableTable;
303  }
304 
305  public static TableInfo GetTableInfo(this ITransaction transaction, ObjectName tableName) {
306  var tableManager = transaction.GetObjectManager(DbObjectType.Table) as TableManager;
307  if (tableManager == null)
308  throw new InvalidOperationException("No table manager was found.");
309 
310  return tableManager.GetTableInfo(tableName);
311  }
312 
313  public static string GetTableType(this ITransaction transaction, ObjectName tableName) {
314  var tableManager = transaction.GetTableManager();
315  if (tableManager == null)
316  throw new InvalidOperationException("No table manager was found.");
317 
318  return tableManager.GetTableType(tableName);
319  }
320 
321  public static void CreateTable(this ITransaction transaction, TableInfo tableInfo) {
322  CreateTable(transaction, tableInfo, false);
323  }
324 
325  public static void CreateTable(this ITransaction transaction, TableInfo tableInfo, bool temporary) {
326  var tableManager = transaction.GetTableManager();
327  if (temporary) {
328  tableManager.CreateTemporaryTable(tableInfo);
329  } else {
330  tableManager.CreateTable(tableInfo);
331  }
332  }
333 
346  public static void AlterTable(this ITransaction transaction, TableInfo tableInfo) {
347  transaction.AlterObject(tableInfo);
348  }
349 
350  public static bool DropTable(this ITransaction transaction, ObjectName tableName) {
351  return transaction.DropObject(DbObjectType.Table, tableName);
352  }
353 
369  public static SqlNumber SetTableId(this ITransaction transaction, ObjectName tableName, SqlNumber value) {
370  transaction.AssertNotReadOnly();
371 
372  var tableManager = transaction.GetTableManager();
373  if (tableManager == null)
374  throw new InvalidOperationException();
375 
376  return tableManager.SetUniqueId(tableName, value);
377  }
378 
387  public static SqlNumber NextTableId(this ITransaction transaction, ObjectName tableName) {
388  transaction.AssertNotReadOnly();
389 
390  var tableManager = transaction.GetTableManager();
391  if (tableManager == null)
392  throw new InvalidOperationException();
393 
394  return tableManager.NextUniqueId(tableName);
395  }
396 
397  #endregion
398 
399  #region Variables
400 
401  public static string CurrentSchema(this ITransaction transaction) {
402  return transaction.Context.CurrentSchema();
403  }
404 
405  public static void CurrentSchema(this ITransaction transaction, string value) {
406  transaction.Context.CurrentSchema(value);
407  }
408 
409  public static bool IgnoreIdentifiersCase(this ITransaction transaction) {
410  return transaction.Context.IgnoreIdentifiersCase();
411  }
412 
413  public static void IgnoreIdentifiersCase(this ITransaction transaction, bool value) {
414  transaction.Context.IgnoreIdentifiersCase(value);
415  }
416 
417  public static bool AutoCommit(this ITransaction transaction) {
418  return transaction.Context.AutoCommit();
419  }
420 
421  public static void AutoCommit(this ITransaction transaction, bool value) {
422  transaction.Context.AutoCommit(value);
423  }
424 
425  public static QueryParameterStyle ParameterStyle(this ITransaction transaction) {
426  return transaction.Context.ParameterStyle();
427  }
428 
429  public static void ParameterStyle(this ITransaction transaction, QueryParameterStyle value) {
430  transaction.Context.ParameterStyle(value);
431  }
432 
433  public static bool ReadOnly(this ITransaction transaction) {
434  return transaction.Context.ReadOnly();
435  }
436 
437  public static void ReadOnly(this ITransaction transaction, bool value) {
438  transaction.Context.ReadOnly(value);
439  }
440 
441  public static bool ErrorOnDirtySelect(this ITransaction transaction) {
442  return transaction.Context.ErrorOnDirtySelect();
443  }
444 
445  public static void ErrorOnDirtySelect(this ITransaction transaction, bool value) {
446  transaction.Context.ErrorOnDirtySelect(value);
447  }
448 
449  #endregion
450 
451  #region Sequences
452 
453  public static void CreateSequence(this ITransaction transaction, SequenceInfo sequenceInfo) {
454  transaction.CreateObject(sequenceInfo);
455  }
456 
457  public static void CreateNativeSequence(this ITransaction transaction, ObjectName tableName) {
458  transaction.CreateSequence(SequenceInfo.Native(tableName));
459  }
460 
461  public static void RemoveNativeSequence(this ITransaction transaction, ObjectName tableName) {
462  transaction.DropSequence(tableName);
463  }
464 
465  public static bool DropSequence(this ITransaction transaction, ObjectName sequenceName) {
466  return transaction.DropObject(DbObjectType.Sequence, sequenceName);
467  }
468 
469  #endregion
470 
471  #region Locks
472 
473  public static LockHandle LockTables(this ITransaction transaction, IEnumerable<ObjectName> tableNames, AccessType accessType, LockingMode mode) {
474  var tables = tableNames.Select(transaction.GetTable).OfType<ILockable>();
475  return transaction.Database.Locker.Lock(tables.ToArray(), accessType, mode);
476  }
477 
478  public static bool IsTableLocked(this ITransaction transaction, ITable table) {
479  var lockable = table as ILockable;
480  if (lockable == null)
481  return false;
482 
483  return transaction.Database.Locker.IsLocked(lockable);
484  }
485 
486  #endregion
487  }
488 }
static bool AutoCommit(this ITransaction transaction)
static bool DropTable(this ITransaction transaction, ObjectName tableName)
static bool RealObjectExists(this ITransaction transaction, DbObjectType objType, ObjectName objName)
static void CreateSystemSchema(this ITransaction transaction)
static IDbObject FindObject(this ITransaction transaction, ObjectName objName)
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
static void CreateTable(this ITransaction transaction, TableInfo tableInfo)
static void ErrorOnDirtySelect(this ITransaction transaction, bool value)
static bool ErrorOnDirtySelect(this ITransaction transaction)
A long string in the system.
void Create()
Initializes the manager into the underlying system.
static IObjectManager GetObjectManager(this ITransaction transaction, DbObjectType objectType)
static ObjectName ResolveTableName(this ITransaction transaction, ObjectName tableName)
static IEnumerable< IObjectManager > GetObjectManagers(this ITransaction transaction)
LockingMode
The mode applied to a lock over a resource during a transaction.
Definition: LockingMode.cs:24
static void CreateNativeSequence(this ITransaction transaction, ObjectName tableName)
Provides some convenience extension methods to ITransaction instances.
Locker Locker
Gets the objects that is used to lock database objects between transactions.
Definition: IDatabase.cs:74
static void CreateSystem(this ITransaction transaction)
Represents a database object, such as a table, a trigger, a type or a column.
Definition: IDbObject.cs:24
static string GetTableType(this ITransaction transaction, ObjectName tableName)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
static TableInfo GetTableInfo(this ITransaction transaction, ObjectName tableName)
IDatabase Database
Gets the database this transaction belongs to.
Definition: ITransaction.cs:48
static bool ObjectExists(this ITransaction transaction, DbObjectType objType, ObjectName objName)
static bool ReadOnly(this ITransaction transaction)
static void AlterTable(this ITransaction transaction, TableInfo tableInfo)
Alters the table with the given name within this transaction to the specified table definition...
override bool Equals(object obj)
Definition: ObjectName.cs:241
static void RemoveNativeSequence(this ITransaction transaction, ObjectName tableName)
static bool DropSequence(this ITransaction transaction, ObjectName sequenceName)
static void CreateSequence(this ITransaction transaction, SequenceInfo sequenceInfo)
static void CurrentSchema(this ITransaction transaction, string value)
static ObjectName ResolveObjectName(this ITransaction transaction, DbObjectType objectType, ObjectName objectName)
Provides the meta information about a ISequence configuring its operative behavior.
Definition: SequenceInfo.cs:28
static ObjectName ResolveObjectName(this ITransaction transaction, ObjectName objectName)
static void RemoveVisibleTable(this ITransaction transaction, TableSource table)
static void ReadOnly(this ITransaction transaction, bool value)
static IDbObject GetObject(this ITransaction transaction, DbObjectType objType, ObjectName objName)
static TriggerManager GetTriggerManager(this ITransaction transaction)
static SequenceInfo Native(ObjectName tableName)
Creates an object that describes a native sequence for the table having the specified name...
new ITransactionContext Context
Definition: ITransaction.cs:31
static ObjectName ResolveObjectName(this ITransaction transaction, string objectName)
QueryParameterStyle
In a SQL query object, this is the form of parameters passed from the client side to the server side...
Provides utilities and properties for handling the SYSTEN schema of a database.
Definition: SystemSchema.cs:37
static void AutoCommit(this ITransaction transaction, bool value)
static ObjectName ResolveObjectName(this ITransaction transaction, string schemaName, string objectName)
An object that access to a set of indexes.
Definition: IIndexSet.cs:27
static void CreateObject(this ITransaction transaction, IObjectInfo objInfo)
static ObjectName ResolveReservedTableName(ObjectName tableName)
static void CreateTable(this ITransaction transaction, TableInfo tableInfo, bool temporary)
static bool ObjectExists(this ITransaction transaction, ObjectName objName)
static QueryParameterStyle ParameterStyle(this ITransaction transaction)
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
Definition: ObjectName.cs:99
static void IgnoreIdentifiersCase(this ITransaction transaction, bool value)
static TableManager GetTableManager(this ITransaction transaction)
static ITable GetTable(this ITransaction transaction, ObjectName tableName)
Tries to get an object with the given name formed as table.
string Name
Gets the name of the object being referenced.
Definition: ObjectName.cs:108
ITable OldDataTable
The tUserContextTable object that represents the OLD table, if set.
static bool AlterObject(this ITransaction transaction, IObjectInfo objInfo)
static void AssertNotReadOnly(this ITransaction transaction)
static bool TableExists(this ITransaction transaction, ObjectName tableName)
static IIndexSet GetIndexSetForTable(this ITransaction transaction, TableSource tableSource)
static SqlNumber NextTableId(this ITransaction transaction, ObjectName tableName)
Gets the next value of a table native sequence.
static IMutableTable GetMutableTable(this ITransaction transaction, ObjectName tableName)
Defines the contract for the business managers of database objects of a given type.
static readonly ObjectName OldTriggerTableName
const string Name
The name of the system schema that contains tables referring to system information.
OldNewTableState TableState
Gets an object that olds the state before and after a table event.
The simplest implementation of a transaction.
Definition: ITransaction.cs:30
static LockHandle LockTables(this ITransaction transaction, IEnumerable< ObjectName > tableNames, AccessType accessType, LockingMode mode)
static IEnumerable< ITableSource > GetVisibleTables(this ITransaction transaction)
DbObjectType
The kind of objects that can be handled by a database system and its managers
Definition: DbObjectType.cs:27
static void ParameterStyle(this ITransaction transaction, QueryParameterStyle value)
static void UpdateVisibleTable(this ITransaction transaction, TableSource tableSource, IIndexSet indexSet)
Describes the properties of a schema in a database system.
Definition: SchemaInfo.cs:39
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
static bool RealTableExists(this ITransaction transaction, ObjectName objName)
static bool IsTableLocked(this ITransaction transaction, ITable table)
static bool IgnoreIdentifiersCase(this ITransaction transaction)
static SqlNumber SetTableId(this ITransaction transaction, ObjectName tableName, SqlNumber value)
Sets the current value of a table native sequence.
static void CreateSchema(this ITransaction transaction, SchemaInfo schemaInfo)
An interface that defines contracts to alter the contents of a table.
static bool DropObject(this ITransaction transaction, DbObjectType objType, ObjectName objName)
static string CurrentSchema(this ITransaction transaction)
static readonly ObjectName NewTriggerTableName