Ejemplo n.º 1
0
        internal void Parse(string domain)
        {
            if (!string.IsNullOrEmpty(СтрокаЗапрос))
            {
                if (СтрокаЗапрос.Contains("<Запрос>"))
                {
                    var xml = new XmlDocument();
                    xml.LoadXml(ParseSql(СтрокаЗапрос, domain));
                    var xmlNode = xml.SelectSingleNode("//Sql");
                    if (xmlNode != null)
                    {
                        Sql = xmlNode.InnerText;
                    }
                }
                else if (СтрокаЗапрос.StartsWith("http://") || СтрокаЗапрос.StartsWith("https://"))
                {
                    //загрузка xml
                }
                else if (СтрокаЗапрос.StartsWith("["))
                {
                    #region parse
                    var matchs = Regex.Matches(СтрокаЗапрос.Trim("[]".ToArray()), @"(?<FUNCTION>([\w]+?))=(?<PARAM>([^;]+))[;]?", RegexOptions.Singleline | RegexOptions.Compiled);
                    foreach (Match item in matchs)
                    {
                        switch (item.Groups["FUNCTION"].Value.Trim())
                        {
                        case "Типы":
                        {
                            var _Типы = item.Groups["PARAM"].Value;
                            //удалить первые скобочки
                            if (_Типы.StartsWith(@"(") && _Типы.EndsWith(")"))
                            {
                                _Типы = _Типы.Substring(1, _Типы.Length - 2);
                            }

                            Типы.AddRange(_Типы.Split(',').Select(p => p.Trim()));
                        }
                        break;

                        case "ВыводимыеКолонки":
                        case "Колонки":
                        {
                            var _ВыводимыеКолонки = item.Groups["PARAM"].Value;
                            //удалить первые скобочки
                            if (_ВыводимыеКолонки.StartsWith(@"(") && _ВыводимыеКолонки.EndsWith(")"))
                            {
                                _ВыводимыеКолонки = _ВыводимыеКолонки.Substring(1, _ВыводимыеКолонки.Length - 2);
                            }

                            foreach (var i in _ВыводимыеКолонки.Split(','))
                            {
                                var match     = Regex.Match(i, @"\(?(?<FUNCTION>(\w+))?\((?<PARAM>(.+))\)|(?<PARAM>(.+))\)?");
                                var _FUNCTION = match.Groups["FUNCTION"].Value.Trim();
                                var aggr      = string.IsNullOrEmpty(_FUNCTION)
                                                   ? ФункцияАгрегации.None
                                                   : (ФункцияАгрегации)Enum.Parse(typeof(ФункцияАгрегации), _FUNCTION, true);

                                ВыводимыеКолонки.Add(new Колонка()
                                    {
                                        Атрибут = match.Groups["PARAM"].Value.Trim(),
                                        Функция = aggr
                                    });
                            }
                        }
                        break;

                        case "МестаПоиска":
                        case "Места":
                        {
                            foreach (Match i in Regex.Matches(item.Groups["PARAM"].Value, @"\((?<Attr1>(.+?))\,(?<Attr2>(.+?))\)"))
                            {
                                try
                                {
                                    МестаПоиска.Add(new Query.МестоПоиска()
                                        {
                                            id_node             = Convert.ToDecimal(i.Groups["Attr1"].Value),
                                            МаксимальнаяГлубина = Convert.ToInt32(i.Groups["Attr2"].Value)
                                        });
                                }
                                catch
                                {
                                    МестаПоиска.Add(new Query.МестоПоиска()
                                        {
                                            id_node             = i.Groups["Attr1"].Value,
                                            МаксимальнаяГлубина = Convert.ToInt32(i.Groups["Attr2"].Value)
                                        });
                                }
                            }
                        }
                        break;

                        case "УсловияПоиска":
                        case "Условия":
                        {
                            foreach (Match i in Regex.Matches(item.Groups["PARAM"].Value, @"\((?<Attr1>(.+?))\,(\""(?<Attr2>(.+?))\""|'(?<Attr2>(.+?))'|(?<Attr2>(.+?)))\,(?<Attr3>(.+?))\)"))
                            {
                                var cond = new Query.УсловиеПоиска()
                                {
                                    Атрибут  = i.Groups["Attr1"].Value,
                                    Значение = i.Groups["Attr2"].Value,
                                    Оператор = (Query.Оператор)Enum.Parse(typeof(Query.Оператор), i.Groups["Attr3"].Value)
                                };

                                if (cond.Атрибут != null && cond.Атрибут.EndsWith("%"))
                                {
                                    cond.УчитыватьВремя = true;
                                    cond.Атрибут        = cond.Атрибут.Substring(0, cond.Атрибут.Length - 1);
                                }

                                УсловияПоиска.Add(cond);
                            }
                        }
                        break;

                        case "Сортировки":
                        {
                            foreach (Match i in Regex.Matches(item.Groups["PARAM"].Value, @"\((?<Attr1>(.+?))\,(?<Attr2>(.+?))\)"))
                            {
                                Сортировки.Add(new Query.Сортировка()
                                    {
                                        Атрибут     = i.Groups["Attr1"].Value,
                                        Направление = (Query.НаправлениеСортировки)Enum.Parse(typeof(Query.НаправлениеСортировки), i.Groups["Attr2"].Value)
                                    });
                            }
                        }
                        break;

                        case "КоличествоВыводимыхДанных":
                        case "Количество":
                        {
                            КоличествоВыводимыхДанных = Convert.ToInt32(item.Groups["PARAM"].Value);
                        }
                        break;

                        case "КоличествоВыводимыхСтраниц":
                        case "КоличествоСтраниц":
                        case "Страниц":
                        {
                            КоличествоВыводимыхСтраниц = Convert.ToInt32(item.Groups["PARAM"].Value);
                        }
                        break;

                        case "Группировки":
                        {
                            Группировки.AddRange(item.Groups["PARAM"].Value.Trim("()".ToCharArray()).Split(','));
                        }
                        break;

                        case "Объединения":
                        {
                            foreach (Match i in Regex.Matches(item.Groups["PARAM"].Value, @"\((?<Attr1>(.+?))\,(?<Attr2>(.+?))\)"))
                            {
                                Объединения.Add(new Query.Объединение()
                                    {
                                        Атрибут     = i.Groups["Attr1"].Value,
                                        МестоПоиска = new МестоПоиска()
                                        {
                                            id_node = i.Groups["Attr2"].Value, МаксимальнаяГлубина = 0
                                        }
                                    });
                            }
                        }
                        break;

                        case "ВКорзине":
                        {
                            ВКорзине = item.Groups["PARAM"].Value == "1";
                        }
                        break;

                        case "CacheName":
                        {
                            CacheName = item.Groups["PARAM"].Value;
                        }
                        break;

                        case "Файл":
                        {
                            Файл = item.Groups["PARAM"].Value;
                        }
                        break;


                        case "Атрибут":
                        {
                            Атрибут = item.Groups["PARAM"].Value;
                        }
                        break;

                        case "ФорматДат":
                        {
                            ФорматДат = (ФорматДаты)Enum.Parse(typeof(ФорматДаты), item.Groups["PARAM"].Value);
                        }
                        break;

                        default:
                            throw new Exception(string.Format("Не известный параметр {0}", item.Groups["FUNCTION"].Value));
                        }
                    }
                    #endregion
                }
                else
                {
                    Sql = СтрокаЗапрос;
                }
            }

            //проверить все ли параметры в запросе есть
            if (УсловияПоиска != null)
            {
                foreach (var item in УсловияПоиска.Where(p => !p.ИгрнорироватьПараметр))
                {
                    if (Convert.ToString(item.Значение).StartsWith("@"))
                    {
                        var param = Параметры.SingleOrDefault(p => p.Имя == (string)item.Значение);
                        if (param == null)
                        {
                            throw new Exception(string.Format("Параметр '{0}' не задан.", item.Значение));
                        }
                    }
                }

                //проверить если ли условия поиска по всем атрибутам
                var itemFull = УсловияПоиска.FirstOrDefault(p => p.Атрибут.Equals("*"));
                if (itemFull != null && !(itemFull.Значение == null ||
                                          itemFull.Значение.Equals(string.Empty) ||
                                          itemFull.Значение.Equals("%%") || itemFull.Значение.Equals("%")))
                {
                    IsПоискПоСодержимому = true;

                    //проверить если указано как параметр
                    if (Convert.ToString(itemFull.Значение).StartsWith("@") &&
                        Параметры != null &&
                        Параметры.FirstOrDefault(p => p.Имя.Equals(itemFull.Значение) &&
                                                 string.IsNullOrEmpty(p.Значение as string)
                                                 ) != null)
                    {
                        IsПоискПоСодержимому = false;
                    }
                }
            }
            if (МестаПоиска != null)
            {
                foreach (var item in МестаПоиска)
                {
                    if (Convert.ToString(item.id_node).StartsWith("@"))
                    {
                        var param = Параметры.SingleOrDefault(p => p.Имя == (string)item.id_node);
                        if (param == null)
                        {
                            throw new Exception(string.Format("Параметр '{0}' не задан.", item.id_node));
                        }
                    }
                }
            }
            if (!string.IsNullOrEmpty(CacheName) && CacheName.Length >= 2 && CacheName.First() == '{' && CacheName.Last() == '}')
            {
                CacheReadOnly = true;
                CacheName     = CacheName.Substring(1, CacheName.Length - 2);
            }

            #region Подставить параметры, если они есть
            if (Параметры != null && Параметры.Count > 0)
            {
                foreach (var item in УсловияПоиска.Where(p => !p.ИгрнорироватьПараметр &&
                                                         p.Значение is string && ((string)p.Значение).StartsWith("@")))
                {
                    item.Значение = Параметры.SingleOrDefault(p => p.Имя == (string)item.Значение).Значение;
                }
            }
            #endregion
        }