Пример #1
0
        protected override void GenerateJoin(ParameterDependant dependant, ref CharWriteBuffer sb)
        {
            foreach (var child in dependant.Dependants.Values)
            {
                if (child.ModelDetail.IdentityProperties.Count != 1)
                {
                    throw new NotSupportedException($"Relational queries support only one identity on {child.ModelDetail.Type.GetNiceName()}");
                }
                var dependantIdentity = child.ModelDetail.IdentityProperties[0];

                sb.Write("JOIN`");
                sb.Write(child.ModelDetail.DataSourceEntityName);
                sb.Write("`ON`");
                sb.Write(dependant.ModelDetail.DataSourceEntityName);
                sb.Write("`.`");
                sb.Write(child.ParentMember?.ForeignIdentity);
                sb.Write("`=`");
                sb.Write(child.ModelDetail.DataSourceEntityName);
                sb.Write("`.`");
                sb.Write(dependantIdentity.PropertySourceName);
                sb.Write('`');

                AppendLineBreak(ref sb);

                GenerateJoin(child, ref sb);
            }
        }
Пример #2
0
        protected void Convert(ref CharWriteBuffer sb, QueryOperation select, Expression where, QueryOrder order, int?skip, int?take, Graph graph, ModelDetail modelDetail, MemberContext operationContext)
        {
            var hasWhere         = where != null;
            var hasOrderSkipTake = (select == QueryOperation.Many || select == QueryOperation.First) && (order?.OrderExpressions.Length > 0 || skip > 0 || take > 0);

            GenerateSelect(select, graph, modelDetail, ref sb);

            GenerateFrom(modelDetail, ref sb);

            if (hasWhere || hasOrderSkipTake)
            {
                var rootDependant = new ParameterDependant(modelDetail, null);
                var sbWhereOrder  = new CharWriteBuffer();
                try
                {
                    if (hasWhere)
                    {
                        GenerateWhere(where, ref sbWhereOrder, rootDependant, operationContext);
                    }
                    if (hasOrderSkipTake)
                    {
                        GenerateOrderSkipTake(order, skip, take, ref sbWhereOrder, rootDependant, operationContext);
                    }

                    GenerateJoin(rootDependant, ref sb);

                    sb.Write(sbWhereOrder);
                }
                finally
                {
                    sbWhereOrder.Dispose();
                }
            }

            GenerateEnding(select, graph, modelDetail, ref sb);
        }
Пример #3
0
        protected override void GenerateOrderSkipTake(QueryOrder order, int?skip, int?take, ref CharWriteBuffer sb, ParameterDependant rootDependant, MemberContext operationContext)
        {
            if (order?.OrderExpressions.Length > 0)
            {
                sb.Write("ORDER BY");
                var hasOrder = false;
                foreach (var orderExp in order.OrderExpressions)
                {
                    var context = new BuilderContext(rootDependant, operationContext);
                    if (hasOrder)
                    {
                        sb.Write(',');
                    }
                    else
                    {
                        hasOrder = true;
                    }
                    ConvertToSql(orderExp.Expression, ref sb, context);
                    if (orderExp.Descending)
                    {
                        sb.Write("DESC");
                    }
                }
                AppendLineBreak(ref sb);
            }
            else if (skip.HasValue || take.HasValue)
            {
                sb.Write("ORDER BY CURRENT_TIMESTAMP");
                AppendLineBreak(ref sb);
            }

            if (skip.HasValue || take.HasValue)
            {
                sb.Write("OFFSET ");
                sb.Write(skip ?? 0);
                sb.Write(" ROWS");
                AppendLineBreak(ref sb);
                if (take.HasValue)
                {
                    sb.Write("FETCH NEXT ");
                    sb.Write(take.Value);
                    sb.Write(" ROWS ONLY");
                    AppendLineBreak(ref sb);
                }
            }
        }
Пример #4
0
        protected override void GenerateWhere(Expression where, ref CharWriteBuffer sb, ParameterDependant rootDependant, MemberContext operationContext)
        {
            if (where == null)
            {
                return;
            }

            sb.Write("WHERE");
            var context = new BuilderContext(rootDependant, operationContext);

            ConvertToSql(where, ref sb, context);
            AppendLineBreak(ref sb);
        }
