예제 #1
0
        protected virtual void VisitFields(ExpressionVisitorContext context, UpdateStatement statement, ICollection <FieldValue> fields)
        {
            var index = 0;

            foreach (var field in fields)
            {
                if (index++ > 0)
                {
                    context.WriteLine(",");
                }

                context.Visit(field.Field);
                context.Write("=");

                var parenthesisRequired = field.Value is IStatementBase;

                if (parenthesisRequired)
                {
                    context.Write("(");
                }

                context.Visit(field.Value);

                if (parenthesisRequired)
                {
                    context.Write(")");
                }
            }
        }
예제 #2
0
        private void VisitReturning(ExpressionVisitorContext context, ReturningClause returning)
        {
            if (returning == null)
            {
                return;
            }

            context.WriteLine();
            context.Write("RETURNING ");

            if (returning.Members == null || returning.Members.Count == 0)
            {
                context.Write("*");
            }
            else
            {
                int index = 0;

                foreach (var member in returning.Members)
                {
                    if (index++ > 0)
                    {
                        context.Write(",");
                    }

                    context.Visit(member.Field);
                }
            }

            if (returning.Table != null)
            {
                context.Write(" INTO ");
                context.Write(context.Dialect.GetIdentifier(returning.Table.Identifier()));
            }
        }
예제 #3
0
        protected virtual void VisitGroupBy(ExpressionVisitorContext context, GroupByClause clause)
        {
            if (clause == null || clause.Keys.Count == 0)
            {
                return;
            }

            if (context.Output.Length > 0)
            {
                context.WriteLine();
            }

            context.Write("GROUP BY ");

            int index = 0;

            foreach (var key in clause.Keys)
            {
                if (index++ > 0)
                {
                    context.Write(",");
                }

                context.Visit(key);
            }

            if (clause.Having != null)
            {
                context.WriteLine();
                context.Write("HAVING ");
                context.Visit(clause.Having);
            }
        }
예제 #4
0
        protected virtual void VisitUnary(ExpressionVisitorContext context, UnaryExpression unary)
        {
            switch (unary.Operator)
            {
            case Operator.Not:
            case Operator.Negate:
            case Operator.Exists:
            case Operator.NotExists:
                context.Write(this.GetSymbol(unary.Operator));
                break;
            }

            //只有常量和标记表达式才不需要加小括号
            bool parenthesisRequired = !(unary.Operand is ConstantExpression || unary.Operand is IIdentifier);

            if (parenthesisRequired)
            {
                context.Write("(");
            }

            if (unary.Operator == Operator.Exists || unary.Operator == Operator.NotExists)
            {
                this.VisitExists(context, unary.Operand);
            }
            else
            {
                this.OnVisit(context, unary.Operand);
            }

            if (parenthesisRequired)
            {
                context.Write(")");
            }
        }
예제 #5
0
        protected virtual void VisitCondition(ExpressionVisitorContext context, ConditionExpression condition)
        {
            if (condition == null || condition.Count == 0)
            {
                return;
            }

            int index       = 0;
            var combination = condition.Combination == ConditionCombination.And ? Operator.AndAlso : Operator.OrElse;

            if (condition.Count > 1 && context.Counter.Indent())
            {
                context.Write("(");
            }

            foreach (var item in condition)
            {
                if (index++ > 0)
                {
                    context.Write(this.GetSymbol(combination));
                }

                this.OnVisit(context, item);
            }

            if (condition.Count > 1 && context.Counter.Dedent())
            {
                context.Write(")");
            }
        }
