mirror of
https://github.com/tormozit/RDT1C.git
synced 2025-12-17 21:24:11 +00:00
2124 lines
146 KiB
Plaintext
2124 lines
146 KiB
Plaintext
//ирПортативный Перем ирПортативный Экспорт;
|
||
//ирПортативный Перем ирОбщий Экспорт;
|
||
//ирПортативный Перем ирСервер Экспорт;
|
||
//ирПортативный Перем ирКэш Экспорт;
|
||
//ирПортативный Перем ирПривилегированный Экспорт;
|
||
|
||
Перем мТаблицаКолонок Экспорт;
|
||
Перем мСписокКолонок Экспорт;
|
||
//Перем КлючиЗагруженныхСтрок;
|
||
Перем мСвойстваСИменамиБД Экспорт;
|
||
Перем RegExpПараметры;
|
||
Перем RegExpМета;
|
||
Перем шБуква;
|
||
Перем шГраничныйСимволИмени;
|
||
//Перем МинимальнаяДатаЗагрузки Экспорт;
|
||
//Перем мЧисловыеСвойства;
|
||
|
||
Перем мИменаВозвращаемыхСвойств Экспорт;
|
||
Перем мТипСУБД Экспорт;
|
||
Перем мКартыФайлов Экспорт;
|
||
Перем мНепустыеКолонкиЖурнала Экспорт;
|
||
|
||
Перем мСерверныеТипыПроцессов Экспорт;
|
||
Перем мПлатформа Экспорт;
|
||
//Перем мСоставСвойствСобытий Экспорт;
|
||
Перем мСвойстваСобытий Экспорт;
|
||
Перем мАдресЧужойСхемыБД Экспорт;
|
||
|
||
Перем КонецПериодаКлиента Экспорт;
|
||
Перем НачалоПериодаКлиента Экспорт;
|
||
Перем КонецПериодаСервера Экспорт;
|
||
Перем НачалоПериодаСервера Экспорт;
|
||
Перем мИдентификаторТрассы Экспорт;
|
||
Перем мЛиАнализТрассыЗапроса Экспорт;
|
||
Перем мСоответствиеКолонок;
|
||
|
||
// СдвигВремени - Число - в секундах задается, нужно для компенсации разницы времени между компьютерами
|
||
// ОтборПоПроцессу и ОтборПоСеансу частично игнорируются когда ЗагружатьТолькоТекущийСеанс = Истина
|
||
Функция ПрочитатьПроизвольныйЖурнал(СообщитьРазмер = Неопределено, СдвигВремени = 0, ОтборПоПроцессу = Неопределено, ОтборПоСеансу = Неопределено,
|
||
НаСервере = Неопределено)
|
||
|
||
#Если Сервер И Не Сервер Тогда
|
||
мПлатформа = Обработки.ирПлатформа.Создать();
|
||
#КонецЕсли
|
||
НеизвестныеСвойства = Новый Соответствие();
|
||
Если Ложь
|
||
Или (НаСервере <> Неопределено И мЛиАнализТрассыЗапроса <> Истина)
|
||
Или Не ЗначениеЗаполнено(КаталогЖурнала)
|
||
Тогда
|
||
КаталогЖурнала = ПолучитьКаталогТекущегоЖурнала(НаСервере = Истина);
|
||
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если Не ирОбщий.ЛиКаталогДоступенЛкс(КаталогЖурнала) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Если ЗагружатьТолькоТекущийСеанс Тогда
|
||
Если Ложь
|
||
Или ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Или Не НаСервере = Истина
|
||
Тогда
|
||
ОтборПоПроцессу = ирКэш.Получить().ИдентификаторПроцессаОС();
|
||
КонецЕсли;
|
||
Если НаСервере = Истина Тогда
|
||
ОтборПоСеансу = НомерСеансаИнформационнойБазы();
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
лПоследнееВремяНачалаЗагрузки = ТекущаяДата();
|
||
Если ПериодПоследниеМинуты > 0 Тогда
|
||
НачалоПериода = лПоследнееВремяНачалаЗагрузки - 60 * ПериодПоследниеМинуты;
|
||
КонецПериода = Неопределено;
|
||
КонецЕсли;
|
||
//Если ТаблицаЖурнала.Количество() = 0 Тогда
|
||
// МинимальнаяДатаЗагрузки = ТекущаяДата() + 100000;
|
||
//КонецЕсли;
|
||
//Если МинимальнаяДатаЗагрузки > НачалоПериода Тогда
|
||
// ТаблицаЖурнала.Очистить();
|
||
//КонецЕсли;
|
||
//РежимДозагрузки = Истина
|
||
// И ТаблицаЖурнала.Количество() > 0
|
||
// И МинимальнаяДатаЗагрузки <= НачалоПериода;
|
||
Если СообщитьРазмер = Неопределено Тогда
|
||
СообщитьРазмер = (ТаблицаЖурнала.Количество() = 0) Или КомментироватьЗагрузку;
|
||
КонецЕсли;
|
||
Если ТаблицаЖурнала.Количество() = 0 Тогда
|
||
мКартыФайлов.Очистить();
|
||
КонецЕсли;
|
||
|
||
ирОбщий.ЛиКаталогТехножурналаНедоступенЛкс(КаталогЖурнала);
|
||
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.log", Истина);
|
||
ОбщийРазмер = 0;
|
||
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
|
||
ОбщийРазмер = ОбщийРазмер + ФайлЖурнала.Размер();
|
||
КонецЦикла;
|
||
Если СообщитьРазмер Тогда
|
||
ирОбщий.СообщитьЛкс("В каталоге """ + КаталогЖурнала + """ обнаружено для обработки " + Формат(Цел(ОбщийРазмер / 1024), "ЧН=") + "КБ логов");
|
||
ПредставлениеОтбора = "";
|
||
Если СписокЗагружаемыхТиповСобытий.Количество() > 0 Тогда
|
||
ПредставлениеОтбора = ПредставлениеОтбора + " события " + СписокЗагружаемыхТиповСобытий;
|
||
КонецЕсли;
|
||
Если ЗначениеЗаполнено(НачалоПериода) Тогда
|
||
ПредставлениеОтбора = ПредставлениеОтбора + " с " + НачалоПериода;
|
||
КонецЕсли;
|
||
Если ЗначениеЗаполнено(КонецПериода) Тогда
|
||
ПредставлениеОтбора = ПредставлениеОтбора + " по " + КонецПериода;
|
||
КонецЕсли;
|
||
Если ЗначениеЗаполнено("" + ФильтрЗагрузки) Тогда
|
||
Если ЗначениеЗаполнено(ПредставлениеОтбора) Тогда
|
||
ПредставлениеОтбора = ПредставлениеОтбора + " И";
|
||
КонецЕсли;
|
||
ПредставлениеОтбора = ПредставлениеОтбора + " " + ФильтрЗагрузки;
|
||
КонецЕсли;
|
||
Если ЗначениеЗаполнено(ПредставлениеОтбора) Тогда
|
||
ирОбщий.СообщитьЛкс("Отбор загрузки:" + ПредставлениеОтбора);
|
||
КонецЕсли;
|
||
Если мПлатформа.ИдентификаторыПроцессовОтладчиков().Количество() > 0 Тогда
|
||
ирОбщий.СообщитьЛкс("Возможно подключен отладчик и тогда он замедляет загрузку логов. Отключите отладчик для ускорения загрузки.");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
//БезопасныйРазмерЖурнала = 10*1000*1000; // 10МБ
|
||
//Если ОбщийРазмер > БезопасныйРазмерЖурнала Тогда
|
||
// Ответ = Вопрос("Размер журнала составляет " + Формат(Цел(ОбщийРазмер / 1000000)) + " МБ.
|
||
// |Чтение журнала может продолжаться длительное время, продолжить?", РежимДиалогаВопрос.ДаНет);
|
||
//Иначе
|
||
// Ответ = КодВозвратаДиалога.Да;
|
||
//КонецЕсли;
|
||
//Если Ответ = КодВозвратаДиалога.Нет Тогда
|
||
// Возврат Ложь;
|
||
//КонецЕсли;
|
||
НеОбрабатывать = Ложь;
|
||
СтрокаСобытия = "";
|
||
СтруктураЗаписиТЖ = Новый Структура();
|
||
РеквизитыТЧ = Метаданные().ТабличныеЧасти.ТаблицаЖурнала.Реквизиты;
|
||
шСимвол = "[" + шБуква + "\d\._#{}-]";
|
||
////ШаблонСвойствоЗначение = ",([\w\:]+)=(?:'\s*([^']*)'|""\s*([^""]*)""|([^'""\n\r,]*))";
|
||
////Шаблон = "(\d\d:\d\d)\.(\d+)-(\d+),(" + шСимвол + "+),\d+"
|
||
////+ "((?:" + ШаблонСвойствоЗначение + ")*)";
|
||
//ШаблонСвойствоЗначение = "([\w\:]+)=(?:'\s*((?:.|\n|\r)*?)'|""\s*([^""]*)""|([^'""\n\r,]*))(?:,|\r|$)"; // Так были очень большие трассы вычисления RegExp
|
||
ШаблонСвойствоЗначение = "([\w\:]+)=(?:'\s*([\s\S]*?)'|""\s*((?:""""|[^""])*)""|([^'""\n\r,]*))(?:,|\r|\n|$)+";
|
||
Шаблон = "(\d\d:\d\d)\.(\d+)-(\d+),(" + шСимвол + "+),(\d+)"
|
||
+ ",((?:" + ШаблонСвойствоЗначение + ")*)";
|
||
|
||
мПлатформа = ирКэш.Получить();
|
||
RegExp = мПлатформа.RegExp;
|
||
RegExp2 = мПлатформа.RegExp2;
|
||
//: RegExp = Новый COMОбъект("VBScript.RegExp");
|
||
RegExp.Pattern = Шаблон;
|
||
//RegExp.Multiline = Истина;
|
||
RegExp.Global = Истина;
|
||
RegExp2.Pattern = ШаблонСвойствоЗначение;
|
||
RegExp2.Global = Истина;
|
||
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ОбщийРазмер, "Загрузка файлов");
|
||
ПустаяДата = Дата("00010101");
|
||
РазмерОбработанныхДанных = 0;
|
||
//лНачалоПериода = НачалоПериода;
|
||
//Если Не РежимДозагрузки Тогда
|
||
// //ТаблицаЖурнала.Очистить();
|
||
// КлючиЗагруженныхСтрок = Новый Соответствие;
|
||
//Иначе
|
||
// Если НаСервере = Истина Тогда
|
||
// лДатаЗагрузки = ПоследнееВремяНачалаЗагрузкиСервера;
|
||
// Иначе
|
||
// лДатаЗагрузки = ПоследнееВремяНачалаЗагрузки;
|
||
// КонецЕсли;
|
||
// Если ЗначениеЗаполнено(лДатаЗагрузки) Тогда
|
||
// лНачалоПериода = лДатаЗагрузки - НаложениеПриДозагрузкеСекунд;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если УдалятьДанныеВнеПериода Тогда
|
||
ТаблицаЖурнала.Сортировать("МоментВремени");
|
||
КоличествоСтрок = ТаблицаЖурнала.Количество();
|
||
Пока Истина
|
||
И КоличествоСтрок > 0
|
||
И ТаблицаЖурнала[0].Дата < НачалоПериода
|
||
Цикл
|
||
ТаблицаЖурнала.Удалить(0);
|
||
КоличествоСтрок = КоличествоСтрок - 1;
|
||
КонецЦикла;
|
||
Если ЗначениеЗаполнено(КонецПериода) Тогда
|
||
ИндексСтроки = КоличествоСтрок - 1;
|
||
Пока Истина
|
||
И КоличествоСтрок > 0
|
||
И ТаблицаЖурнала[ИндексСтроки].Дата > КонецПериода
|
||
Цикл
|
||
ТаблицаЖурнала.Удалить(ИндексСтроки);
|
||
ИндексСтроки = ИндексСтроки - 1;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ДостигнутоПредельноеКоличество = Ложь;
|
||
//НовыеКлючиЗагруженныхСтрок = Новый Соответствие();
|
||
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
|
||
#Если Сервер И Не Сервер Тогда
|
||
ФайлЖурнала = Новый файл;
|
||
#КонецЕсли
|
||
Попытка
|
||
РазмерФайла = ФайлЖурнала.Размер();
|
||
Исключение
|
||
РазмерФайла = "?";
|
||
КонецПопытки;
|
||
Если ТипЗнч(РазмерФайла) = Тип("Число") Тогда
|
||
РазмерОбработанныхДанных = РазмерОбработанныхДанных + РазмерФайла;
|
||
КонецЕсли;
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор, РазмерОбработанныхДанных);
|
||
Если КомментироватьЗагрузку Тогда
|
||
ирОбщий.СообщитьЛкс("Читаем " + ФайлЖурнала.ПолноеИмя + ", размер - " + РазмерФайла);
|
||
КонецЕсли;
|
||
ПолноеИмяКаталогаПроцесса = Лев(ФайлЖурнала.Путь, СтрДлина(ФайлЖурнала.Путь) - 1);
|
||
Длина1 = СтрДлина(ПолноеИмяКаталогаПроцесса);
|
||
СтрокаЧасаЗаписи = "20" + Сред(ФайлЖурнала.ПолноеИмя, Длина1 + 2, 8);
|
||
ДатаЧасЗаписи = Дата(СтрокаЧасаЗаписи + "0000");
|
||
ИдентификаторПроцессаСтрока = ирОбщий.СтрокаБезКонцаЛкс(ирОбщий.ПоследнийФрагментЛкс(ФайлЖурнала.Путь, "_"), 1);
|
||
Попытка
|
||
ИдентификаторПроцесса = Число(ИдентификаторПроцессаСтрока);
|
||
Исключение
|
||
ирОбщий.СообщитьЛкс("Неверная структура каталогов техножурнала", СтатусСообщения.Внимание);
|
||
Возврат Ложь;
|
||
КонецПопытки;
|
||
//ЛиФайлВИнтервалеПолностью = ирОбщий.ЛиДатаВИнтервалеБезГраницЛкс(ДатаЧасЗаписи, НачалоЧаса(лНачалоПериода), НачалоЧаса(КонецПериода));
|
||
//ЛиДатаВИнтервале = ирОбщий.ЛиДатаВИнтервалеСГраницамиЛкс(ДатаЧасЗаписи, НачалоЧаса(лНачалоПериода), НачалоЧаса(КонецПериода));
|
||
ЛиФайлВИнтервалеПолностью = ирОбщий.ЛиДатаВИнтервалеБезГраницЛкс(ДатаЧасЗаписи, НачалоЧаса(НачалоПериода), НачалоЧаса(КонецПериода));
|
||
ЛиДатаВИнтервале = ирОбщий.ЛиДатаВИнтервалеСГраницамиЛкс(ДатаЧасЗаписи, НачалоЧаса(НачалоПериода), НачалоЧаса(КонецПериода));
|
||
Если Не ЛиДатаВИнтервале Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ОтборПоПроцессу <> Неопределено
|
||
И ИдентификаторПроцесса <> ОтборПоПроцессу
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ПоследняяСтрокаТаблицыФайла = Неопределено;
|
||
ТекстФайла = ""; // Уничтожаем старый текст, т.к. он может быть очень большим
|
||
Попытка
|
||
ЧтениеТекста = Новый ЧтениеТекста(ФайлЖурнала.ПолноеИмя, КодировкаТекста.UTF8, ,,Ложь);
|
||
//ТекстовыйДокумент.Прочитать(ФайлЖурнала.ПолноеИмя, КодировкаТекста.UTF8);
|
||
Исключение
|
||
ирОбщий.СообщитьЛкс("Не удалось прочитать данные из файла " + ФайлЖурнала.ПолноеИмя, СтатусСообщения.Внимание);
|
||
Продолжить;
|
||
КонецПопытки;
|
||
СигнатураФайла = ЧтениеТекста.Прочитать(20); // Для идентификации файла
|
||
Если ПустаяСтрока(СигнатураФайла) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
РазмерПорции = 2 * 1000 * 1000; // Подобрано экспериментально
|
||
КраткоеИмяКаталогаПроцесса = ирОбщий.ПоследнийФрагментЛкс(ПолноеИмяКаталогаПроцесса, "\");
|
||
ЧислоПорций = Цел(РазмерФайла / РазмерПорции) + 1;
|
||
ЧтениеТекста = Новый ЧтениеТекста(ФайлЖурнала.ПолноеИмя, КодировкаТекста.UTF8, ,,Ложь);
|
||
АбсолютнаяПозицияВФайле = 0;
|
||
КлючКарты = Новый Структура("ИмяКаталогаПроцесса, ИмяТекущегоФайла, СигнатураТекущегоФайла, ОтборПоСеансу",
|
||
КраткоеИмяКаталогаПроцесса, ФайлЖурнала.Имя, СигнатураФайла, ОтборПоСеансу);
|
||
СтрокиКарт = мКартыФайлов.НайтиСтроки(КлючКарты);
|
||
Если СтрокиКарт.Количество() > 0 Тогда
|
||
КартаФайла = СтрокиКарт[0];
|
||
Иначе
|
||
КартаФайла = мКартыФайлов.Добавить();
|
||
ЗаполнитьЗначенияСвойств(КартаФайла, КлючКарты);
|
||
КартаФайла.КонецПериода = Дата(1000, 1, 1);
|
||
КонецЕсли;
|
||
Если ирОбщий.ЛиДатаВИнтервалеСГраницамиЛкс(НачалоПериода, КартаФайла.НачалоПериода, КартаФайла.КонецПериода) Тогда
|
||
АбсолютнаяПозицияВФайле = КартаФайла.ПозицияКонца;
|
||
ИначеЕсли Ложь
|
||
Или НачалоПериода > КартаФайла.НачалоПериода
|
||
Или КонецПериода < КартаФайла.КонецПериода
|
||
Тогда
|
||
// Периоды не сшиваются. Очищаем карту.
|
||
КартаФайла.ПозицияНачала = -1;
|
||
КартаФайла.ПозицияКонца = -1;
|
||
КартаФайла.НачалоПериода = НачалоПериода;
|
||
КартаФайла.КонецПериода = КонецПериода;
|
||
КартаФайла.ДатаИзмененияФайла = Неопределено;
|
||
КонецЕсли;
|
||
Если АбсолютнаяПозицияВФайле > 0 Тогда
|
||
Если ЗначениеЗаполнено(КартаФайла.ДатаИзмененияФайла) Тогда
|
||
Если КартаФайла.ДатаИзмененияФайла = ФайлЖурнала.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс() Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ЧтениеТекста.Прочитать(АбсолютнаяПозицияВФайле);
|
||
КонецЕсли;
|
||
ПозицияНачалаСчитанныхДанных = -1;
|
||
Если ЧислоПорций > 1 Тогда
|
||
ИндикаторФайла = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ЧислоПорций, "" + КраткоеИмяКаталогаПроцесса + "\" + ФайлЖурнала.Имя);
|
||
Иначе
|
||
ИндикаторФайла = Неопределено;
|
||
КонецЕсли;
|
||
РазрешенныеТипыСобытий = Неопределено;
|
||
Если СписокЗагружаемыхТиповСобытий.Количество() > 0 Тогда
|
||
РазрешенныеТипыСобытий = Новый Структура;
|
||
Для Каждого ТипСобытия Из СписокЗагружаемыхТиповСобытий.ВыгрузитьЗначения() Цикл
|
||
РазрешенныеТипыСобытий.Вставить(ТипСобытия);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
СтрокаТЧ = Неопределено;
|
||
РазмерТекущейПорции = 0;
|
||
Пока Истина Цикл
|
||
КартаФайла.ДатаИзмененияФайла = ФайлЖурнала.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
|
||
ПорцияТекстаФайла = ЧтениеТекста.Прочитать(РазмерПорции);
|
||
Если Ложь
|
||
Или ПорцияТекстаФайла = Неопределено
|
||
Или ПустаяСтрока(ПорцияТекстаФайла)
|
||
Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
Если ИндикаторФайла <> Неопределено Тогда
|
||
ирОбщий.ОбработатьИндикаторЛкс(ИндикаторФайла);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И АбсолютнаяПозицияВФайле >= КартаФайла.ПозицияНачала
|
||
И АбсолютнаяПозицияВФайле + СтрДлина(ПорцияТекстаФайла) + СтрДлина(ТекстФайла) < КартаФайла.ПозицияКонца
|
||
Тогда
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + СтрДлина(ПорцияТекстаФайла) + СтрДлина(ТекстФайла);
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ТекстФайла = ТекстФайла + ПорцияТекстаФайла;
|
||
РазборТекстаРазрешен = Истина;
|
||
ОписаниеОшибки = "";
|
||
МаксимальныйРазмерТекстДляАнализа = 20000000; // Экспериментально подобрано http://devtool1c.ucoz.ru/forum/2-270-1#1145
|
||
Если СтрДлина(ТекстФайла) > МаксимальныйРазмерТекстДляАнализа Тогда
|
||
Если Истина
|
||
И РазмерТекущейПорции = РазмерПорции
|
||
И СтрокаТЧ <> Неопределено
|
||
Тогда
|
||
СтрокаТЧ.ТекстSDBL = "<?>";
|
||
СтрокаТЧ.ТекстСУБД = "<?>";
|
||
ирОбщий.СообщитьЛкс("При анализе файла """ + ФайлЖурнала.ПолноеИмя + """ некоторые свойства события пропущены, т.к. оно превышает допустимый размер "
|
||
+ XMLСтрока(Цел(МаксимальныйРазмерТекстДляАнализа/1024/1024)) + "МБ: " + Лев(СокрЛ(СтрЗаменить(ТекстФайла, Символы.ПС, "")), 80) + "...");
|
||
Иначе
|
||
ОписаниеОшибки = "Событие превышает допустимый размер 20МБ";
|
||
КонецЕсли;
|
||
РазборТекстаРазрешен = Ложь;
|
||
Иначе
|
||
Если Истина
|
||
И РазмерТекущейПорции = РазмерПорции
|
||
И СтрокаТЧ <> Неопределено
|
||
Тогда
|
||
ТаблицаЖурнала.Удалить(ТаблицаЖурнала.Количество() - 1);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Вхождения = RegExp.Execute("");
|
||
Если РазборТекстаРазрешен Тогда
|
||
Попытка
|
||
Вхождения = RegExp.Execute(ТекстФайла);
|
||
Исключение
|
||
ОписаниеОшибки = ОписаниеОшибки();
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
Если ОписаниеОшибки <> "" Тогда
|
||
ирОбщий.СообщитьЛкс("При анализе файла """ + ФайлЖурнала.ПолноеИмя + """ пропущена порция """ + Лев(СокрЛ(СтрЗаменить(ТекстФайла, Символы.ПС, "")), 80) + "..."":
|
||
| " + ОписаниеОшибки);
|
||
Иначе
|
||
Если КомментироватьЗагрузку Тогда
|
||
ирОбщий.СообщитьЛкс("Анализ порции " + СтрДлина(ТекстФайла) + " символов обнаружил " + Вхождения.Count + " событий");
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
СтрокаТекущегоКонтекста = Неопределено;
|
||
СтрокаТЧ = Неопределено;
|
||
Вхождение = Неопределено;
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
#Если Клиент Тогда
|
||
ОбработкаПрерыванияПользователя();
|
||
#КонецЕсли
|
||
СтрокаТЧ = Неопределено;
|
||
АбсолютнаяПозицияВхождения = АбсолютнаяПозицияВФайле + Вхождение.FirstIndex;
|
||
Если Истина
|
||
И КартаФайла.ПозицияНачала > -1
|
||
И АбсолютнаяПозицияВхождения >= КартаФайла.ПозицияНачала
|
||
И АбсолютнаяПозицияВхождения < КартаФайла.ПозицияКонца
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
СтрокаВремениЗаписи = СтрокаЧасаЗаписи + СтрЗаменить(Вхождение.SubMatches(0), ":", "");
|
||
ДатаТекущегоСобытия = Дата(СтрокаВремениЗаписи);
|
||
Если Не ЛиФайлВИнтервалеПолностью Тогда
|
||
//ЛиДатаВИнтервале = ирОбщий.ЛиДатаВИнтервалеСГраницамиЛкс(ДатаТекущегоСобытия, лНачалоПериода, КонецПериода);
|
||
//Если Не ЛиДатаВИнтервале Тогда
|
||
// Продолжить;
|
||
//КонецЕсли;
|
||
Если Истина
|
||
И ЗначениеЗаполнено(НачалоПериода)
|
||
И ДатаТекущегоСобытия < НачалоПериода
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ЗначениеЗаполнено(КонецПериода)
|
||
И ДатаТекущегоСобытия > КонецПериода
|
||
Тогда
|
||
Вхождение = Неопределено;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ТипСобытия = ВРег(Вхождение.SubMatches(3));
|
||
Если Истина
|
||
И РазрешенныеТипыСобытий <> Неопределено
|
||
И Не РазрешенныеТипыСобытий.Свойство(ТипСобытия)
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если ПозицияНачалаСчитанныхДанных = -1 Тогда
|
||
ПозицияНачалаСчитанныхДанных = АбсолютнаяПозицияВхождения;
|
||
КонецЕсли;
|
||
КонецМикросекунды = Вхождение.SubMatches(1);
|
||
//КлючСтроки = МоментВремени + ";" + ФайлЖурнала.ПолноеИмя;
|
||
//Если РежимДозагрузки Тогда
|
||
// Если КлючиЗагруженныхСтрок[КлючСтроки] = 1 Тогда
|
||
// Продолжить;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если СтрДлина(КонецМикросекунды) = 6 Тогда
|
||
//Это 8.3
|
||
ЧислоМикросекунд = Число(КонецМикросекунды);
|
||
ПродолжительностьВМикросекундах = Число(Вхождение.SubMatches(2));
|
||
Иначе
|
||
//Это 8.2
|
||
ЧислоМикросекунд = Число(КонецМикросекунды) * 100;
|
||
ПродолжительностьВМикросекундах = Число(Вхождение.SubMatches(2)) * 100;
|
||
КонецЕсли;
|
||
Если ТаблицаЖурнала.Количество() = МаксТысячСобытий * 1000 Тогда
|
||
УдалитьСтрокиВнеФильтра();
|
||
Если ТаблицаЖурнала.Количество() = МаксТысячСобытий * 1000 Тогда
|
||
ДостигнутоПредельноеКоличество = Истина;
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
СтрокаТЧ = ТаблицаЖурнала.Добавить();
|
||
СтрокаТЧ.Дата = ДатаТекущегоСобытия - СдвигВремени;
|
||
СтрокаТЧ.МоментВремени = ПолучитьМоментВремени(СтрокаТЧ.Дата, КонецМикросекунды);
|
||
СтрокаТЧ.ИмяФайлаЛога = ФайлЖурнала.ПолноеИмя;
|
||
СтрокаТЧ.ПроцессОС = ИдентификаторПроцесса;
|
||
//СтрокаТЧ.ТекстЖурнала = Вхождение.Value; // Теперь это только для отладки будем включать
|
||
СтрокаТЧ.Длительность = ПродолжительностьВМикросекундах / 1000; // Переводим длительность в миллисекунды
|
||
Длительность1Секунды = Цел(ПродолжительностьВМикросекундах / 1000000);
|
||
Длительность1Микросекунды = ПродолжительностьВМикросекундах - Длительность1Секунды * 1000000;
|
||
ДатаНачала = СтрокаТЧ.Дата - Длительность1Секунды;
|
||
НачалоМикросекунды = КонецМикросекунды - Длительность1Микросекунды;
|
||
Если НачалоМикросекунды < 0 Тогда
|
||
ДатаНачала = ДатаНачала - 1;
|
||
НачалоМикросекунды = 1000000 + НачалоМикросекунды;
|
||
КонецЕсли;
|
||
СтрокаТЧ.ДатаНачала = ДатаНачала;
|
||
СтрокаТЧ.МоментВремениНачала = ПолучитьМоментВремени(ДатаНачала, НачалоМикросекунды);
|
||
СтрокаТЧ.Событие = ТипСобытия;
|
||
СтрокаТЧ.Вложенность = Число(Вхождение.SubMatches(4));
|
||
ВхожденияСвойств = RegExp2.Execute(Вхождение.SubMatches(5));
|
||
|
||
//// Пассивный оригинал расположенного ниже однострочного кода. Выполняйте изменения синхронно в обоих вариантах.
|
||
//#Если Сервер И Не Сервер Тогда
|
||
Для Каждого ВхождениеСвойства Из ВхожденияСвойств Цикл
|
||
//Для Индекс = 0 По мТаблицаКолонок.Количество() - 1 Цикл
|
||
//Индекс + СмещениеПервойКолонки
|
||
ИмяСвойства = ВхождениеСвойства.SubMatches(0);
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(3);
|
||
//Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
Если ЗначениеСвойства = Неопределено Тогда // Скорость критична
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(2);
|
||
КонецЕсли;
|
||
//Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
Если ЗначениеСвойства = Неопределено Тогда // Скорость критична
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(1);
|
||
КонецЕсли;
|
||
//Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
Если ЗначениеСвойства = Неопределено Тогда // Скорость критична
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ИмяКолонкиТЧ = мСоответствиеКолонок[НРег(ИмяСвойства)];
|
||
Если ИмяКолонкиТЧ = Неопределено Тогда
|
||
//Если НеизвестныеСвойства[ИмяСвойства] = Неопределено Тогда
|
||
// НеизвестныеСвойства[ИмяСвойства] = 1;
|
||
// ирОбщий.СообщитьЛкс("Обнаружено неизвестное свойство """ + ИмяСвойства + """ события " + ТипСобытия, СтатусСообщения.Информация);
|
||
//КонецЕсли;
|
||
СтрокаТЧ.НеизвестныеСвойства = СтрокаТЧ.НеизвестныеСвойства + ИмяСвойства + "=" + ЗначениеСвойства + ", ";
|
||
Иначе
|
||
//Если мЧисловыеСвойства.Свойство(ИмяКолонкиТЧ) Тогда
|
||
// Если Не ЗначениеЗаполнено(ЗначениеСвойства) Тогда
|
||
// ЗначениеСвойства = 0;
|
||
// Иначе
|
||
// Попытка
|
||
// ЗначениеСвойства = Число(ЗначениеСвойства);
|
||
// Исключение
|
||
// ВызватьИсключение "Некорректное представление """ + ЗначениеСвойства + """ значения числового свойства """ + ИмяКолонкиТЧ + """";
|
||
// КонецПопытки;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если ТипЗнч(СтрокаТЧ[ИмяКолонкиТЧ]) = Тип("Булево") Тогда
|
||
ЗначениеСвойства = ?(ЗначениеСвойства = "1" Или Нрег(ЗначениеСвойства) = "true", Истина, Ложь);
|
||
КонецЕсли;
|
||
Если Не мНепустыеКолонкиЖурнала.Свойство(ИмяКолонкиТЧ) Тогда
|
||
Если ЗначениеЗаполнено(ЗначениеСвойства) Тогда
|
||
мНепустыеКолонкиЖурнала.Вставить(ИмяКолонкиТЧ);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Попытка
|
||
СтрокаТЧ[ИмяКолонкиТЧ] = ЗначениеСвойства;
|
||
Исключение
|
||
ВызватьИсключение "Некорректное представление """ + ЗначениеСвойства + """ значения свойства """ + ИмяКолонкиТЧ + """";
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
//#КонецЕсли
|
||
//// Однострочный код использован для ускорения. Выше расположен оригинал. Выполняйте изменения синхронно в обоих вариантах. Преобразовано консолью кода из подсистемы "Инструменты разработчика" (http://devtool1c.ucoz.ru)
|
||
//Для Каждого ВхождениеСвойства Из ВхожденияСвойств Цикл ИмяСвойства = ВхождениеСвойства.SubMatches(0); ЗначениеСвойства = ВхождениеСвойства.SubMatches(3); Если ЗначениеСвойства = Неопределено Тогда ЗначениеСвойства = ВхождениеСвойства.SubMatches(2); КонецЕсли; Если ЗначениеСвойства = Неопределено Тогда ЗначениеСвойства = ВхождениеСвойства.SubMatches(1); КонецЕсли; Если ЗначениеСвойства = Неопределено Тогда Продолжить; КонецЕсли; ИмяКолонкиТЧ = мСоответствиеКолонок[НРег(ИмяСвойства)]; Если ИмяКолонкиТЧ = Неопределено Тогда СтрокаТЧ.НеизвестныеСвойства = СтрокаТЧ.НеизвестныеСвойства + ИмяСвойства + "=" + ЗначениеСвойства + ", "; Иначе Если ТипЗнч(СтрокаТЧ[ИмяКолонкиТЧ]) = Тип("Булево") Тогда ЗначениеСвойства = ?(ЗначениеСвойства = "1" Или Нрег(ЗначениеСвойства) = "true", Истина, Ложь); КонецЕсли; Если Не мНепустыеКолонкиЖурнала.Свойство(ИмяКолонкиТЧ) Тогда Если ЗначениеЗаполнено(ЗначениеСвойства) Тогда мНепустыеКолонкиЖурнала.Вставить(ИмяКолонкиТЧ); КонецЕсли; КонецЕсли; Попытка СтрокаТЧ[ИмяКолонкиТЧ] = ЗначениеСвойства; Исключение ВызватьИсключение "Некорректное представление """ + ЗначениеСвойства + """ значения свойства """ + ИмяКолонкиТЧ + """"; КонецПопытки; КонецЕсли; КонецЦикла;
|
||
|
||
//АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + Вхождение.Length;
|
||
Если Истина
|
||
И ОтборПоСеансу <> Неопределено
|
||
И СтрокаТЧ.Сеанс <> ОтборПоСеансу
|
||
Тогда
|
||
ТаблицаЖурнала.Удалить(СтрокаТЧ);
|
||
СтрокаТЧ = Неопределено;
|
||
#Если Сервер И Не Сервер Тогда
|
||
СтрокаТЧ = ТаблицаЖурнала.Добавить();
|
||
#КонецЕсли
|
||
Продолжить;
|
||
КонецЕсли;
|
||
//Если НаСервере <> Неопределено Тогда
|
||
// СтрокаТЧ.НаСервере = НаСервере;
|
||
//Иначе
|
||
Если Ложь
|
||
Или ТипСобытия = "SCOM"
|
||
Тогда
|
||
СтрокаТЧ.НаСервере = Истина;
|
||
Иначе
|
||
ИмяТипаПроцесса = "_" + СтрЗаменить(СтрокаТЧ.ТипПроцессаОС, "#", "");
|
||
Попытка
|
||
СтрокаТЧ.НаСервере = мСерверныеТипыПроцессов.Свойство(ИмяТипаПроцесса);
|
||
Исключение
|
||
// Бывают типы процессов с UID, к сожалению тогда невозможно определить
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
//КонецЕсли;
|
||
Если СтрокаТЧ.Контекст <> "" Тогда
|
||
КонтекстТД = Новый ТекстовыйДокумент;
|
||
КонтекстТД.УстановитьТекст(СтрокаТЧ.Контекст);
|
||
СтрокаТЧ.СтрокаМодуля = СокрЛП(КонтекстТД.ПолучитьСтроку(КонтекстТД.КоличествоСтрок()));
|
||
Если БазовыйУровеньСтека > 0 Тогда
|
||
ЗаполнитьСтрокуБазовогоУровня(СтрокаТЧ);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
//Если ДатаТекущегоСобытия > лПоследнееВремяНачалаЗагрузки - НаложениеПриДозагрузкеСекунд Тогда
|
||
// НовыеКлючиЗагруженныхСтрок[КлючСтроки] = 1;
|
||
//КонецЕсли;
|
||
Если ирОбщий.СтрокиРавныЛкс(ТипСобытия, "Context") Тогда
|
||
// Встроим контекст в предыдущие события
|
||
Индекс = ТаблицаЖурнала.Количество() - 2;
|
||
Пока Индекс >= 0 Цикл
|
||
СтрокаБезКонтекста = ТаблицаЖурнала[Индекс];
|
||
Индекс = Индекс - 1;
|
||
Если Ложь
|
||
Или СтрокаБезКонтекста.Сеанс <> СтрокаТЧ.Сеанс
|
||
Или СтрокаБезКонтекста.Инфобаза <> СтрокаТЧ.Инфобаза
|
||
Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
Если Не СтрокаБезКонтекста.СтрокаМодуля = "" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
ЗаполнитьЗначенияСвойств(СтрокаБезКонтекста, СтрокаТЧ, "СтрокаМодуля, Контекст");
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ДостигнутоПредельноеКоличество Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
// Для отката к началу последнего события
|
||
РазмерТекущейПорции = СтрДлина(ПорцияТекстаФайла);
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + СтрДлина(ТекстФайла);
|
||
Если РазмерТекущейПорции = РазмерПорции Тогда
|
||
//Если СтрокаТЧ <> Неопределено Тогда
|
||
// ТаблицаЖурнала.Удалить(ТаблицаЖурнала.Количество() - 1);
|
||
//КонецЕсли;
|
||
Если Вхождение <> Неопределено Тогда
|
||
ТекстФайла = Сред(ТекстФайла, Вхождение.FirstIndex);
|
||
Иначе
|
||
ТекстФайла = Прав(ТекстФайла, 1000); // Страховка
|
||
КонецЕсли;
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле - СтрДлина(ТекстФайла);
|
||
Иначе
|
||
ТекстФайла = "";
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ИндикаторФайла <> Неопределено Тогда
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
КонецЕсли;
|
||
Если ДостигнутоПредельноеКоличество Тогда
|
||
ТекстСообщения = "Загрузка остановлена по достижению максимального количества событий в таблице";
|
||
Если Не ЗначениеЗаполнено("" + ФильтрЗагрузки) Тогда
|
||
ТекстСообщения = ТекстСообщения + ". Если задать фильтр отображения таблицы, то будет предложено применить его при загрузке нового журнала.";
|
||
КонецЕсли;
|
||
ирОбщий.СообщитьЛкс(ТекстСообщения);
|
||
Прервать;
|
||
КонецЕсли;
|
||
КартаФайла.ПозицияКонца = АбсолютнаяПозицияВФайле;
|
||
Если Истина
|
||
И ПозицияНачалаСчитанныхДанных <> -1
|
||
И (Ложь
|
||
Или КартаФайла.ПозицияНачала = -1
|
||
Или КартаФайла.ПозицияНачала > ПозицияНачалаСчитанныхДанных)
|
||
Тогда
|
||
КартаФайла.ПозицияНачала = ПозицияНачалаСчитанныхДанных;
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или Не ЗначениеЗаполнено(КонецПериода)
|
||
Или КонецПериода > КартаФайла.КонецПериода
|
||
Тогда
|
||
КартаФайла.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или Не ЗначениеЗаполнено(НачалоПериода)
|
||
Или НачалоПериода < КартаФайла.НачалоПериода
|
||
Тогда
|
||
КартаФайла.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
УдалитьСтрокиВнеФильтра();
|
||
//КлючиЗагруженныхСтрок = НовыеКлючиЗагруженныхСтрок;
|
||
//Если НаСервере = Истина Тогда
|
||
// ЭтотОбъект.ПоследнееВремяНачалаЗагрузкиСервера = лПоследнееВремяНачалаЗагрузки;
|
||
//Иначе
|
||
// ЭтотОбъект.ПоследнееВремяНачалаЗагрузки = лПоследнееВремяНачалаЗагрузки;
|
||
//КонецЕсли;
|
||
//МинимальнаяДатаЗагрузки = Мин(НачалоПериода, МинимальнаяДатаЗагрузки);
|
||
ТаблицаЖурнала.Сортировать("МоментВремени");
|
||
//ТаблицаЖурнала.Сортировать("МоментВремениНачала");
|
||
|
||
ОпределитьНепустыеКолонки();
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Процедура УдалитьСтрокиВнеФильтра()
|
||
|
||
Если ЗначениеЗаполнено("" + ФильтрЗагрузки) Тогда
|
||
Построитель = Новый ПостроительЗапроса;
|
||
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблицаЖурнала);
|
||
ирОбщий.СкопироватьОтборПостроителяЛкс(Построитель.Отбор, ФильтрЗагрузки);
|
||
ТаблицаЖурнала.Загрузить(Построитель.Результат.Выгрузить());
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОпределитьНепустыеКолонки() Экспорт
|
||
|
||
Если мНепустыеКолонкиЖурнала.Количество() = 0 Тогда // Загрузили данные из файла
|
||
// Долгая операция
|
||
Для Каждого Реквизит Из Метаданные().ТабличныеЧасти.ТаблицаЖурнала.Реквизиты Цикл
|
||
Если ТаблицаЖурнала.НайтиСтроки(Новый Структура(Реквизит.Имя, Реквизит.Тип.ПривестиЗначение())).Количество() < ТаблицаЖурнала.Количество() Тогда
|
||
мНепустыеКолонкиЖурнала.Вставить(Реквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
//Пустота производных колонок
|
||
мНепустыеКолонкиЖурнала.Вставить("Длительность");
|
||
мНепустыеКолонкиЖурнала.Вставить("Дата");
|
||
мНепустыеКолонкиЖурнала.Вставить("ДатаНачала");
|
||
//мНепустыеКолонкиЖурнала.Вставить("Картинка");
|
||
Если мНепустыеКолонкиЖурнала.Свойство("Контекст") Тогда
|
||
мНепустыеКолонкиЖурнала.Вставить("СтрокаМодуля");
|
||
мНепустыеКолонкиЖурнала.Вставить("СтрокаБазовогоМодуля");
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПолучитьМоментВремени(Дата, Микросекунды) Экспорт
|
||
|
||
Результат = Формат(Дата, "ДФ=yyyyMMddHHmmss") + Формат(Микросекунды, "ЧЦ=6; ЧВН=; ЧГ=");
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция РазностьМоментовВремени(МоментВремениУменьшаемый, МоментВремениВычитаемый) Экспорт
|
||
|
||
Если СтрДлина(МоментВремениВычитаемый) <> СтрДлина(МоментВремениВычитаемый) Тогда
|
||
ВызватьИсключение "Размерность моментов времени не совпадает";
|
||
КонецЕсли;
|
||
ДлинаЧастиДаты = 14;
|
||
ДатаУменьшаемая = Дата(Лев(МоментВремениУменьшаемый, ДлинаЧастиДаты));
|
||
ДатаВычитаемая = Дата(Лев(МоментВремениВычитаемый, ДлинаЧастиДаты));
|
||
РазрядностьДолейСекунд = СтрДлина(МоментВремениУменьшаемый) - ДлинаЧастиДаты;
|
||
РазностьСекунд = ДатаУменьшаемая - ДатаВычитаемая;
|
||
Результат = РазностьСекунд;
|
||
Для Счетчик = 1 По РазрядностьДолейСекунд Цикл
|
||
Результат = Результат * 10;
|
||
КонецЦикла;
|
||
Результат = Результат + Число(Сред(МоментВремениУменьшаемый, ДлинаЧастиДаты + 1)) - Число(Сред(МоментВремениВычитаемый, ДлинаЧастиДаты + 1));
|
||
Возврат Результат;
|
||
|
||
КонецФункции // РазностьМоментовВремени()
|
||
|
||
Функция ЗаполнитьСтрокуБазовогоУровня(СтрокаТЧ)
|
||
|
||
Если БазовыйУровеньСтека > 0 Тогда
|
||
//МаркерБазовогоМодуля = Символы.Таб + мИмяБазовогоМодуля + " : ";
|
||
//ПозицияМаркераМодуля = Найти(СтрокаТЧ.Контекст, МаркерБазовогоМодуля);
|
||
//КонецСтроки = Сред(СтрокаТЧ.Контекст, ПозицияМаркераМодуля + СтрДлина(МаркерБазовогоМодуля));
|
||
НовоеЗначение = СокрЛ(СтрПолучитьСтроку(СтрокаТЧ.Контекст, БазовыйУровеньСтека));
|
||
Иначе
|
||
НовоеЗначение = "";
|
||
КонецЕсли;
|
||
ирОбщий.ПрисвоитьЕслиНеРавноЛкс(СтрокаТЧ.СтрокаМодуляБазовогоУровня, НовоеЗначение);
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// ПопытокЧтения - Число, используется только при РежимТрассы = Истина
|
||
Функция ПрочитатьСобственныйЖурналДвухСторон(УдалитьДополнительныеСобытия = Истина, ИменаНеполезныхКолонок = "", РежимТрассы = Истина,
|
||
ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено)
|
||
|
||
Если РежимТрассы Тогда
|
||
Если мИдентификаторТрассы = Неопределено Тогда
|
||
Если Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
ирОбщий.ЛиТехножурналВключенЛкс(Истина, Истина, Истина);
|
||
КонецЕсли;
|
||
ирОбщий.ЛиТехножурналВключенЛкс(, Истина, Истина);
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
ЭтотОбъект.ЗагружатьЖурналКлиента = Истина;
|
||
ЭтотОбъект.ЗагружатьЖурналСервера = Не ирКэш.ЭтоФайловаяБазаЛкс();
|
||
ЭтотОбъект.ЗагружатьТолькоТекущийСеанс = Истина;
|
||
КонецЕсли;
|
||
ВыраниватьДатуПоСерверу = Ложь;
|
||
#Если Клиент Тогда
|
||
ВыраниватьДатуПоСерверу = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.ВыраниватьДатуПоСерверу") = Истина;
|
||
#КонецЕсли
|
||
Если РежимТрассы Тогда
|
||
РазницаВремениКлиентСервер = НачалоПериодаКлиента - НачалоПериодаСервера;
|
||
Иначе
|
||
РазницаВремениКлиентСервер = ирОбщий.ПолучитьТекущуюДатуЛкс() - ирОбщий.ПолучитьТекущуюДатуЛкс(Истина);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И Не ирКэш.Получить().ЭтоФайловаяБаза
|
||
И ЗагружатьЖурналСервера
|
||
Тогда
|
||
ЭтотОбъект.КаталогЖурнала = "";
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
СдвигВремени = 0;
|
||
Иначе
|
||
СдвигВремени = -РазницаВремениКлиентСервер;
|
||
КонецЕсли;
|
||
РезультатСервера = ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериодаСервера, КонецПериодаСервера, Истина, СдвигВремени,
|
||
РежимТрассы, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
КонецЕсли;
|
||
РезультатКлиента = Неопределено;
|
||
#Если Клиент Тогда
|
||
Если ЗагружатьЖурналКлиента Тогда
|
||
ЭтотОбъект.КаталогЖурнала = "";
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
СдвигВремени = РазницаВремениКлиентСервер;
|
||
Иначе
|
||
СдвигВремени = 0;
|
||
КонецЕсли;
|
||
РезультатКлиента = ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериодаКлиента, КонецПериодаКлиента, Ложь, СдвигВремени,
|
||
РежимТрассы, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
Если Истина
|
||
И РезультатКлиента = Неопределено
|
||
И РезультатСервера = Неопределено
|
||
Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Если УдалитьДополнительныеСобытия Тогда
|
||
УдалитьСтрокиПоОтборуЛкс(Новый Структура("Действие", "getExecSQLStatistics"));
|
||
УдалитьСтрокиПоОтборуЛкс(Новый Структура("Событие", "CONTEXT"));
|
||
КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
ЭтотОбъект.ВключитьСвойстваСИменамиМетаданных = Истина;
|
||
КонецЕсли;
|
||
Если ВключитьСвойстваСИменамиМетаданных Тогда
|
||
ОбновитьСвойстваВТерминахМетаданных();
|
||
КонецЕсли;
|
||
//ОбновитьСтрокиБазовогоУровня();
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериода = Неопределено, КонецПериода = Неопределено, НаСервере = Истина, СдвигВремени = 0,
|
||
РежимТрассы = Истина, ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено)
|
||
|
||
Если НачалоПериода <> Неопределено Тогда
|
||
ЭтотОбъект.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
Если КонецПериода <> Неопределено Тогда
|
||
ЭтотОбъект.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
ТехножурналВключен = ирОбщий.ЛиТехножурналВключенЛкс(НаСервере,, Истина);
|
||
Если Истина
|
||
И Не ТехножурналВключен
|
||
И РежимТрассы
|
||
Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
МассивТиповСУБД = Новый Массив();
|
||
Если ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
МассивТиповСУБД.Добавить("DBV8DBENG");
|
||
//ОтборТЧ = Новый Структура("Событие", "SDBL");
|
||
Иначе
|
||
МассивТиповСУБД.Добавить("DBMSSQL");
|
||
МассивТиповСУБД.Добавить("DBPOSTGRS");
|
||
МассивТиповСУБД.Добавить("DBORACLE");
|
||
МассивТиповСУБД.Добавить("DB2");
|
||
//ОтборТЧ = Новый Структура("Событие", "CONTEXT");
|
||
КонецЕсли;
|
||
СообщитьРазмер = Неопределено;
|
||
МаркерНачалаНайден = Ложь;
|
||
Для Счетчик = 1 По ПопытокЧтения Цикл
|
||
#Если Клиент Тогда
|
||
ОбработкаПрерыванияПользователя();
|
||
#КонецЕсли
|
||
Если Счетчик > 1 Тогда
|
||
ирОбщий.СостояниеЛкс("Ожидание техножурнала");
|
||
ирОбщий.ПаузаЛкс(0.5);
|
||
СообщитьРазмер = Ложь;
|
||
КонецЕсли;
|
||
ЖурналСчитан = ПрочитатьПроизвольныйЖурнал(СообщитьРазмер, СдвигВремени, , , НаСервере);
|
||
Если Не ЖурналСчитан Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
//ТехножурналВключен = ирОбщий.ЛиТехножурналВключенЛкс(Истина,, Истина);
|
||
//Если ТехножурналВключен Тогда
|
||
// Если АвтоочисткаТехножурнала Тогда
|
||
// КаталогТекущегоЖурнала = ПолучитьКаталогТекущегоЖурнала();
|
||
// Если ЗначениеЗаполнено(КаталогТекущегоЖурнала) Тогда
|
||
// ирОбщий.ОчиститьКаталогТехножурналаЛкс(КаталогТекущегоЖурнала, Истина, Ложь);
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
Если Ложь
|
||
Или Не ирКэш.ЛиПортативныйРежимЛкс()
|
||
Или Не НаСервере
|
||
Тогда
|
||
МаркерНачала = Новый Структура("Описание", "{(1, 1)}: Ожидается выражение ""ВЫБРАТЬ""
|
||
|<<?>>НачалоТрассы_" + мИдентификаторТрассы);
|
||
МаркерКонца = Новый Структура("Описание", "{(1, 1)}: Ожидается выражение ""ВЫБРАТЬ""
|
||
|<<?>>КонецТрассы_" + мИдентификаторТрассы);
|
||
Иначе
|
||
МаркерНачала = Новый Структура("ТекстSDBL", "SELECT
|
||
|""НачалоТрассы_" + мИдентификаторТрассы + """
|
||
|");
|
||
МаркерКонца = Новый Структура("ТекстSDBL", "SELECT
|
||
|""КонецТрассы_" + мИдентификаторТрассы + """
|
||
|");
|
||
КонецЕсли;
|
||
|
||
// Удаляем лишние строки до маркера начала и после маркера конца
|
||
Если Не МаркерНачалаНайден Тогда
|
||
НайденныеСтроки = ТаблицаЖурнала.НайтиСтроки(МаркерНачала);
|
||
Если НайденныеСтроки.Количество() = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
НачальнаяСтрока = НайденныеСтроки[0];
|
||
#Если Сервер И Не Сервер Тогда
|
||
НачальнаяСтрока = ТаблицаЖурнала.Добавить();
|
||
#КонецЕсли
|
||
Если СмещениеБазовогоУровня <> Неопределено Тогда
|
||
ЭтотОбъект.БазовыйУровеньСтека = СтрЧислоСтрок(НачальнаяСтрока.Контекст) + СмещениеБазовогоУровня;
|
||
КонецЕсли;
|
||
КонечныйИндекс = ТаблицаЖурнала.Индекс(НачальнаяСтрока);
|
||
Для Индекс = 0 По КонечныйИндекс Цикл
|
||
Если ТаблицаЖурнала[0].НаСервере = НаСервере Тогда
|
||
ТаблицаЖурнала.Удалить(0);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
МаркерНачалаНайден = Истина;
|
||
КонецЕсли;
|
||
|
||
НайденныеСтроки = ТаблицаЖурнала.НайтиСтроки(МаркерКонца);
|
||
Если НайденныеСтроки.Количество() = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
КонечнаяСтрока = НайденныеСтроки[0];
|
||
НачальныйИндекс = ТаблицаЖурнала.Индекс(КонечнаяСтрока);
|
||
Если Ложь
|
||
Или НаСервере
|
||
Или ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Тогда
|
||
КонечнаяСтрока1 = ТаблицаЖурнала[НачальныйИндекс];
|
||
Если МассивТиповСУБД.Найти(КонечнаяСтрока1.Событие) <> Неопределено Тогда // Опасно. Учитывается регистр букв
|
||
мТипСУБД = КонечнаяСтрока1.Событие;
|
||
НачальныйИндекс = НачальныйИндекс - 1;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НачальноеКоличество = ТаблицаЖурнала.Количество();
|
||
Для Индекс = 1 По НачальноеКоличество - НачальныйИндекс Цикл
|
||
СтрокаЖурнала = ТаблицаЖурнала[НачальноеКоличество - Индекс];
|
||
Если СтрокаЖурнала.НаСервере = НаСервере Тогда
|
||
ТаблицаЖурнала.Удалить(СтрокаЖурнала);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Пока Истина
|
||
И ТаблицаЖурнала.Количество() > 0
|
||
И ТаблицаЖурнала[0].НаСервере = НаСервере
|
||
И Найти(ТаблицаЖурнала[0].Контекст, "Обработка.ирАнализТехножурнала.МодульОбъекта") > 0
|
||
Цикл
|
||
ТаблицаЖурнала.Удалить(0);
|
||
КонецЦикла;
|
||
Пока Истина
|
||
И ТаблицаЖурнала.Количество() > 0
|
||
И ТаблицаЖурнала[ТаблицаЖурнала.Количество() - 1].НаСервере = НаСервере
|
||
И Найти(ТаблицаЖурнала[ТаблицаЖурнала.Количество() - 1].Контекст, "Обработка.ирАнализТехножурнала.МодульОбъекта") > 0
|
||
Цикл
|
||
ТаблицаЖурнала.Удалить(ТаблицаЖурнала.Количество() - 1);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Прервать;
|
||
КонецЦикла;
|
||
Если РежимТрассы Тогда
|
||
Если КонечнаяСтрока = Неопределено Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
// ФрагментыНачальнойСтрокиМодуля = ирОбщий.СтрРазделитьЛкс(ТаблицаЖурнала[0].СтрокаМодуля, ":", Истина);
|
||
// ФрагментыКонечнойСтрокиМодуля = ирОбщий.СтрРазделитьЛкс(ТаблицаЖурнала[ТаблицаЖурнала.Количество() - 1].СтрокаМодуля, ":", Истина);
|
||
// ИмяМодуляНачальнойСтроки = ФрагментыНачальнойСтрокиМодуля[0];
|
||
// ИмяМодуляКонечнойСтроки = ФрагментыКонечнойСтрокиМодуля[0];
|
||
// НомерНачальнойСтроки = Число(ФрагментыНачальнойСтрокиМодуля[1]);
|
||
// НомерКонечнойСтроки = Число(ФрагментыКонечнойСтрокиМодуля[1]);
|
||
// ЕстьВызовыМетодовМодулей = Ложь
|
||
// Или ИмяМодуляНачальнойСтроки <> ИмяМодуляНачальнойСтроки
|
||
// Или НомерНачальнойСтроки > НомерКонечнойСтроки;
|
||
// СтрокиВызововМетодов = НайтиВызовыМетодовМодулей(ИмяМодуляНачальнойСтроки, НомерНачальнойСтроки, НомерКонечнойСтроки, Истина);
|
||
// Если СтрокиВызововМетодов.Количество() > 0 Тогда
|
||
// Ответ = Вопрос("В трассе обнаружены вызовы методов модулей. Хотите удалить их из трассы?", РежимДиалогаВопрос.ДаНет);
|
||
// Если Ответ = КодВозвратаДиалога.Да Тогда
|
||
// СтрокиВызововМетодов = НайтиВызовыМетодовМодулей(ИмяМодуляНачальнойСтроки, НомерНачальнойСтроки, НомерКонечнойСтроки, Ложь);
|
||
// Для Каждого СтрокаВызоваМетода Из СтрокиВызововМетодов Цикл
|
||
// ТаблицаЖурнала.Удалить(СтрокаВызоваМетода);
|
||
// КонецЦикла;
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
КонецЕсли;
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПрочитатьЖурнал(Фильтр = Неопределено) Экспорт
|
||
|
||
БазовыйУровеньКонтекста = 0;
|
||
ЭтотОбъект.КонецПериодаСервера = Неопределено;
|
||
ЭтотОбъект.КонецПериодаКлиента = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаСервера = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаКлиента = Неопределено;
|
||
ЭтотОбъект.ФильтрЗагрузки = Фильтр;
|
||
Если Ложь
|
||
Или ЗагружатьЖурналКлиента
|
||
Или ЗагружатьЖурналСервера
|
||
Тогда
|
||
ЖурналПрочитан = ПрочитатьСобственныйЖурналДвухСторон(,, Ложь);
|
||
Иначе
|
||
ЖурналПрочитан = ПрочитатьПроизвольныйЖурнал();
|
||
Если ВключитьСвойстваСИменамиМетаданных Тогда
|
||
ОбновитьСвойстваВТерминахМетаданных();
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Возврат ЖурналПрочитан;
|
||
|
||
КонецФункции
|
||
|
||
// ТолькоПустые - заполнять только ранее не заполненные свойства
|
||
Процедура ЗаполнитьСвойстваСИменамиМетаданных(ВыбраннаяСтрока, Принудительно = Ложь) Экспорт
|
||
|
||
Если Не Принудительно И ВыбраннаяСтрока.СвойстваСИменамиМетаданныхАктуальны Тогда
|
||
Возврат;
|
||
КонецЕсли;
|
||
Попытка
|
||
Инфобаза = ВыбраннаяСтрока.Инфобаза;
|
||
Исключение
|
||
Инфобаза = "";
|
||
КонецПопытки;
|
||
ЧужаяСхемаБД = ирОбщий.ПолучитьЧужуюСхемуБДЛкс(мАдресЧужойСхемыБД);
|
||
ЭтоГарантированоСобытиеВыбраннойЧужойБазы = Истина
|
||
И ЗначениеЗаполнено(Инфобаза)
|
||
И ЧужаяСхемаБД <> Неопределено
|
||
И ирОбщий.СтрокиРавныЛкс(Инфобаза, НСтр(ЧужаяСхемаБД.СтрокаСоединения, "Ref"));
|
||
ЭтоГарантированоСобытиеСобственнойБазы = Истина
|
||
И ЗначениеЗаполнено(Инфобаза)
|
||
И Не ЭтоГарантированоСобытиеВыбраннойЧужойБазы
|
||
И ирОбщий.СтрокиРавныЛкс(Инфобаза, НСтр(СтрокаСоединенияИнформационнойБазы(), "Ref"));
|
||
НайденныеТаблицы = Новый ТаблицаЗначений;
|
||
Для Каждого КлючИЗначение Из мСвойстваСИменамиБД Цикл
|
||
ИмяСвойства = КлючИЗначение.Ключ;
|
||
Если Найти(ИмяСвойства, "Шаблон") > 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Попытка
|
||
Пустышка = ТипЗнч(ВыбраннаяСтрока[ИмяСвойства]); // т.к. строки длинные, то их копирование в новую переменную накладно
|
||
Исключение
|
||
// Такого свойства нет - пропускаем
|
||
Продолжить;
|
||
КонецПопытки;
|
||
ЗначениеСвойства = ВыбраннаяСтрока[ИмяСвойства];
|
||
// Берем только имя базы, т.к. кластер может быть по-разному написан
|
||
Если Истина
|
||
И ЗначениеЗаполнено(ЗначениеСвойства)
|
||
И (Ложь
|
||
Или Инфобаза = ""
|
||
Или ЭтоГарантированоСобытиеСобственнойБазы
|
||
Или ЭтоГарантированоСобытиеВыбраннойЧужойБазы)
|
||
Тогда
|
||
ЛиМенаБД = КлючИЗначение.Значение;
|
||
Если Не ЛиМенаБД Тогда
|
||
ТипСУБД = "";
|
||
Иначе
|
||
Попытка
|
||
ТипСУБД = ВыбраннаяСтрока.Событие;
|
||
Исключение
|
||
ТипСУБД = Сред(ИмяСвойства, СтрДлина("Текст") + 1); // Опасно
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
//Попытка
|
||
ТекстМета = ПеревестиТекстБДВТерминыМетаданных(ЗначениеСвойства, , , ТипСУБД, НайденныеТаблицы,, Ложь,, ЭтоГарантированоСобытиеСобственнойБазы);
|
||
//Исключение
|
||
// ТекстМета = "";
|
||
//КонецПопытки;
|
||
//Если ТекстМета <> "" Тогда
|
||
ВыбраннаяСтрока[ИмяСвойства + "Мета"] = ТекстМета;
|
||
//КонецЕсли;
|
||
Иначе
|
||
// База чужая. Не делаем преобразования
|
||
//ВыбраннаяСтрока[ИмяСвойства + "Мета"] = ЗначениеСвойства;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если НайденныеТаблицы.Количество() > 0 Тогда
|
||
НайденныеТаблицы.Свернуть("ИмяМета");
|
||
НайденныеТаблицы.Сортировать("ИмяМета");
|
||
ВыбраннаяСтрока.ТаблицыМетаданных = ирОбщий.СтрСоединитьЛкс(НайденныеТаблицы.ВыгрузитьКолонку("ИмяМета"));
|
||
мНепустыеКолонкиЖурнала.Вставить("ТаблицыМетаданных");
|
||
КонецЕсли;
|
||
Попытка
|
||
ТекстSDBLШаблонМета = ВыбраннаяСтрока.ТекстSDBLШаблонМета;
|
||
Исключение
|
||
ТекстSDBLШаблонМета = Неопределено;
|
||
КонецПопытки;
|
||
Если ТекстSDBLШаблонМета <> Неопределено Тогда
|
||
Инфобаза = "";
|
||
ТекстSDBLМета = "";
|
||
Попытка
|
||
Инфобаза = ВыбраннаяСтрока.Инфобаза;
|
||
ТекстSDBLМета = ВыбраннаяСтрока.ТекстSDBLМета;
|
||
Исключение
|
||
КонецПопытки;
|
||
Если Ложь
|
||
Или Инфобаза = ""
|
||
Или ЭтоГарантированоСобытиеСобственнойБазы
|
||
Или ЭтоГарантированоСобытиеВыбраннойЧужойБазы
|
||
Тогда
|
||
Если Истина
|
||
И ТекстSDBLМета <> ""
|
||
Тогда
|
||
ВыбраннаяСтрока.ТекстSDBLШаблонМета = ПолучитьШаблонТекстаБД(ТекстSDBLМета);
|
||
Иначе
|
||
ВыбраннаяСтрока.ТекстSDBLШаблонМета = ПеревестиТекстБДВТерминыМетаданных(ВыбраннаяСтрока.ТекстSDBLШаблон,,,,,, Ложь,, ЭтоГарантированоСобытиеСобственнойБазы);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Попытка
|
||
ТекстСУБДШаблонМета = ВыбраннаяСтрока.ТекстСУБДШаблонМета;
|
||
Исключение
|
||
ТекстСУБДШаблонМета = Неопределено;
|
||
КонецПопытки;
|
||
Если ТекстСУБДШаблонМета <> Неопределено Тогда
|
||
Инфобаза = "";
|
||
ТекстСУБДМета = "";
|
||
Попытка
|
||
Инфобаза = ВыбраннаяСтрока.Инфобаза;
|
||
ТекстСУБДМета = ВыбраннаяСтрока.ТекстСУБДМета;
|
||
Исключение
|
||
КонецПопытки;
|
||
Если Ложь
|
||
Или Инфобаза = ""
|
||
Или ЭтоГарантированоСобытиеСобственнойБазы
|
||
Или ЭтоГарантированоСобытиеВыбраннойЧужойБазы
|
||
Тогда
|
||
Если Истина
|
||
И ТекстСУБДМета <> ""
|
||
Тогда
|
||
ВыбраннаяСтрока.ТекстСУБДШаблонМета = ПолучитьШаблонТекстаБД(ТекстСУБДМета);
|
||
Иначе
|
||
ВыбраннаяСтрока.ТекстСУБДШаблонМета = ПеревестиТекстБДВТерминыМетаданных(ВыбраннаяСтрока.ТекстСУБДШаблон,,, мТипСУБД,,, Ложь,, ЭтоГарантированоСобытиеСобственнойБазы);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ВыбраннаяСтрока.СвойстваСИменамиМетаданныхАктуальны = Истина;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПолучитьКаталогТекущегоЖурнала(НаСервере) Экспорт
|
||
|
||
Результат = Неопределено;
|
||
Если НаСервере Тогда
|
||
#Если Клиент Тогда
|
||
Если мЛиАнализТрассыЗапроса = Истина Тогда
|
||
Результат = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогТрассировкиЗапросов");
|
||
Иначе
|
||
Результат = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера");
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
КонецЕсли;
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Если мЛиАнализТрассыЗапроса = Истина Тогда
|
||
Результат = ирСервер.КаталогТрассировкиЗапросовЛкс();
|
||
Иначе
|
||
Результат = ирОбщий.КаталогТехножурналаЛкс(НаСервере);
|
||
КонецЕсли;
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Если НаСервере Тогда
|
||
ТекстКлиентСервер = "сервера";
|
||
Иначе
|
||
ТекстКлиентСервер = "клиента";
|
||
КонецЕсли;
|
||
ирОбщий.СообщитьЛкс("Технологический журнал " + ТекстКлиентСервер + " выключен. Невозможно определить каталог журнала по умолчанию.");
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
Если НаСервере Тогда
|
||
КлиентЗапущенНаКомпьютереСервера = ирОбщий.ЛиКлиентЗапущенНаКомпьютереСервераЛкс();
|
||
Если Не КлиентЗапущенНаКомпьютереСервера Тогда
|
||
Если ЭтоЛокальныйПутьЛкс(Результат) Тогда
|
||
ирОбщий.СообщитьЛкс("Клиент запущен не на компьютере сервера (" + ирСервер.ИмяКомпьютераЛкс() +
|
||
"), а в серверной настройке техножурнала указан локальный каталог. Необходимо указать сетевой путь к техножурналу сервера");
|
||
#Если Клиент Тогда
|
||
ФормаНастройки = ПолучитьФорму("НастройкаЧтения");
|
||
РезультатНастройки = ФормаНастройки.ОткрытьМодально();
|
||
Если РезультатНастройки = Истина Тогда
|
||
Если мЛиАнализТрассыЗапроса = Истина Тогда
|
||
Результат = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогТрассировкиЗапросов");
|
||
Иначе
|
||
Результат = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.КаталогЖурналаСервера");
|
||
КонецЕсли;
|
||
Иначе
|
||
Результат = Неопределено;
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция ЭтоЛокальныйПутьЛкс(Путь) Экспорт
|
||
|
||
ЭтоЛокальныйРесурс = Ложь
|
||
Или Найти(НРег(Путь), "\\localhost") = 1
|
||
Или Найти(НРег(Путь), "\\127.0.0.1") = 1
|
||
Или Лев(Путь, 2) <> "\\";
|
||
Возврат ЭтоЛокальныйРесурс;
|
||
|
||
КонецФункции // ЭтоЛокальныйПуть()
|
||
|
||
Функция ОткрытьСПараметрами(пКаталогЖурнала) Экспорт
|
||
|
||
Форма = ПолучитьФорму();
|
||
Форма.Открыть();
|
||
ЭтотОбъект.ЗагружатьТолькоТекущийСеанс = Ложь;
|
||
ЭтотОбъект.ЗагружатьЖурналСервера = Ложь;
|
||
ЭтотОбъект.ЗагружатьЖурналКлиента = Ложь;
|
||
Форма.ОбновитьДоступность();
|
||
Форма.КаталогЖурнала = пКаталогЖурнала;
|
||
Возврат Форма;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОткрытьСОтбором(НачалоПериода = Неопределено, КонецПериода = Неопределено, СтруктураОтбора = Неопределено) Экспорт
|
||
|
||
Форма = ПолучитьФорму(,,);
|
||
Форма.Открыть();
|
||
Отбор = Форма.ЭлементыФормы.ТаблицаЖурнала.ОтборСтрок;
|
||
Отбор.Сбросить();
|
||
Если НачалоПериода <> Неопределено Тогда
|
||
Форма.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
Если КонецПериода <> Неопределено Тогда
|
||
Форма.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
Если СтруктураОтбора <> Неопределено Тогда
|
||
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
|
||
Отбор[КлючИЗначение.Ключ].Установить(КлючИЗначение.Значение);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Возврат Форма;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьИмяСвойстваБезМета(Знач МестноеИмя) Экспорт
|
||
|
||
Если ирОбщий.СтрокиРавныЛкс(Прав(МестноеИмя, 4), "мета") Тогда
|
||
МестноеИмя = Лев(МестноеИмя, СтрДлина(МестноеИмя) - 4);
|
||
КонецЕсли;
|
||
Возврат МестноеИмя;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ОбновитьСвойстваВТерминахМетаданных() Экспорт
|
||
|
||
ВыбранныеСтроки = ТаблицаЖурнала.НайтиСтроки(Новый Структура("СвойстваСИменамиМетаданныхАктуальны", Ложь));
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ВыбранныеСтроки.Количество(), "Перевод в термины метаданных");
|
||
Для Каждого СтрокаТаблицыЖурнала Из ВыбранныеСтроки Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
ЗаполнитьСвойстваСИменамиМетаданных(СтрокаТаблицыЖурнала);
|
||
КонецЦикла;
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс();
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОбновитьСтрокиБазовогоУровня() Экспорт
|
||
|
||
//Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЖурнала.Количество());
|
||
Для Каждого СтрокаТаблицыЖурнала Из ТаблицаЖурнала Цикл
|
||
//ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
ЗаполнитьСтрокуБазовогоУровня(СтрокаТаблицыЖурнала);
|
||
КонецЦикла;
|
||
//Для Каждого СтрокаКонтекста Из Контексты Цикл
|
||
// ЗаполнитьСтрокуБазовогоУровня(СтрокаКонтекста);
|
||
//КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПолучитьШаблонТекстаБД(ТекстБД, ЗаменаПеременныхФрагментов = "7") Экспорт
|
||
|
||
ШаблонТекстаБД = RegExpПараметры.Replace(ТекстБД, "$1$2" + ЗаменаПеременныхФрагментов);
|
||
Возврат ШаблонТекстаБД;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ЗаполнитьСвойстваШаблоны() Экспорт
|
||
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ТаблицаЖурнала.Количество());
|
||
Для Каждого СтрокаТаблицыЖурнала Из ТаблицаЖурнала Цикл
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
Если Истина
|
||
И СтрокаТаблицыЖурнала.ТекстSDBL <> ""
|
||
И СтрокаТаблицыЖурнала.ТекстSDBLШаблон = ""
|
||
Тогда
|
||
СтрокаТаблицыЖурнала.ТекстSDBLШаблон = ПолучитьШаблонТекстаБД(СтрокаТаблицыЖурнала.ТекстSDBL);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И СтрокаТаблицыЖурнала.ТекстСУБД <> ""
|
||
И СтрокаТаблицыЖурнала.ТекстСУБДШаблон = ""
|
||
Тогда
|
||
СтрокаТаблицыЖурнала.ТекстСУБДШаблон = ПолучитьШаблонТекстаБД(СтрокаТаблицыЖурнала.ТекстСУБД);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И СтрокаТаблицыЖурнала.Описание <> ""
|
||
И СтрокаТаблицыЖурнала.ОписаниеШаблон = ""
|
||
Тогда
|
||
СтрокаТаблицыЖурнала.ОписаниеШаблон = ПолучитьШаблонТекстаБД(СтрокаТаблицыЖурнала.Описание);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОставитьТолькоСтрокиПоОтбору(СтруктураОтбора) Экспорт
|
||
|
||
НужныеСтроки = ТаблицаЖурнала.НайтиСтроки(СтруктураОтбора);
|
||
КоличествоСтрок = ТаблицаЖурнала.Количество();
|
||
Для Счетчик = 1 По КоличествоСтрок Цикл
|
||
Индекс = КоличествоСтрок - Счетчик;
|
||
СтрокаЖурнала = ТаблицаЖурнала[Индекс];
|
||
Если НужныеСтроки.Найти(СтрокаЖурнала) = Неопределено Тогда
|
||
ТаблицаЖурнала.Удалить(СтрокаЖурнала);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура УдалитьСтрокиПоОтборуЛкс(СтруктураОтбора) Экспорт
|
||
|
||
НенужныеСтроки = ТаблицаЖурнала.НайтиСтроки(СтруктураОтбора);
|
||
Для Каждого НенужнаяСтрока Из НенужныеСтроки Цикл
|
||
ТаблицаЖурнала.Удалить(НенужнаяСтрока);
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаписатьМаркерВТехножурнал(Маркер, ДляКлиента = Истина, ДляСервера = Истина) Экспорт
|
||
|
||
ЗапросМаркер = Новый Запрос();
|
||
Если ДляКлиента Тогда
|
||
ЗапросМаркер.Текст = Маркер;
|
||
Попытка
|
||
ЗапросМаркер.Выполнить(); // Генерируем для клиента маркер-событие QERR
|
||
Исключение
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ДляСервера
|
||
И Не ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Тогда
|
||
Если Не ирКэш.ЛиПортативныйРежимЛкс() Тогда
|
||
Попытка
|
||
ирСервер.ВыполнитьЗапросЛкс(Маркер); // Генерируем для сервера маркер-событие QERR
|
||
Исключение
|
||
КонецПопытки;
|
||
Иначе
|
||
ЗапросМаркер.Текст = "ВЫБРАТЬ """ + Маркер + """";
|
||
Попытка
|
||
ЗапросМаркер.Выполнить(); // Генерируем для клиента маркер-событие SDBL
|
||
Исключение
|
||
// Может возникнуть ошибка "В данной транзакции уже происходили ошибки!"
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция НачатьТрассу(ПрефиксТрассы = "", ВыводитьСообщения = Ложь) Экспорт
|
||
|
||
Если ВыводитьСообщения Тогда
|
||
// Попробовать сделать проверку регистрации событий QERR в настройке техножурнала на сервере
|
||
// Вызовы ЛиТехножурналВключенЛкс могут быть очень долгими, если в анализе техножурнала пользователь сохранил сетевой путь к логам на сервере и он недоступен
|
||
Если Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
ТехножурналСервераВключен = ирОбщий.ЛиТехножурналВключенЛкс(Истина, ВыводитьСообщения);
|
||
КонецЕсли;
|
||
ТехножурналКлиентаВключен = ирОбщий.ЛиТехножурналВключенЛкс(, ВыводитьСообщения);
|
||
Если Истина
|
||
И ТехножурналСервераВключен <> Истина
|
||
И Не ТехножурналКлиентаВключен
|
||
Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
ЭтотОбъект.КонецПериодаСервера = Неопределено;
|
||
ЭтотОбъект.КонецПериодаКлиента = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаСервера = ирОбщий.ПолучитьТекущуюДатуЛкс(Истина);
|
||
ЭтотОбъект.НачалоПериодаКлиента = ирОбщий.ПолучитьТекущуюДатуЛкс(Ложь);
|
||
мИдентификаторТрассы = ПрефиксТрассы + "_" + СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
|
||
ЗаписатьМаркерВТехножурнал("НачалоТрассы_" + мИдентификаторТрассы);
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция КончитьТрассу() Экспорт
|
||
|
||
Если ЗначениеЗаполнено(ЭтотОбъект.КонецПериодаКлиента) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
ЗаписатьМаркерВТехножурнал("КонецТрассы_" + мИдентификаторТрассы);
|
||
ЭтотОбъект.КонецПериодаСервера = ирОбщий.ПолучитьТекущуюДатуЛкс(Истина);
|
||
ЭтотОбъект.КонецПериодаКлиента = ирОбщий.ПолучитьТекущуюДатуЛкс(Ложь);
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьТекстSQLДляПоискаВТехножурнале(Текст) Экспорт
|
||
|
||
RegExpМета.Pattern = "([^A-ZА-ЯЁ_0-9]|^)(?:@P\d+)";
|
||
Результат = RegExpМета.Replace(Текст, "$1?");
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
#Если Клиент Тогда
|
||
|
||
Функция ПоказатьТрассу(УдалитьДополнительныеСобытия = Истина, ИменаНеполезныхКолонок = "", ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено) Экспорт
|
||
|
||
Если ЭтотОбъект.КонецПериодаСервера = Неопределено Тогда
|
||
Предупреждение("Сформируйте трассу заново");
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
ОчиститьТаблицуЖурнала();
|
||
ЖурналПрочитан = ПрочитатьСобственныйЖурналДвухСторон(УдалитьДополнительныеСобытия, ИменаНеполезныхКолонок, Истина, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
Если Не ЖурналПрочитан Тогда
|
||
ирОбщий.СообщитьЛкс("Не удалось найти маркеры трассы в логах. Проверьте включенность регистрации события QERR в настройке техножурнала");
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
ВыраниватьДатуПоСерверу = ирОбщий.ВосстановитьЗначениеЛкс("ирАнализТехножурнала.ВыраниватьДатуПоСерверу") = Истина;
|
||
лКаталогЖурнала = КаталогЖурнала;
|
||
ФормаАнализа = ПолучитьФорму();
|
||
ФормаАнализа.ЭтоТрасса = Истина;
|
||
ФормаАнализа.Открыть();
|
||
ФормаАнализа.ЗагружатьТолькоТекущийСеанс = Истина;
|
||
ФормаАнализа.ЗагружатьЖурналКлиента = Истина;
|
||
ФормаАнализа.ЗагружатьЖурналСервера = Не ирКэш.ЭтоФайловаяБазаЛкс();
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
ФормаАнализа.КонецПериода = КонецПериодаСервера;
|
||
ФормаАнализа.НачалоПериода = НачалоПериодаСервера;
|
||
Иначе
|
||
ФормаАнализа.КонецПериода = КонецПериодаКлиента;
|
||
ФормаАнализа.НачалоПериода = НачалоПериодаКлиента;
|
||
КонецЕсли;
|
||
ФормаАнализа.КаталогЖурнала = лКаталогЖурнала;
|
||
ФормаАнализа.УстановитьРежимИтогов(ТаблицаЖурнала.Количество() > 20);
|
||
ФормаАнализа.ПериодПоследниеМинуты = 0;
|
||
ФормаАнализа.ОбновитьДоступность();
|
||
ФормаАнализа.ЭлементыФормы.ПанельНастройки.ТекущаяСтраница = ФормаАнализа.ЭлементыФормы.ПанельНастройки.Страницы.Анализ;
|
||
ФормаАнализа.УстановитьБесполезныеКолонки(ИменаНеполезныхКолонок);
|
||
Если мЛиАнализТрассыЗапроса = Истина Тогда
|
||
ТаблицаЖурнала.Сортировать("МоментВремениНачала");
|
||
КонецЕсли;
|
||
Возврат ФормаАнализа;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПоказатьТрассуЗапроса() Экспорт
|
||
|
||
мЛиАнализТрассыЗапроса = Истина;
|
||
ФормаАнализа = ПоказатьТрассу(, "СтрокаМодуля",, 0);
|
||
мЛиАнализТрассыЗапроса = Ложь;
|
||
Возврат ФормаАнализа;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОчиститьТаблицуЖурнала() Экспорт
|
||
|
||
мНепустыеКолонкиЖурнала = Новый Структура();
|
||
ТаблицаЖурнала.Очистить();
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОткрытьТекстБДВКонверторе(ТекстБД, СразуПеревестиВМета = Истина, КлючУникальности = Неопределено, ЭтоТекстSDBL = Истина) Экспорт
|
||
|
||
ФормаЗапроса = ПолучитьФорму("КонверторТекстаСУБД", , КлючУникальности);
|
||
ФормаЗапроса.ЭтоТекстSDBL = ЭтоТекстSDBL;
|
||
ФормаЗапроса.ЭлементыФормы.ТекстБД.УстановитьТекст(ТекстБД);
|
||
ФормаЗапроса.ПереводитьВМета = СразуПеревестиВМета;
|
||
ФормаЗапроса.Открыть();
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ОткрытьНастройкуТехножурналаДляРегистрацииВыполненияЗапроса(Знач ТекстБД, ЭтоТекстSDBL = Ложь, ТипСУБД = Неопределено, ИмяБазы = "") Экспорт
|
||
|
||
Если Не ЭтоТекстSDBL Тогда
|
||
ТекстБД = ПолучитьТекстSQLДляПоискаВТехножурнале(ТекстБД);
|
||
КонецЕсли;
|
||
Если СтрДлина(ТекстБД) > 1000 Тогда
|
||
ТекстБД = Лев(ТекстБД , 1000) + "%";
|
||
КонецЕсли;
|
||
ТекстБД = ПолучитьШаблонТекстаБД(ТекстБД, "%");
|
||
ТекстБД = СтрЗаменить(ТекстБД, Символы.ПС, "%");
|
||
ТекстБД = СтрЗаменить(ТекстБД, "%%", "%");
|
||
ФормаНастройки = ирОбщий.ПолучитьФормуЛкс("Обработка.ирНастройкаТехножурнала.Форма");
|
||
ФормаНастройки.Открыть();
|
||
ФормаНастройки.НаСервере = Не ирКэш.Получить().ЭтоФайловаяБаза;
|
||
ФормаНастройки.ПриИзмененииПравилаПолученияФайлаНастройки();
|
||
Ответ = Вопрос("Хотите создать новую настройку?", РежимДиалогаВопрос.ДаНет);
|
||
Если Ответ = КодВозвратаДиалога.Да Тогда
|
||
ФормаНастройки.ЗагрузитьФайлНастройки("ШаблонЗаписьИсключительныхСитуаций", Истина, Истина, Ложь);
|
||
КонецЕсли;
|
||
СтрокаКаталога = ФормаНастройки.ТабличноеПолеЖурналы[0];
|
||
ФормаНастройки.ЭлементыФормы.ТабличноеПолеЖурналы.ТекущаяСтрока = СтрокаКаталога;
|
||
ФормаЖурнала = ФормаНастройки.ОткрытьФормуРедактированияЖурнала();
|
||
Если ЭтоТекстSDBL Тогда
|
||
УстановитьОтборПоСвойствуСобытияВФормеЖурнала(ФормаЖурнала, "SDBL", "sdbl", ТекстБД, , ИмяБазы);
|
||
Иначе
|
||
Если Не ЗначениеЗаполнено(ТипСУБД) Тогда
|
||
ВызватьИсключение "Для текста СУБД необходимо указать тип СУБД";
|
||
КонецЕсли;
|
||
УстановитьОтборПоСвойствуСобытияВФормеЖурнала(ФормаЖурнала, ТипСУБД, "sql", ТекстБД, , ИмяБазы);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
// Сравнение - Строка - как оно задается в настройке техножурнала (eq, ne, like и т.д.)
|
||
Процедура УстановитьОтборПоСвойствуСобытияВФормеЖурнала(ФормаЖурнала, ИмяСобытия, Знач ИмяСвойства, Знач ШаблонЗапроса, Сравнение = "like", Знач ИмяБазы = "") Экспорт
|
||
|
||
ТабличноеПолеСписокСобытий = ФормаЖурнала.ЭлементыФормы.ТабличноеПолеСписокСобытий;
|
||
ТабличноеПолеСписокСобытий.ВыделенныеСтроки.Очистить();
|
||
СтрокаСобытия = ФормаЖурнала.УстановитьРегистрациюСобытия(ИмяСобытия, Истина);
|
||
ТабличноеПолеСписокСобытий.ТекущаяСтрока = СтрокаСобытия;
|
||
ФормаЖурнала.УстановитьЭлементОтбораВВыделенныхГруппахИ(ИмяСвойства, ШаблонЗапроса, Сравнение);
|
||
Если Истина
|
||
И ЗначениеЗаполнено(ИмяБазы)
|
||
И Не ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Тогда
|
||
// К сожалению в файловой СУБД это свойство не заполняется
|
||
//ФормаЖурнала.КП_ДетальныйФильтрСобытийТекущаяБаза();
|
||
ФормаЖурнала.УстановитьЭлементОтбораВВыделенныхГруппахИ("p:processname", ИмяБазы);
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
#КонецЕсли
|
||
|
||
Функция ПолучитьВариантПросмотраТекстПоИмениРеквизита(ИмяРеквизита) Экспорт
|
||
|
||
Если Ложь
|
||
Или мСвойстваСИменамиБД.Свойство(ПолучитьИмяСвойстваБезМета(ИмяРеквизита))
|
||
Или ирОбщий.СтрокиРавныЛкс(ИмяРеквизита, "ТекстЗапроса1С")
|
||
Тогда
|
||
ВариантПросмотра = "ЯзыкЗапросов";
|
||
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ИмяРеквизита, "Контекст") <> Неопределено Тогда
|
||
ВариантПросмотра = "ВстроенныйЯзык";
|
||
Иначе
|
||
ВариантПросмотра = "Компактный";
|
||
КонецЕсли;
|
||
Возврат ВариантПросмотра;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПреобразоватьЗначениеВSDBL(Ссылка) Экспорт
|
||
|
||
СтруктураБД = ирКэш.СтруктураХраненияБДЛкс(,, мАдресЧужойСхемыБД);
|
||
Если ТипЗнч(Ссылка) = Тип("Строка") Тогда
|
||
Текст = "";
|
||
Иначе
|
||
СтруктураПоиска = Новый Структура("Метаданные, Назначение", Ссылка.Метаданные().ПолноеИмя(), "Основная");
|
||
СтрокаТаблицы = СтруктураБД.НайтиСтроки(СтруктураПоиска)[0];
|
||
RegExp = ирКэш.Получить().RegExp;
|
||
RegExp.Pattern = "\d+";
|
||
РезультатПоиска = RegExp.Execute(СтрокаТаблицы.ИмяТаблицыХранения);
|
||
Текст = РезультатПоиска.Item(0).Value + ":" + ирОбщий.ПолучитьГУИДИнверсныйИзПрямогоЛкс("" + Ссылка.УникальныйИдентификатор());
|
||
КонецЕсли;
|
||
Возврат Текст;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьСтруктуруЗапросаИзТекстаБД(ТекстБД, ТипСУБД = "", ПересобратьТекст = Ложь, ПеревестиИндексы = Истина, ПереводитьВМета = Истина, ЗаменитьHexЛитералы = Ложь,
|
||
ВстраиватьПараметры = Истина) Экспорт
|
||
|
||
Текст = ТекстБД;
|
||
//ТаблицаПараметров = Новый ТаблицаЗначений;
|
||
//ТаблицаПараметров.Колонки.Добавить("ЗначениеSDBL", Новый ОписаниеТипов("Строка"));
|
||
//ТаблицаПараметров.Колонки.Добавить("Значение");
|
||
//ТаблицаПараметров.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
|
||
ТаблицаПараметров = ПараметрыЗапроса.ВыгрузитьКолонки();
|
||
ТаблицаПараметров.Индексы.Добавить("ЗначениеSDBL");
|
||
ТаблицаПараметров.Индексы.Добавить("Имя");
|
||
RegExp = мПлатформа.RegExp;
|
||
RegExp.Global = Истина;
|
||
RegExp.Multiline = Истина;
|
||
Если ЗначениеЗаполнено(ТипСУБД) Тогда
|
||
Если ПереводитьВМета Тогда
|
||
RegExp.Pattern = "TRef\s*=\s*(0x[\da-z]+)"; // замена обращений к типам
|
||
Вхождения = RegExp.Execute(Текст);
|
||
ОбработанныеОбращения = Новый Соответствие;
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
ЗначениеСУБД = Вхождение.Value;
|
||
Если ОбработанныеОбращения[ЗначениеСУБД] = Неопределено Тогда
|
||
ПолноеИмяМД = ирОбщий.ПолучитьМетаданныеПоНомеруСсылочнойТаблицыЛкс(ирОбщий.СтрокаHEXtoINTЛкс(Вхождение.SubMatches(0)), мАдресЧужойСхемыБД);
|
||
Если ПолноеИмяМД <> Неопределено Тогда
|
||
ЗаменаСтроки = "TRef = " + ПолноеИмяМД;
|
||
ОбработанныеОбращения[ЗначениеСУБД] = ЗаменаСтроки;
|
||
Текст = СтрЗаменить(Текст, ЗначениеСУБД, ЗаменаСтроки);
|
||
Иначе
|
||
ОбработанныеОбращения[ЗначениеСУБД] = 1;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
RegExp.Pattern = "^\s*\(@P\d+\s+\w+(?:\(\d+(?:,\d+)?\))?(,@P\d+\s+\w+(?:\(\d+(?:,\d+)?\))?)*\)"; // для удаления типов параметров MSSQL
|
||
Текст = RegExp.Replace(Текст, "");
|
||
КонецЕсли;
|
||
Иначе
|
||
RegExp.Pattern = "([A-F0-9]+):([A-F0-9]+|0x[A-F0-9]+)"; // замена ссылочных констант
|
||
Вхождения = RegExp.Execute(Текст);
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
ЗначениеSDBL = Вхождение.Value;
|
||
Если СтрДлина(ЗначениеSDBL) < 32 Тогда
|
||
// Защита от частей литерала Дата
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если ТаблицаПараметров.Найти(ЗначениеSDBL, "ЗначениеSDBL") = Неопределено Тогда
|
||
ЗначениеПараметра = ирОбщий.ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL, мАдресЧужойСхемыБД);
|
||
СтрокаПараметра = ирОбщий.НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров,,, ЗначениеПараметра);
|
||
СтрокаПараметра.ЗначениеSDBL = ЗначениеSDBL;
|
||
ОбъектМД = ирОбщий.ПолучитьМетаданныеЛкс(ЗначениеПараметра);
|
||
Если ОбъектМД <> Неопределено Тогда
|
||
СтрокаПараметра.Метаданные = ОбъектМД.ПолноеИмя();
|
||
КонецЕсли;
|
||
Если ПереводитьВМета Тогда
|
||
Текст = СтрЗаменить(Текст, ЗначениеSDBL, "&" + СтрокаПараметра.Имя);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Если ЗаменитьHexЛитералы Тогда
|
||
RegExp.Pattern = "0x[\da-z]+"; // замена значений констант
|
||
Вхождения = RegExp.Execute(Текст);
|
||
СоответствиеКонстант = Новый Соответствие;
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
ЗначениеСУБД = Вхождение.Value;
|
||
Если СоответствиеКонстант[ЗначениеСУБД] = Неопределено Тогда
|
||
ЗаменаСтроки = "_" + ЗначениеСУБД;
|
||
СоответствиеКонстант[ЗначениеСУБД] = ЗаменаСтроки;
|
||
Текст = СтрЗаменить(Текст, ЗначениеСУБД, ЗаменаСтроки);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
//RegExp.Pattern = "#(T[\d_A-Z]+)"; // имена временных таблиц
|
||
//Текст = RegExp.Replace(Текст, "_$1");
|
||
RegExp.Pattern = "\{ts '(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)'\}"; // литералы Дата DBV8DBEng
|
||
Текст = RegExp.Replace(Текст, "DATETIME($1,$2,$3,$4,$5,$6)");
|
||
ТаблицаТаблиц = Новый ТаблицаЗначений;
|
||
Если ПереводитьВМета Тогда
|
||
RegExp.Pattern = "N'([^']*)'"; // для замены юникодных литералов типа Строка MSSQL
|
||
Текст = RegExp.Replace(Текст, """$1""");
|
||
КонецЕсли;
|
||
ТекстМета = ПеревестиТекстБДВТерминыМетаданных(Текст,,, ТипСУБД, ТаблицаТаблиц, 999999, ПеревестиИндексы, ПереводитьВМета);
|
||
Если Не ПереводитьВМета Тогда
|
||
ТекстМета = Текст;
|
||
КонецЕсли;
|
||
ТаблицаТаблиц.Сортировать("ИмяМета");
|
||
ЧастьПараметров = "";
|
||
Если ЗначениеЗаполнено(ТипСУБД) Тогда
|
||
ДиалектSQL = "MSSQL";
|
||
ПозицияНачалаПараметров = Найти(ТекстМета, "p_0:");
|
||
Если ПозицияНачалаПараметров > 0 Тогда
|
||
ЧастьПараметров = Сред(ТекстМета, ПозицияНачалаПараметров);
|
||
ТекстМета = Лев(ТекстМета, ПозицияНачалаПараметров - 1);
|
||
КонецЕсли;
|
||
Иначе
|
||
ДиалектSQL = "1С";
|
||
КонецЕсли;
|
||
ШаблонИмениПараметра = "Parameter";
|
||
Если ЗначениеЗаполнено(ЧастьПараметров) Тогда
|
||
ТекстовыйДокумент = Новый ТекстовыйДокумент;
|
||
ТекстовыйДокумент.УстановитьТекст(ЧастьПараметров);
|
||
Для Счетчик = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
|
||
СтрокаПараметра = ТаблицаПараметров.Добавить();
|
||
Фрагменты = ирОбщий.СтрРазделитьЛкс(ТекстовыйДокумент.ПолучитьСтроку(Счетчик), ":");
|
||
СтрокаПараметра.Имя = СокрЛП(Фрагменты[0]);
|
||
СтрокаПараметра.Значение = СокрЛП(Фрагменты[1]);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
|
||
// Встроим имена парамаетров вместо знаков "?"
|
||
ЗаписьXML = Новый ЗаписьXML;
|
||
ЗаписьXML.УстановитьСтроку("");
|
||
ИндексПараметра = 0;
|
||
СтрокаПоиска = "?";
|
||
Пока ТекстМета <> "" Цикл
|
||
ПозицияПараметра = Найти(ТекстМета, СтрокаПоиска);
|
||
Если ПозицияПараметра > 0 Тогда
|
||
Если ИндексПараметра < ТаблицаПараметров.Количество() Тогда
|
||
СтрокаПараметра = ТаблицаПараметров[ИндексПараметра];
|
||
Иначе
|
||
СтрокаПараметра = ТаблицаПараметров.Добавить();
|
||
СтрокаПараметра.Имя = ШаблонИмениПараметра + XMLСтрока(ТаблицаПараметров.Количество() - 1);
|
||
КонецЕсли;
|
||
ЗаписьXML.ЗаписатьБезОбработки(Лев(ТекстМета, ПозицияПараметра - 1) + СтрокаПоиска + СтрокаПараметра.Имя);
|
||
ТекстМета = Сред(ТекстМета, ПозицияПараметра + СтрДлина(СтрокаПоиска));
|
||
ИндексПараметра = ИндексПараметра + 1;
|
||
Иначе
|
||
ЗаписьXML.ЗаписатьБезОбработки(ТекстМета);
|
||
ТекстМета = "";
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ТекстМета = ЗаписьXML.Закрыть();
|
||
|
||
Если Истина
|
||
И ПересобратьТекст
|
||
И ЗначениеЗаполнено(ТекстМета)
|
||
Тогда
|
||
ПолеТекста = ирОбщий.СоздатьОбъектПоПолномуИмениМетаданныхЛкс("Обработка.ирКлсПолеТекстаПрограммы");
|
||
ПолеТекста.ИнициализироватьНеинтерактивно(1);
|
||
//ПолеТекста.ПолеТекстовогоДокумента = ПолеТекстаЗапроса;
|
||
КонструкторЗапроса = ПолеТекста.ПолучитьФорму("КонструкторЗапроса");
|
||
КонструкторЗапроса.Английский1С = Не ПереводитьВМета;
|
||
ИменованныеПараметры = Истина;
|
||
Если ПолеТекста.ЗагрузитьТекстВКонструктор(ТекстМета, КонструкторЗапроса,, ДиалектSQL, ИменованныеПараметры) Тогда
|
||
ТекстМета = КонструкторЗапроса.СобратьПолныйТекст(, Истина);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ВстраиватьПараметры Тогда
|
||
ЗаписьXML = Новый ЗаписьXML;
|
||
ЗаписьXML.УстановитьСтроку("");
|
||
ИндексПараметра = 0;
|
||
Пока ТекстМета <> "" Цикл
|
||
ПозицияПараметра = 0;
|
||
Если ИндексПараметра < ТаблицаПараметров.Количество() Тогда
|
||
СтрокаПоиска = "?" + ТаблицаПараметров[ИндексПараметра].Имя;
|
||
ПозицияПараметра = Найти(ТекстМета, СтрокаПоиска);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ПозицияПараметра > 0
|
||
Тогда
|
||
ЗаписьXML.ЗаписатьБезОбработки(Лев(ТекстМета, ПозицияПараметра - 1) + ТаблицаПараметров[ИндексПараметра].Значение);
|
||
ИндексПараметра = ИндексПараметра + 1;
|
||
ТекстМета = Сред(ТекстМета, ПозицияПараметра + СтрДлина(СтрокаПоиска));
|
||
Иначе
|
||
ЗаписьXML.ЗаписатьБезОбработки(ТекстМета);
|
||
ТекстМета = "";
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ТекстМета = ЗаписьXML.Закрыть();
|
||
КонецЕсли;
|
||
Результат = Новый Структура();
|
||
Результат.Вставить("Текст", ТекстМета);
|
||
Результат.Вставить("Параметры", ТаблицаПараметров);
|
||
Результат.Вставить("Таблицы", ТаблицаТаблиц);
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция НайтиВызовыМетодовМодулей(ИмяМодуля, НомерНачальнойСтроки, НомерКонечнойСтроки, ТолькоОдну = Истина)
|
||
|
||
Результат = Новый Массив();
|
||
Для Каждого СтрокаТаблицы Из ТаблицаЖурнала Цикл
|
||
ФрагментыНачальнойСтрокиМодуля = ирОбщий.СтрРазделитьЛкс(СтрокаТаблицы.СтрокаМодуля, ":", Истина);
|
||
Если ФрагментыНачальнойСтрокиМодуля[0] <> ИмяМодуля Тогда
|
||
Результат.Вставить(0, СтрокаТаблицы);
|
||
Если ТолькоОдну Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НомерСтрокиМодуля = Число(ФрагментыНачальнойСтрокиМодуля[1]);
|
||
Если Ложь
|
||
Или НомерСтрокиМодуля < НомерНачальнойСтроки
|
||
Или НомерСтрокиМодуля > НомерКонечнойСтроки
|
||
Тогда
|
||
Результат.Вставить(0, СтрокаТаблицы);
|
||
Если ТолькоОдну Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Получить словарь имен таблиц входящих в запрос и соответствующих
|
||
// шаблонам словаря метаданных
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - Строка, текст запроса для которого строится словарь
|
||
// СловарьШаблоновМетаданных - Соответствие, словарь шаблонов метаданных
|
||
// ТипСУБД - Строка (Перечисление.ТипСУБД)
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие - Словарь имен таблиц запроса
|
||
//
|
||
Функция ИменаМетаданныхЗапросаСУБД(Знач ТекстЗапроса, СловарьШаблоновМетаданных, ТипСУБД = "") Экспорт
|
||
|
||
Результат = Новый ТаблицаЗначений;
|
||
Результат.Колонки.Добавить("Имя");
|
||
Результат.Колонки.Добавить("Длина");
|
||
ТекстЗапроса = НРег(ТекстЗапроса);
|
||
//Если НРег(ТипСУБД) = НРег("DB2") Тогда
|
||
// ТекстЗапроса = ВРег(ТекстЗапроса);
|
||
//КонецЕсли;
|
||
Для Каждого СтрокаСловаряМетаданных Из СловарьШаблоновМетаданных Цикл
|
||
ТаблицаВхождений = ирОбщий.НайтиРегулярноеВыражениеЛкс(ТекстЗапроса, СтрокаСловаряМетаданных.РегулярныйШаблон,,,,,, Истина);
|
||
#Если Сервер И Не Сервер Тогда
|
||
ТаблицаВхождений = Обработки.ирПлатформа.Создать().ВхожденияРегулярногоВыражения;
|
||
#КонецЕсли
|
||
Для Каждого СтрокаВхождения Из ТаблицаВхождений Цикл
|
||
НоваяСтрока = Результат.Добавить();
|
||
НоваяСтрока.Имя = СтрокаВхождения.ТекстВхождения;
|
||
НоваяСтрока.Длина = СтрДлина(НоваяСтрока.Имя);
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
Результат.Сортировать("Длина Убыв");
|
||
Результат.Свернуть("Имя");
|
||
|
||
Возврат Результат;
|
||
|
||
КонецФункции // ПолучитьСловарьЗапроса()
|
||
|
||
// Получить число из строки в которой число находится в начале строки
|
||
//
|
||
// Праметры:
|
||
// ИсходнаяСтрока - Строка, строка в которой находится число
|
||
//
|
||
// Возвращаемое значение:
|
||
// Число - если оно есть, неопределено, если числа нет
|
||
//
|
||
Функция ПолучитьЧислоСтрокой(ИсходнаяСтрока, КоличествоСимволов)
|
||
|
||
КоличествоСимволов = 0;
|
||
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
|
||
|
||
Для Сч = 1 По ДлинаСтроки Цикл
|
||
|
||
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
|
||
|
||
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
|
||
КоличествоСимволов = КоличествоСимволов + 1;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если КоличествоСимволов > 0 Тогда
|
||
Возврат Лев(ИсходнаяСтрока, КоличествоСимволов);
|
||
Иначе
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
КонецФункции // ПолучитьЧислоСтрокой()
|
||
|
||
// Перевести часть запроса из терминов СУБД в термины метаданных
|
||
//
|
||
// Параметры:
|
||
// Запрос - Строка, сапрос в терминах СУБД
|
||
// СтруктураХраненияБазыДанных - ТаблицаЗначений
|
||
// СловарьШаблоновМетаданных - Соответствие, подробности в функции
|
||
// ПолучитьСловарьШаблоновМетаданных()
|
||
// ТипСУБД - Строка, (Перечисление.ТипСУБД)
|
||
// выхТаблицы - ТаблицаЗначений, *Неопределено - описание использованных в тексте таблиц, заполняется только если таблица передана (без колонок)
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка, запрос в терминах метаданных
|
||
//
|
||
Функция ПеревестиТекстБДВТерминыМетаданных(Знач Текст, СтруктураХраненияБазыДанных = Неопределено,
|
||
СловарьШаблоновМетаданных = Неопределено, Знач ТипСУБД = "", выхТаблицы = Неопределено, ДопустимыйРазмер = 20000, ПереводитьИндексы = Истина, ПереводитьВМета = Истина,
|
||
ЭтоГарантированоТекстСобственнойБазы = Ложь) Экспорт
|
||
|
||
Если выхТаблицы <> Неопределено Тогда
|
||
#Если Сервер И Не Сервер Тогда
|
||
выхТаблицы = Новый ТаблицаЗначений;
|
||
#КонецЕсли
|
||
//выхТаблицы.Колонки.Очистить();
|
||
Если выхТаблицы.Колонки.Найти("ИмяБД") = Неопределено Тогда
|
||
выхТаблицы.Колонки.Добавить("ИмяБД", Новый ОписаниеТипов("Строка"));
|
||
КонецЕсли;
|
||
Если выхТаблицы.Колонки.Найти("ИмяМета") = Неопределено Тогда
|
||
выхТаблицы.Колонки.Добавить("ИмяМета", Новый ОписаниеТипов("Строка"));
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или Не ЗначениеЗаполнено(Текст)
|
||
Тогда
|
||
Возврат "";
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ДопустимыйРазмер > 0
|
||
И СтрДлина(Текст) > ДопустимыйРазмер
|
||
И ПереводитьВМета
|
||
Тогда
|
||
Возврат РезультатПереводаСлишкомБольшогоТекста();
|
||
КонецЕсли;
|
||
Если ирОбщий.СтрокиРавныЛкс(ТипСУБД, "sdbl") Тогда
|
||
ТипСУБД = "";
|
||
КонецЕсли;
|
||
АдресЧужойСхемыБД = "";
|
||
Если Не ЭтоГарантированоТекстСобственнойБазы Тогда
|
||
АдресЧужойСхемыБД = мАдресЧужойСхемыБД;
|
||
КонецЕсли;
|
||
Если СтруктураХраненияБазыДанных = Неопределено Тогда
|
||
СтруктураХраненияБазыДанных = ирКэш.СтруктураХраненияБДЛкс(ЗначениеЗаполнено(ТипСУБД),, АдресЧужойСхемыБД);
|
||
КонецЕсли;
|
||
Если СловарьШаблоновМетаданных = Неопределено Тогда
|
||
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданныхЛкс(ЗначениеЗаполнено(ТипСУБД), АдресЧужойСхемыБД);
|
||
КонецЕсли;
|
||
Текст = Текст + Символы.ПС;
|
||
ИменаМетаданныхЗапроса = ИменаМетаданныхЗапросаСУБД(Текст, СловарьШаблоновМетаданных, ТипСУБД);
|
||
|
||
Если НРег(ТипСУБД) = НРег("DB2") Тогда
|
||
Текст = ВРег(Текст);
|
||
КонецЕсли;
|
||
|
||
// Поиск имен таблиц в строке запроса
|
||
Если ИменаМетаданныхЗапроса.Количество() > 10 Тогда
|
||
Индикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ИменаМетаданныхЗапроса.Количество(), "Преобразование в имена метаданных");
|
||
КонецЕсли;
|
||
Для Каждого ИмяМетаданного Из ИменаМетаданныхЗапроса Цикл
|
||
Если Индикатор <> Неопределено Тогда
|
||
ирОбщий.ОбработатьИндикаторЛкс(Индикатор);
|
||
КонецЕсли;
|
||
ОписаниеТаблицы = Неопределено;
|
||
Если выхТаблицы <> Неопределено Тогда
|
||
Если Найти(ИмяМетаданного.Имя, ".") = 0 Тогда
|
||
ОписаниеТаблицы = выхТаблицы.Добавить();
|
||
ОписаниеТаблицы.ИмяБД = ИмяМетаданного.Имя;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
// Получить имя таблицы
|
||
СтрокаСтруктуры = СтруктураХраненияБазыДанных.Найти(ирОбщий.ПоследнийФрагментЛкс(ИмяМетаданного.Имя), "КраткоеИмяТаблицыХранения");
|
||
Если СтрокаСтруктуры = Неопределено Тогда
|
||
// Видимо чужие метаданные
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ИмяТаблицы = СтрокаСтруктуры.КраткоеИмяТаблицыХранения;
|
||
МетаПолноеИмяТаблицы = СтрокаСтруктуры.ИмяТаблицы;
|
||
Если ОписаниеТаблицы <> Неопределено Тогда
|
||
ОписаниеТаблицы.ИмяМета = МетаПолноеИмяТаблицы;
|
||
КонецЕсли;
|
||
Если Не ПереводитьВМета Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Синонимы = ПолучитьСинонимы(Текст, ИмяТаблицы, МетаПолноеИмяТаблицы, ТипСУБД);
|
||
//Синонимы.Вставить(ИмяТаблицы, МетаИмяТаблицы);
|
||
ЭтоТабличнаяЧасть = СтрокаСтруктуры.Назначение = "ТабличнаяЧасть";
|
||
Для Каждого СтрокаПоля Из СтрокаСтруктуры.Поля Цикл
|
||
Если Найти(Текст, СтрокаПоля.ИмяПоляХранения) = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ПредставлениеПоля = ирОбщий.ПолучитьПредставлениеПоляБДЛкс(СтрокаПоля, ТипСУБД <> "", ЭтоТабличнаяЧасть);
|
||
Если Не ЗначениеЗаполнено(ПредставлениеПоля) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
RegExpМета.Pattern = шГраничныйСимволИмени + СтрокаПоля.ИмяПоляХранения + "([^&" + шБуква + "\d]|Balance|Turnover|Receipt|Expense|^|$)";
|
||
// Можно оптимизировать путем создания шаблона мультизамены
|
||
Текст = RegExpМета.Replace(Текст, "$1" + ПредставлениеПоля + "$2");
|
||
КонецЦикла;
|
||
Если ПереводитьИндексы Тогда
|
||
Для Каждого СтрокаИндекса Из СтрокаСтруктуры.Индексы Цикл
|
||
ПредставлениеИндекса = СтрокаИндекса.ИмяИндекса;
|
||
СтрокаДляЗамены = СтрокаИндекса.ИмяИндексаХранения;
|
||
Если ирОбщий.СтрокиРавныЛкс(ТипСУБД, "DBPOSTGRS") Тогда
|
||
СтрокаДляЗамены = ВРег(СтрокаИндекса.ИмяИндексаХранения);
|
||
ИначеЕсли ирОбщий.СтрокиРавныЛкс(ТипСУБД, "DBV8DBEng") Тогда
|
||
СтрокаДляЗамены = ВРег(СтрокаИндекса.ИмяИндексаХранения);
|
||
КонецЕсли;
|
||
// Имена индексов достаточно уникальны, чтобы использовать СтрЗаменить
|
||
Текст = СтрЗаменить(Текст, СтрокаДляЗамены, ПредставлениеИндекса);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Для Каждого Синоним Из Синонимы Цикл
|
||
// Заменить псевдоним таблицы
|
||
RegExpМета.Pattern = шГраничныйСимволИмени + Синоним.Ключ + шГраничныйСимволИмени;
|
||
Текст = RegExpМета.Replace(Текст, "$1" + Синоним.Значение + "$2");
|
||
//RegExpМета.Pattern = ИмяТаблицы + " " + Синоним.Ключ + шГраничныйСимволИмени;
|
||
//Запрос = RegExpМета.Replace(Текст, ИмяТаблицы + " AS " + Синоним.Значение + "$1");
|
||
КонецЦикла;
|
||
// Заменить имя таблицы
|
||
RegExpМета.Pattern = шГраничныйСимволИмени + СтрокаСтруктуры.ИмяТаблицыХранения + шГраничныйСимволИмени;
|
||
Текст = RegExpМета.Replace(Текст, "$1" + МетаПолноеИмяТаблицы + "$2");
|
||
Если НРег(СтрокаСтруктуры.ИмяТаблицыХранения) <> СтрокаСтруктуры.КраткоеИмяТаблицыХранения Тогда
|
||
RegExpМета.Pattern = шГраничныйСимволИмени + СтрокаСтруктуры.КраткоеИмяТаблицыХранения + шГраничныйСимволИмени;
|
||
Текст = RegExpМета.Replace(Текст, "$1" + ирОбщий.ПоследнийФрагментЛкс(МетаПолноеИмяТаблицы) + "$2");
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если Индикатор <> Неопределено Тогда
|
||
ирОбщий.ОсвободитьИндикаторПроцессаЛкс(Индикатор);
|
||
КонецЕсли;
|
||
// Заменим приведение к ссылочному типу
|
||
Если Не ЗначениеЗаполнено(ТипСУБД) Тогда
|
||
Текст = СтрЗаменить(Текст, "AS REF(", "AS (");
|
||
КонецЕсли;
|
||
Текст = СокрП(Текст);
|
||
Возврат Текст;
|
||
|
||
КонецФункции
|
||
|
||
Функция РезультатПереводаСлишкомБольшогоТекста() Экспорт
|
||
|
||
Возврат "<Текст слишком большой для быстрого перевода>"
|
||
|
||
КонецФункции
|
||
|
||
// Получить синонимы имени таблицы в запросе
|
||
//
|
||
// Параметры:
|
||
// Запрос - Строка, текст запроса
|
||
// ИмяТаблицы - Строка, имя таблицы для которой ищутся синонимы
|
||
// МетаИмяТаблицы - Строка, имя таблицы в терминах метаданных
|
||
//
|
||
// Возвращаемое занчение:
|
||
// Соответствие, имена синонимов и их мета имена
|
||
//
|
||
Функция ПолучитьСинонимы(Запрос, ИмяТаблицы, МетаИмяТаблицы, ТипСУБД = "") Экспорт
|
||
|
||
// Построить список синонимом ими таблицы
|
||
Синонимы = Новый Соответствие;
|
||
RegExpМета.Pattern = ИмяТаблицы + " " + "(?:([" + шБуква + "\d]+)|\(([" + шБуква + "\d]+)\))" + шГраничныйСимволИмени;
|
||
Вхождения = RegExpМета.Execute(Запрос);
|
||
ПсевдонимТаблицы = ирОбщий.ПоследнийФрагментЛкс(МетаИмяТаблицы, ".");
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
Синоним = Вхождение.SubMatches(0);
|
||
Если ирОбщий.ЛиПустаяПодгруппаRegExpЛкс(Синоним) Тогда
|
||
Синоним = Вхождение.SubMatches(1);
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или (Истина
|
||
И ирОбщий.СтрокиРавныЛкс(ТипСУБД, "DBMSSQL")
|
||
И ирОбщий.СтрокиРавныЛкс(Синоним, "WITH"))
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "WHERE")
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "GROUP")
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "HAVING")
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "SET")
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "ORDER")
|
||
Или ирОбщий.СтрокиРавныЛкс(Синоним, "THEN")
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Синонимы.Вставить(Синоним, ПсевдонимТаблицы + "_" + Синоним);
|
||
КонецЦикла;
|
||
|
||
Возврат Синонимы;
|
||
|
||
КонецФункции // ПолучитьСинонимы()
|
||
|
||
//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
|
||
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
|
||
//ирПортативный #Если Клиент Тогда
|
||
//ирПортативный Контейнер = Новый Структура();
|
||
//ирПортативный Оповестить("ирПолучитьБазовуюФорму", Контейнер);
|
||
//ирПортативный Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
|
||
//ирПортативный ирПортативный.Открыть();
|
||
//ирПортативный КонецЕсли;
|
||
//ирПортативный #Иначе
|
||
//ирПортативный ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
|
||
//ирПортативный #КонецЕсли
|
||
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
|
||
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
|
||
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
|
||
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");
|
||
|
||
мПлатформа = ирКэш.Получить();
|
||
мНепустыеКолонкиЖурнала = Новый Структура();
|
||
//ЭтотОбъект.НаложениеПриДозагрузкеСекунд = 30;
|
||
RegExpПараметры = мПлатформа.ПолучитьНовыйВычислительРегулярныхВыражений();
|
||
RegExpПараметры.IgnoreCase = Истина;
|
||
RegExpПараметры.Global = Истина;
|
||
RegExpПараметры.Pattern = "([^A-ZА-ЯЁ_0-9]|^)(?:[A-F0-9]+:[A-F0-9]+|0x[A-F0-9]+|[A-F0-9]+(?:-[A-F0-9]+)+-[A-F0-9]+|(#TT?)[_A-F0-9]+|[0-9]+)"; // для стирания констант и имен временных таблиц
|
||
RegExpМета = мПлатформа.ПолучитьНовыйВычислительРегулярныхВыражений();
|
||
RegExpМета.IgnoreCase = Истина;
|
||
RegExpМета.Global = Истина;
|
||
|
||
мСписокКолонок = Новый СписокЗначений;
|
||
//мСписокКолонок.Добавить("Name", "Событие"); // В некоторых случаях нужно
|
||
мСписокКолонок.Добавить("SrcName", "Источник");
|
||
мСписокКолонок.Добавить("OSThread", "ПотокОС");
|
||
мСписокКолонок.Добавить("process", "ТипПроцессаОС");
|
||
мСписокКолонок.Добавить("p:processName", "Инфобаза");
|
||
мСписокКолонок.Добавить("t:clientID", "Соединение_");
|
||
мСписокКолонок.Добавить("t:applicationName", "Приложение");
|
||
мСписокКолонок.Добавить("t:computerName", "Компьютер");
|
||
мСписокКолонок.Добавить("t:connectID", "TCPСоединение");
|
||
мСписокКолонок.Добавить("SessionID", "Сеанс");
|
||
мСписокКолонок.Добавить("Usr", "Пользователь");
|
||
мСписокКолонок.Добавить("OSException", "ИсключениеОС");
|
||
мСписокКолонок.Добавить("Interface", "Интерфейс");
|
||
мСписокКолонок.Добавить("Method", "Метод");
|
||
мСписокКолонок.Добавить("Exception", "ТипИсключения");
|
||
мСписокКолонок.Добавить("Descr", "Описание");
|
||
мСписокКолонок.Добавить("ClientComputerName", "КомпьютерКлиента");
|
||
мСписокКолонок.Добавить("ServerComputerName", "КомпьютерСервера");
|
||
мСписокКолонок.Добавить("UserName", "Пользователь");
|
||
мСписокКолонок.Добавить("ConnectString", "СтрокаСоединения");
|
||
мСписокКолонок.Добавить("ProcessName", "ТипПроцессаОС");
|
||
мСписокКолонок.Добавить("SrcProcessName", "Инфобаза");
|
||
//мСписокКолонок.Добавить("Trans", "Транзакция");
|
||
мСписокКолонок.Добавить("Func", "Действие");
|
||
мСписокКолонок.Добавить("Sdbl", "ТекстSDBL");
|
||
мСписокКолонок.Добавить("dbpid", "ПроцессСУБД");
|
||
мСписокКолонок.Добавить("Sql", "ТекстСУБД");
|
||
мСписокКолонок.Добавить("NParams", "КоличествоПараметров");
|
||
мСписокКолонок.Добавить("Rows", "ЧислоСтрок");
|
||
мСписокКолонок.Добавить("RowsAffected", "ЧислоИзменныхСтрок");
|
||
мСписокКолонок.Добавить("planSQLText", "ПланСУБД");
|
||
мСписокКолонок.Добавить("Context", "Контекст");
|
||
мСписокКолонок.Добавить("CatName", "КаталогСУБД");
|
||
мСписокКолонок.Добавить("WaitConnections", "Блокираторы");
|
||
мСписокКолонок.Добавить("FileName", "ФайлСУБД");
|
||
мСписокКолонок.Добавить("DeadlockConnectionIntersections", "Взаимоблокировка");
|
||
мСписокКолонок.Добавить("Finish", "ПричинаЗавершения");
|
||
мСписокКолонок.Добавить("Err", "ТипСообщения");
|
||
мСписокКолонок.Добавить("Txt", "ТекстСообщения");
|
||
мСписокКолонок.Добавить("URI", "Ресурс");
|
||
мСписокКолонок.Добавить("Administrator", "Администратор");
|
||
мСписокКолонок.Добавить("Body", "РазмерЗапроса");
|
||
мСписокКолонок.Добавить("Cluster", "НомерПорта");
|
||
мСписокКолонок.Добавить("Val", "ЗначениеПараметра");
|
||
|
||
// Свойства найденные экспериментально. Они не документированы.
|
||
мСписокКолонок.Добавить("Query", "ТекстЗапроса1С"); // События: QERR
|
||
мСписокКолонок.Добавить("From", "From_"); // События: DBV8DBENG
|
||
//мСписокКолонок.Добавить("AppID", "AppID"); // События: QERR, DBMSSQL (дублируется t:applicationName), SDBL (дублирует t:applicationName)
|
||
мСписокКолонок.Добавить("Index", "Index_");
|
||
//мСписокКолонок.Добавить("setUnhandledExceptionFilter", "setUnhandledExceptionFilter");
|
||
мСписокКолонок.Добавить("Module", "МодульКонфигурации"); // События: EXCPCNTX
|
||
мСписокКолонок.Добавить("ClientID", "Клиент"); // События: EXCPCNTX, SCALL, EXCP (дублируется t:clientID ?)
|
||
|
||
мТаблицаКолонок = Новый ТаблицаЗначений;
|
||
мТаблицаКолонок.Колонки.Добавить("ВнутреннееИмя", Новый ОписаниеТипов("Строка"));
|
||
мТаблицаКолонок.Колонки.Добавить("ИмяВТаблице", Новый ОписаниеТипов("Строка"));
|
||
мТаблицаКолонок.Индексы.Добавить("ВнутреннееИмя");
|
||
мТаблицаКолонок.Индексы.Добавить("ИмяВТаблице");
|
||
//мЧисловыеСвойства = Новый Структура;
|
||
мСоответствиеКолонок = Новый Соответствие;
|
||
МетаРеквизиты = Метаданные().ТабличныеЧасти.ТаблицаЖурнала.Реквизиты;
|
||
Для Каждого ЭлементСписка Из мСписокКолонок Цикл
|
||
мСоответствиеКолонок.Вставить(НРег(ЭлементСписка.Значение), ЭлементСписка.Представление);
|
||
СтрокаСоответствия = мТаблицаКолонок.Добавить();
|
||
СтрокаСоответствия.ВнутреннееИмя = ЭлементСписка.Значение;
|
||
СтрокаСоответствия.ИмяВТаблице = ЭлементСписка.Представление;
|
||
//Если МетаРеквизиты[ЭлементСписка.Представление].Тип.СодержитТип(Тип("Число")) Тогда
|
||
// мЧисловыеСвойства.Вставить(ЭлементСписка.Представление);
|
||
//КонецЕсли;
|
||
КонецЦикла;
|
||
Для Каждого МетаРеквизит Из МетаРеквизиты Цикл
|
||
Если мСоответствиеКолонок[МетаРеквизит.Имя] = Неопределено Тогда
|
||
мСоответствиеКолонок.Вставить(НРег(МетаРеквизит.Имя), МетаРеквизит.Имя);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
мКартыФайлов = Новый ТаблицаЗначений;
|
||
мКартыФайлов.Колонки.Добавить("ИмяКаталогаПроцесса", Новый ОписаниеТипов("Строка"));
|
||
мКартыФайлов.Колонки.Добавить("ИмяТекущегоФайла", Новый ОписаниеТипов("Строка"));
|
||
мКартыФайлов.Колонки.Добавить("СигнатураТекущегоФайла", Новый ОписаниеТипов("Строка"));
|
||
мКартыФайлов.Колонки.Добавить("ОтборПоСеансу");
|
||
мКартыФайлов.Колонки.Добавить("ПозицияНачала", Новый ОписаниеТипов("Число"));
|
||
мКартыФайлов.Колонки.Добавить("ПозицияКонца", Новый ОписаниеТипов("Число"));
|
||
мКартыФайлов.Колонки.Добавить("НачалоПериода", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Колонки.Добавить("КонецПериода", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Колонки.Добавить("ДатаИзмененияФайла", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Индексы.Добавить("ИмяКаталогаПроцесса, ИмяТекущегоФайла, СигнатураТекущегоФайла, ОтборПоСеансу");
|
||
|
||
мСвойстваСИменамиБД = Новый Структура();
|
||
мСвойстваСИменамиБД.Вставить("ТекстSDBL", Ложь);
|
||
мСвойстваСИменамиБД.Вставить("ТекстSDBLШаблон", Ложь);
|
||
мСвойстваСИменамиБД.Вставить("ТекстСУБД", Истина);
|
||
мСвойстваСИменамиБД.Вставить("ТекстСУБДШаблон", Ложь);
|
||
мСвойстваСИменамиБД.Вставить("ПланСУБД", Истина);
|
||
мСвойстваСИменамиБД.Вставить("Взаимоблокировка", Ложь);
|
||
мСвойстваСИменамиБД.Вставить("Regions", Ложь);
|
||
мСвойстваСИменамиБД.Вставить("Locks", Ложь);
|
||
|
||
мСерверныеТипыПроцессов = Новый Структура;
|
||
мСерверныеТипыПроцессов.Вставить("_adminprocess"); // ##AdminProcess##
|
||
мСерверныеТипыПроцессов.Вставить("_rphost");
|
||
мСерверныеТипыПроцессов.Вставить("_rmngr");
|
||
мСерверныеТипыПроцессов.Вставить("_ragent");
|
||
|
||
МаксТысячСобытий = 100;
|
||
мАдресЧужойСхемыБД = "";
|
||
шБуква = мПлатформа.шБуква;
|
||
шГраничныйСимволИмени = "([^&" + шБуква + "\d]|^|$)";
|
||
мИменаВозвращаемыхСвойств = "мКартыФайлов, мНепустыеКолонкиЖурнала, мТипСУБД";
|
||
|