/// <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); }
/// <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); }
/// <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()); } }
/// <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(); }
/// <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); }