Быстрая распаковка CF




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?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='\

30 Comments

  1. baton_pk

    > Если есть необходимость, могу сделать версию для Linux.

    Lazarus?

    Reply
  2. cmd_vasec

    Зачем необходимо делать распаковку CF-файла?

    Reply
  3. Magister

    (1)

    Да

    (2)

    Например, для этого: http://infostart.ru/public/106310/

    Reply
  4. СергейКа

    При попытке просмотра выдает ошибку (скрин приложен).

    Это к чему?

    Reply
  5. Magister

    (4) Или битый файл или глюк в программе.

    Если нет ничего секретного — выложите файл, на котором есть ошибка, посмотрю.

    Reply
  6. СергейКа

    (5) Скорее всего не с файлом проблема.

    Пробовал на 5 разных конфигурациях — все время эта ошибка.

    При этом распаковка в каталог происходит нормально.

    Система XP SP3.

    На компе администратор, с правами не может быть проблема.

    Reply
  7. Magister

    (6) Тем не менее, скриншот я ведь не с потолка взял 🙂

    Дайте пример, мне нужно увидеть ошибку на конкретном файле — тогда что-то получится.

    И да, я тестировал только на Windows 7. XP у меня нет.

    Reply
  8. pumbaE

    1. Программа вообще отказывается воспринимать кириллицу — недопустимо использование кириллистических символов и в наименовании файла распаковки и в наименовании каталога выгрузки.(предыдущая версия все-таки с кириллицей в наименовании файла распаковки работала — хотя бы из командной строки).

    2. cfu не распаковывает.

    Reply
  9. СергейКа

    (7) Посмотрел, такая проблема возникает с конфигурациями, в которых есть закрытые модули (паролем, либо отсутствующие).

    Конкретные файлы к сожалению приложить не могу, связано с корп. правилами безопасности.

    Reply
  10. Magister

    (8) Странно, проверю.

    CFU тоже проверю, на нем я вобщем-то и не тестировал…

    (9) Ясно, спасибо. Попробую создать закрытый модуль и проверю.

    Reply
  11. iceflash

    Особо не вникал, а что мешает сделать тогда и сборку обратно в cf?

    Reply
  12. Magister

    (11) А какое практическое применение этому?

    Reply
  13. semen_2008

    (12) Как какое? А восстановить битую базу. А если в конфигуратор зайти нельзя, а есть cf уже можно продолжать разработку (имею ввиду базу без данных). Да и вообще unpak 8 уже давно не поддерживается.

    Reply
  14. Magister

    (13) Восстановить битую базу — инструмент есть, V8Unpack.

    Моя программа делает ровно то же самое, но быстрее. В случае восстановления скорость разница в скорости некритична.

    И да, бекапы никто не отменял 🙂

    Так что аргумент сомнителен.



    Полезным для меня была бы разборка-сборка конфигурации в удобочитаемую структуру для использования VCS, но такого, пока что, никто не сделал. Разборку — да, сделали (V8Reader — http://infostart.ru/public/106310/). А вот обратную операцию нет.

    Reply
  15. Tango600

    При попытке распаковать конфигурацию от 8.2, выдаёт ошибку.

    Reply
  16. Magister

    (15) Эта ошибка значит, что программа вообще не смогла открыть файл.

    Права на него точно есть? Он нигде не открыт в другой программе параллельно?



    И да, выше тут писали про проблемы с кириллицей в имени файла — проверьте, чтобы в пути и имени были только латинские буквы.

    Reply
  17. MRAK

    Начинание хорошее. Ждем исправления всех косяков)

    Reply
  18. MMF

    «Полезным для меня была бы разборка-сборка конфигурации в удобочитаемую структуру для использования VCS, но такого, пока что, никто не сделал. Разборку — да, сделали (V8Reader — http://infostart.ru/public/106310/). А вот обратную операцию нет.»

    — уже лет 6 как промышленно используется в cvs и сборка и разборка. При этом разбирается не в бинарное представление, а в человекопонятное и быстрее, чем твоим. Как всегда «кто-то уже сделал до нас и лучше нас, поэтому нам есть куда расти»

    Reply
  19. Magister

    (18) Я имел ввиду доступные для всех решения.

    Про свое решение ты уже писал как-то, помню. Но выкладывать куда-либо, насколько я понял, не будешь.

    Кстати, а насколько быстрее? И интересно, а как этого можно достичь? У меня вроде как скорость упирается в диск, по крайней мере на моём ноуте (сужу по тому, что ядро процессора не постоянно загружено на 100%).

    Reply
  20. MMF

    (19) решение мое, но принадлежит заказчику http://abelov.com/rms4/index.php, запишись на удаленную разработку и получишь парсер. А как ты определил, что скорость упирается в диск? Профилирование может дать совершенно неожиданные результаты.

    Reply
  21. Magister

    (20) Определил «на глаз» — по загрузке ядра процессора. Знаю, что это не гарантированно корректный результат, к тому же на ноуте винт не шибко быстрый — наверное потому и упирается в него.

    Впрочем, немного подумал, нашел где можно оптимизировать именно распаковку — есть одно (или два?) лишних копирования данных в памяти. Но это потом, пока что делал вобщем-то как быстрее написать и при этом чтоб не сильно тормозило.

    > запишись на удаленную разработку и получишь парсер

    Записываться только ради этого совесть не позволяет 🙂

    А реально работать — времени нет, я сейчас на полный день… да и российские конфы изучать придется.

    Reply
  22. MMF

    (21) на чем писано?

    Reply
  23. Magister

    (22) Lazarus (компилятор FreePascal 2.6.1). В том числе и реализация zlib на чистом Паскале (paszlib).

    Reply
  24. MMF

    (23) можешь перекомпилить под дельфями и отпрофилировать AQTime.

    Reply
  25. andrewks

    (23) кстати, paszlib подглючивает на маленьких размерах данных. не сталкивались?

    Reply
  26. Magister

    (25) Я решил проблему тем, что всегда добавляю один нулевой байт в буфер со сжатыми данными.

    Тогда всё нормально распаковывается.

    Reply
  27. buganov

    Ошибка по нажатию на unpack — Failed to open RAW file. И вылетает. Пробовал обычные формы, управляемые, обработки. Все одно да потому. Ось вин 7 х64

    Reply
  28. buganov

    (27) buganov, блин кириллица (

    Reply
  29. lazarenko

    как можно сопоставить идентификатор объекта метаданнных с реальным, т.е. мне нужно найти конкретный объект по имени, как?

    Reply
  30. МихаилМ

    (19) если имеете ввиду объект метаданных найти в бд 1с8 , то через dbnames

    если имеете ввиду но имени метаданного найти его в конфиг — парсить весь конфиг .

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *