<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55
global $wpdb2;
global $failure;
global $file_hist;
///// echo '<H2><b>Старт загрузки</b></H2><br>';
$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
///// echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
{ foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\
Рекомендую изучение подобной темы начинать с описания работы кэшей на ИТС:
— Объектный кэш
— Транзакционный кэш
— Кэш представлений ссылок
Также полезно техножурналом смотреть сначала запросы модели базы данных (SDBL), т.к. в них меньше «мусора» и лучше видна логика работы платформы.
(1) Это все понятно:) Но мое стремление было — увидеть своими глазами, что делает СУБД. Ибо документация может и не отражать всех особенностей.
Как бы известно, что если по ссылке получаешь реквизит, например:
ЗаказСсылка.Номер
то из СУБД считывается целиком объект со всеми реквизитами и табличными частями
поэтому, если нужно считать 1 или несколько реквизитов из сложного объекта, типа документа, то рекомендуют делать это через Запрос
Своими глазами ты например не увидел проверку в СУБД версии данных при обращении к объекту, находящемуся в объектном кэше.
(4) Видел вполне себе… Все-пре-все наблюдения — не было целью описать.
(5) Ну статья же вроде обещает рассказать «что при этом делает СУБД». Считаю, что без упоминания запроса проверки версии данных статья лишена важного элемента.
(6) Принято. Подумаю, как дополнить. Но с другой стороны, такими проверками особо не порулить.
А какие поля опрашиваются при вызове метода «Представление» в запросе?
(8) Точно! Хотел ведь глянуть итоговый такой запрос. К концу сегодня (28.02) докину пример.
Про обращение к константе добавь
Про разделители напиши
Про то, как изменятся запрос при применении RLS тоже важно было бы упомянуть
(8)
(6)
пардон не туда нажал
(9)Не забудьте заодно и про метод «ПРЕДСТАВЛЕНИЕССЫЛКИ» и про свойство «.Представление»
В БСП с целью оптимизации обращения с СУБД как раз и используется
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита, ВыбратьРазрешенные = Ложь).
Не пренебрегайте этой функцией и, тем самым, сократите время выполнения кода.
Дописал про ПРЕДСТАВЛЕНИЕССЫЛКИ / ПРЕДСТАВЛЕНИЕ.
Попытался. В самописную конфу вставил функцию из БСП.
Задача: приСозданииНаСервере() в реквизит «кладовщик» прописать значение реквизита «сотрудник» справочника «Пользователи». Ссылка на пользователя находится в параметре сеанса «ТекущийПользователь»:
p.s. неудачно скриншоты получились.
Там где обращение тупо кладовщикВыдачи = ПараметрыСеанса.ТекущийПользователь.Сотрудник время 0,003309, а там где КладовщикВыдачи = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ПараметрыСеанса.ТекущийПользователь,»Сотрудник»); время 0,039332 — ровно на порядок. Может пример неудачный?
Статья как уже заметил (1) не достаточно объективная.
Что решит обычный разработчик прочитав ее?
«Получать через точку не выгодно».
А на самом деле зачастую выгоднее получать через «.» особенно если объект это какой то НСИ который редко меняется.
Т.к. с высокой долей вероятности значение всех полей уже есть в кэше и чтение из БД не потребует чтения из базы.
В то время как использование функций БСП гарантированно приводит к чтению данных.
Так например обращение к реквизиту формы через «.» с вероятностью 90% приведет к чтению кэша а не к получению данных из ИБ.
Думаю что для полноты статьи нужно провести эксперименты с учетом кэширования.
Кэширование повышает риск недостоверности данных. оптимизируется не скорость, а надежность.
Здравствуйте !
я не верю, что Сообщить(Строка(Валюта)); не считывает весь объект. Вы запускали эту команду первой, или Вы запускаете ее, когда объект помещен в кэш ?
(18) Я писал в публикации, что при нескольких разыменованиях используется кеширование.
А вообще, я вопрос не понял. Во что вы таки не верите?
(19) я считаю, что Сообщить(Строка(Валюта)); должен считать весь объект, если раньше не было объектного чтения для переменной «Валюта». Profiler мне пока недоступен.
(20) Ну не знаю:) Запросы из профайлера, вам, видимо, не аргумент. Но и ваш аргумент «не верю» — слабоват. Поэтому либо верьте, либо не верьте, либо проверяйте тех.журналом.
(21) запросы из Профайлера для меня нормальный аргумент. Я просто спрашиваю: было ли перед командой Сообщить(Строка(Валюта)) объектное чтение переменной Валюта или нет ?
(22) Нет, конечно. Ведь основная цель была не в исследовании кеширования.
Хотелось бы такой же проверки для более новых версий платформы (8.3.14 — 8.3.15)
Могу ошибаться, но вроде как обещали изменить поведение при чтении стандартных реквизитов (номер, дата и т.д.)
(24) Про изменение поведения тоже краем уха слышал. Для себя спланировал, что как выйдет следующий релиз 14 платформы (после 1779), так и займусь.
(16) Уот так уот, оказывается методами БСП невыгодно получать реквизит. Нонсенс!
Давайте поможем Даше получить оптимальнее контрагента из ссылки на заказ.
Вариант 1. Через точку. При этом считаются все реквизиты, табличные части из СУБД. В лучшем случае из кеша. Но в кеш то надо еще получить!
Вариант 2. Управляемый. С помощью запроса за 3 мс получить значение нужного реквизита без мусора. Гарантировано всегда быстро.
Ах да, писатели типовых ведь сплошь стажеры, придумали фигню, лучше бы всю базу в кеш затолкали, а чего, быстро же будет!
(18) для случая Сообщить(Валюта) точно не считывает — в этом случае платформа понимает, что нужно получить только представление объекта, оно кэшируется. А вот для случая преобразования в строку — это вопрос, но он по сути не имеет смысла, т.к. этот код в любом случае методическая ошибка.
(24) Планирую заняться подобными исследованиями на 8.3.16.1063.
Кому что интересно — пишите.
Пока что в ближайших планах — проверить вычитывание ТЧ и стандартные реквизиты (код, номер, дата).
Прошу не писать про кеширование — по максимуму буду избегать его использование.