Beispiel #1
0
        /// <summary>
        /// Pass command?
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="table">Table.</param>
        /// <param name="row">Row.</param>
        /// <param name="from">Use state FROM keyword.</param>
        public static bool Pass(string command, MochaTableResult table, MochaRow row, bool from)
        {
            string[] parts = Mhql_LEXER.SplitFunctionParameters(command);
            if (parts.Length != 3)
            {
                throw new ArgumentOutOfRangeException("The BETWEEN function can only take 3 parameters!");
            }

            int dex = Mhql_GRAMMAR.GetIndexOfColumn(parts[0], table.Columns, from);
            decimal
                range1,
                range2,
                value;

            if (!decimal.TryParse(parts[1].Trim(), out range1) ||
                !decimal.TryParse(parts[2].Trim(), out range2) ||
                !decimal.TryParse(row.Datas[dex].Data.ToString(), out value))
            {
                throw new ArithmeticException("The parameter of the BETWEEN command was not a number!");
            }

            return
                (range1 <= range2 ?
                 range1 <= value && value <= range2 :
                 range2 <= value && value <= range1);
        }
Beispiel #2
0
        /// <summary>
        /// Pass command?
        /// </summary>
        /// <param name="command">Command.</param>
        /// <param name="table">Table.</param>
        /// <param name="row">Row.</param>
        /// <param name="from">Use state FROM keyword.</param>
        public static bool Pass(string command, MochaTableResult table, MochaRow row, bool from)
        {
            string[] parts = Mhql_LEXER.SplitFunctionParameters(command);
            int      dex   = Mhql_GRAMMAR.GetIndexOfColumn(parts[0], table.Columns, from);

            for (int index = 1; index < parts.Length; ++index)
            {
                if (row.Datas[dex].Data.ToString().StartsWith(parts[index]))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #3
0
        /// <summary>
        /// Process in keyword.
        /// </summary>
        /// <param name="tdb">Target database.</param>
        /// <param name="command">Command.</param>
        /// <param name="table">Destination table.</param>
        /// <param name="row">Destination row.</param>
        /// <param name="from">Use state of FROM keyword.</param>
        /// <param name="inmode">Set true if command is execute as in mode, set false if ineq mode.</param>
        /// <returns>True if subquery is success, false if not.</returns>
        public static bool Process(MochaDatabase tdb, string command, MochaTableResult table, MochaRow row,
                                   bool from, bool inmode)
        {
            command = command.Substring(inmode ? 2 : 4).TrimStart();
            int obrace = command.IndexOf(Mhql_LEXER.LBRACE);

            if (obrace == -1)
            {
                throw new Exception($"{Mhql_LEXER.LBRACE} is not found!");
            }
            MochaColumn column = table.Columns[Mhql_GRAMMAR.GetIndexOfColumn(
                                                   command.Substring(0, obrace).Trim(), table.Columns, from)];
            MochaTableResult result = new MochaDbCommand(tdb).ExecuteScalar(Mhql_LEXER.RangeSubqueryBrace(
                                                                                command.Substring(obrace)));

            if (result.Columns.Length != 1)
            {
                throw new Exception("Subqueries should only return one column!");
            }
            else if (MochaData.IsNumericType(column.DataType) != MochaData.IsNumericType(result.Columns[0].DataType) &&
                     column.DataType != result.Columns[0].DataType)
            {
                throw new Exception("Column data type is not same of subquery result!");
            }
            if (inmode)
            {
                for (int index = 0; index < row.Datas.Count; ++index)
                {
                    for (int rindex = 0; rindex < result.Columns[0].Datas.Count; ++rindex)
                    {
                        if (row.Datas[index].Data.ToString() == result.Columns[0].Datas[rindex].Data.ToString())
                        {
                            return(true);
                        }
                    }
                }
                return(false);
            }
            else
            {
                if (result.Rows.Length != 1)
                {
                    return(false);
                }
                return(row.Datas[0].Data.ToString() == result.Columns[0].Datas[0].Data.ToString());
            }
        }
Beispiel #4
0
        /// <summary>
        /// Orderby by command.
        /// </summary>
        /// <param name="command">Orderby command.</param>
        /// <param name="table">Table to ordering.</param>
        /// <param name="from">Use state FROM keyword.</param>
        public void OrderBy(string command, ref MochaTableResult table, bool from)
        {
            MHQLOrderType DecomposeOrder(string cmd, ref MochaTableResult tbl, out int coldex)
            {
                string[] orderparts = cmd.Trim().Split(' ');
                if (orderparts.Length > 2)
                {
                    throw new ArgumentOutOfRangeException("A single ORDERBY parameter can consist of up to 2 parts!");
                }
                coldex = Mhql_GRAMMAR.GetIndexOfColumn(orderparts[0].Trim(), tbl.Columns, from);

                if (orderparts.Length == 1)
                {
                    return(0);
                }

                string order = orderparts[orderparts.Length - 1].Trim();

                return(order == string.Empty ||
                       order.StartsWith("ASC", StringComparison.OrdinalIgnoreCase) ?
                       MHQLOrderType.ASC :
                       order.StartsWith("DESC", StringComparison.OrdinalIgnoreCase) ?
                       MHQLOrderType.DESC :
                       throw new Exception("ORDERBY could not understand this '" + order + "' sort type!"));
            }

            command = command.Trim();
            string[] parts = Mhql_LEXER.SplitParameters(command);
            int      columndex;

            IOrderedEnumerable <MochaRow> rows =
                DecomposeOrder(parts[0], ref table, out columndex) == 0 ?
                table.Rows.OrderBy(x => x.Datas[columndex].ToString(), new ORDERBYComparer()) :
                table.Rows.OrderByDescending(x => x.Datas[columndex].ToString(), new ORDERBYComparer());

            for (int index = 1; index < parts.Length; ++index)
            {
                int coldex;
                rows =
                    DecomposeOrder(parts[index], ref table, out coldex) == 0 ?
                    rows.ThenBy(x => x.Datas[coldex].ToString(), new ORDERBYComparer()) :
                    rows.ThenByDescending(x => x.Datas[coldex].ToString(), new ORDERBYComparer());
            }
            table.Rows = rows.ToArray();
            table.SetDatasByRows();
        }
Beispiel #5
0
        /// <summary>
        /// Returns table by use command.
        /// </summary>
        /// <param name="usecommand">Use command.</param>
        public MochaTableResult GetTable(string usecommand, bool from)
        {
            MochaColumn GetColumn(string cmd, IList <MochaColumn> cols)
            {
                string decomposeBrackets(string value)
                {
                    int dex;

                    if ((dex = value.IndexOf('(')) != -1)
                    {
                        return(value.Substring(dex + 1, value.Length - dex - 2));
                    }
                    return(value);
                }

                string name = Mhql_AS.GetAS(ref cmd);

                if (Mhql_GRAMMAR.UseFunctions.MatchKey(cmd))
                {
                    MochaColumn column = new MochaColumn();
                    column.MHQLAsText = name;
                    column.Tag        =
                        Mhql_GRAMMAR.UseFunctions.GetValueByMatchKey(cmd);
                    if (column.Tag != "COUNT")
                    {
                        column.Description =
                            Mhql_GRAMMAR.GetIndexOfColumn(decomposeBrackets(cmd), cols, from).ToString();
                    }
                    return(column);
                }
                else
                {
                    string colname = cmd.StartsWith("$") ? cmd.Substring(1).Trim() : cmd;
                    IEnumerable <MochaColumn> result = cols.Where(x => x.Name == colname);
                    if (!result.Any())
                    {
                        throw new Exception($"Could not find a column with the name '{cmd}'!");
                    }
                    MochaColumn column = result.First();
                    column.Tag        = colname != cmd ? "$" : null;
                    column.MHQLAsText = name;
                    return(column);
                }
            }

            List <MochaColumn> columns     = new List <MochaColumn>();
            MochaTableResult   resulttable = new MochaTableResult();

            if (from)
            {
                int                dex       = Mhql_FROM.GetIndex(ref usecommand);
                string             tablename = usecommand.Substring(dex + 5).Trim();
                List <string>      parts     = Mhql_LEXER.SplitUseParameters(usecommand.Substring(0, dex));
                List <MochaColumn> _columns  = Tdb.GetColumns(tablename);
                if (parts.Count == 1 && parts[0].Trim() == "*")
                {
                    columns.AddRange(_columns);
                }
                else
                {
                    if (parts[0].TrimStart().StartsWith("$") &&
                        parts[0].TrimStart().Substring(1).TrimStart().StartsWith($"{Mhql_LEXER.LBRACE}"))
                    {
                        throw new InvalidOperationException("Cannot be used with subquery FROM keyword!");
                    }
                    for (int index = 0; index < parts.Count; ++index)
                    {
                        columns.Add(GetColumn(parts[index].Trim(), _columns));
                    }
                }
            }
            else
            {
                List <string> parts = Mhql_LEXER.SplitUseParameters(usecommand);
                for (int index = 0; index < parts.Count; ++index)
                {
                    string callcmd = parts[index].Trim();
                    if (callcmd == "*")
                    {
                        List <MochaTable> tables = Tdb.GetTables();
                        for (int tindex = 0; tindex < tables.Count; ++tindex)
                        {
                            columns.AddRange(tables[tindex].Columns);
                        }
                        continue;
                    }
                    int obrace = callcmd.IndexOf(Mhql_LEXER.LBRACE);
                    if (obrace != -1)
                    {
                        IList <MochaColumn> _cols = (new MochaDbCommand(Tdb).ExecuteScalar(Mhql_LEXER.RangeSubqueryBrace(
                                                                                               callcmd.Substring(obrace).Trim()))).Columns;
                        string mode =
                            callcmd.Substring(0, obrace).TrimStart().StartsWith("$") ?
                            "$" : string.Empty;
                        for (int cindex = 0; cindex < _cols.Count; ++cindex)
                        {
                            columns.Add(GetColumn($"{mode}{_cols[cindex].Name}", _cols));
                        }
                        continue;
                    }
                    if (callcmd.StartsWith("$"))
                    {
                        callcmd = callcmd.Substring(1).Trim();
                        List <MochaColumn> _cols = Tdb.GetColumns(callcmd);
                        for (int cindex = 0; cindex < _cols.Count; ++cindex)
                        {
                            columns.Add(GetColumn($"${_cols[cindex].Name}", _cols));
                        }
                        continue;
                    }

                    string[] callparts = Mhql_LEXER.SplitSubCalls(callcmd);
                    if (callparts.Length > 2)
                    {
                        throw new InvalidOperationException($"'{callcmd}' command is cannot processed!");
                    }
                    for (byte partindex = 0; partindex < callparts.Length; ++partindex)
                    {
                        callparts[partindex] = callparts[partindex].Trim();
                    }
                    List <MochaColumn> _columns = Tdb.GetColumns(callparts[0]);
                    if (callparts.Length == 1)
                    {
                        columns.AddRange(_columns);
                    }
                    else
                    {
                        columns.Add(GetColumn(callparts[1], _columns));
                    }
                }
            }
            resulttable.Columns = columns.ToArray();
            resulttable.SetRowsByDatas();
            return(resulttable);
        }