public void ExecuteInsert <T>(T entity, IExecutionContext context) where T : class { var helper = new ExecutionHelper(this.Database); var table = this.Database.Tables.FindTable <T>(); table.Contraints.Apply(entity, context); // Find referred relations // Do not add referring relations! RelationGroup relations = helper.FindRelations(table.Indexes, referring: false); // Acquire locks this.AcquireWriteLock(table, context); this.LockRelatedTables(relations, context, table); try { // Validate the inserted record helper.ValidateForeignKeys(relations.Referred, new[] { entity }); using (AtomicLogScope logScope = this.StartAtomicLogOperation(context)) { foreach (IIndex <T> index in table.Indexes) { index.Insert(entity); logScope.Log.WriteIndexInsert(index, entity); } logScope.Complete(); } } finally { this.ReleaseWriteLock(table, context); } }
public IEnumerable <T> ExecuteUpdater <T>( IExecutionPlan <IEnumerable <T> > plan, IUpdater <T> updater, IExecutionContext context) where T : class { var helper = new ExecutionHelper(this.Database); var table = this.Database.Tables.FindTable <T>(); var cloner = EntityPropertyCloner <T> .Instance; // Determine which indexes are affected by the change // If the key of an index containes a changed property, it is affected IList <IIndex <T> > affectedIndexes = helper.FindAffectedIndexes(table, updater.Changes); // Find relations // Add both referring and referred relations! RelationGroup relations = helper.FindRelations(affectedIndexes); this.AcquireWriteLock(table, context); var storedEntities = Query(plan, table, context); // Lock related tables (based on found relations) this.LockRelatedTables(relations, context, table); // Find the entities referring the entities that are about to be updated var referringEntities = helper.FindReferringEntities(storedEntities, relations.Referring); using (AtomicLogScope logScope = this.StartAtomicLogOperation(context)) { // Delete invalid index records (keys are invalid) for (int i = 0; i < storedEntities.Count; i++) { T storedEntity = storedEntities[i]; foreach (IIndex <T> index in affectedIndexes) { index.Delete(storedEntity); logScope.Log.WriteIndexDelete(index, storedEntity); } } // Modify entity properties for (int i = 0; i < storedEntities.Count; i++) { T storedEntity = storedEntities[i]; // Create backup T backup = Activator.CreateInstance <T>(); cloner.Clone(storedEntity, backup); T newEntity = updater.Update(storedEntity); // Apply contraints on the entity table.Contraints.Apply(newEntity, context); // Update entity cloner.Clone(newEntity, storedEntity); logScope.Log.WriteEntityUpdate(cloner, storedEntity, backup); } // Insert to indexes the entities were removed from for (int i = 0; i < storedEntities.Count; i++) { T storedEntity = storedEntities[i]; foreach (IIndex <T> index in affectedIndexes) { index.Insert(storedEntity); logScope.Log.WriteIndexInsert(index, storedEntity); } } // Validate the updated entities helper.ValidateForeignKeys(relations.Referred, storedEntities); // Validate the entities that were referring to the old version of entities helper.ValidateForeignKeys(relations.Referring, referringEntities); logScope.Complete(); } return(storedEntities); }