18 using System.Collections.Generic;
26 namespace Deveel.Data.Sql.Tables {
34 private readonly Dictionary<ObjectName, IMutableTable>
tableCache;
39 if (transaction == null)
40 throw new ArgumentNullException(
"transaction");
44 Composite = composite;
46 visibleTables =
new List<ITableSource>();
47 tableIndices =
new List<IIndexSet>();
48 accessedTables =
new List<IMutableTable>();
49 tableCache =
new Dictionary<ObjectName, IMutableTable>();
50 selectedTables =
new List<ITableSource>();
61 internal IEnumerable<IMutableTable> AccessedTables {
62 get {
return accessedTables; }
65 internal IEnumerable<ITableSource> SelectedTables {
67 lock (selectedTables) {
68 return selectedTables.ToArray();
73 private bool IgnoreIdentifiersCase {
79 GC.SuppressFinalize(
this);
85 foreach (var tableIndex
in tableIndices) {
94 if (cleanupQueue != null) {
95 for (
int i = 0; i < cleanupQueue.Count; i += 2) {
101 }
catch (Exception) {
110 foreach (var table
in accessedTables) {
114 accessedTables.Clear();
115 }
catch (Exception) {
118 accessedTables = null;
125 DisposeTouchedTables();
143 tableInfo = tableInfo.AsReadOnly();
151 tableInfo = tableInfo.AsReadOnly();
165 tableInfo = tableInfo.AsReadOnly();
174 tableInfo = tableInfo.AsReadOnly();
184 tableInfo = tableInfo.AsReadOnly();
192 tableInfo = tableInfo.AsReadOnly();
204 tableInfo = tableInfo.AsReadOnly();
210 if (tableInfo == null)
211 throw new ArgumentException();
213 CreateTable(tableInfo);
217 CreateTable(tableInfo,
false);
222 var source = FindVisibleTable(tableName,
false);
224 throw new InvalidOperationException(
String.Format(
"Table '{0}' already exists.", tableName));
228 source = Composite.CreateTableSource(tableInfo, temporary);
231 AddVisibleTable(source, source.CreateIndexSet());
233 int tableId = source.TableId;
240 CreateTable(tableInfo,
true);
245 if (IsDynamicTable(tableName))
248 var source = FindVisibleTable(tableName,
false);
252 lock (selectedTables) {
253 if (!selectedTables.Contains(source))
254 selectedTables.Add(source);
260 var currentTable = FindVisibleTable(tableName,
false);
261 if (currentTable == null)
265 if (currentTable.CanCompact) {
267 var indexSet = GetIndexSetForTable(currentTable);
270 DropTable(tableName);
273 CopyTable(currentTable, indexSet);
280 var source = FindVisibleTable(tableName,
false);
285 source = Composite.CopySourceTable(tableSource, indexSet);
287 AddVisibleTable(source, source.CreateIndexSet());
290 int tableId = source.TableId;
297 int sz = tableIndices.Count;
298 for (
int i = 0; i < sz; ++i) {
299 if (visibleTables[i].TableId == tableSource.
TableId) {
300 return tableIndices[i];
304 throw new Exception(
"Table source not found in this transaction.");
309 throw new Exception(
"Transaction is Read-only.");
311 visibleTables.Add(table);
312 tableIndices.Add(indexSet);
315 private static int IndexOfTable(IList<ITableSource> sources,
int tableId) {
316 for (
int i = 0; i < sources.Count; i++) {
317 var source = sources[i];
318 if (source.TableId == tableId)
327 throw new Exception(
"Transaction is Read-only.");
329 var i = IndexOfTable(visibleTables, table.
TableId);
331 visibleTables.RemoveAt(i);
333 tableIndices.RemoveAt(i);
334 if (cleanupQueue == null)
335 cleanupQueue =
new List<object>();
337 cleanupQueue.Add(table);
338 cleanupQueue.Add(indexSet);
342 tableCache.Remove(tableName);
348 throw new Exception(
"Transaction is Read-only.");
350 RemoveVisibleTable(table);
351 AddVisibleTable(table, indexSet);
356 .FirstOrDefault(source => source != null &&
357 source.TableInfo.TableName.Equals(tableName, ignoreCase));
361 var tableSource = FindVisibleTable(tableName,
false);
362 if (tableSource == null)
364 String.Format(
"Table with name '{0}' could not be found to set the unique id.", tableName));
366 tableSource.SetUniqueId(value.
ToInt64());
371 var tableSource = FindVisibleTable(tableName,
false);
372 if (tableSource == null)
374 String.Format(
"Table with name '{0}' could not be found to retrieve unique id.", tableName));
376 var value = tableSource.GetNextUniqueId();
381 if (internalTables == null)
384 return internalTables.Any(info => info != null && info.ContainsTable(tableName));
388 foreach (var info
in internalTables) {
390 int index = info.FindByName(tableName);
392 return info.GetTable(index);
396 throw new ArgumentException(
String.Format(
"Table '{0}' is not a dynamic table.", tableName));
401 foreach (var info
in internalTables) {
403 int index = info.FindByName(tableName);
405 return info.GetTableType(index);
409 throw new ArgumentException(
String.Format(
"Table '{0}' is not a dynamic table.", tableName));
413 return RealTableExists(objName);
417 return FindVisibleTable(tableName,
false) != null;
421 return TableExists(objName);
425 return IsDynamicTable(tableName) ||
426 RealTableExists(tableName);
430 return GetTable(objName);
436 if (tableCache.TryGetValue(tableName, out table))
439 var source = FindVisibleTable(tableName,
false);
441 if (source == null) {
442 if (IsDynamicTable(tableName))
443 return GetDynamicTable(tableName);
447 table = CreateTableAtCommit(source);
450 tableCache[tableName] = table;
457 if (tableName == null)
458 throw new ArgumentNullException(
"tableName");
460 if (IsDynamicTable(tableName))
461 return GetDynamicTableType(tableName);
462 if (FindVisibleTable(tableName,
false) != null)
470 int sz = internalTables.Where(container => container != null).Sum(container => container.TableCount);
475 foreach (var container
in internalTables) {
476 if (container != null) {
477 int tableCount = container.TableCount;
478 for (
int i = 0; i < tableCount; ++i) {
479 list[++index] = container.GetTableName(i);
489 var table = FindVisibleTable(tableName,
true);
491 return table.TableInfo.TableName;
493 var comparison = IgnoreIdentifiersCase
494 ? StringComparison.OrdinalIgnoreCase
495 : StringComparison.Ordinal;
499 string tname = tableName.
Name;
500 var list = GetDynamicTables();
501 foreach (var ctable
in list) {
502 if (
String.Equals(ctable.ParentName, tschema, comparison) &&
503 String.Equals(ctable.Name, tname, comparison)) {
513 var table = GetTable(tableName);
518 throw new InvalidOperationException();
520 return (IMutableTable) table;
524 foreach (var info
in internalTables) {
526 int index = info.FindByName(tableName);
528 return info.GetTableInfo(index);
532 throw new Exception(
"Not an internal table: " + tableName);
537 if (IsDynamicTable(tableName))
538 return GetDynamicTableInfo(tableName);
542 .Select(table => table.TableInfo)
543 .FirstOrDefault(tableInfo => tableInfo.TableName.Equals(tableName));
550 accessedTables.Add(table);
559 if (tableInfo == null)
560 throw new ArgumentException();
562 return AlterTable(tableInfo);
573 using (var context = session.CreateQuery()) {
576 var nextId = NextUniqueId(tableName);
579 var cTable = GetTable(tableName);
580 var droppedTableId = cTable.TableInfo.Id;
582 DropTable(tableName);
585 CreateTable(tableInfo);
587 var alteredTable = GetMutableTable(tableName);
588 var source = FindVisibleTable(tableName,
false);
589 int alteredTableId = source.TableId;
592 source.SetUniqueId(nextId.ToInt64());
596 var origTd = cTable.TableInfo;
597 for (
int i = 0; i < colMap.Length; ++i) {
598 string colName = tableInfo[i].ColumnName;
604 var e = cTable.GetEnumerator();
605 while (e.MoveNext()) {
606 int rowIndex = e.Current.RowId.RowNumber;
607 var dataRow = alteredTable.NewRow();
608 for (
int i = 0; i < colMap.Length; ++i) {
611 dataRow.SetValue(i, cTable.GetValue(rowIndex, col));
615 dataRow.SetDefault(context);
620 int newRowNumber = source.AddRow(dataRow);
623 source.WriteRecordState(newRowNumber,
RecordState.CommittedAdded);
630 source.BuildIndexes();
633 SetIndexSetForTable(source, source.CreateIndexSet());
636 FlushTableCache(tableName);
654 tableCache.Remove(tableName);
658 int sz = tableIndices.Count;
659 for (
int i = 0; i < sz; ++i) {
660 if (visibleTables[i].TableId == source.
TableId) {
661 tableIndices[i] = indexSet;
666 throw new Exception(
"Table source not found in this transaction.");
670 return DropTable(objName);
675 var table = FindVisibleTable(objName, ignoreCase);
677 return table.TableInfo.TableName;
681 string tname = objName.
Name;
682 var list = GetDynamicTables();
684 var comparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
685 foreach (var ctable
in list) {
686 if (
String.Equals(ctable.ParentName, tschema, comparison) &&
687 String.Equals(ctable.Name, tname, comparison)) {
697 var source = FindVisibleTable(tableName,
false);
702 RemoveVisibleTable(source);
705 int tableId = source.TableId;
714 throw new NotImplementedException();
718 if (internalTables == null)
719 internalTables =
new List<ITableContainer>();
721 internalTables.Add(container);
725 return visibleTables.ToArray();
728 internal void AddVisibleTables(IEnumerable<TableSource> tableSources, IEnumerable<IIndexSet> indexSets) {
729 var tableList = tableSources.ToList();
730 var indexSetList = indexSets.ToList();
731 for (
int i = 0; i < tableList.Count; i++) {
732 AddVisibleTable(tableList[i], indexSetList[i]);
737 var result = (visibleTables
738 .Where(tableSource => tableSource != null)
739 .Select(tableSource => tableSource.TableInfo.TableName)).ToList();
741 var dynamicTables = GetDynamicTables();
742 if (dynamicTables != null)
743 result.AddRange(dynamicTables);
745 return result.ToArray();
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
String GetTableType(ObjectName tableName)
void AssertConstraints(ObjectName tableName)
void Dispose(bool disposing)
bool AlterObject(IObjectInfo objInfo)
Modifies an existing object managed, identified by IObjectInfo.FullName component of the given specif...
bool TableExists(ObjectName tableName)
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.
ITable GetTable(ObjectName tableName)
SqlNumber SetUniqueId(ObjectName tableName, SqlNumber value)
ObjectName[] GetDynamicTables()
A long string in the system.
The system implementation of a transaction model that handles isolated operations within a database c...
void FlushTableCache(ObjectName tableName)
void SetIndexSetForTable(ITableSource source, IIndexSet indexSet)
bool RealObjectExists(ObjectName objName)
Checks if an object really exists in the system.
string GetDynamicTableType(ObjectName tableName)
void UpdateVisibleTable(TableSource table, IIndexSet indexSet)
Represents a database object, such as a table, a trigger, a type or a column.
void CreateTemporaryTable(TableInfo tableInfo)
IMutableTable CreateTableAtCommit(ITransaction transaction)
static BinaryType Binary(int maxSize)
static readonly ObjectName CheckInfoTableName
void RegisterEvent(ITransactionEvent e)
Describes the name of an object within a database.
static readonly ObjectName PrimaryKeyInfoTableName
void CreateTable(TableInfo tableInfo)
static readonly ObjectName UniqueKeyInfoTableName
ITable GetDynamicTable(ObjectName tableName)
void AddVisibleTables(IEnumerable< TableSource > tableSources, IEnumerable< IIndexSet > indexSets)
bool AlterTable(TableInfo tableInfo)
static readonly ObjectName UniqueKeyColumnsTableName
RecordState
An enumeration that represents the various states of a record.
ObjectName TableName
Gets the fully qualified name of the table that is ensured to be unique within the system...
List< object > cleanupQueue
A new table was created during a transaction.
static readonly ObjectName ForeignKeyInfoTableName
bool RealTableExists(ObjectName tableName)
bool DropTable(ObjectName tableName)
static readonly ObjectName ForeignKeyColumnsTableName
void RemoveVisibleTable(ITableSource table)
static NumericType Numeric()
void CreateObject(IObjectInfo objInfo)
Create a new object of the ObjectType given the specifications given.
List< ITableSource > selectedTables
TransactionRegistry Registry
Provides the constant names of the types of tables in a database system.
TableInfo AsReadOnly()
Creates a new instance of TableInfo as an immutable copy of this table metadata.
ObjectName ResolveName(ObjectName objName, bool ignoreCase)
Normalizes the input object name using the case sensitivity specified.
void AddInternalTables(ITableContainer container)
A table was accessed during the transaction.
TableInfo GetDynamicTableInfo(ObjectName tableName)
void Create()
Initializes the manager into the underlying system.
ObjectName TryResolveCase(ObjectName tableName)
A container for any system tables that are generated from information inside the database engine...
TableInfo GetTableInfo(ObjectName tableName)
Provides utilities and properties for handling the SYSTEN schema of a database.
IIndexSet GetIndexSetForTable(ITableSource tableSource)
SqlNumber NextUniqueId(ObjectName tableName)
void DisposeTouchedTables()
DbObjectType ObjectType
Gets the type of objects managed by this instance.
An object that access to a set of indexes.
int IndexOfColumn(string columnName)
Gets the offset of the column with the given name.
IEnumerable< ITableSource > GetVisibleTables()
long IConvertible. ToInt64(IFormatProvider provider)
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
IEnumerable< ObjectName > GetTableNames()
string Name
Gets the name of the object being referenced.
static StringType String()
static readonly ObjectName PrimaryKeyColumnsTableName
int ColumnCount
Gets a count of the columns defined by this object.
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.
readonly Dictionary< ObjectName, IMutableTable > tableCache
IMutableTable CreateTableAtCommit(ITableSource source)
List< ITableContainer > internalTables
readonly List< ITableSource > visibleTables
readonly List< IIndexSet > tableIndices
void AddVisibleTable(ITableSource table, IIndexSet indexSet)
bool IsDynamicTable(ObjectName tableName)
Defines the contract for the business managers of database objects of a given type.
The simplest implementation of a transaction.
DbObjectType
The kind of objects that can be handled by a database system and its managers
static int IndexOfTable(IList< ITableSource > sources, int tableId)
void SelectTable(ObjectName tableName)
Defines the metadata properties of a table existing within a database.
void CreateTable(TableInfo tableInfo, bool temporary)
TableManager(ITransaction transaction, ITableSourceComposite composite)
void CompactTable(ObjectName tableName)
void CopyTable(ITableSource tableSource, IIndexSet indexSet)
List< IMutableTable > accessedTables
An interface that defines contracts to alter the contents of a table.
ITableSource FindVisibleTable(ObjectName tableName, bool ignoreCase)
IMutableTable GetMutableTable(ObjectName tableName)