Exemple #1
0
        /// <summary>
        /// Creates the command processor.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="connection">The connection.</param>
        /// <returns>Created command processor.</returns>
        public CommandProcessor CreateCommandProcessor(Session session, SqlConnection connection)
        {
            var configuration = session.Configuration;
            var useBatches    = configuration.BatchSize > 1 &&
                                providerInfo.Supports(ProviderFeatures.DmlBatches);
            var useCursorParameters =
                providerInfo.Supports(ProviderFeatures.MultipleResultsViaCursorParameters);

            var factory = useCursorParameters
        ? new CursorCommandFactory(driver, session, connection)
        : new CommandFactory(driver, session, connection);

            var processor = useBatches
        ? new BatchingCommandProcessor(factory, configuration.BatchSize, session.Domain.StorageProviderInfo.MaxQueryParameterCount)
        : (CommandProcessor) new SimpleCommandProcessor(factory, session.Domain.StorageProviderInfo.MaxQueryParameterCount);

            return(processor);
        }
        // Constructors

        public ExpressionProcessor(
            LambdaExpression lambda, HandlerAccessor handlers, SqlCompiler compiler, params IReadOnlyList <SqlExpression>[] sourceColumns)
        {
            ArgumentValidator.EnsureArgumentNotNull(lambda, "lambda");
            ArgumentValidator.EnsureArgumentNotNull(handlers, "handlers");
            ArgumentValidator.EnsureArgumentNotNull(sourceColumns, "sourceColumns");

            this.compiler      = compiler; // This might be null, check before use!
            this.lambda        = lambda;
            this.sourceColumns = sourceColumns;

            providerInfo = handlers.ProviderInfo;
            driver       = handlers.StorageDriver;

            fixBooleanExpressions      = !providerInfo.Supports(ProviderFeatures.FullFeaturedBooleanExpressions);
            emptyStringIsNull          = providerInfo.Supports(ProviderFeatures.TreatEmptyStringAsNull);
            dateTimeEmulation          = providerInfo.Supports(ProviderFeatures.DateTimeEmulation);
            dateTimeOffsetEmulation    = providerInfo.Supports(ProviderFeatures.DateTimeOffsetEmulation);
            memberCompilerProvider     = handlers.DomainHandler.GetMemberCompilerProvider <SqlExpression>();
            specialByteArrayComparison = providerInfo.ProviderName.Equals(WellKnown.Provider.Oracle);

            bindings           = new HashSet <QueryParameterBinding>();
            activeParameters   = new List <ParameterExpression>();
            evaluator          = new ExpressionEvaluator(lambda);
            parameterExtractor = new ParameterExtractor(evaluator);

            if (fixBooleanExpressions)
            {
                booleanExpressionConverter = new BooleanExpressionConverter(driver);
            }
            if (lambda.Parameters.Count != sourceColumns.Length)
            {
                throw Exceptions.InternalError(Strings.ExParametersCountIsNotSameAsSourceColumnListsCount, OrmLog.Instance);
            }
            if (sourceColumns.Any(list => list.Any(c => c.IsNullReference())))
            {
                throw Exceptions.InternalError(Strings.ExSourceColumnListContainsNullValues, OrmLog.Instance);
            }
            sourceMapping = new Dictionary <ParameterExpression, IReadOnlyList <SqlExpression> >();
        }
        internal ICollection <PersistRequest> Build(StorageNode node, PersistRequestBuilderTask task)
        {
            var context = new PersistRequestBuilderContext(task, node.Mapping, node.Configuration);
            List <PersistRequest> result;

            switch (task.Kind)
            {
            case PersistRequestKind.Insert:
                result = BuildInsertRequest(context);
                break;

            case PersistRequestKind.Remove:
                result = BuildRemoveRequest(context);
                break;

            case PersistRequestKind.Update:
                result = BuildUpdateRequest(context);
                break;

            default:
                throw new ArgumentOutOfRangeException("task.Kind");
            }

            // Merging requests for servers which support batching
            // unless version validation is requested.
            if (providerInfo.Supports(ProviderFeatures.Batches) && result.Count > 1 && !task.ValidateVersion)
            {
                var batch    = SqlDml.Batch();
                var bindings = new HashSet <PersistParameterBinding>();
                foreach (var request in result)
                {
                    batch.Add(request.Statement);
                    bindings.UnionWith(request.ParameterBindings);
                }
                var batchRequest = CreatePersistRequest(batch, bindings, node.Configuration);
                batchRequest.Prepare();
                return(new List <PersistRequest> {
                    batchRequest
                }.AsReadOnly());
            }

            foreach (var item in result)
            {
                item.Prepare();
            }

            return(result.AsReadOnly());
        }
        // Constructors

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        public SqlCompiler(HandlerAccessor handlers, CompilerConfiguration configuration)
        {
            Handlers          = handlers;
            OuterReferences   = new BindingCollection <ApplyParameter, Pair <SqlProvider, bool> >();
            Mapping           = configuration.StorageNode.Mapping;
            TypeIdRegistry    = configuration.StorageNode.TypeIdRegistry;
            NodeConfiguration = configuration.StorageNode.Configuration;

            providerInfo             = Handlers.ProviderInfo;
            temporaryTablesSupported = DomainHandler.TemporaryTableManager.Supported;

            if (!providerInfo.Supports(ProviderFeatures.FullFeaturedBooleanExpressions))
            {
                booleanExpressionConverter = new BooleanExpressionConverter(Driver);
            }

            stubColumnMap = new Dictionary <SqlColumnStub, SqlExpression>();
        }
        /// <inheritdoc/>
        protected override SqlProvider VisitJoin(JoinProvider provider)
        {
            var left  = Compile(provider.Left);
            var right = Compile(provider.Right);

            // SQLite does not allow certain join combinations
            // Any right part of join expression should not be join itself
            // See IssueA363_WrongInnerJoin for example of such query

            var strictJoinWorkAround =
                providerInfo.Supports(ProviderFeatures.StrictJoinSyntax) &&
                right.Request.Statement.From is SqlJoinedTable;

            var leftShouldUseReference = ShouldUseQueryReference(provider, left);
            var leftTable = leftShouldUseReference
        ? left.PermanentReference
        : left.Request.Statement.From;
            var leftColumns = leftShouldUseReference
        ? leftTable.Columns.Cast <SqlColumn>()
        : left.Request.Statement.Columns;
            var leftExpressions = leftShouldUseReference
        ? leftTable.Columns.Cast <SqlExpression>().ToList()
        : ExtractColumnExpressions(left.Request.Statement);

            var rightShouldUseReference = strictJoinWorkAround || ShouldUseQueryReference(provider, right);
            var rightTable = rightShouldUseReference
        ? right.PermanentReference
        : right.Request.Statement.From;
            var rightColumns = rightShouldUseReference
        ? rightTable.Columns.Cast <SqlColumn>()
        : right.Request.Statement.Columns;
            var rightExpressions = rightShouldUseReference
        ? rightTable.Columns.Cast <SqlExpression>().ToList()
        : ExtractColumnExpressions(right.Request.Statement);

            var joinType = provider.JoinType == JoinType.LeftOuter
        ? SqlJoinType.LeftOuterJoin
        : SqlJoinType.InnerJoin;

            SqlExpression joinExpression = null;

            for (var i = 0; i < provider.EqualIndexes.Count(); ++i)
            {
                var leftExpression  = leftExpressions[provider.EqualIndexes[i].First];
                var rightExpression = rightExpressions[provider.EqualIndexes[i].Second];
                joinExpression &= GetJoinExpression(leftExpression, rightExpression, provider, i);
            }

            var joinedTable = SqlDml.Join(
                joinType,
                leftTable,
                rightTable,
                leftColumns.ToList(),
                rightColumns.ToList(),
                joinExpression);

            var query = SqlDml.Select(joinedTable);

            if (!leftShouldUseReference)
            {
                query.Where &= left.Request.Statement.Where;
            }
            if (!rightShouldUseReference)
            {
                query.Where &= right.Request.Statement.Where;
            }
            query.Columns.AddRange(joinedTable.AliasedColumns);
            return(CreateProvider(query, provider, left, right));
        }