예제 #6
0
        protected virtual void VisitOrderBy(ExpressionVisitorContext context, OrderByClause clause)
        {
            if (clause == null || clause.Members.Count == 0)
            {
                return;
            }

            if (context.Output.Length > 0)
            {
                context.WriteLine();
            }

            context.Write("ORDER BY ");

            int index = 0;

            foreach (var member in clause.Members)
            {
                if (index++ > 0)
                {
                    context.Write(",");
                }

                context.Visit(member.Field);

                if (member.Mode == SortingMode.Descending)
                {
                    context.Write(" DESC");
                }
            }
        }
        public static void VisitJoin(this ExpressionVisitorContext context, JoinClause joining)
        {
            context.WriteLine();

            switch (joining.Type)
            {
            case JoinType.Inner:
                context.Write("INNER JOIN ");
                break;

            case JoinType.Left:
                context.Write("LEFT JOIN ");
                break;

            case JoinType.Right:
                context.Write("RIGHT JOIN ");
                break;

            case JoinType.Full:
                context.Write("FULL JOIN ");
                break;
            }

            switch (joining.Target)
            {
            case TableIdentifier table:
                context.Visit(table);

                if (string.IsNullOrEmpty(joining.Name))
                {
                    context.WriteLine(" ON");
                }
                else
                {
                    context.WriteLine(" ON /* " + joining.Name + " */");
                }

                break;

            case SelectStatement subquery:
                context.Write("(");

                //递归生成子查询语句
                context.Visit(subquery);

                if (string.IsNullOrEmpty(subquery.Alias))
                {
                    context.WriteLine(") ON");
                }
                else
                {
                    context.WriteLine(") AS " + subquery.Alias + " ON");
                }

                break;
            }

            context.Visit(joining.Conditions);
        }
예제 #8
0
        protected virtual void VisitTable(ExpressionVisitorContext context, TableIdentifier table)
        {
            context.Write(this.GetIdentifier(table));

            if (!string.IsNullOrEmpty(table.Alias) && !string.Equals(table.Name, table.Alias))
            {
                context.Write(" AS " + table.Alias);
            }
        }
예제 #9
0
 protected virtual void VisitVariable(ExpressionVisitorContext context, VariableIdentifier variable)
 {
     if (variable.IsGlobal)
     {
         context.Write("@@" + variable.Name);
     }
     else
     {
         context.Write("@" + variable.Name);
     }
 }
예제 #10
0
        protected virtual void VisitField(ExpressionVisitorContext context, FieldDefinition field)
        {
            context.Write($"{field.Name} {this.Dialect.GetDbType(field.DbType, field.Length, field.Precision, field.Scale)}");

            if (field.Nullable)
            {
                context.Write(" NULL");
            }
            else
            {
                context.Write(" NOT NULL");
            }
        }
        public static void VisitFrom(this ExpressionVisitorContext context, ICollection <ISource> sources, Action <ExpressionVisitorContext, JoinClause> join)
        {
            if (sources == null || sources.Count == 0)
            {
                return;
            }

            context.Write(" FROM ");

            foreach (var source in sources)
            {
                switch (source)
                {
                case TableIdentifier table:
                    context.Visit(table);

                    break;

                case SelectStatement subquery:
                    context.Write("(");

                    //递归生成子查询语句
                    context.Visit(subquery);

                    if (string.IsNullOrEmpty(subquery.Alias))
                    {
                        context.Write(")");
                    }
                    else
                    {
                        context.Write(") AS " + subquery.Alias);
                    }

                    break;

                case JoinClause joining:
                    if (join == null)
                    {
                        VisitJoin(context, joining);
                    }
                    else
                    {
                        join(context, joining);
                    }

                    break;
                }
            }
        }
예제 #12
0
        protected override void OnVisit(ExpressionVisitorContext context, UpdateStatement statement)
        {
            if (statement.Tables == null || statement.Tables.Count == 0)
            {
                throw new DataException("Missing required tables in the update statement.");
            }

            if (statement.Fields == null || statement.Fields.Count == 0)
            {
                throw new DataException("Missing required fields in the update statment.");
            }

            if (statement.Returning != null && statement.Returning.Table != null)
            {
                context.Visit(statement.Returning.Table);
            }

            context.Write("UPDATE ");
            this.VisitTables(context, statement, statement.Tables);

            context.WriteLine(" SET");
            this.VisitFields(context, statement, statement.Fields);

            this.VisitFrom(context, statement, statement.From);
            this.VisitWhere(context, statement, statement.Where);

            context.WriteLine(";");
        }
예제 #13
0
 protected virtual void VisitSelectOption(ExpressionVisitorContext context, SelectClause clause)
 {
     if (clause.IsDistinct)
     {
         context.Write("DISTINCT ");
     }
 }
예제 #14
0
 protected virtual void VisitComment(ExpressionVisitorContext context, CommentExpression comment)
 {
     //输出注释文本
     if (!string.IsNullOrEmpty(comment.Text))
     {
         context.Write("/* " + comment.Text + " */");
     }
 }
