Ejemplo n.º 1
0
        public void Release(Scope scope, bool valid)
        {
            switch (Mode)
            {
            case PoolMode.None:
                Queries.EndQuery(scope.Query, valid);
                scope.Factory.Dispose();
                break;

            default:
                if (valid && !scope.Query.InTransaction && Scopes.Count < Size)
                {
                    Scopes.Add(scope);
                }
                else
                {
                    Queries.EndQuery(scope.Query, valid);
                    scope.Factory.Dispose();
                    if (Scopes.Count < Size)
                    {
                        Scopes.Add(SetupReadonlyScope());
                    }
                }
                break;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Rollback started transaction.
        /// </summary>
        /// <param name="manager">query manager</param>
        /// <param name="query">ADO.NET driver</param>
        public static void Rollback(this IDatabaseQueryManager manager, IDatabaseQuery query)
        {
            Contract.Requires(manager != null);
            Contract.Requires(query != null);

            if (!query.InTransaction)
            {
                throw new ArgumentException("Only queries in transaction can be rollbacked");
            }
            manager.EndQuery(query, false);
        }
Ejemplo n.º 3
0
        public IProcessingResult <TOutput> Execute <TInput, TOutput>(IServerCommandDescription <TInput>[] commandDescriptions)
        {
            if (commandDescriptions == null || commandDescriptions.Length == 0)
            {
                return
                    (ProcessingResult <TOutput> .Create(
                         "There are no commands to execute.",
                         HttpStatusCode.BadRequest,
                         null,
                         0));
            }

            var stopwatch = Stopwatch.StartNew();

            foreach (var c in commandDescriptions)
            {
                if (!Permissions.CanAccess(c.CommandType))
                {
                    Logger.Trace(
                        () => "Access denied. User: {0}. Target: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            c.CommandType.FullName));
                    return
                        (ProcessingResult <TOutput> .Create(
                             "You don't have permission to execute command: " + c.CommandType.FullName,
                             HttpStatusCode.Forbidden,
                             null,
                             stopwatch.ElapsedMilliseconds));
                }
            }

            var inputSerializer  = GetSerializer <TInput>();
            var outputSerializer = GetSerializer <TOutput>();

            var commands       = new CommandInfo <TInput> [commandDescriptions.Length];
            var useTransaction = false;

            for (int i = 0; i < commands.Length; i++)
            {
                var c = commands[i] = new CommandInfo <TInput>(commandDescriptions[i], ActualCommands);
                useTransaction = useTransaction || !c.IsReadOnly;
                if (c.Target == null)
                {
                    Logger.Trace(
                        () => "Unknown target. User: {0}. Target: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            commandDescriptions[i].CommandType.FullName));
                    return
                        (ProcessingResult <TOutput> .Create(
                             "Unknown command: {0}. Check if requested command is registered in the system".With(
                                 c.Description.CommandType),
                             HttpStatusCode.BadRequest,
                             null,
                             stopwatch.ElapsedMilliseconds));
                }
            }

            var scopeID = useTransaction ? Guid.NewGuid().ToString() : null;

            using (var scope = ObjectFactory.CreateScope(scopeID))
            {
                var            executedCommands = new List <ICommandResultDescription <TOutput> >(commandDescriptions.Length);
                IDatabaseQuery query            = null;
                try
                {
                    try
                    {
                        query = TransactionManager.StartQuery(useTransaction);
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Can't start query. Error: " + ex.ToString());
                        return(Exceptions.DebugMode
                                                        ? ProcessingResult <TOutput> .Create(
                                   ex.ToString(),
                                   HttpStatusCode.ServiceUnavailable,
                                   null,
                                   stopwatch.ElapsedMilliseconds)
                                                        : ProcessingResult <TOutput> .Create(
                                   "Unable to create database connection",
                                   HttpStatusCode.ServiceUnavailable,
                                   null,
                                   stopwatch.ElapsedMilliseconds));
                    }
                    scope.RegisterInstance(query);
                    if (useTransaction)
                    {
                        scope.RegisterInstance <IEnumerable <IServerCommandDescription <TInput> > >(commandDescriptions);
                        scope.RegisterInstance <IEnumerable <ICommandResultDescription <TOutput> > >(executedCommands);
                        scope.RegisterType(typeof(ProcessingContext), typeof(IProcessingEngine), InstanceScope.Singleton);
                    }
                    foreach (var cmd in commands)
                    {
                        var result = cmd.GetCommand(scope).Execute(inputSerializer, outputSerializer, cmd.Description.Data);
                        if (result == null)
                        {
                            throw new FrameworkException("Result returned null for " + cmd.Target.FullName);
                        }
                        executedCommands.Add(CommandResultDescription <TOutput> .Create(cmd.Description.RequestID, result));
                        if ((int)result.Status >= 400)
                        {
                            TransactionManager.EndQuery(query, false);
                            return(ProcessingResult <TOutput> .Create(
                                       result.Message,
                                       result.Status,
                                       executedCommands,
                                       stopwatch.ElapsedMilliseconds));
                        }
                    }

                    TransactionManager.EndQuery(query, true);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "Commands executed in: " + stopwatch.ElapsedMilliseconds.ToString() + " ms.",
                             HttpStatusCode.OK,
                             executedCommands,
                             stopwatch.ElapsedMilliseconds));
                }
                catch (SecurityException ex)
                {
                    Logger.Trace(
                        () => "Security error. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.ToString()));
                    TransactionManager.EndQuery(query, false);
                    return
                        (ProcessingResult <TOutput> .Create(
                             "You don't have authorization to perform requested action: " + ex.Message,
                             HttpStatusCode.Forbidden,
                             executedCommands,
                             stopwatch.ElapsedMilliseconds));
                }
                catch (AggregateException ex)
                {
                    Logger.Trace(
                        () => "Multiple errors. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.GetDetailedExplanation()));
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               string.Join(Environment.NewLine, ex.InnerExceptions.Select(it => it.Message)),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
                catch (OutOfMemoryException ex)
                {
                    Logger.Error("Out of memory error. Error: " + ex.GetDetailedExplanation());
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.ServiceUnavailable,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               ex.Message,
                               HttpStatusCode.ServiceUnavailable,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
                catch (Exception ex)
                {
                    Logger.Trace(
                        () => "Unexpected error. User: {0}. Error: {1}.".With(
                            Thread.CurrentPrincipal.Identity.Name,
                            ex.GetDetailedExplanation()));
                    TransactionManager.EndQuery(query, false);
                    return(Exceptions.DebugMode
                                                ? ProcessingResult <TOutput> .Create(
                               ex.GetDetailedExplanation(),
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds)
                                                : ProcessingResult <TOutput> .Create(
                               ex.Message,
                               HttpStatusCode.InternalServerError,
                               executedCommands,
                               stopwatch.ElapsedMilliseconds));
                }
            }
        }