Exemple #6
0
        public void Visit(SqlSelect node)
        {
            foreach (var column in node.Columns)
            {
                Visit(column);
            }
            foreach (var column in node.GroupBy)
            {
                Visit(column);
            }
            foreach (var column in node.OrderBy)
            {
                Visit(column);
            }
            if (node.From != null)
            {
                Visit(node.From);
            }
            if (!node.Having.IsNullReference())
            {
                Visit(node.Having);
            }
            if (!node.Limit.IsNullReference())
            {
                Visit(node.Limit);
            }
            if (!node.Offset.IsNullReference())
            {
                Visit(node.Offset);
            }
            if (!node.Where.IsNullReference())
            {
                Visit(node.Where);
            }
            foreach (var hint in node.Hints)
            {
                Visit(hint);
            }

            if (node.Columns.Count == 0)
            {
                node.Columns.Add(SqlDml.Null, "NULL");
            }

            var hasPaging = node.HasLimit || node.HasOffset;

            var keepOrderBy = ReferenceEquals(node, rootSelect) || hasPaging;

            if (!keepOrderBy)
            {
                node.OrderBy.Clear();
            }

            var addOrderBy = hasPaging &&
                             node.OrderBy.Count == 0 &&
                             providerInfo.Supports(ProviderFeatures.PagingRequiresOrderBy);

            if (addOrderBy)
            {
                node.OrderBy.Add(1);
            }
        }