/// <summary> /// Delete one or more entities as a single ACID transaction /// </summary> /// <param name="entities"></param> public void Delete(params IEntity[] entities) { Conflicts conflicts = new Conflicts(); if (!CanDelete(entities, conflicts)) { throw new OptimisticConcurrencyException(conflicts); } DoDelete(entities); }
/// <summary> /// Update one or more existing entities by replacing if id, type and version match exactly. /// </summary> /// <param name="entities"></param> internal void _Update(params IEntity[] entities) { Conflicts conflicts = new Conflicts(); if (!CanUpdate(entities, conflicts)) { throw new OptimisticConcurrencyException(conflicts); } DoUpsert(entities); }
/// <summary> /// Throw an exception if any of the keys exist /// </summary> private bool CanInsert(IEnumerable <IEntity> entities, Conflicts conflicts = null) { conflicts = conflicts ?? new Conflicts(); int numConflicts = conflicts.Inserts.Count; foreach (var entity in entities) { var set = For(entity); IEntity existing; if (set.TryGetValue(entity.Id, out existing)) { conflicts.Inserts.Add(new EntityKey(existing)); } } return(numConflicts == conflicts.Inserts.Count); }
/// <summary> /// Execute multiple inserts, updates, deletes as a single ACID transaction /// </summary> /// <param name="batch"></param> public void DoExecute(Batch batch) { var missingTypes = batch.Types().Except(_entitySets.Keys).ToArray(); if (missingTypes.Any()) { throw new MissingTypesException(missingTypes); } Conflicts conflicts = new Conflicts(); if (!CanExecute(batch, conflicts)) { throw new OptimisticConcurrencyException(conflicts); } DoUpsert(batch.Updates); DoUpsert(batch.Inserts); DoDelete(batch.Deletes); }
private bool CanUpdate(IEnumerable <IEntity> entities, Conflicts conflicts = null) { conflicts = conflicts ?? new Conflicts(); int numConflicts = conflicts.Updates.Count; foreach (var entity in entities) { var set = For(entity); if (!set.ContainsKey(entity.Id)) { conflicts.Updates.Add(new EntityKey(entity) { Version = 0 }); } else if (set[entity.Id].Version != entity.Version) { conflicts.Updates.Add(new EntityKey(set[entity.Id])); } } return(numConflicts == conflicts.Updates.Count); }
/// <summary> /// True if every entity exists and has a matching version /// </summary> private bool CanDelete(IEnumerable <IEntity> entities, Conflicts conflicts = null) { conflicts = conflicts ?? new Conflicts(); int numConflicts = conflicts.Deletes.Count; foreach (var entity in entities) { var set = For(entity); IEntity existing; if (!set.TryGetValue(entity.Id, out existing)) { conflicts.Deletes.Add(new EntityKey(entity) { Version = 0 }); } else if (existing.Version != entity.Version) { conflicts.Deletes.Add(new EntityKey(existing)); } } return(numConflicts == conflicts.Deletes.Count); }
public OptimisticConcurrencyException(Conflicts conflicts) { Conflicts = conflicts; }
private bool CanExecute(Batch batch, Conflicts conflicts) { return(CanDelete(batch.Deletes, conflicts) && CanInsert(batch.Inserts, conflicts) && CanUpdate(batch.Updates, conflicts)); }