예제 #15
0
        protected virtual void VisitConstant(ExpressionVisitorContext context, ConstantExpression constant)
        {
            if (constant.Value == null)
            {
                context.Write("NULL");
                return;
            }

            if (constant.ValueType == typeof(bool) || Zongsoft.Common.TypeExtension.IsNumeric(constant.ValueType))
            {
                context.Write(constant.Value.ToString());
            }
            else
            {
                context.Write("'" + constant.Value.ToString() + "'");
            }
        }
예제 #16
0
 protected virtual void VisitLiteral(ExpressionVisitorContext context, LiteralExpression literal)
 {
     //输出字面量文本
     if (!string.IsNullOrEmpty(literal.Text))
     {
         context.Write(literal.Text);
     }
 }
예제 #17
0
        protected virtual void VisitFields(ExpressionVisitorContext context, InsertStatement statement, ICollection <FieldIdentifier> fields)
        {
            int index = 0;

            context.Write(" (");

            foreach (var field in fields)
            {
                if (index++ > 0)
                {
                    context.Write(",");
                }

                context.Visit(field);
            }

            context.Write(")");
        }
예제 #18
0
        protected virtual void VisitTables(ExpressionVisitorContext context, DeleteStatement statement, IList <TableIdentifier> tables)
        {
            for (int i = 0; i < tables.Count; i++)
            {
                if (i > 0)
                {
                    context.Write(",");
                }

                if (string.IsNullOrEmpty(tables[i].Alias))
                {
                    context.Write(tables[i].Name);
                }
                else
                {
                    context.Write(tables[i].Alias);
                }
            }
        }
예제 #19
0
        protected virtual void VisitInto(ExpressionVisitorContext context, IIdentifier into)
        {
            if (into == null)
            {
                return;
            }

            context.Write(" INTO ");
            context.Visit(into);
        }
예제 #20
0
        protected virtual void VisitMethod(ExpressionVisitorContext context, MethodExpression expression)
        {
            var methodName = this.Dialect.GetMethodName(expression);

            //先输出方法或变量名
            context.Write(methodName);

            if (expression.MethodType == MethodType.Function)
            {
                context.Write("(");

                if (expression is AggregateExpression aggregate && aggregate.Distinct)
                {
                    context.Write("DISTINCT ");
                }

                if (expression.Arguments != null)
                {
                    var index = 0;

                    foreach (var argument in expression.Arguments)
                    {
                        if (index++ > 0)
                        {
                            context.Write(",");
                        }

                        var parenthesized = argument != null && typeof(IStatementBase).IsAssignableFrom(argument.GetType());

                        if (parenthesized)
                        {
                            context.Write("(");
                        }

                        this.OnVisit(context, argument);

                        if (parenthesized)
                        {
                            context.Write(")");
                        }
                    }
                }

                context.Write(")");
            }

            if (!string.IsNullOrEmpty(expression.Alias))
            {
                context.Write(" AS " + this.GetAlias(expression.Alias));
            }
        }
예제 #21
0
        protected virtual void VisitTables(ExpressionVisitorContext context, UpdateStatement statement, IList <TableIdentifier> tables)
        {
            for (int i = 0; i < tables.Count; i++)
            {
                if (i > 0)
                {
                    context.Write(",");
                }

                context.Visit(tables[i]);
            }
        }
예제 #22
0
        protected virtual void VisitValues(ExpressionVisitorContext context, InsertStatement statement, ICollection <IExpression> values, int rounds)
        {
            int index = 0;

            context.WriteLine(" VALUES");

            foreach (var value in values)
            {
                if (index > 0)
                {
                    context.Write(",");
                }

                if (index % rounds == 0)
                {
                    context.Write("(");
                }

                var parenthesisRequired = value is IStatementBase;

                if (parenthesisRequired)
                {
                    context.Write("(");
                }

                context.Visit(value);

                if (parenthesisRequired)
                {
                    context.Write(")");
                }

                if (++index % rounds == 0)
                {
                    context.Write(")");
                }
            }
        }
