Beispiel #1
0
        public override IDbCommand SELECT(DBConnection db, Tabloid tabloid, IEnumerable <string> columnNames = null, Manager <Condition> conditions = null, Manager <Join> joins = null, Order order = null, GroupBy groupBy = null, int?limit = null, Page page = null, DropStep dropStep = null)
        {
            MySqlCommand  command   = new MySqlCommand();
            List <string> withTable = new List <string>();

            /// get columns to select
            List <Tuple <string, string> > columns = new List <Tuple <string, string> >();

            // column are set
            if (columnNames != null && columnNames.Any())
            {
                columns.AddRange(ColumnsToTuple(db.Application, tabloid.Name, columnNames));
            }
            // all columns
            else
            {
                // origin table
                columns.AddRange(tabloid.Columns.Select(c => new Tuple <string, string>(tabloid.Name, c.Name)));
                // table not found - every table have some column
                if (columns.Count == 0)
                {
                    throw new Exception($"Tabulka/View [{tabloid.Name}]({tabloid.RealName}) nenalezena!");
                }
                // joined tables
                foreach (Join join in joins)
                {
                    columns.AddRange(new Tabloid(db)
                    {
                        Name = join.joinTableName
                    }.Columns.Select(c => new Tuple <string, string>(join.joinTableName, c.Name)));
                }
            }
            List <Tuple <string, string> > whereColumns = new List <Tuple <string, string> >(columns);

            foreach (Condition condition in conditions)
            {
                Tuple <string, string> tuple = ColumnsToTuple(db.Application, tabloid.Name, new List <string> {
                    condition.column
                }).First();
                if (!whereColumns.Any(wc => wc.Item1.ToLower() == tuple.Item1.ToLower() && wc.Item2.ToLower() == tuple.Item2.ToLower()))
                {
                    whereColumns.Add(tuple);
                }
            }

            /// SELECT FROM, JOIN
            command.CommandText =
                $"SELECT {ColumnTuplesToString(db.Application, whereColumns)} FROM {ToRealTableName(db.Application, tabloid.Name)} {joins.ToSql(this, command)}";

            /// WHERE, GROUP, HAVING
            string conditionString = conditions.ToSql(this, command);

            if (!string.IsNullOrEmpty(conditionString) || groupBy != null)
            {
                withTable.Add($"__table1 as ({command.CommandText})");

                // WHERE
                if (!string.IsNullOrEmpty(conditionString))
                {
                    conditionString =
                        $"WHERE {conditionString}";

                    if (groupBy == null)
                    {
                        command.CommandText =
                            $"SELECT {ColumnTuplesToString(db.Application, columns, true, false)} FROM __table1 {conditionString}";
                    }
                }

                // GROUP BY
                if (groupBy != null)
                {
                    string havingString = groupBy.Having.ToSql(this, command);
                    if (!string.IsNullOrEmpty(havingString))
                    {
                        havingString = $"HAVING {havingString}";
                    }

                    if (groupBy.Function == ESqlFunction.none)
                    {
                        columns = ColumnsToTuple(db.Application, tabloid.Name, groupBy.Columns);

                        command.CommandText =
                            $"SELECT {ColumnTuplesToString(db.Application, columns, true, false)} FROM __table1 {conditionString} GROUP BY {ColumnTuplesToString(db.Application, columns, true, false)} {havingString}";
                    }
                    // first, last -> inner query
                    else if (groupBy.Function.NeedsInnerQuery())
                    {
                        command.CommandText =
                            $"SELECT * FROM __table1 WHERE {conditionString} {(string.IsNullOrEmpty(conditionString) ? "" : "AND")} {FullPrimaryKey(tabloid.Name)} IN (SELECT {(groupBy.Function == ESqlFunction.FIRST ? "MIN" : "MAX")}({FullPrimaryKey(tabloid.Name)}) FROM __table1 GROUP BY {ColumnTuplesToString(db.Application, ColumnsToTuple(db.Application, tabloid.Name, groupBy.Columns), true, false)} {havingString})";
                    }
                    // other functions
                    else
                    {
                        // get only numeric columns
                        if (groupBy.Function.RequireNumeric())
                        {
                            List <Tuple <string, string> > currentColumns = ColumnsToTuple(db.Application, tabloid.Name, groupBy.Columns);
                            foreach (string tabloidName in columns.Select(c => c.Item1).Distinct())
                            {
                                Tabloid currentTabloid = tabloidName == tabloid.Name
                                    ? tabloid
                                    : new Tabloid(db)
                                {
                                    Name = tabloidName
                                };

                                currentColumns = currentColumns.Concat(ColumnsToTuple(db.Application, currentTabloid.Name, currentTabloid.Columns.Where(c => columns.Contains(new Tuple <string, string>(currentTabloid.Name, c.Name)) && DataType.IsNumeric(c.Type)).Select(c => c.Name))).ToList();
                            }

                            columns = currentColumns;
                        }

                        command.CommandText =
                            $"SELECT {ColumnTuplesToString(db.Application, columns, true, false, groupBy.Function.ToString(), groupBy.Columns)} FROM __table1 {conditionString} GROUP BY {ColumnTuplesToString(db.Application, ColumnsToTuple(db.Application, tabloid.Name, groupBy.Columns), true, false)} {havingString}";
                    }
                }
            }

            /// Drop step
            if (dropStep != null)
            {
                if (dropStep.Order == null)
                {
                    throw new ArgumentException("Order needs to be filled");
                }

                withTable.Add($"__table2 as ({command.CommandText})");
                string rowNum = $"FLOOR((@__ROWNUM:=@__ROWNUM+1)*{dropStep.FinalCount}/(SELECT Count(*) FROM __table2)) _rowNum";

                if (dropStep.Function == ESqlFunction.none)
                {
                    throw new ArgumentException("DropStep with no function return no data!");
                }

                // first, last -> inner query
                else if (dropStep.Function.NeedsInnerQuery())
                {
                    command.CommandText =
                        $"SELECT * FROM __table2 WHERE {FullPrimaryKey(tabloid.Name)} IN (SELECT {(dropStep.Function == ESqlFunction.FIRST ? "MIN" : "MAX")}({FullPrimaryKey(tabloid.Name)}) FROM (SELECT {rowNum}, __table2.* FROM __table2, (SELECT @__ROWNUM:=-1) __fooo) __t GROUP BY _rowNum)";
                }
                // other functions
                else
                {
                    command.CommandText =
                        $"SELECT {ColumnTuplesToString(db.Application, columns, true, false, dropStep.Function.ToString())} FROM (SELECT {rowNum}, __table2.* FROM __table2, (SELECT @__ROWNUM:=-1) __fooo) __t GROUP BY _rowNum";
                }
            }

            string limitString = page != null
                ? $"LIMIT {page.RowsPerPage} OFFSET {page.PageIndex * page.RowsPerPage}"
                : limit != null
                    ? $"LIMIT {limit}"
                    : "";

            command.CommandText =
                $"{(withTable.Any() ? "with " : "")}{string.Join(",", withTable)} {command.CommandText} {order?.ToSql(this, command)} {limitString}";

            return(command);
        }
Beispiel #2
0
 public abstract IDbCommand SELECT(DBConnection db, Tabloid table, IEnumerable <string> columnNames = null, Manager <Condition> conditions = null, Manager <Join> joins = null, Order order = null, GroupBy groupBy = null, int?limit = null, Page page = null, DropStep dropStep = null);