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));
        }
Exemple #3
0
 public BaseController(IMapper mapper,
                       IUnitOfWork uow,
                       IExecutionPlan executionPlan)
 {
     Map           = mapper;
     Uow           = uow;
     ExecutionPlan = executionPlan;
 }
Exemple #4
0
 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>();
 }
Exemple #5
0
        public void Compile()
        {
            if (this.plan != null || !this.storeCompilation)
            {
                return;
            }

            this.plan = this.CompilePlan();
        }
Exemple #6
0
        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);
                }
            }
        }
Exemple #8
0
 // 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);
            }
        }
Exemple #14
0
        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);
                }
            }
        }
Exemple #15
0
        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];
 }
Exemple #17
0
            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);
        }
Exemple #21
0
 public virtual void Execute(IExecution execution, IExecutionPlan executionPlan)
 {
     executionPlan.Proceed(execution, this);
 }
Exemple #22
0
 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);
            }
        }