private ITable[] FindChangedTables(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables) { var changedTableSource = new ITable[normalizedChangedTables.Length]; // Set up the above arrays for (int i = 0; i < normalizedChangedTables.Length; ++i) { // Get the information for this changed table CommitTableInfo tableInfo = normalizedChangedTables[i]; // Get the master table that changed from the normalized list. TableSource master = tableInfo.Master; // Did this table change since the transaction started? TableEventRegistry[] allTableChanges = tableInfo.ChangesSinceCommit; if (allTableChanges == null || allTableChanges.Length == 0) { // No changes so we can pick the correct IIndexSet from the current // transaction. // Get the state of the changed tables from the Transaction var mtable = Transaction.GetMutableTable(master.TableName); // Get the current index set of the changed table tableInfo.IndexSet = Transaction.GetIndexSetForTable(master); // Flush all index changes in the table mtable.FlushIndexes(); // Set the 'check_transaction' object with the latest version of the // table. checkTransaction.UpdateVisibleTable(tableInfo.Master, tableInfo.IndexSet); } else { // There were changes so we need to merge the changes with the // current view of the table. // It's not immediately obvious how this merge update works, but // basically what happens is we WriteByte the table journal with all the // changes into a new IMutableTableDataSource of the current // committed state, and then we flush all the changes into the // index and then update the 'check_transaction' with this change. // Create the IMutableTableDataSource with the changes from this // journal. var mtable = master.CreateTableAtCommit(checkTransaction, tableInfo.Journal); // Get the current index set of the changed table tableInfo.IndexSet = checkTransaction.GetIndexSetForTable(master); // Flush all index changes in the table mtable.FlushIndexes(); // Dispose the table mtable.Dispose(); } // And now refresh the 'changedTableSource' entry changedTableSource[i] = checkTransaction.GetTable(master.TableName); } return(changedTableSource); }
private void CheckConstraintViolations(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables, ITable[] changedTableSource) { // Any tables that the constraints were altered for we need to check // if any rows in the table violate the new constraints. foreach (var tableId in ConstraintAlteredTables) { // We need to check there are no constraint violations for all the // rows in the table. for (int n = 0; n < normalizedChangedTables.Length; ++n) { CommitTableInfo tableInfo = normalizedChangedTables[n]; if (tableInfo.Master.TableId == tableId) { checkTransaction.CheckAddConstraintViolations(changedTableSource[n], ConstraintDeferrability.InitiallyDeferred); } } } // For each changed table we must determine the rows that // were deleted and perform the remove constraint checks on the // deleted rows. Note that this happens after the records are // removed from the index. // For each changed table, for (int i = 0; i < normalizedChangedTables.Length; ++i) { CommitTableInfo tableInfo = normalizedChangedTables[i]; // Get the journal that details the change to the table. TableEventRegistry changeJournal = tableInfo.Journal; if (changeJournal != null) { // Find the normalized deleted rows. int[] normalizedRemovedRows = changeJournal.RemovedRows.ToArray(); // Check removing any of the data doesn't cause a constraint // violation. checkTransaction.CheckRemoveConstraintViolations(changedTableSource[i], normalizedRemovedRows, ConstraintDeferrability.InitiallyDeferred); // Find the normalized added rows. int[] normalizedAddedRows = changeJournal.AddedRows.ToArray(); // Check adding any of the data doesn't cause a constraint // violation. checkTransaction.CheckAddConstraintViolations(changedTableSource[i], normalizedAddedRows, ConstraintDeferrability.InitiallyDeferred); // Set up the list of added and removed rows tableInfo.NormalizedAddedRows = normalizedAddedRows; tableInfo.NormalizedRemovedRows = normalizedRemovedRows; } } }
private CommitTableInfo[] GetNormalizedChangedTables() { // Create a normalized list of TableSource of all tables that // were either changed (and not dropped), and created (and not dropped). // This list represents all tables that are either new or changed in // this transaction. var normalizedChangedTables = new List <CommitTableInfo>(8); // Add all tables that were changed and not dropped in this transaction. normalizedChangedTables.AddRange( ChangedTables.Select(tableJournal => new { tableJournal, tableId = tableJournal.TableId }) .Where(t => !DroppedTables.Contains(t.tableId)) .Select(t => new { t, masterTable = Composite.GetTableSource(t.tableId) }) .Select(t => new CommitTableInfo { Master = t.masterTable, Journal = t.t.tableJournal, ChangesSinceCommit = t.masterTable.FindChangesSinceCmmit(CommitId).ToArray() })); // Add all tables that were created and not dropped in this transaction. foreach (var tableId in CreatedTables) { // If this table is not dropped in this transaction then this is a // new table in this transaction. if (!DroppedTables.Contains(tableId)) { TableSource masterTable = Composite.GetTableSource(tableId); if (!CommitTableListContains(normalizedChangedTables, masterTable)) { // This is for entries that are created but modified (no journal). var tableInfo = new CommitTableInfo { Master = masterTable }; normalizedChangedTables.Add(tableInfo); } } } return(normalizedChangedTables.ToArray()); }
private CommitTableInfo[] GetNormalizedChangedTables() { // Create a normalized list of TableSource of all tables that // were either changed (and not dropped), and created (and not dropped). // This list represents all tables that are either new or changed in // this transaction. var normalizedChangedTables = new List<CommitTableInfo>(8); // Add all tables that were changed and not dropped in this transaction. normalizedChangedTables.AddRange( ChangedTables.Select(tableJournal => new { tableJournal, tableId = tableJournal.TableId }) .Where(t => !DroppedTables.Contains(t.tableId)) .Select(t => new { t, masterTable = Composite.GetTableSource(t.tableId) }) .Select(t => new CommitTableInfo { Master = t.masterTable, Journal = t.t.tableJournal, ChangesSinceCommit = t.masterTable.FindChangesSinceCmmit(CommitId).ToArray() })); // Add all tables that were created and not dropped in this transaction. foreach (var tableId in CreatedTables) { // If this table is not dropped in this transaction then this is a // new table in this transaction. if (!DroppedTables.Contains(tableId)) { TableSource masterTable = Composite.GetTableSource(tableId); if (!CommitTableListContains(normalizedChangedTables, masterTable)) { // This is for entries that are created but modified (no journal). var tableInfo = new CommitTableInfo { Master = masterTable }; normalizedChangedTables.Add(tableInfo); } } } return normalizedChangedTables.ToArray(); }
private void FireChangeEvents(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables, Action<TableCommitInfo> commitActions) { if (commitActions == null) return; foreach (var tableInfo in normalizedChangedTables) { // Get the journal that details the change to the table. TableEventRegistry changeJournal = tableInfo.Journal; if (changeJournal != null) { // Get the table name var tableName = tableInfo.Master.TableName; commitActions(new TableCommitInfo(checkTransaction.CommitId, tableName, tableInfo.NormalizedAddedRows, tableInfo.NormalizedAddedRows)); } } }
private ITable[] FindChangedTables(ITransaction checkTransaction, CommitTableInfo[] normalizedChangedTables) { var changedTableSource = new ITable[normalizedChangedTables.Length]; // Set up the above arrays for (int i = 0; i < normalizedChangedTables.Length; ++i) { // Get the information for this changed table CommitTableInfo tableInfo = normalizedChangedTables[i]; // Get the master table that changed from the normalized list. TableSource master = tableInfo.Master; // Did this table change since the transaction started? TableEventRegistry[] allTableChanges = tableInfo.ChangesSinceCommit; if (allTableChanges == null || allTableChanges.Length == 0) { // No changes so we can pick the correct IIndexSet from the current // transaction. // Get the state of the changed tables from the Transaction var mtable = Transaction.GetMutableTable(master.TableName); // Get the current index set of the changed table tableInfo.IndexSet = Transaction.GetIndexSetForTable(master); // Flush all index changes in the table mtable.FlushIndexes(); // Set the 'check_transaction' object with the latest version of the // table. checkTransaction.UpdateVisibleTable(tableInfo.Master, tableInfo.IndexSet); } else { // There were changes so we need to merge the changes with the // current view of the table. // It's not immediately obvious how this merge update works, but // basically what happens is we WriteByte the table journal with all the // changes into a new IMutableTableDataSource of the current // committed state, and then we flush all the changes into the // index and then update the 'check_transaction' with this change. // Create the IMutableTableDataSource with the changes from this // journal. var mtable = master.CreateTableAtCommit(checkTransaction, tableInfo.Journal); // Get the current index set of the changed table tableInfo.IndexSet = checkTransaction.GetIndexSetForTable(master); // Flush all index changes in the table mtable.FlushIndexes(); // Dispose the table mtable.Dispose(); } // And now refresh the 'changedTableSource' entry changedTableSource[i] = checkTransaction.GetTable(master.TableName); } return changedTableSource; }