<?php // Полная загрузка сервисных книжек, создан 2025-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='\
много текста и сразу необходимо вникать в чьи-то проблемы
не логичнее ли в первой строке простынь ответить понятно и просто одной строкой зачем это нужно?
В 1С для этого хеш используют. Возможно вы про это не слышали?
Статью не читал!
(2) нет, не слышал, расскажите пожалуйста подробнее: от чего вычисляется хэш и какие гарантии это даёт?
(3) ну хеш это как у пароля есть контрольная сумма, которая шифруется.
Как простой пример. Зашифровать дату записи и его значения измерений. Если изменилось хоть одна запись, то хеш будет другой.
Сам не применял, но например в обработке игры в шахматы видел алгоритм.
Плюс есть регистры в типовых или нет, не скажу, которые как раз используют реквизит с одноименным названием.
На 8.3 вычисления хеша кажись уже можно платформой делать. До этого использовали компоненту.
(4) да, эта история понятна, но хэширование не дает гарантировано уникальный хэш на каждое новое значение. Хэширование дает очень высокую вероятность уникального значения, но не гарантию, поэтому в строгих алгоритмах его использовать нельзя, только для вспомогательных нужд. Об этом собственно и статья )
(5) что на 1 хеш можно 2 пароля придумать и авторизуешься?
Где такое вычитали?
(6) к этому вопросу можно подойти с двух сторон: гугла и логики.
https://en.wikipedia.org/wiki/MD5
пример двух строк с одинаковым хэшем MD5 можно найти например тут:
логически можно рассудить, что MD5 состоит из 32 шеснадцатиричных цифр 0-9,a-f. Соответственно, если мы хэшируем все варианты строк, состоящих из 33 шеснадцатиричных цифр — количества вариантов хэшей не хватит на все варианты исходных строк и какие-то строки неизбежно будут иметь одинаковые хэши
(7) да про Коллизии MD5 не слышал. Теперь в курсе.
Но там говорится про суффиксы. Не думаю что они будут отличаться в 1С. Также есть же и другие алгоритмы шифрования? И там говорится только про 128 битный ключ. А про 256 ничего.
По разделу «Мелкий шрифт», есть же концепция CRDT — бесконфликтная синхронизация данных, где данная возможность зашивается в прям в сам тип который передается.
(8) 128, 256, 512… все это будет уменьшать вероятность дублей, но не исключать их
(10) вы не поняли. хеш я так представляю формируется по перфиксам из 1С, а суффикс остается всегда один. Поэтому коллизий не будет.
Алгоритм формирования не читал.
Интересная концепция, спасибо. У меня получается state-based CRDT, я в тренде ))
Но основная то проблема в том, что когда писали РТ имели в виду strong consistency и то, что все работает — весьма интересный результат
Статью прочитал на 80-90% — всё надеялся найти в тексте обоснование, для чего это нужно в реальной задаче и не нашел.
Единственная описанная проблема: «записали набор с одной записью, выгружаем 100500». Ну допустим… А как Ваше решение поможет этого избежать? Может я что-то пропустил по тексту, но я ответа на этот вопрос не нашел.
По-моему, если надо идентифицировать набор записей ссылкой, то хорош способ, применяемый в типовых конфигурациях на УФ для контроля уникальности элементов справочника по значениям реквизитов. Это регистр сведений и справочник с одинаковым набором измерений регистра и ключевых реквизитов справочника, по которым необходимо контролировать уникальность. Я говорю про справочники КлючиАналитикиУчетаХХХХХ и регистры сведений АналитикаУчетаХХХХХ.
Ещё, так сказать, замечание не по теме.
Вы пишете такое:
На своем опыте могу утверждать, что «Новый УникальныйИдентификатор()» дает дубли при циклическом вызове. Была как-то необходимость связать строки нескольких деревьев значений на форме: при изменении значения в строке одного дерева менять также в другом дереве. Было решено для простоты генерации ключа строки использовать УникальныйИдентификатор. В общем практика показала, что он иногда НЕ уникальный. Его 99.(9)% уникальность гарантирована только в составе ссылок в рамках одной таблицы базы данных. (За годы работы более десяти баз по модели РИБ не появилось ни одного дубля ссылки среди документов одного типа, но была один раз группа номенклатуры с такой же ссылкой, как элемент в другой базе, что привело к останоке обмена, естественно).
(13)
Зачем мне это нужно — я постарался описать в спойлере «суть моей проблемы».
Вести пару РС-справочник для каждого регистра — это довольно нудное мероприятие (хотя для задачи, где задействовано 1-2-3 регистра — может подойти), плюс такой подход будет довольно затратным с точки зрения производительности
Про неуникальность ГУИДа — мое мнение — все такие случаи — это недорасследованные ошибки в коде. Я не хочу вас обидеть, у всех есть факапы, а сам я так иногда косячу, что аж п-ц, но когда в следующий раз такое увидите — ищите свой баг
(14) Я понимаю Ваше подозрение на мой баг, но после замены гуида на последовательно назначаемые номера все проблемы ушли сразу без прочих правок кода. Минус такого подхода — необходимость вести глобальный счетчик этих номеров в реквизите формы, например. Поэтому хотелось использовать гуиды.
Самое полезное, что я вынес из этой статьи — это пассаж про компьютер сайенс, и да, я этим буду пользоваться, спасибо большое! xD
Справедливости ради ДНК это не сигнатура человека — это сигнатура набора однояйцевых близнецов в общем случае)))