public IEnumerable <T> ExecuteDelete <T>( IExecutionPlan <IEnumerable <T> > plan, IExecutionContext context) where T : class { var helper = new ExecutionHelper(this.Database); var table = this.Database.Tables.FindTable <T>(); var cascadedTables = helper.GetCascadedTables(table); var allTables = cascadedTables.Concat(new[] { table }).ToArray(); // Find relations // Do not add referred relations! RelationGroup allRelations = helper.FindRelations(allTables.SelectMany(x => x.Indexes), referred: false); this.AcquireWriteLock(table, context); var storedEntities = this.Query(plan, table, context); this.AcquireWriteLock(cascadedTables, context); this.LockRelatedTables(allRelations, context, except: allTables); using (AtomicLogScope log = this.StartAtomicLogOperation(context)) { IDeletePrimitive primitive = new DeletePrimitive(this.Database, log); primitive.Delete(storedEntities); log.Complete(); } return(storedEntities.ToArray()); }
public IEnumerator <T> ExecuteQuery <T>( IExecutionPlan <IEnumerable <T> > plan, IExecutionContext context) { ITable[] tables = TableLocator.FindAffectedTables(context.Database, plan); return(ExecuteQuery(plan, context, tables, cloneEntities: true)); }
public BaseController(IMapper mapper, IUnitOfWork uow, IExecutionPlan executionPlan) { Map = mapper; Uow = uow; ExecutionPlan = executionPlan; }
public Execution(string identifier, string workflowInstanceIdentifier, IWorkflowDefinition workflowDefinition, IExecutionPlan executionPlan) { Identifier = identifier; WorkflowInstanceIdentifier = workflowInstanceIdentifier; Children = new List<IExecution>(); this.executionPlan = executionPlan; this.workflowDefinition = workflowDefinition; Data = new Dictionary<string, object>(); }
public void Compile() { if (this.plan != null || !this.storeCompilation) { return; } this.plan = this.CompilePlan(); }
private IEnumerator <T> ExecuteQuery <T>( IExecutionPlan <IEnumerable <T> > plan, IExecutionContext context, ITable[] tablesToLock, bool cloneEntities) { ITable[] tables = TableLocator.FindAffectedTables(context.Database, plan); Action <T, T> cloner = null; if (cloneEntities && this.database.Tables.IsEntityType <T>()) { cloner = context .GetService <IEntityService>() .CloneProperties <T>; } LinkedList <T> result = new LinkedList <T>(); for (int i = 0; i < tablesToLock.Length; i++) { this.AcquireReadLock(tablesToLock[i], context); } IEnumerable <T> query = plan.Execute(context); try { foreach (T item in query) { if (cloner != null && item != null) { T resultEntity = Activator.CreateInstance <T>(); cloner(item, resultEntity); result.AddLast(resultEntity); } else { result.AddLast(item); } } } finally { for (int i = 0; i < tablesToLock.Length; i++) { this.ReleaseReadLock(tablesToLock[i], context); } } return(result.GetEnumerator()); }
public T ExecuteQuery <T>( IExecutionPlan <T> plan, IExecutionContext context) { ITable[] tables = TableLocator.FindAffectedTables(context.Database, plan); for (int i = 0; i < tables.Length; i++) { this.AcquireReadLock(tables[i], context); } try { var item = plan.Execute(context); EntityPropertyCloner <T> cloner = null; if (this.database.Tables.IsEntityType <T>()) { cloner = EntityPropertyCloner <T> .Instance; } if (cloner != null && item != null) { var cloned = Activator.CreateInstance <T>(); cloner.Clone(item, cloned); // Remove Aliased Attributes these are getting added by the Query Plan Execution #pragma warning disable IDE0019 // Use pattern matching var entity = item as Entity; #pragma warning restore IDE0019 // Use pattern matching if (entity != null) { foreach (var attribute in entity.Attributes.ToList().Where(attribute => attribute.Value is AliasedValue)) { entity.Attributes.Remove(attribute.Key); } } return(cloned); } else { return(item); } } finally { for (int i = 0; i < tables.Length; i++) { this.ReleaseReadLock(tables[i], context); } } }
// TODO: builder public Execution(IExecution parent, INode currentNode, bool isActive, bool isFinished, IDictionary<string, object> data, string incomingTransition, string identifier, string workflowInstanceIdentifier, IExecutionPlan executionPlan, IList<IExecution> children, IWorkflowDefinition workflowDefinition) : this(identifier, workflowInstanceIdentifier, workflowDefinition, executionPlan) { Parent = parent; IncomingTransition = incomingTransition; CurrentNode = currentNode; IsActive = isActive; Data = data; Children = children; IsFinished = isFinished; }
public static ITable[] FindAffectedTables(IDatabase database, IExecutionPlan plan) { EntityTypeSearchVisitor search = new EntityTypeSearchVisitor(); search.Visit(plan.Info.Final); ISet<ITable> result = new HashSet<ITable>(); foreach (Type entityType in search.FoundEntityTypes) { result.Add(database.Tables.FindTable(entityType)); } return result.ToArray(); }
public IExecution TransformBack(ExecutionModel model, IWorkflowDefinition workflowDefinition, IExecutionPlan plan) { if (model == null) { return null; } var root = FindRoot(model); var transformedRoot = TransformBack(root, plan, workflowDefinition, null); var collector = new ExecutionCollector(e => e.Identifier == model.Identifier); transformedRoot.Accept(collector); return collector.Result.First(); }
public static ITable[] FindAffectedTables(IDatabase database, IExecutionPlan plan) { EntityTypeSearchVisitor search = new EntityTypeSearchVisitor(); search.Visit(plan.Info.Final); ISet <ITable> result = new HashSet <ITable>(); foreach (Type entityType in search.FoundEntityTypes) { result.Add(database.Tables.FindTable(entityType)); } return(result.ToArray()); }
private List <T> Query <T>( IExecutionPlan <IEnumerable <T> > plan, ITable <T> table, IExecutionContext context) where T : class { ITable[] queryTables = TableLocator.FindAffectedTables(context.Database, plan); var query = this.ExecuteQuery( plan, context, queryTables.Except(new[] { table }).ToArray(), cloneEntities: false); return(query.ToEnumerable().ToList()); }
public TResult Execute <TResult>(Expression expression) { Transaction transaction = Transaction.TryGetAmbientEnlistedTransaction(); using (var tran = Transaction.EnsureTransaction(ref transaction, this.database)) { IExecutionPlan <TResult> plan = this.database.DatabaseEngine.Compiler.Compile <TResult>(expression); IExecutionContext context = new ExecutionContext( this.database, transaction, OperationType.Query); TResult result = this.database.DatabaseEngine.Executor.ExecuteQuery <TResult>(plan, context); tran.Complete(); return(result); } }
public T ExecuteQuery <T>( IExecutionPlan <T> plan, IExecutionContext context) { ITable[] tables = TableLocator.FindAffectedTables(context.Database, plan); for (int i = 0; i < tables.Length; i++) { this.AcquireReadLock(tables[i], context); } Action <T, T> cloner = context .GetService <IEntityService>() .CloneProperties <T>; try { var result = plan.Execute(context); if (this.database.Tables.IsEntityType <T>() && result != null) { T resultEntity = Activator.CreateInstance <T>(); cloner(result, resultEntity); result = resultEntity; } return(result); } finally { for (int i = 0; i < tables.Length; i++) { this.ReleaseReadLock(tables[i], context); } } }
internal IEnumerator <TEntity> GetEnumerator( IDictionary <string, object> parameters, Transaction transaction) { IExecutionPlan <IEnumerable <TEntity> > planToExecute = null; if (this.storeCompilation) { this.Compile(); planToExecute = this.plan; } else { planToExecute = this.CompilePlan(); } using (TransactionContext transactionContext = Transaction.EnsureTransaction(ref transaction, this.Database)) { IExecutionContext executionContext = new ExecutionContext( this.Database, transaction, OperationType.Query, parameters); IEnumerator <TEntity> result = this.Database.DatabaseEngine.Executor.ExecuteQuery( planToExecute, executionContext); transactionContext.Complete(); return(result); } }
public IExecution LoadExecution(string executionIdentifier, IExecutionPlan plan) { return executions[executionIdentifier]; }
public override void Execute(IExecution execution, IExecutionPlan executionPlan) { action(true); base.Execute(execution, executionPlan); }
private IEnumerator <T> ExecuteQuery <T>( IExecutionPlan <IEnumerable <T> > plan, IExecutionContext context, ITable[] tablesToLock, bool cloneEntities) { ITable[] tables = TableLocator.FindAffectedTables(context.Database, plan); EntityPropertyCloner <T> cloner = null; if (cloneEntities && this.database.Tables.IsEntityType <T>()) { cloner = EntityPropertyCloner <T> .Instance; } LinkedList <T> result = new LinkedList <T>(); for (int i = 0; i < tablesToLock.Length; i++) { this.AcquireReadLock(tablesToLock[i], context); } IEnumerable <T> query = plan.Execute(context); try { foreach (T item in query) { if (cloner != null) { T resultEntity = Activator.CreateInstance <T>(); cloner.Clone(item, resultEntity); result.AddLast(resultEntity); // Remove Aliased Attributes these are getting added by the Query Plan Execution #pragma warning disable IDE0019 // Use pattern matching var entity = item as Entity; #pragma warning restore IDE0019 // Use pattern matching if (entity != null) { foreach (var attribute in entity.Attributes.ToList().Where(attribute => attribute.Value is AliasedValue)) { entity.Attributes.Remove(attribute.Key); } } } else { result.AddLast(item); } } } finally { for (int i = 0; i < tablesToLock.Length; i++) { this.ReleaseReadLock(tablesToLock[i], context); } } return(result.GetEnumerator()); }
public BlogController(IMapper mapper, IUnitOfWork uow, IExecutionPlan executionPlan) : base(mapper, uow, executionPlan) { }
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); }
public virtual void Execute(IExecution execution, IExecutionPlan executionPlan) { executionPlan.Proceed(execution, this); }
public Lift(FloorConfiguration floorConfiguration, IExecutionPlan executionPlan) { _floorConfiguration = floorConfiguration; _executionPlan = executionPlan; }
public IExecution LoadExecution(string executionIdentifier, IExecutionPlan executionPlan) { var rootQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})") .OptionalMatch("(r:Execution)-[:PARENT_OF*]->(e)") .OptionalMatch("(r)-[:EXECUTES]->(currentNode:Node)") .Where("NOT (:Execution)-[:PARENT_OF*]->(r)") .WithParam("id", executionIdentifier) .Return((r, e, currentNode) => new { Root = r.As<ExecutionModel>(), Current = e.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); var executionModel = rootQuery.Results.Last(); var root = executionModel.Root ?? executionModel.Current; var wfQuery = graphClient.Cypher .Match("(e:Execution {Identifier: {id}})-[*]->(n:Node)") .Match("(wf:WorkflowDefinition)-[*]->(n)") .OptionalMatch( "(e:Execution {Identifier: {id}})-[:REFERENCES]->(wf:WorkflowDefinition)") .WithParam("id", root.Identifier) .Return(wf => wf.As<WorkflowDefinitionModel>()); var workflowDefinition = LoadWorkflowDefinition(wfQuery.Results.First().Identifier); Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(root.Data, typeof (Dictionary<string, object>)); var children = new List<IExecution>(); var rootExecution = new Execution(null, executionModel.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == executionModel.CurrentNode.Identifier), root.IsActive, root.IsFinished, data, root.IncomingTransition, root.Identifier, root.WorkflowInstanceIdentifier, executionPlan, children, workflowDefinition); FillChildren(rootExecution, children, executionPlan, workflowDefinition); var collector = new ExecutionCollector(e => e.Identifier == executionIdentifier); rootExecution.Accept(collector); return collector.Result.First(); }
private IExecution TransformBack(ExecutionModel model, IExecutionPlan plan, IWorkflowDefinition workflowDefinition, IExecution parent) { IDictionary<string, object> data = new Dictionary<string, object>(); foreach (var variable in model.Variables) { data.Add(variable.VariableKey, serializer.Deserialize(variable.SerializedValue, Type.GetType(variable.ValueType))); } IList<IExecution> children = new List<IExecution>(); var execution = new Execution(parent, workflowDefinition.Nodes.FirstOrDefault(n => n.Identifier == model.CurrentNodeIdentifier), model.IsActive, model.IsFinished, data, model.IncomingTransition, model.Identifier, model.WorkflowInstanceIdentifier, plan, children, workflowDefinition); foreach (var child in model.Children) { children.Add(TransformBack(child, plan, workflowDefinition, execution)); } return execution; }
public IExecution LoadExecution(string executionIdentifier, IExecutionPlan executionPlan) { using (var session = sessionFactory.OpenSession()) { var model = session.QueryOver<ExecutionModel>() .Where(w => w.Identifier == executionIdentifier) .SingleOrDefault(); if (model == null) { return null; } var wf = LoadWorkflowDefinition(model.WorkflowDefinitionIdentifier); return executionTransformer.TransformBack(model, wf, executionPlan); } }
private void FillChildren(IExecution parent, List<IExecution> children, IExecutionPlan executionPlan, IWorkflowDefinition workflowDefinition) { var result = graphClient.Cypher .Match("(root:Execution {Identifier: {id}})") .Match("(root)-[:PARENT_OF]->(child:Execution)") .OptionalMatch("(child)-[:EXECUTES]->(currentNode:Node)") .WithParam("id", parent.Identifier) .Return((child, currentNode) => new { Child = child.As<ExecutionModel>(), CurrentNode = currentNode.As<NodeModel>() }); foreach (var r in result.Results) { Dictionary<string, object> data = (Dictionary<string, object>) objectSerializer.Deserialize(r.Child.Data, typeof (Dictionary<string, object>)); var childExecutions = new List<IExecution>(); var e = new Execution(parent, r.CurrentNode == null ? null : workflowDefinition.Nodes.First(n => n.Identifier == r.CurrentNode.Identifier), r.Child.IsActive, r.Child.IsFinished, data, r.Child.IncomingTransition, r.Child.Identifier, r.Child.WorkflowInstanceIdentifier, executionPlan, childExecutions, workflowDefinition); children.Add(e); FillChildren(e, childExecutions, executionPlan, workflowDefinition); } }