mirror of
https://github.com/tormozit/RDT1C.git
synced 2025-12-17 13:14:11 +00:00
1582 lines
102 KiB
Plaintext
1582 lines
102 KiB
Plaintext
Перем мТаблицаКолонок Экспорт;
|
||
Перем мСписокКолонок Экспорт;
|
||
Перем КлючиЗагруженныхСтрок;
|
||
Перем мСвойстваСИменамиБД Экспорт;
|
||
Перем RegExpПараметры;
|
||
Перем RegExpМета;
|
||
Перем шБуква;
|
||
Перем шГраничныйСимволИмени;
|
||
//Перем МинимальнаяДатаЗагрузки Экспорт;
|
||
Перем мЧисловыеСвойства;
|
||
Перем мТипСУБД Экспорт;
|
||
Перем мСерверныеТипыПроцессов Экспорт;
|
||
Перем мКартыФайлов;
|
||
Перем мПлатформа;
|
||
|
||
//Трассировка
|
||
Перем КонецПериодаКлиента Экспорт;
|
||
Перем НачалоПериодаКлиента Экспорт;
|
||
Перем КонецПериодаСервера Экспорт;
|
||
Перем НачалоПериодаСервера Экспорт;
|
||
Перем мИдентификаторТрассы Экспорт;
|
||
Перем мНепустыеКолонкиЖурнала Экспорт;
|
||
Перем мСоответствиеКолонок;
|
||
|
||
// СдвигВремени - Число - в секундах задается, нужно для компенсации разницы времени между компьютерами
|
||
// ОтборПоПроцессу и ОтборПоСеансу частично игнорируются когда ЗагружатьТолькоТекущийСеанс = Истина
|
||
Функция ПрочитатьПроизвольныйЖурнал(СообщитьРазмер = Неопределено, СдвигВремени = 0, ОтборПоПроцессу = Неопределено, ОтборПоСеансу = Неопределено,
|
||
НаСервере = Неопределено)
|
||
|
||
Если Ложь
|
||
Или НаСервере <> Неопределено
|
||
Или Не ЗначениеЗаполнено(КаталогЖурнала)
|
||
Тогда
|
||
КаталогЖурнала = ПолучитьКаталогТекущегоЖурнала(НаСервере = Истина);
|
||
Если Не ЗначениеЗаполнено(КаталогЖурнала) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если Не ирНеглобальный.ЛиКаталогДоступенЛкс(КаталогЖурнала) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Если ЗагружатьТолькоТекущийСеанс Тогда
|
||
Если Ложь
|
||
Или ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Или Не НаСервере = Истина
|
||
Тогда
|
||
ОтборПоПроцессу = ирКэш.Получить().ПолучитьИдентификаторПроцессаОС();
|
||
КонецЕсли;
|
||
Если НаСервере = Истина Тогда
|
||
ОтборПоСеансу = НомерСеансаИнформационнойБазы();
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
лПоследнееВремяНачалаЗагрузки = ТекущаяДата();
|
||
Если ПериодПоследниеМинуты > 0 Тогда
|
||
НачалоПериода = лПоследнееВремяНачалаЗагрузки - 60 * ПериодПоследниеМинуты;
|
||
КонецПериода = Неопределено;
|
||
КонецЕсли;
|
||
//Если ТаблицаЖурнала.Количество() = 0 Тогда
|
||
// МинимальнаяДатаЗагрузки = ТекущаяДата() + 100000;
|
||
//КонецЕсли;
|
||
//Если МинимальнаяДатаЗагрузки > НачалоПериода Тогда
|
||
// ТаблицаЖурнала.Очистить();
|
||
//КонецЕсли;
|
||
//РежимДозагрузки = Истина
|
||
// И ТаблицаЖурнала.Количество() > 0
|
||
// И МинимальнаяДатаЗагрузки <= НачалоПериода;
|
||
Если СообщитьРазмер = Неопределено Тогда
|
||
СообщитьРазмер = (ТаблицаЖурнала.Количество() = 0);
|
||
КонецЕсли;
|
||
Если ТаблицаЖурнала.Количество() = 0 Тогда
|
||
мКартыФайлов.Очистить();
|
||
КонецЕсли;
|
||
|
||
ирНеглобальный.ЛиКаталогТехножурналаСодержитБлокирующиеФайлыЛкс(КаталогЖурнала);
|
||
ФайлыЖурнала = НайтиФайлы(КаталогЖурнала, "*.log", Истина);
|
||
ОбщийРазмер = 0;
|
||
Для Каждого ФайлЖурнала Из ФайлыЖурнала Цикл
|
||
ОбщийРазмер = ОбщийРазмер + ФайлЖурнала.Размер();
|
||
КонецЦикла;
|
||
Если СообщитьРазмер Тогда
|
||
Сообщить("В журнале """ + КаталогЖурнала + """ обнаружено " + Формат(Цел(ОбщийРазмер / 1024), "ЧН=") + " КБ логов");
|
||
КонецЕсли;
|
||
//БезопасныйРазмерЖурнала = 10*1000*1000; // 10МБ
|
||
//Если ОбщийРазмер > БезопасныйРазмерЖурнала Тогда
|
||
// Ответ = Вопрос("Размер журнала составляет " + Формат(Цел(ОбщийРазмер / 1000000)) + " МБ.
|
||
// |Чтение журнала может продолжаться длительное время, продолжить?", РежимДиалогаВопрос.ДаНет);
|
||
//Иначе
|
||
// Ответ = КодВозвратаДиалога.Да;
|
||
//КонецЕсли;
|
||
//Если Ответ = КодВозвратаДиалога.Нет Тогда
|
||
// Возврат Ложь;
|
||
//КонецЕсли;
|
||
НеОбрабатывать = Ложь;
|
||
СтрокаСобытия = "";
|
||
СтруктураЗаписиТЖ = Новый Структура();
|
||
РеквизитыТЧ = Метаданные().ТабличныеЧасти.ТаблицаЖурнала.Реквизиты;
|
||
шСимвол = "[" + шБуква + "\d\._#{}-]";
|
||
ШаблонСвойствоЗначение = ",([\w\:]+)=(?:'\s*([^']*)'|""\s*([^""]*)""|([^'""\n\r,]*))";
|
||
Шаблон = "(\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 Тогда
|
||
ИндикаторФайла = ЛксПолучитьИндикаторПроцесса(ЧислоПорций, "" + ИмяФайлаСРодителем + "\" + ФайлЖурнала.Имя);
|
||
Иначе
|
||
ИндикаторФайла = Неопределено;
|
||
КонецЕсли;
|
||
Пока Истина Цикл
|
||
КартаФайла.ДатаИзменения = ФайлЖурнала.ПолучитьВремяИзменения();
|
||
ПорцияТекстаФайла = ЧтениеТекста.Прочитать(РазмерПорции);
|
||
Если Ложь
|
||
Или ПорцияТекстаФайла = Неопределено
|
||
Или ПустаяСтрока(ПорцияТекстаФайла)
|
||
Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
#Если Клиент Тогда
|
||
Если ИндикаторФайла <> Неопределено Тогда
|
||
ЛксОбработатьИндикатор(ИндикаторФайла);
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
Если Истина
|
||
И АбсолютнаяПозицияВФайле >= КартаФайла.ПозицияНачала
|
||
И АбсолютнаяПозицияВФайле + СтрДлина(ПорцияТекстаФайла) + СтрДлина(ТекстФайла) < КартаФайла.ПозицияКонца
|
||
Тогда
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + СтрДлина(ПорцияТекстаФайла) + СтрДлина(ТекстФайла);
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ТекстФайла = ТекстФайла + ПорцияТекстаФайла;
|
||
Попытка
|
||
Вхождения = RegExp.Execute(ТекстФайла);
|
||
Исключение
|
||
Сообщить("Ошибка анализа файла """ + ФайлЖурнала.ПолноеИмя + """: " + ОписаниеОшибки());
|
||
Прервать;
|
||
КонецПопытки;
|
||
Если КомментироватьЗагрузку Тогда
|
||
Сообщить("Анализ порции " + СтрДлина(ТекстФайла) + " символов обнаружил " + Вхождения.Count + " событий");
|
||
КонецЕсли;
|
||
СтрокаТекущегоКонтекста = Неопределено;
|
||
СтрокаТЧ = Неопределено;
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
#Если Клиент Тогда
|
||
ОбработкаПрерыванияПользователя();
|
||
#КонецЕсли
|
||
СтрокаТЧ = Неопределено;
|
||
АбсолютнаяПозицияВхождения = АбсолютнаяПозицияВФайле + Вхождение.FirstIndex;
|
||
Если Истина
|
||
И КартаФайла.ПозицияНачала > -1
|
||
И АбсолютнаяПозицияВхождения >= КартаФайла.ПозицияНачала
|
||
И АбсолютнаяПозицияВхождения < КартаФайла.ПозицияКонца
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
СтрокаВремениЗаписи = СтрокаЧасаЗаписи + СтрЗаменить(Вхождение.SubMatches(0), ":", "");
|
||
ДатаВремяЗаписи = Дата(СтрокаВремениЗаписи);
|
||
Если Не ЛиФайлВИнтервалеПолностью Тогда
|
||
//ЛиДатаВИнтервале = ирНеглобальный.ЛиДатаВИнтервалеСГраницамиЛкс(ДатаВремяЗаписи, лНачалоПериода, КонецПериода);
|
||
//Если Не ЛиДатаВИнтервале Тогда
|
||
// Продолжить;
|
||
//КонецЕсли;
|
||
Если Истина
|
||
И ЗначениеЗаполнено(НачалоПериода)
|
||
И ДатаВремяЗаписи < НачалоПериода
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ЗначениеЗаполнено(КонецПериода)
|
||
И ДатаВремяЗаписи > КонецПериода
|
||
Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ПозицияНачалаСчитанныхДанных = -1 Тогда
|
||
ПозицияНачалаСчитанныхДанных = АбсолютнаяПозицияВхождения;
|
||
КонецЕсли;
|
||
МоментВремени = СтрокаВремениЗаписи + Вхождение.SubMatches(1);
|
||
//КлючСтроки = МоментВремени + ";" + ФайлЖурнала.ПолноеИмя;
|
||
//Если РежимДозагрузки Тогда
|
||
// Если КлючиЗагруженныхСтрок[КлючСтроки] = 1 Тогда
|
||
// Продолжить;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
СтрокаТЧ = ТаблицаЖурнала.Добавить();
|
||
СтрокаТЧ.МоментВремени = Число(МоментВремени) - СдвигВремени * 10000;
|
||
СтрокаТЧ.ИмяФайлаЛога = ФайлЖурнала.ПолноеИмя;
|
||
СтрокаТЧ.Дата = ДатаВремяЗаписи - СдвигВремени;
|
||
СтрокаТЧ.ПроцессОС = ИдентификаторПроцесса;
|
||
//СтрокаТЧ.ТекстЖурнала = Вхождение.Value; // Теперь это только для отладки будем включать
|
||
СтрокаТЧ.Длительность = Число(Вхождение.SubMatches(2)) / 10; // Делаем из десятитысячных тысячные (мс) секудны
|
||
СтрокаТЧ.Событие = ВРег(Вхождение.SubMatches(3));
|
||
ВхожденияСвойств = RegExp2.Execute(Вхождение.SubMatches(4));
|
||
Для Каждого ВхождениеСвойства Из ВхожденияСвойств Цикл
|
||
//Для Индекс = 0 По мТаблицаКолонок.Количество() - 1 Цикл
|
||
//Индекс + СмещениеПервойКолонки
|
||
ИмяСвойства = ВхождениеСвойства.SubMatches(0);
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(3);
|
||
Если ирНеглобальный.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(2);
|
||
КонецЕсли;
|
||
Если ирНеглобальный.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
ЗначениеСвойства = ВхождениеСвойства.SubMatches(1);
|
||
КонецЕсли;
|
||
Если ирНеглобальный.ЛиПустаяПодгруппаRegExpЛкс(ЗначениеСвойства) Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ИмяКолонкиТЧ = мСоответствиеКолонок[ИмяСвойства];
|
||
Если ИмяКолонкиТЧ = Неопределено Тогда
|
||
Если КомментироватьЗагрузку Тогда
|
||
Сообщить("Обнаружено неизвестное свойство """ + ИмяСвойства + """");
|
||
КонецЕсли;
|
||
Продолжить;
|
||
КонецЕсли;
|
||
//Если мЧисловыеСвойства.Свойство(ИмяКолонкиТЧ) Тогда
|
||
// Если Не ЗначениеЗаполнено(ЗначениеСвойства) Тогда
|
||
// ЗначениеСвойства = 0;
|
||
// Иначе
|
||
// Попытка
|
||
// ЗначениеСвойства = Число(ЗначениеСвойства);
|
||
// Исключение
|
||
// ВызватьИсключение "Некорректное представление """ + ЗначениеСвойства + """ значения числового свойства """ + ИмяКолонкиТЧ + """";
|
||
// КонецПопытки;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если Не мНепустыеКолонкиЖурнала.Свойство(ИмяКолонкиТЧ) Тогда
|
||
Если ЗначениеЗаполнено(ЗначениеСвойства) Тогда
|
||
мНепустыеКолонкиЖурнала.Вставить(ИмяКолонкиТЧ);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Попытка
|
||
СтрокаТЧ[ИмяКолонкиТЧ] = ЗначениеСвойства;
|
||
Исключение
|
||
ВызватьИсключение "Некорректное представление """ + ЗначениеСвойства + """ значения свойства """ + ИмяКолонкиТЧ + """";
|
||
КонецПопытки;
|
||
КонецЦикла;
|
||
//АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + Вхождение.Length;
|
||
Если Истина
|
||
И ОтборПоСеансу <> Неопределено
|
||
И СтрокаТЧ.Сеанс <> ОтборПоСеансу
|
||
Тогда
|
||
ТаблицаЖурнала.Удалить(СтрокаТЧ);
|
||
СтрокаТЧ = Неопределено;
|
||
#Если _ Тогда
|
||
СтрокаТЧ = ТаблицаЖурнала.Добавить();
|
||
#КонецЕсли
|
||
Продолжить;
|
||
КонецЕсли;
|
||
//Если НаСервере <> Неопределено Тогда
|
||
// СтрокаТЧ.НаСервере = НаСервере;
|
||
//Иначе
|
||
Если Ложь
|
||
Или СтрокаТЧ.Событие = "SCOM"
|
||
Тогда
|
||
СтрокаТЧ.НаСервере = Истина;
|
||
Иначе
|
||
ИмяТипаПроцесса = "_" + СтрЗаменить(СтрокаТЧ.ТипПроцессаОС, "#", "");
|
||
Попытка
|
||
СтрокаТЧ.НаСервере = мСерверныеТипыПроцессов.Свойство(ИмяТипаПроцесса);
|
||
Исключение
|
||
// Бывают типы процессов с UID, к сожалению тогда невозможно определить
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
//КонецЕсли;
|
||
Если СтрокаТЧ.Контекст <> "" Тогда
|
||
СтрокаТЧ.СтрокаМодуля = СокрЛП(СтрПолучитьСтроку(СтрокаТЧ.Контекст, СтрЧислоСтрок(СтрокаТЧ.Контекст)));
|
||
Если БазовыйУровеньСтека > 0 Тогда
|
||
ЗаполнитьСтрокуБазовогоУровня(СтрокаТЧ);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если ВключитьСвойстваСИменамиМетаданных Тогда
|
||
ЗаполнитьСвойстваСИменамиМетаданных(СтрокаТЧ);
|
||
КонецЕсли;
|
||
//Если ДатаВремяЗаписи > лПоследнееВремяНачалаЗагрузки - НаложениеПриДозагрузкеСекунд Тогда
|
||
// НовыеКлючиЗагруженныхСтрок[КлючСтроки] = 1;
|
||
//КонецЕсли;
|
||
Если ирНеглобальный.СтрокиРавныЛкс(СтрокаТЧ.Событие, "Context") Тогда
|
||
// Встроим контекст в предыдущие события
|
||
Индекс = ТаблицаЖурнала.Количество() - 2;
|
||
Пока Индекс >= 0 Цикл
|
||
СтрокаБезКонтекста = ТаблицаЖурнала[Индекс];
|
||
Индекс = Индекс - 1;
|
||
Если Ложь
|
||
Или СтрокаБезКонтекста.Сеанс <> СтрокаТЧ.Сеанс
|
||
Или СтрокаБезКонтекста.Инфобаза <> СтрокаТЧ.Инфобаза
|
||
Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
Если Не СтрокаБезКонтекста.СтрокаМодуля = "" Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
ЗаполнитьЗначенияСвойств(СтрокаБезКонтекста, СтрокаТЧ, "СтрокаМодуля, Контекст");
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
// Для отката к началу последнего события
|
||
РазмерТекущейПорции = СтрДлина(ПорцияТекстаФайла);
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле + СтрДлина(ТекстФайла);
|
||
Если РазмерТекущейПорции = РазмерПорции Тогда
|
||
Если СтрокаТЧ <> Неопределено Тогда
|
||
ТаблицаЖурнала.Удалить(ТаблицаЖурнала.Количество() - 1);
|
||
КонецЕсли;
|
||
Если Вхождение <> Неопределено Тогда
|
||
ТекстФайла = Сред(ТекстФайла, Вхождение.FirstIndex);
|
||
Иначе
|
||
ТекстФайла = Прав(ТекстФайла, 1000); // Страховка
|
||
КонецЕсли;
|
||
АбсолютнаяПозицияВФайле = АбсолютнаяПозицияВФайле - СтрДлина(ТекстФайла);
|
||
Иначе
|
||
ТекстФайла = "";
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Если ИндикаторФайла <> Неопределено Тогда
|
||
ЛксОсвободитьИндикаторПроцесса();
|
||
КонецЕсли;
|
||
КартаФайла.ПозицияКонца = АбсолютнаяПозицияВФайле;
|
||
Если Истина
|
||
И ПозицияНачалаСчитанныхДанных <> -1
|
||
И (Ложь
|
||
Или КартаФайла.ПозицияНачала = -1
|
||
Или КартаФайла.ПозицияНачала > ПозицияНачалаСчитанныхДанных)
|
||
Тогда
|
||
КартаФайла.ПозицияНачала = ПозицияНачалаСчитанныхДанных;
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или Не ЗначениеЗаполнено(КонецПериода)
|
||
Или КонецПериода > КартаФайла.КонецПериода
|
||
Тогда
|
||
КартаФайла.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
Если Ложь
|
||
Или Не ЗначениеЗаполнено(НачалоПериода)
|
||
Или НачалоПериода < КартаФайла.НачалоПериода
|
||
Тогда
|
||
КартаФайла.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
ЛксОсвободитьИндикаторПроцесса();
|
||
|
||
//КлючиЗагруженныхСтрок = НовыеКлючиЗагруженныхСтрок;
|
||
//Если НаСервере = Истина Тогда
|
||
// ЭтотОбъект.ПоследнееВремяНачалаЗагрузкиСервера = лПоследнееВремяНачалаЗагрузки;
|
||
//Иначе
|
||
// ЭтотОбъект.ПоследнееВремяНачалаЗагрузки = лПоследнееВремяНачалаЗагрузки;
|
||
//КонецЕсли;
|
||
//МинимальнаяДатаЗагрузки = Мин(НачалоПериода, МинимальнаяДатаЗагрузки);
|
||
ТаблицаЖурнала.Сортировать("МоментВремени");
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ЗаполнитьСтрокуБазовогоУровня(СтрокаТЧ)
|
||
|
||
Если БазовыйУровеньСтека > 0 Тогда
|
||
//МаркерБазовогоМодуля = Символы.Таб + мИмяБазовогоМодуля + " : ";
|
||
//ПозицияМаркераМодуля = Найти(СтрокаТЧ.Контекст, МаркерБазовогоМодуля);
|
||
//КонецСтроки = Сред(СтрокаТЧ.Контекст, ПозицияМаркераМодуля + СтрДлина(МаркерБазовогоМодуля));
|
||
НовоеЗначение = СокрЛ(СтрПолучитьСтроку(СтрокаТЧ.Контекст, БазовыйУровеньСтека));
|
||
Иначе
|
||
НовоеЗначение = "";
|
||
КонецЕсли;
|
||
ЛксПрисвоитьЕслиНеРавно(СтрокаТЧ.СтрокаМодуляБазовогоУровня, НовоеЗначение);
|
||
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
// ПопытокЧтения - Число, используется только при РежимТрассы = Истина
|
||
Функция ПрочитатьСобственныйЖурналДвухСторон(УдалитьДополнительныеСобытия = Истина, ИменаНеполезныхКолонок = "", РежимТрассы = Истина,
|
||
ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено)
|
||
|
||
Если РежимТрассы Тогда
|
||
Если мИдентификаторТрассы = Неопределено Тогда
|
||
Если Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
ирНеглобальный.ЛиТехножурналВключенЛкс(Истина, Истина);
|
||
КонецЕсли;
|
||
ирНеглобальный.ЛиТехножурналВключенЛкс(, Истина);
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
ЭтотОбъект.ВключитьСвойстваСИменамиМетаданных = Ложь; // Для ускорения выключаем, т.к. фильтрация будет многостадийной
|
||
ЭтотОбъект.ЗагружатьЖурналКлиента = Истина;
|
||
ЭтотОбъект.ЗагружатьЖурналСервера = Не ирКэш.ЭтоФайловаяБазаЛкс();
|
||
ЭтотОбъект.ЗагружатьТолькоТекущийСеанс = Истина;
|
||
КонецЕсли;
|
||
ВыраниватьДатуПоСерверу = Ложь;
|
||
#Если Клиент Тогда
|
||
ВыраниватьДатуПоСерверу = ВосстановитьЗначение("ирАнализТехножурнала.ВыраниватьДатуПоСерверу") = Истина;
|
||
#КонецЕсли
|
||
Если РежимТрассы Тогда
|
||
РазницаВремениКлиентСервер = НачалоПериодаКлиента - НачалоПериодаСервера;
|
||
Иначе
|
||
РазницаВремениКлиентСервер = ирНеглобальный.ПолучитьТекущуюДатуЛкс() - ирНеглобальный.ПолучитьТекущуюДатуЛкс(Истина);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И Не ирКэш.Получить().ЭтоФайловаяБаза
|
||
И ЗагружатьЖурналСервера
|
||
Тогда
|
||
ЭтотОбъект.КаталогЖурнала = "";
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
СдвигВремени = 0;
|
||
Иначе
|
||
СдвигВремени = -РазницаВремениКлиентСервер;
|
||
КонецЕсли;
|
||
РезультатСервера = ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериодаСервера, КонецПериодаСервера, Истина, СдвигВремени,
|
||
РежимТрассы, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
КонецЕсли;
|
||
Если ЗагружатьЖурналКлиента Тогда
|
||
ЭтотОбъект.КаталогЖурнала = "";
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
СдвигВремени = РазницаВремениКлиентСервер;
|
||
Иначе
|
||
СдвигВремени = 0;
|
||
КонецЕсли;
|
||
РезультатКлиента = ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериодаКлиента, КонецПериодаКлиента, Ложь, СдвигВремени,
|
||
РежимТрассы, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
КонецЕсли;
|
||
Если Истина
|
||
И РезультатКлиента = Неопределено
|
||
И РезультатСервера = Неопределено
|
||
Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
Если УдалитьДополнительныеСобытия Тогда
|
||
УдалитьСтрокиПоОтбору(Новый Структура("Действие", "getExecSQLStatistics"));
|
||
УдалитьСтрокиПоОтбору(Новый Структура("Событие", "CONTEXT"));
|
||
КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
ЭтотОбъект.ВключитьСвойстваСИменамиМетаданных = Истина;
|
||
КонецЕсли;
|
||
Если ВключитьСвойстваСИменамиМетаданных Тогда
|
||
ОбновитьСвойстваВТерминахМетаданных();
|
||
КонецЕсли;
|
||
//ОбновитьСтрокиБазовогоУровня();
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПрочитатьСобственныйЖурналОднойСтороны(НачалоПериода = Неопределено, КонецПериода = Неопределено, НаСервере = Истина, СдвигВремени = 0,
|
||
РежимТрассы = Истина, ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено)
|
||
|
||
Если НачалоПериода <> Неопределено Тогда
|
||
ЭтотОбъект.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
Если КонецПериода <> Неопределено Тогда
|
||
ЭтотОбъект.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
ТехножурналВключен = ирНеглобальный.ЛиТехножурналВключенЛкс(НаСервере);
|
||
Если Истина
|
||
И Не ТехножурналВключен
|
||
И РежимТрассы
|
||
Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
МассивТиповСУБД = Новый Массив();
|
||
Если ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
МассивТиповСУБД.Добавить("DBV8DBENG");
|
||
//ОтборТЧ = Новый Структура("Событие", "SDBL");
|
||
Иначе
|
||
МассивТиповСУБД.Добавить("DBMSSQL");
|
||
МассивТиповСУБД.Добавить("DBPOSTGRS");
|
||
МассивТиповСУБД.Добавить("DBORACLE");
|
||
МассивТиповСУБД.Добавить("DB2");
|
||
//ОтборТЧ = Новый Структура("Событие", "CONTEXT");
|
||
КонецЕсли;
|
||
СообщитьРазмер = Неопределено;
|
||
Для Счетчик = 1 По ПопытокЧтения Цикл
|
||
#Если Клиент Тогда
|
||
ОбработкаПрерыванияПользователя();
|
||
#КонецЕсли
|
||
Если Счетчик > 1 Тогда
|
||
#Если Клиент Тогда
|
||
Состояние("Ожидание техножурнала");
|
||
#КонецЕсли
|
||
ирКэш.Получить().Sleep(500);
|
||
СообщитьРазмер = Ложь;
|
||
КонецЕсли;
|
||
ЖурналСчитан = ПрочитатьПроизвольныйЖурнал(СообщитьРазмер, СдвигВремени, , , НаСервере);
|
||
Если Не ЖурналСчитан Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
//ТехножурналВключен = ирНеглобальный.ЛиТехножурналВключенЛкс(Истина);
|
||
//Если ТехножурналВключен Тогда
|
||
// Если АвтоочисткаТехножурнала Тогда
|
||
// КаталогТекущегоЖурнала = ПолучитьКаталогТекущегоЖурнала();
|
||
// Если ЗначениеЗаполнено(КаталогТекущегоЖурнала) Тогда
|
||
// ирНеглобальный.ОчиститьКаталогЖурналаЛкс(КаталогТекущегоЖурнала, Истина, Ложь);
|
||
// КонецЕсли;
|
||
// КонецЕсли;
|
||
//КонецЕсли;
|
||
Если РежимТрассы Тогда
|
||
МаркерНачала = Новый Структура("Описание", "{(1, 1)}: Ожидается выражение ""ВЫБРАТЬ""
|
||
|<<?>>НачалоТрассы_" + мИдентификаторТрассы);
|
||
МаркерКонца = Новый Структура("Описание", "{(1, 1)}: Ожидается выражение ""ВЫБРАТЬ""
|
||
|<<?>>КонецТрассы_" + мИдентификаторТрассы);
|
||
|
||
// Удаляем лишние строки до маркера начала и после маркера конца
|
||
|
||
НайденныеСтроки = ТаблицаЖурнала.НайтиСтроки(МаркерНачала);
|
||
Если НайденныеСтроки.Количество() = 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;
|
||
ЭтотОбъект.КонецПериодаСервера = Неопределено;
|
||
ЭтотОбъект.КонецПериодаКлиента = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаСервера = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаКлиента = Неопределено;
|
||
Если Ложь
|
||
Или ЗагружатьЖурналКлиента
|
||
Или ЗагружатьЖурналСервера
|
||
Тогда
|
||
ЖурналПрочитан = ПрочитатьСобственныйЖурналДвухСторон(,, Ложь);
|
||
Иначе
|
||
ЖурналПрочитан = ПрочитатьПроизвольныйЖурнал();
|
||
КонецЕсли;
|
||
Возврат ЖурналПрочитан;
|
||
|
||
КонецФункции
|
||
|
||
// ТолькоПустые - заполнять только ранее не заполненные свойства
|
||
Процедура ЗаполнитьСвойстваСИменамиМетаданных(ВыбраннаяСтрока, ТолькоПустые = Истина) Экспорт
|
||
|
||
Для Каждого ИмяСвойства Из мСвойстваСИменамиБД Цикл
|
||
Если Найти(ИмяСвойства, "БезПараметров") > 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Попытка
|
||
Пустышка = ТипЗнч(ВыбраннаяСтрока[ИмяСвойства]); // т.к. строки длинные, то их копирование в новую переменную накладно
|
||
Исключение
|
||
// Такого свойства нет - пропускаем
|
||
Продолжить;
|
||
КонецПопытки;
|
||
Если Истина
|
||
И ЗначениеЗаполнено(ВыбраннаяСтрока[ИмяСвойства])
|
||
И (Ложь
|
||
Или Не ТолькоПустые
|
||
Или ПустаяСтрока(ВыбраннаяСтрока[ИмяСвойства + "Мета"]))
|
||
Тогда
|
||
Если Ложь
|
||
Или ВыбраннаяСтрока.Инфобаза = ""
|
||
Или ирНеглобальный.СтрокиРавныЛкс(ВыбраннаяСтрока.Инфобаза, НСтр(СтрокаСоединенияИнформационнойБазы(), "Ref"))
|
||
Тогда
|
||
Попытка
|
||
ТипСУБД = ВыбраннаяСтрока.Событие;
|
||
Исключение
|
||
ТипСУБД = Сред(ИмяСвойства, СтрДлина("Текст") + 1); // Опасно
|
||
КонецПопытки;
|
||
//Попытка
|
||
ТекстМета = ПолучитьЗапросВТерминахМетаданных(ВыбраннаяСтрока[ИмяСвойства], , , ТипСУБД);
|
||
//Исключение
|
||
// ТекстМета = "";
|
||
//КонецПопытки;
|
||
//Если ТекстМета <> "" Тогда
|
||
ВыбраннаяСтрока[ИмяСвойства + "Мета"] = ТекстМета;
|
||
//КонецЕсли;
|
||
Иначе
|
||
// База чужая. Не делаем преобразования
|
||
ВыбраннаяСтрока[ИмяСвойства + "Мета"] = ВыбраннаяСтрока[ИмяСвойства];
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если Ложь
|
||
Или Не ТолькоПустые
|
||
Или Не ЗначениеЗаполнено(ВыбраннаяСтрока.ТекстБезПараметровSDBLМета)
|
||
Тогда
|
||
Инфобаза = "";
|
||
ТекстSDBLМета = "";
|
||
Попытка
|
||
Инфобаза = ВыбраннаяСтрока.Инфобаза;
|
||
ТекстSDBLМета = ВыбраннаяСтрока.ТекстSDBLМета;
|
||
Исключение
|
||
КонецПопытки;
|
||
Если Ложь
|
||
Или Инфобаза = ""
|
||
Или ирНеглобальный.СтрокиРавныЛкс(Инфобаза, НСтр(СтрокаСоединенияИнформационнойБазы(), "Ref"))
|
||
Тогда
|
||
Если Истина
|
||
И ТекстSDBLМета <> ""
|
||
Тогда
|
||
ВыбраннаяСтрока.ТекстБезПараметровSDBLМета = RegExpПараметры.Replace(ТекстSDBLМета, "&P");
|
||
Иначе
|
||
ВыбраннаяСтрока.ТекстБезПараметровSDBLМета = ПолучитьЗапросВТерминахМетаданных(ВыбраннаяСтрока.ТекстБезПараметровSDBL);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция ПолучитьКаталогТекущегоЖурнала(НаСервере) Экспорт
|
||
|
||
Результат = Неопределено;
|
||
Если НаСервере Тогда
|
||
#Если Клиент Тогда
|
||
Результат = ВосстановитьЗначение("ирАнализТехножурнала.КаталогЖурналаСервера");
|
||
#КонецЕсли
|
||
КонецЕсли;
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Результат = ирНеглобальный.ПолучитьКаталогТехножурналаЛкс(НаСервере);
|
||
Если Не ЗначениеЗаполнено(Результат) Тогда
|
||
Сообщить("Технологический журнал выключен. Невозможно определить каталог журнала по умолчанию.");
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
Если НаСервере Тогда
|
||
КлиентЗапущенНаКомпьютереСервера = ирНеглобальный.ЛиКлиентЗапущенНаКомпьютереСервераЛкс();
|
||
Если Не КлиентЗапущенНаКомпьютереСервера Тогда
|
||
Если ЭтоЛокальныйПутьЛкс(Результат) Тогда
|
||
Сообщить("Клиент запущен не на компьютере сервера (" + ирСервер.ПолучитьИмяКомпьютераЛкс() +
|
||
"), а в серверной настройке техножурнала указан локальный каталог. Необходимо указать сетевой путь к техножурналу сервера");
|
||
#Если Клиент Тогда
|
||
ФормаНастройки = ПолучитьФорму("НастройкаЧтения");
|
||
РезультатНастройки = ФормаНастройки.ОткрытьМодально();
|
||
Если РезультатНастройки = Истина Тогда
|
||
Результат = ВосстановитьЗначение("ирАнализТехножурнала.КаталогЖурналаСервера");
|
||
Иначе
|
||
Результат = Неопределено;
|
||
КонецЕсли;
|
||
#КонецЕсли
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
КонецЕсли;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция ЭтоЛокальныйПутьЛкс(Путь) Экспорт
|
||
|
||
ЭтоЛокальныйРесурс = Ложь
|
||
Или Найти(НРег(Путь), "\\localhost") = 1
|
||
Или Найти(НРег(Путь), "\\127.0.0.1") = 1
|
||
Или Лев(Путь, 2) <> "\\";
|
||
Возврат ЭтоЛокальныйРесурс;
|
||
|
||
КонецФункции // ЭтоЛокальныйПуть()
|
||
|
||
Функция ОткрытьСПараметрами(пКаталогЖурнала) Экспорт
|
||
|
||
Форма = ПолучитьФорму();
|
||
Форма.Открыть();
|
||
Форма.КаталогЖурнала = пКаталогЖурнала;
|
||
Возврат Форма;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОткрытьСОтбором(НачалоПериода = Неопределено, КонецПериода = Неопределено, СтруктураОтбора = Неопределено) Экспорт
|
||
|
||
Форма = ПолучитьФорму(,,);
|
||
Форма.Открыть();
|
||
Отбор = Форма.ЭлементыФормы.ТаблицаЖурнала.ОтборСтрок;
|
||
Отбор.Сбросить();
|
||
Если НачалоПериода <> Неопределено Тогда
|
||
Форма.НачалоПериода = НачалоПериода;
|
||
КонецЕсли;
|
||
Если КонецПериода <> Неопределено Тогда
|
||
Форма.КонецПериода = КонецПериода;
|
||
КонецЕсли;
|
||
Если СтруктураОтбора <> Неопределено Тогда
|
||
Для Каждого КлючИЗначение Из СтруктураОтбора Цикл
|
||
Отбор[КлючИЗначение.Ключ].Установить(КлючИЗначение.Значение);
|
||
КонецЦикла;
|
||
КонецЕсли;
|
||
Возврат Форма;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьИмяСвойстваБезМета(Знач МестноеИмя) Экспорт
|
||
|
||
Если ирНеглобальный.СтрокиРавныЛкс(Прав(МестноеИмя, 4), "мета") Тогда
|
||
МестноеИмя = Лев(МестноеИмя, СтрДлина(МестноеИмя) - 4);
|
||
КонецЕсли;
|
||
Возврат МестноеИмя;
|
||
|
||
КонецФункции
|
||
|
||
Процедура ОбновитьСвойстваВТерминахМетаданных(ВыбранныеСтроки = Неопределено) Экспорт
|
||
|
||
Если ВыбранныеСтроки = Неопределено Тогда
|
||
ВыбранныеСтроки = ТаблицаЖурнала;
|
||
КонецЕсли;
|
||
Индикатор = ЛксПолучитьИндикаторПроцесса(ТаблицаЖурнала.Количество(), "Перевод в термины метаданных");
|
||
Для Каждого СтрокаТаблицыЖурнала Из ВыбранныеСтроки Цикл
|
||
ЛксОбработатьИндикатор(Индикатор);
|
||
ЗаполнитьСвойстваСИменамиМетаданных(СтрокаТаблицыЖурнала);
|
||
КонецЦикла;
|
||
ЛксОсвободитьИндикаторПроцесса();
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОбновитьСтрокиБазовогоУровня() Экспорт
|
||
|
||
//Индикатор = ЛксПолучитьИндикаторПроцесса(ТаблицаЖурнала.Количество());
|
||
Для Каждого СтрокаТаблицыЖурнала Из ТаблицаЖурнала Цикл
|
||
//ЛксОбработатьИндикатор(Индикатор);
|
||
ЗаполнитьСтрокуБазовогоУровня(СтрокаТаблицыЖурнала);
|
||
КонецЦикла;
|
||
//Для Каждого СтрокаКонтекста Из Контексты Цикл
|
||
// ЗаполнитьСтрокуБазовогоУровня(СтрокаКонтекста);
|
||
//КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаполнитьТекстSDBLБезПараметров() Экспорт
|
||
|
||
Индикатор = ЛксПолучитьИндикаторПроцесса(ТаблицаЖурнала.Количество());
|
||
Для Каждого СтрокаТаблицыЖурнала Из ТаблицаЖурнала Цикл
|
||
ЛксОбработатьИндикатор(Индикатор);
|
||
Если Истина
|
||
И СтрокаТаблицыЖурнала.ТекстSDBL <> ""
|
||
И СтрокаТаблицыЖурнала.ТекстБезПараметровSDBL = ""
|
||
Тогда
|
||
СтрокаТаблицыЖурнала.ТекстБезПараметровSDBL = RegExpПараметры.Replace(СтрокаТаблицыЖурнала.ТекстSDBL, "&P");
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ОставитьТолькоСтрокиПоОтбору(СтруктураОтбора) Экспорт
|
||
|
||
НужныеСтроки = ТаблицаЖурнала.НайтиСтроки(СтруктураОтбора);
|
||
КоличествоСтрок = ТаблицаЖурнала.Количество();
|
||
Для Счетчик = 1 По КоличествоСтрок Цикл
|
||
Индекс = КоличествоСтрок - Счетчик;
|
||
СтрокаЖурнала = ТаблицаЖурнала[Индекс];
|
||
Если НужныеСтроки.Найти(СтрокаЖурнала) = Неопределено Тогда
|
||
ТаблицаЖурнала.Удалить(СтрокаЖурнала);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура УдалитьСтрокиПоОтбору(СтруктураОтбора) Экспорт
|
||
|
||
НенужныеСтроки = ТаблицаЖурнала.НайтиСтроки(СтруктураОтбора);
|
||
Для Каждого НенужнаяСтрока Из НенужныеСтроки Цикл
|
||
ТаблицаЖурнала.Удалить(НенужнаяСтрока);
|
||
КонецЦикла;
|
||
|
||
КонецПроцедуры
|
||
|
||
Процедура ЗаписатьМаркерВТехножурнал(Маркер, ДляКлиента = Истина, ДляСервера = Истина) Экспорт
|
||
|
||
Если ДляКлиента Тогда
|
||
ЗапросМаркер = Новый Запрос();
|
||
ЗапросМаркер.Текст = Маркер;
|
||
Попытка
|
||
ЗапросМаркер.Выполнить(); // Генерируем для клиента маркер-событие QERR
|
||
Исключение
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
Если Истина
|
||
И ДляСервера
|
||
И Не ирКэш.ЭтоФайловаяБазаЛкс()
|
||
Тогда
|
||
Попытка
|
||
ирСервер.ВыполнитьЗапросЛкс(Маркер); // Генерируем для сервереа маркер-событие QERR
|
||
Исключение
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
|
||
КонецПроцедуры
|
||
|
||
Функция НачатьТрассу(ПрефиксТрассы = "", ВыводитьСообщения = Ложь) Экспорт
|
||
|
||
// Попробовать сделать проверку регистрации событий QERR в настройке техножурнала на сервере
|
||
Если Не ирКэш.ЭтоФайловаяБазаЛкс() Тогда
|
||
ТехножурналСервераВключен = ирНеглобальный.ЛиТехножурналВключенЛкс(Истина, ВыводитьСообщения);
|
||
КонецЕсли;
|
||
ТехножурналКлиентаВключен = ирНеглобальный.ЛиТехножурналВключенЛкс(, ВыводитьСообщения);
|
||
Если Истина
|
||
И ТехножурналСервераВключен <> Истина
|
||
И Не ТехножурналКлиентаВключен
|
||
Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
ЭтотОбъект.КонецПериодаСервера = Неопределено;
|
||
ЭтотОбъект.КонецПериодаКлиента = Неопределено;
|
||
ЭтотОбъект.НачалоПериодаСервера = ирНеглобальный.ПолучитьТекущуюДатуЛкс(Истина);
|
||
ЭтотОбъект.НачалоПериодаКлиента = ирНеглобальный.ПолучитьТекущуюДатуЛкс(Ложь);
|
||
мИдентификаторТрассы = ПрефиксТрассы + "_" + СтрЗаменить(Новый УникальныйИдентификатор(), "-", "");
|
||
ЗаписатьМаркерВТехножурнал("НачалоТрассы_" + мИдентификаторТрассы);
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
Функция КончитьТрассу() Экспорт
|
||
|
||
Если ЗначениеЗаполнено(ЭтотОбъект.КонецПериодаКлиента) Тогда
|
||
Возврат Ложь;
|
||
КонецЕсли;
|
||
ЭтотОбъект.КонецПериодаСервера = ирНеглобальный.ПолучитьТекущуюДатуЛкс(Истина);
|
||
ЭтотОбъект.КонецПериодаКлиента = ирНеглобальный.ПолучитьТекущуюДатуЛкс(Ложь);
|
||
ЗаписатьМаркерВТехножурнал("КонецТрассы_" + мИдентификаторТрассы);
|
||
Возврат Истина;
|
||
|
||
КонецФункции
|
||
|
||
#Если Клиент Тогда
|
||
|
||
Функция ПоказатьТрассу(УдалитьДополнительныеСобытия = Истина, ИменаНеполезныхКолонок = "", ПопытокЧтения = 10, СмещениеБазовогоУровня = Неопределено) Экспорт
|
||
|
||
Если ЭтотОбъект.КонецПериодаСервера = Неопределено Тогда
|
||
Предупреждение("Сформируйте трассу заново");
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
ОчиститьТаблицуЖурнала();
|
||
ЖурналПрочитан = ПрочитатьСобственныйЖурналДвухСторон(УдалитьДополнительныеСобытия, ИменаНеполезныхКолонок, Истина, ПопытокЧтения, СмещениеБазовогоУровня);
|
||
Если Не ЖурналПрочитан Тогда
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
ВыраниватьДатуПоСерверу = ВосстановитьЗначение("ирАнализТехножурнала.ВыраниватьДатуПоСерверу") = Истина;
|
||
лКаталогЖурнала = КаталогЖурнала;
|
||
ФормаАнализа = ПолучитьФорму();
|
||
ФормаАнализа.ЭтоТрасса = Истина;
|
||
ФормаАнализа.Открыть();
|
||
ФормаАнализа.ЗагружатьТолькоТекущийСеанс = Истина;
|
||
ФормаАнализа.ЗагружатьЖурналКлиента = Истина;
|
||
ФормаАнализа.ЗагружатьЖурналСервера = Не ирКэш.ЭтоФайловаяБазаЛкс();
|
||
Если ВыраниватьДатуПоСерверу Тогда
|
||
ФормаАнализа.КонецПериода = КонецПериодаСервера;
|
||
ФормаАнализа.НачалоПериода = НачалоПериодаСервера;
|
||
Иначе
|
||
ФормаАнализа.КонецПериода = КонецПериодаКлиента;
|
||
ФормаАнализа.НачалоПериода = НачалоПериодаКлиента;
|
||
КонецЕсли;
|
||
ФормаАнализа.КаталогЖурнала = лКаталогЖурнала;
|
||
ФормаАнализа.ИтогиВключены = ТаблицаЖурнала.Количество() > 20;
|
||
ФормаАнализа.ИтогиВключеныПриИзменении();
|
||
ФормаАнализа.ПериодПоследниеМинуты = 0;
|
||
ФормаАнализа.ОбновитьДоступность();
|
||
ФормаАнализа.ЭлементыФормы.ПанельНастройки.ТекущаяСтраница = ФормаАнализа.ЭлементыФормы.ПанельНастройки.Страницы.Анализ;
|
||
ФормаАнализа.УстановитьБесполезныеКолонки(ИменаНеполезныхКолонок);
|
||
Возврат ФормаАнализа;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОчиститьТаблицуЖурнала() Экспорт
|
||
|
||
мНепустыеКолонкиЖурнала = Новый Структура();
|
||
ТаблицаЖурнала.Очистить();
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
Функция ОткрытьРоднойТекстSDBL(ТекстSDBL, ОткрытьСтраницуЗапроса = Истина, КлючУникальности = Неопределено) Экспорт
|
||
|
||
ФормаЗапроса = ПолучитьФорму("КонверторВМета", , КлючУникальности);
|
||
ФормаЗапроса.ЭлементыФормы.ТекстБД.УстановитьТекст(ТекстSDBL);
|
||
Если ОткрытьСтраницуЗапроса Тогда
|
||
ПанельОсновная = ФормаЗапроса.ЭлементыФормы.ПанельОсновная;
|
||
ПанельОсновная.ТекущаяСтраница = ПанельОсновная.Страницы.ТекстСМетаданными;
|
||
КонецЕсли;
|
||
ФормаЗапроса.Открыть();
|
||
Возврат Неопределено;
|
||
|
||
КонецФункции
|
||
|
||
#КонецЕсли
|
||
|
||
Функция ПреобразоватьЗначениеВSDBL(Ссылка) Экспорт
|
||
|
||
СтруктураБД = ирКэш.ПолучитьСтруктуруХраненияБДЛкс();
|
||
СтруктураПоиска = Новый Структура("Метаданные, Назначение", Ссылка.Метаданные().ПолноеИмя(), "Основная");
|
||
СтрокаТаблицы = СтруктураБД.НайтиСтроки(СтруктураПоиска)[0];
|
||
RegExp = ирКэш.Получить().RegExp;
|
||
RegExp.Pattern = "\d+";
|
||
РезультатПоиска = RegExp.Execute(СтрокаТаблицы.ИмяТаблицыХранения);
|
||
Текст = РезультатПоиска.Item(0).Value + ":" + ЛксПолучитьГУИДИнверсныйИзПрямого("" + Ссылка.УникальныйИдентификатор());
|
||
Возврат Текст;
|
||
|
||
КонецФункции
|
||
|
||
Функция ПолучитьСтруктуруЗапросаИзТекстаSDBL(ТекстSDBL) Экспорт
|
||
|
||
RegExp = мПлатформа.RegExp;
|
||
RegExp.Pattern = "([A-F0-9]+):([A-F0-9]+|0x[A-F0-9]+)"; // анализа и замены значений параметров
|
||
Вхождения = RegExp.Execute(ТекстSDBL);
|
||
Текст = ТекстSDBL;
|
||
//ТаблицаПараметров = Новый ТаблицаЗначений;
|
||
//ТаблицаПараметров.Колонки.Добавить("ЗначениеSDBL", Новый ОписаниеТипов("Строка"));
|
||
//ТаблицаПараметров.Колонки.Добавить("Значение");
|
||
//ТаблицаПараметров.Колонки.Добавить("Имя", Новый ОписаниеТипов("Строка"));
|
||
ТаблицаПараметров = ПараметрыЗапроса.ВыгрузитьКолонки();
|
||
ТаблицаПараметров.Индексы.Добавить("ЗначениеSDBL");
|
||
ТаблицаПараметров.Индексы.Добавить("Имя");
|
||
Для Каждого Вхождение Из Вхождения Цикл
|
||
ЗначениеSDBL = Вхождение.Value;
|
||
Если ТаблицаПараметров.Найти(ЗначениеSDBL, "ЗначениеSDBL") = Неопределено Тогда
|
||
ЗначениеПараметра = ирНеглобальный.ПреобразоватьЗначениеИзSDBLЛкс(ЗначениеSDBL);
|
||
Если ЗначениеПараметра <> Неопределено Тогда
|
||
СтрокаПараметра = ирНеглобальный.НайтиДобавитьПараметрСсылкуВТаблицуЛкс(ТаблицаПараметров,,, ЗначениеПараметра);
|
||
СтрокаПараметра.ЗначениеSDBL = ЗначениеSDBL;
|
||
ОбъектМД = ЛксПолучитьМетаданные(ЗначениеПараметра);
|
||
Если ОбъектМД <> Неопределено Тогда
|
||
СтрокаПараметра.Метаданные = ОбъектМД.ПолноеИмя();
|
||
КонецЕсли;
|
||
Текст = СтрЗаменить(Текст, ЗначениеSDBL, "&" + СтрокаПараметра.Имя);
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
RegExp.Pattern = "#(T[\d" + мПлатформа.шБуква + "]+)"; // анализа и замены значений параметров
|
||
Текст = RegExp.Replace(Текст, "_$1");
|
||
ТаблицаТаблиц = Новый ТаблицаЗначений;
|
||
ТекстМета = ПолучитьЗапросВТерминахМетаданных(Текст,,,,ТаблицаТаблиц);
|
||
ТаблицаТаблиц.Сортировать("ИмяМета");
|
||
Результат = Новый Структура();
|
||
Результат.Вставить("Текст", ТекстМета);
|
||
Результат.Вставить("Параметры", ТаблицаПараметров);
|
||
Результат.Вставить("Таблицы", ТаблицаТаблиц);
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
Функция НайтиВызовыМетодовМодулей(ИмяМодуля, НомерНачальнойСтроки, НомерКонечнойСтроки, ТолькоОдну = Истина)
|
||
|
||
Результат = Новый Массив();
|
||
Для Каждого СтрокаТаблицы Из ТаблицаЖурнала Цикл
|
||
ФрагментыНачальнойСтрокиМодуля = ЛксПолучитьМассивИзСтрокиСРазделителем(СтрокаТаблицы.СтрокаМодуля, ":", Истина);
|
||
Если ФрагментыНачальнойСтрокиМодуля[0] <> ИмяМодуля Тогда
|
||
Результат.Вставить(0, СтрокаТаблицы);
|
||
Если ТолькоОдну Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
НомерСтрокиМодуля = Число(ФрагментыНачальнойСтрокиМодуля[1]);
|
||
Если Ложь
|
||
Или НомерСтрокиМодуля < НомерНачальнойСтроки
|
||
Или НомерСтрокиМодуля > НомерКонечнойСтроки
|
||
Тогда
|
||
Результат.Вставить(0, СтрокаТаблицы);
|
||
Если ТолькоОдну Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
Возврат Результат;
|
||
|
||
КонецФункции
|
||
|
||
// Получить словарь имен таблиц входящих в запрос и соответствующих
|
||
// шаблонам словаря метаданных
|
||
//
|
||
// Параметры:
|
||
// ТекстЗапроса - Строка, текст запроса для которого строится словарь
|
||
// СловарьШаблоновМетаданных - Соответствие, словарь шаблонов метаданных
|
||
// ТипСУБД - Строка (Перечисление.ТипСУБД)
|
||
//
|
||
// Возвращаемое значение:
|
||
// Соответствие - Словарь имен таблиц запроса
|
||
//
|
||
Функция ПолучитьСловарьЗапроса(Знач ТекстЗапроса, СловарьШаблоновМетаданных, ТипСУБД = "") Экспорт
|
||
|
||
Перем КоличествоСимволов;
|
||
|
||
ТекстЗапроса = НРег(ТекстЗапроса);
|
||
ДлинаТекстаЗапроса = СтрДлина(ТекстЗапроса);
|
||
СловарьЗапроса = Новый Соответствие;
|
||
|
||
//Если НРег(ТипСУБД) = НРег("DB2") Тогда
|
||
// ТекстЗапроса = ВРег(ТекстЗапроса);
|
||
//КонецЕсли;
|
||
ЗавершающиеСимволы = " )(.,][" + Символы.ПС + Символы.ВК;
|
||
|
||
Для Каждого СтрокаСловаряМетаданных Из СловарьШаблоновМетаданных Цикл
|
||
|
||
// Скопировать текст запроса для обработки
|
||
Текст = ТекстЗапроса;
|
||
|
||
// Искать имя таблицы по шаблону
|
||
Пока Истина Цикл
|
||
|
||
// Получить начало шаблона
|
||
Если СтрокаСловаряМетаданных.Значение = 0 Тогда
|
||
Шаблон = СтрокаСловаряМетаданных.Ключ;
|
||
Иначе
|
||
Шаблон = Лев(СтрокаСловаряМетаданных.Ключ, Найти(СтрокаСловаряМетаданных.Ключ, "1") - 1);
|
||
КонецЕсли;
|
||
|
||
ЭлементСловаря = Неопределено;
|
||
ДлинаШаблона = СтрДлина(Шаблон);
|
||
ДлинаТекста = СтрДлина(Текст);
|
||
|
||
// Найти позицию вхождения шаблона в тексте запроса
|
||
ПозицияШаблона = Найти(Текст, Шаблон);
|
||
|
||
// Если шаблона в тексте запроса нет, прекратить поиск этого шаблона
|
||
Если ПозицияШаблона = 0 Или ДлинаТекста < ПозицияШаблона + ДлинаШаблона - 1 Тогда
|
||
Прервать;
|
||
КонецЕсли;
|
||
|
||
// Удалить из текста запроса обработанный фрагмент
|
||
Текст = Прав(Текст, ДлинаТекста - ПозицияШаблона - ДлинаШаблона + 1);
|
||
ЭлементСловаря = Шаблон;
|
||
|
||
// Если шаблон содержит счетчик
|
||
Если СтрокаСловаряМетаданных.Значение <> 0 Тогда
|
||
|
||
// Получить значение счетчика
|
||
ЗначениеЧисла = ПолучитьЧислоСтрокой(Текст, КоличествоСимволов);
|
||
|
||
Если ЗначениеЧисла = Неопределено Тогда
|
||
ЭлементСловаря = Неопределено;
|
||
Продолжить;
|
||
КонецЕсли;
|
||
|
||
// Удалить из текста запроса текстовое представление счетчика имени
|
||
ЭлементСловаря = ЭлементСловаря + ЗначениеЧисла;
|
||
Текст = Прав(Текст, СтрДлина(Текст) - КоличествоСимволов);
|
||
|
||
// Если счетчиков больше одного
|
||
Для Сч = 1 По СтрокаСловаряМетаданных.Значение - 1 Цикл
|
||
|
||
// Получить следующий фрагмент шаблона
|
||
ПозицияПервогоСлота = Найти(СтрокаСловаряМетаданных.Ключ, Строка(Сч));
|
||
ПозицияВторогоСлота = Найти(СтрокаСловаряМетаданных.Ключ, Строка(Сч + 1));
|
||
ФрагментШаблона = Сред(СтрокаСловаряМетаданных.Ключ, ПозицияПервогоСлота + 1, ПозицияВторогоСлота - ПозицияПервогоСлота - 1);
|
||
ДлинаФрагментаШаблона = СтрДлина(ФрагментШаблона);
|
||
ДлинаТекста = СтрДлина(Текст);
|
||
|
||
Если ДлинаФрагментаШаблона > ДлинаТекста Или Лев(Текст, ДлинаФрагментаШаблона) <> ФрагментШаблона Тогда
|
||
ЭлементСловаря = Неопределено;
|
||
Прервать;
|
||
КонецЕсли;
|
||
|
||
// Получить значение счетчика для фрагмента шаблона
|
||
Текст = Прав(Текст, ДлинаТекста - ДлинаФрагментаШаблона);
|
||
ЗначениеЧисла = ПолучитьЧислоСтрокой(Текст, КоличествоСимволов);
|
||
Текст = Прав(Текст, СтрДлина(Текст) - КоличествоСимволов);
|
||
|
||
Если ЗначениеЧисла = Неопределено Тогда
|
||
ЭлементСловаря = Неопределено;
|
||
Прервать;
|
||
КонецЕсли;
|
||
|
||
// Дополнить имя таблицы найденым значением шаблона
|
||
ЭлементСловаря = ЭлементСловаря + ФрагментШаблона + ЗначениеЧисла;
|
||
КонецЦикла;
|
||
|
||
Если ЭлементСловаря = Неопределено Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
// Если найдено имя таблицы по шаблону
|
||
Если ЭлементСловаря <> Неопределено Тогда
|
||
ДлинаТекста = СтрДлина(Текст);
|
||
|
||
// Проверить окончание имени для полного соответствия шаблону
|
||
Если ДлинаТекста > 0 Тогда
|
||
ЗавершающийСимвол = Лев(Текст, 1);
|
||
Текст = Прав(Текст, ДлинаТекста - 1);
|
||
Если Найти(ЗавершающиеСимволы, ЗавершающийСимвол) = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
КонецЕсли;
|
||
|
||
// Сохранить найденное имя таблицы
|
||
СловарьЗапроса.Вставить(ЭлементСловаря);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
КонецЦикла;
|
||
|
||
Возврат СловарьЗапроса;
|
||
|
||
КонецФункции // ПолучитьСловарьЗапроса()
|
||
|
||
// Получить число из строки в которой число находится в начале строки
|
||
//
|
||
// Праметры:
|
||
// ИсходнаяСтрока - Строка, строка в которой находится число
|
||
//
|
||
// Возвращаемое значение:
|
||
// Число - если оно есть, неопределено, если числа нет
|
||
//
|
||
Функция ПолучитьЧислоСтрокой(ИсходнаяСтрока, КоличествоСимволов)
|
||
|
||
КоличествоСимволов = 0;
|
||
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
|
||
|
||
Для Сч = 1 По ДлинаСтроки Цикл
|
||
|
||
ТекущийСимвол = КодСимвола(Сред(ИсходнаяСтрока, Сч, 1));
|
||
|
||
Если 48 <= ТекущийСимвол И ТекущийСимвол <= 57 Тогда
|
||
КоличествоСимволов = КоличествоСимволов + 1;
|
||
Иначе
|
||
Прервать;
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
Если КоличествоСимволов > 0 Тогда
|
||
Возврат Лев(ИсходнаяСтрока, КоличествоСимволов);
|
||
Иначе
|
||
Возврат Неопределено;
|
||
КонецЕсли;
|
||
|
||
КонецФункции // ПолучитьЧислоСтрокой()
|
||
|
||
// Перевести часть запроса из терминов СУБД в термины метаданных
|
||
//
|
||
// Параметры:
|
||
// Запрос - Строка, сапрос в терминах СУБД
|
||
// СтруктураХраненияБазыДанных - ТаблицаЗначений
|
||
// СловарьШаблоновМетаданных - Соответствие, подробности в функции
|
||
// ПолучитьСловарьШаблоновМетаданных()
|
||
// ТипСУБД - Строка, (Перечисление.ТипСУБД)
|
||
// выхТаблицы - ТаблицаЗначений, *Неопределено - описание использованных в тексте таблиц, заполняется только если таблица передана (без колонок)
|
||
//
|
||
// Возвращаемое значение:
|
||
// Строка, запрос в терминах метаданных
|
||
//
|
||
Функция ПолучитьЗапросВТерминахМетаданных(Знач Запрос, СтруктураХраненияБазыДанных = Неопределено,
|
||
СловарьШаблоновМетаданных = Неопределено, Знач ТипСУБД = "", выхТаблицы = Неопределено) Экспорт
|
||
|
||
Если ирНеглобальный.СтрокиРавныЛкс(ТипСУБД, "sdbl") Тогда
|
||
ТипСУБД = "";
|
||
КонецЕсли;
|
||
Если СтруктураХраненияБазыДанных = Неопределено Тогда
|
||
СтруктураХраненияБазыДанных = ирКэш.ПолучитьСтруктуруХраненияБДЛкс(ЗначениеЗаполнено(ТипСУБД));
|
||
КонецЕсли;
|
||
Если СловарьШаблоновМетаданных = Неопределено Тогда
|
||
СловарьШаблоновМетаданных = ирКэш.ПолучитьСловарьШаблоновМетаданных(ЗначениеЗаполнено(ТипСУБД));
|
||
КонецЕсли;
|
||
|
||
Запрос = Запрос + Символы.ПС;
|
||
СловарьЗапроса = ПолучитьСловарьЗапроса(Запрос, СловарьШаблоновМетаданных, ТипСУБД);
|
||
|
||
Если НРег(ТипСУБД) = НРег("DB2") Тогда
|
||
Запрос = ВРег(Запрос);
|
||
КонецЕсли;
|
||
|
||
// Поиск имен таблиц в строке запроса
|
||
Если СловарьЗапроса.Количество() > 10 Тогда
|
||
Индикатор = ЛксПолучитьИндикаторПроцесса(СловарьЗапроса.Количество(), "Преобразование в имена метаданных");
|
||
КонецЕсли;
|
||
Если выхТаблицы <> Неопределено Тогда
|
||
#Если _ Тогда
|
||
выхТаблицы = Новый ТаблицаЗначений;
|
||
#КонецЕсли
|
||
выхТаблицы.Колонки.Очистить();
|
||
выхТаблицы.Колонки.Добавить("ИмяБД", Новый ОписаниеТипов("Строка"));
|
||
выхТаблицы.Колонки.Добавить("ИмяМета", Новый ОписаниеТипов("Строка"));
|
||
//выхТаблицы.Колонки.Добавить("ПсевдонимБД", Новый ОписаниеТипов("Строка"));
|
||
//выхТаблицы.Колонки.Добавить("ПсевдонимМета", Новый ОписаниеТипов("Строка"));
|
||
КонецЕсли;
|
||
Для Каждого СтрокаСловаряЗапроса Из СловарьЗапроса Цикл
|
||
Если Индикатор <> Неопределено Тогда
|
||
ЛксОбработатьИндикатор(Индикатор);
|
||
КонецЕсли;
|
||
Если выхТаблицы <> Неопределено Тогда
|
||
ОписаниеТаблицы = выхТаблицы.Добавить();
|
||
ОписаниеТаблицы.ИмяБД = СтрокаСловаряЗапроса.Ключ;
|
||
КонецЕсли;
|
||
// Получить имя таблицы
|
||
СтрокаСтруктуры = СтруктураХраненияБазыДанных.Найти(СтрокаСловаряЗапроса.Ключ, "КраткоеИмяТаблицыХранения");
|
||
Если СтрокаСтруктуры = Неопределено Тогда
|
||
// Видимо чужие метаданные
|
||
Продолжить;
|
||
КонецЕсли;
|
||
ИмяТаблицы = СтрокаСтруктуры.КраткоеИмяТаблицыХранения;
|
||
МетаПолноеИмяТаблицы = СтрокаСтруктуры.ИмяТаблицы;
|
||
// Антибаг платформы 8.2.16 http://partners.v8.1c.ru/forum/thread.jsp?id=1090307#1090307
|
||
Если ПустаяСтрока(МетаПолноеИмяТаблицы) Тогда
|
||
МетаПолноеИмяТаблицы = "";
|
||
Если ЗначениеЗаполнено(СтрокаСтруктуры.Метаданные) Тогда
|
||
МетаПолноеИмяТаблицы = СтрокаСтруктуры.Метаданные + ".";
|
||
КонецЕсли;
|
||
МетаПолноеИмяТаблицы = МетаПолноеИмяТаблицы + СтрокаСтруктуры.Назначение;
|
||
КонецЕсли;
|
||
Синонимы = ПолучитьСинонимы(Запрос, ИмяТаблицы, МетаПолноеИмяТаблицы, ТипСУБД);
|
||
//Синонимы.Вставить(ИмяТаблицы, МетаИмяТаблицы);
|
||
Если выхТаблицы <> Неопределено Тогда
|
||
ОписаниеТаблицы.ИмяМета = МетаПолноеИмяТаблицы;
|
||
КонецЕсли;
|
||
|
||
Для Каждого СтрокаПоля Из СтрокаСтруктуры.Поля Цикл
|
||
Если Найти(Запрос, СтрокаПоля.ИмяПоляХранения) = 0 Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
// Заменить имя поля
|
||
МетаИмяПоля = ?(ПустаяСтрока(СтрокаПоля.ИмяПоля), СтрокаПоля.ИмяПоляХранения, СтрокаПоля.ИмяПоля);
|
||
RegExpМета.Pattern = шГраничныйСимволИмени + СтрокаПоля.ИмяПоляХранения + шГраничныйСимволИмени;
|
||
// Можно оптимизировать путем создания шаблона мультизамены
|
||
Запрос = RegExpМета.Replace(Запрос, "$1" + МетаИмяПоля + "$2");
|
||
КонецЦикла;
|
||
Для Каждого Синоним Из Синонимы Цикл
|
||
// Заменить псевдоним таблицы
|
||
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")
|
||
Или ирНеглобальный.СтрокиРавныЛкс(Синоним, "ORDER")
|
||
Или ирНеглобальный.СтрокиРавныЛкс(Синоним, "THEN")
|
||
Тогда
|
||
Продолжить;
|
||
КонецЕсли;
|
||
Синонимы.Вставить(Синоним, ПсевдонимТаблицы + "_" + Синоним);
|
||
КонецЦикла;
|
||
|
||
Возврат Синонимы;
|
||
|
||
КонецФункции // ПолучитьСинонимы()
|
||
|
||
мПлатформа = ирКэш.Получить();
|
||
мНепустыеКолонкиЖурнала = Новый Структура();
|
||
//ЭтотОбъект.НаложениеПриДозагрузкеСекунд = 30;
|
||
RegExpПараметры = мПлатформа.ПолучитьНовыйВычислительРегулярныхВыражений();
|
||
RegExpПараметры.IgnoreCase = Истина;
|
||
RegExpПараметры.Global = Истина;
|
||
RegExpПараметры.Pattern = "[A-F0-9]+:[A-F0-9]+|0x[A-F0-9]+"; // для стирания значений параметров
|
||
RegExpМета = мПлатформа.ПолучитьНовыйВычислительРегулярныхВыражений();
|
||
RegExpМета.IgnoreCase = Истина;
|
||
RegExpМета.Global = Истина;
|
||
|
||
мСписокКолонок = Новый СписокЗначений;
|
||
мСписокКолонок.Добавить("Name", "Событие"); // В некоторых случаях нужно
|
||
мСписокКолонок.Добавить("SrcName", "Источник");
|
||
мСписокКолонок.Добавить("OSThread", "ПотокОС");
|
||
мСписокКолонок.Добавить("process", "ТипПроцессаОС");
|
||
мСписокКолонок.Добавить("p:processName", "Инфобаза");
|
||
мСписокКолонок.Добавить("t:clientID", "Соединение_");
|
||
мСписокКолонок.Добавить("t:applicationName", "Приложение");
|
||
мСписокКолонок.Добавить("t:computerName", "Компьютер");
|
||
мСписокКолонок.Добавить("t:connectID", "TCPСоединение");
|
||
мСписокКолонок.Добавить("SessionID", "Сеанс");
|
||
мСписокКолонок.Добавить("Usr", "Пользователь");
|
||
мСписокКолонок.Добавить("OSException", "ИсключениеОС");
|
||
мСписокКолонок.Добавить("ClientID", "Клиент");
|
||
мСписокКолонок.Добавить("Interface", "Интерфейс");
|
||
мСписокКолонок.Добавить("Method", "Метод");
|
||
мСписокКолонок.Добавить("Exception", "ТипИсключения");
|
||
мСписокКолонок.Добавить("Descr", "Описание");
|
||
мСписокКолонок.Добавить("ClientComputerName", "КомпьютерКлиента");
|
||
мСписокКолонок.Добавить("ServerComputerName", "КомпьютерСервера");
|
||
мСписокКолонок.Добавить("UserName", "Пользователь");
|
||
мСписокКолонок.Добавить("ConnectString", "СтрокаСоединения");
|
||
мСписокКолонок.Добавить("ProcessName", "ТипПроцессаОС");
|
||
мСписокКолонок.Добавить("SrcProcessName", "Инфобаза");
|
||
мСписокКолонок.Добавить("Trans", "Транзакция");
|
||
мСписокКолонок.Добавить("Func", "Действие");
|
||
мСписокКолонок.Добавить("Sdbl", "ТекстSDBL");
|
||
мСписокКолонок.Добавить("dbpid", "ПроцессСУБД");
|
||
мСписокКолонок.Добавить("Sql", "ТекстСУБД");
|
||
мСписокКолонок.Добавить("NParams", "КоличествоПараметров");
|
||
мСписокКолонок.Добавить("Rows", "ЧислоСтрок");
|
||
мСписокКолонок.Добавить("RowsAffected", "ЧислоИзменныхСтрок");
|
||
мСписокКолонок.Добавить("planSQLText", "ПланСУБД");
|
||
мСписокКолонок.Добавить("Context", "Контекст");
|
||
мСписокКолонок.Добавить("CatName", "КаталогСУБД");
|
||
мСписокКолонок.Добавить("FileName", "ФайлСУБД");
|
||
мСписокКолонок.Добавить("DeadlockConnectionIntersections", "Взаимоблокировка");
|
||
мСписокКолонок.Добавить("Finish", "ПричинаЗавершения");
|
||
|
||
// Свойства найденные экспериментально. Они не документированы.
|
||
мСписокКолонок.Добавить("FileWild", "FileWild");
|
||
мСписокКолонок.Добавить("LocaleName", "LocaleName");
|
||
мСписокКолонок.Добавить("To", "To");
|
||
мСписокКолонок.Добавить("From", "From_");
|
||
мСписокКолонок.Добавить("ToCat", "ToCat");
|
||
мСписокКолонок.Добавить("FromCat", "FromCat");
|
||
мСписокКолонок.Добавить("Move", "Move");
|
||
мСписокКолонок.Добавить("tableName", "tableName");
|
||
мСписокКолонок.Добавить("What", "What");
|
||
мСписокКолонок.Добавить("Index", "Index_");
|
||
мСписокКолонок.Добавить("Result", "Result");
|
||
мСписокКолонок.Добавить("Prm", "Prm");
|
||
|
||
мТаблицаКолонок = Новый ТаблицаЗначений;
|
||
мТаблицаКолонок.Колонки.Добавить("ВнутреннееИмя", Новый ОписаниеТипов("Строка"));
|
||
мТаблицаКолонок.Колонки.Добавить("ИмяВТаблице", Новый ОписаниеТипов("Строка"));
|
||
мТаблицаКолонок.Индексы.Добавить("ВнутреннееИмя");
|
||
мТаблицаКолонок.Индексы.Добавить("ИмяВТаблице");
|
||
мЧисловыеСвойства = Новый Структура;
|
||
мСоответствиеКолонок = Новый Соответствие;
|
||
Для Каждого ЭлементСписка Из мСписокКолонок Цикл
|
||
мСоответствиеКолонок.Вставить(ЭлементСписка.Значение, ЭлементСписка.Представление);
|
||
СтрокаСоответствия = мТаблицаКолонок.Добавить();
|
||
СтрокаСоответствия.ВнутреннееИмя = ЭлементСписка.Значение;
|
||
СтрокаСоответствия.ИмяВТаблице = ЭлементСписка.Представление;
|
||
Если Метаданные().ТабличныеЧасти.ТаблицаЖурнала.Реквизиты[ЭлементСписка.Представление].Тип.СодержитТип(Тип("Число")) Тогда
|
||
мЧисловыеСвойства.Вставить(ЭлементСписка.Представление);
|
||
КонецЕсли;
|
||
КонецЦикла;
|
||
|
||
мКартыФайлов = Новый ТаблицаЗначений;
|
||
мКартыФайлов.Колонки.Добавить("ПолноеИмяФайла", Новый ОписаниеТипов("Строка"));
|
||
мКартыФайлов.Колонки.Добавить("Сигнатура", Новый ОписаниеТипов("Строка"));
|
||
мКартыФайлов.Колонки.Добавить("ОтборПоСеансу");
|
||
мКартыФайлов.Колонки.Добавить("ПозицияНачала", Новый ОписаниеТипов("Число"));
|
||
мКартыФайлов.Колонки.Добавить("ПозицияКонца", Новый ОписаниеТипов("Число"));
|
||
мКартыФайлов.Колонки.Добавить("НачалоПериода", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Колонки.Добавить("КонецПериода", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Колонки.Добавить("ДатаИзменения", Новый ОписаниеТипов("Дата"));
|
||
мКартыФайлов.Индексы.Добавить("ПолноеИмяФайла, Сигнатура, ОтборПоСеансу");
|
||
|
||
мСвойстваСИменамиБД = Новый Массив();
|
||
мСвойстваСИменамиБД.Добавить("ТекстSDBL");
|
||
мСвойстваСИменамиБД.Добавить("ТекстСУБД");
|
||
мСвойстваСИменамиБД.Добавить("ПланСУБД");
|
||
мСвойстваСИменамиБД.Добавить("ТекстБезПараметровSDBL");
|
||
мСвойстваСИменамиБД.Добавить("Взаимоблокировка");
|
||
|
||
мСерверныеТипыПроцессов = Новый Структура;
|
||
мСерверныеТипыПроцессов.Вставить("_adminprocess"); // ##AdminProcess##
|
||
мСерверныеТипыПроцессов.Вставить("_rphost");
|
||
мСерверныеТипыПроцессов.Вставить("_rmngr");
|
||
мСерверныеТипыПроцессов.Вставить("_ragent");
|
||
|
||
шБуква = мПлатформа.шБуква;
|
||
шГраничныйСимволИмени = "([^&" + шБуква + "\d]|^|$)";
|
||
|
||
|