Пример #5
0
        protected override void ConvertToSqlParameterModel(ModelDetail modelDetail, ref CharWriteBuffer sb, BuilderContext context, bool parameterInContext)
        {
            var member = context.MemberContext.MemberAccessStack.Pop();

            var modelProperty = modelDetail.GetProperty(member.Member.Name);

            if (modelProperty.IsDataSourceEntity && context.MemberContext.MemberAccessStack.Count > 0)
            {
                var subModelInfo = ModelAnalyzer.GetModel(modelProperty.InnerType);
                context.MemberContext.ModelStack.Push(subModelInfo);
                if (parameterInContext)
                {
                    var parentDependant = context.MemberContext.DependantStack.Peek();
                    if (!parentDependant.Dependants.TryGetValue(subModelInfo.Type, out ParameterDependant dependant))
                    {
                        dependant = new ParameterDependant(subModelInfo, modelProperty);
                        parentDependant.Dependants.Add(subModelInfo.Type, dependant);
                    }
                    context.MemberContext.DependantStack.Push(dependant);
                }
                ConvertToSqlParameterModel(subModelInfo, ref sb, context, parameterInContext);
                if (parameterInContext)
                {
                    context.MemberContext.DependantStack.Pop();
                }
                context.MemberContext.ModelStack.Pop();
            }
            else if (context.MemberContext.InCallNoRender > 0)
            {
            }
            else if (context.MemberContext.InCallRenderIdentity > 0)
            {
                if (modelDetail.IdentityProperties.Count != 1)
                {
                    throw new NotSupportedException($"Relational queries support only one identity on {modelDetail.Type.GetNiceName()}");
                }
                var modelIdentity = modelDetail.IdentityProperties[0];

                sb.Write('`');
                sb.Write(modelDetail.DataSourceEntityName);
                sb.Write("`.`");
                sb.Write(modelIdentity.PropertySourceName);
                sb.Write("`");
            }
            else
            {
                bool closeBrace = false;

                if (context.MemberContext.MemberAccessStack.Count > 0)
                {
                    bool memberPropertyHandled = false;
                    var  memberProperty        = context.MemberContext.MemberAccessStack.Pop();

                    if (member.Type.Name == typeof(Nullable <>).Name && memberProperty.Member.Name == "Value")
                    {
                        memberPropertyHandled = true;
                    }
                    else if (member.Type == typeof(DateTime))
                    {
                        memberPropertyHandled = true;
                        closeBrace            = true;
                        switch (memberProperty.Member.Name)
                        {
                        case "Year":
                            sb.Write("YEAR(");
                            break;

                        case "Month":
                            sb.Write("MONTH(");
                            break;

                        case "Day":
                            sb.Write("DAY(day,");
                            break;

                        case "Hour":
                            sb.Write("HOUR(");
                            break;

                        case "Minute":
                            sb.Write("MINUTE(");
                            break;

                        case "Second":
                            sb.Write("SECOND(");
                            break;

                        case "Millisecond":
                            sb.Write("1/1000*MICROSECOND(");
                            break;

                        case "DayOfYear":
                            sb.Write("DAYOFYEAR(");
                            break;

                        case "DayOfWeek":
                            sb.Write("WEEKDAY(");
                            break;

                        default:
                            memberPropertyHandled = false;
                            break;
                        }
                    }

                    if (!memberPropertyHandled)
                    {
                        throw new NotSupportedException($"{member.Member.Name}.{memberProperty.Member.Name} not supported");
                    }
                    context.MemberContext.MemberAccessStack.Push(memberProperty);
                }


                sb.Write('`');
                sb.Write(modelDetail.DataSourceEntityName);
                sb.Write('`');
                sb.Write('.');
                sb.Write('`');
                sb.Write(modelProperty.PropertySourceName);
                sb.Write('`');
                var lastOperator = context.MemberContext.OperatorStack.Peek();
                if (lastOperator == Operator.And || lastOperator == Operator.Or)
                {
                    if (modelProperty.InnerType == typeof(bool))
                    {
                        sb.Write("=1");
                    }
                    else
                    {
                        sb.Write("IS NOT NULL");
                    }
                }

                if (closeBrace)
                {
                    sb.Write(')');
                }
            }

            context.MemberContext.MemberAccessStack.Push(member);
        }
 public BuilderContext(ParameterDependant rootDependant, MemberContext memberContext)
 {
     this.RootDependant = rootDependant;
     this.MemberContext = memberContext;
     this.InvertStack   = 0;
 }