예제 #23
0
        protected virtual void VisitField(ExpressionVisitorContext context, FieldIdentifier field)
        {
            var alias = field.Table?.Alias;

            if (field.Table is IStatementBase statement && !string.IsNullOrEmpty(statement.Table.Alias))
            {
                alias = statement.Table.Alias;
            }

            if (field.Table == null || string.IsNullOrEmpty(alias))
            {
                context.Write(this.GetIdentifier(field));
            }
            else
            {
                context.Write(alias + "." + this.GetIdentifier(field));
            }

            if (!string.IsNullOrEmpty(field.Alias))
            {
                context.Write(" AS " + this.GetAlias(field.Alias));
            }
        }
        public static void VisitWhere(this ExpressionVisitorContext context, IExpression where)
        {
            if (where == null)
            {
                return;
            }

            if (context.Output.Length > 0)
            {
                context.WriteLine();
            }

            context.Write("WHERE ");
            context.Visit(where);
        }
예제 #25
0
        protected override void OnVisit(ExpressionVisitorContext context, DeleteStatement statement)
        {
            if (statement.Returning != null && statement.Returning.Table != null)
            {
                context.Visit(statement.Returning.Table);
            }

            context.Write("DELETE ");

            this.VisitTables(context, statement, statement.Tables);
            this.VisitFrom(context, statement, statement.From);
            this.VisitWhere(context, statement, statement.Where);

            context.WriteLine(";");
        }
예제 #26
0
        protected override void OnVisited(ExpressionVisitorContext context, SelectStatement statement)
        {
            if (context.Depth == 0)
            {
                context.WriteLine(";");
            }

            if (statement.Paging != null && statement.Paging.Enabled)
            {
                /*
                 * 注意:有分组子句的分页和没有分组子句的分页查询是不同的。
                 */

                if (statement.GroupBy == null)
                {
                    context.WriteLine("SELECT COUNT(*)");
                    this.VisitFrom(context, statement.From);
                    this.VisitWhere(context, statement.Where);
                }
                else
                {
                    context.WriteLine("SELECT COUNT(0) FROM (");
                    context.WriteLine("SELECT ");

                    int index = 0;

                    foreach (var key in statement.GroupBy.Keys)
                    {
                        if (index++ > 0)
                        {
                            context.Write(",");
                        }

                        context.Visit(key);
                    }

                    this.VisitFrom(context, statement.From);
                    this.VisitWhere(context, statement.Where);
                    this.VisitGroupBy(context, statement.GroupBy);
                    context.WriteLine(") AS __wrapping__");
                }
            }

            //调用基类同名方法
            base.OnVisited(context, statement);
        }
예제 #27
0
        protected virtual void VisitCollection(ExpressionVisitorContext context, ExpressionCollection collection)
        {
            if (collection.Count == 0)
            {
                return;
            }

            int index = 0;

            foreach (var item in collection)
            {
                if (index++ > 0)
                {
                    context.Write(",");
                }

                this.OnVisit(context, item);
            }
        }
예제 #28
0
        protected override void OnVisit(ExpressionVisitorContext context, InsertStatement statement)
        {
            if (statement.Fields == null || statement.Fields.Count == 0)
            {
                throw new DataException("Missing required fields in the insert statment.");
            }

            if (statement.Returning != null && statement.Returning.Table != null)
            {
                context.Visit(statement.Returning.Table);
            }

            context.Write("INSERT INTO ");
            context.Visit(statement.Table);

            this.VisitFields(context, statement, statement.Fields);
            this.VisitValues(context, statement, statement.Values, statement.Fields.Count);

            context.WriteLine(";");
        }
예제 #29
0
        protected virtual void VisitBlock(ExpressionVisitorContext context, BlockExpression block)
        {
            if (block.Count == 0)
            {
                return;
            }

            int index = 0;

            foreach (var item in block)
            {
                //添加分割符以区隔各块元素
                if (index++ > 0 && block.Delimiter != BlockExpressionDelimiter.None)
                {
                    context.Write(this.GetDelimiter(block.Delimiter));
                }

                this.OnVisit(context, item);
            }
        }
예제 #30
0
        protected virtual void VisitSelect(ExpressionVisitorContext context, SelectClause clause)
        {
            if (context.Output.Length > 0)
            {
                context.WriteLine();
            }

            context.Write("SELECT ");

            this.VisitSelectOption(context, clause);

            int index = 0;

            foreach (var member in clause.Members)
            {
                if (index++ > 0)
                {
                    context.WriteLine(",");
                }

                context.Visit(member);
            }
        }