Категории

понедельник, 7 апреля 2014 г.

Запуск и адаптация МАРК-SQL 1.5.4 для MySQL 5.x

Столкнулся с проблемой, АИБС "МАРК-SQL" для школьных библиотек 1.5.4 не работала с MySQL, а разработчики заверяли, что программа не совместима с MySQL.
Решил проанализировать запросы, которые ходят между программой и сервером при помощи MySQL-Proxy [2].
И сразу увидел некорректный запрос с использованием зарезервированного слова "SEPARATOR":
SELECT TAG,SUBTAG,FLAGS,SEPARATOR,CAPTION FROM TAG
После добавления обратных кавычек к зарезервированному слову SEPARATOR [1] запрос выполнился в MySQL без проблем:
SELECT TAG,SUBTAG,FLAGS,`SEPARATOR`,CAPTION FROM TAG
Значит для нормальной работы программы АИБС "МАРК-SQL" для школьных библиотек 1.5.4 нужно ловить каждый запрос, и если требуется, экранировать зарезервированные слова MySQL на лету. С этой задачей вполне успешно справится MySQL-Proxy [2] с поддержкой lua [4] скриптов.
После установки, запуска MySQL-Proxy и подключения lua скрипта:
function MyDebug(str)
        -- enable\disable debug messages print to stdout.
        local dbg = 0
        if dbg == 1 then
                print('[DEBUG] ' .. str)
        end
end

function read_query(packet)
        local file = io.open('/var/log/mysql-proxy.log', 'a')
        local q = string.sub(packet, 2)

        MyDebug('Orig. Query: ' .. q)
        file:write('Orig. Query: ' .. q .. '\n')

        -- Таблица зарезервированных слов MySQL.
        -- http://dev.mysql.com/doc/mysqld-version-reference/en/mysqld-version-reference-reservedwords-5-7.html

        q = string.gsub(q, '(SEPARATOR)', '`%1`')
        q = string.gsub(q, '(INT%d)', '`%1`')

        -- Исправление поискового запроса (захардкоженного в marcp.exe) и регистронезависимый поиск.
        local _,_,str1,str2,str3 = string.find(q,"SELECT TERM,CNT FROM (.-) WHERE TERM%s*>=%s*('.-')%s(.*)") -- TODO: проверить всегда ли передаются кавычки в поле WHERE TERM >= ''.
        if str1 ~= nil and str2 ~= nil and str3 ~= nil then
                MyDebug('str1: ' .. str1); MyDebug('str2: ' .. str2); MyDebug('str3: ' .. str3)
                str2 = string.gsub(str2, "^'", '') -- Delete start '.
                str2 = string.gsub(str2, "'$", '') -- Delete end '.
                MyDebug('Fixed str2: ' .. str2)
                q = string.format("SELECT TERM,CNT FROM %s WHERE LOWER(TERM) LIKE LOWER('%s%%') %s",str1,str2,str3)
        end

        -- Исправляем кавычки в запросе.
        q = string.gsub(q, 'SELECT CODE,NAME FROM%s+"(.+)"%s*(.*)', 'SELECT CODE,NAME FROM `%1` %2') -- Del start '.

        MyDebug('Fixed query: ' .. q .. '\n')
        file:write('Fixed query: ' .. q .. '\n')
        file:close()

        proxy.queries:append(2, string.char(proxy.COM_QUERY) .. q, {resultset_is_needed = true})

        return proxy.PROXY_SEND_QUERY
end

function read_query_result(inj)
        if inj.id == 1 and inj.resultset.rows ~= nil then
                local file = io.open('/var/log/mysql-proxy.log', 'a')
                for row in inj.resultset.rows do
                local i = 1
                local fields = {}
                while row[i] do
                        if row[i] == row then break end
                                file:write('Response field: ' .. inj.resultset.fields[i].name .. ' => ' .. row[i] .. '\n')
                                i = i + 1
                        end
                end
                file:close()
                return proxy.PROXY_IGNORE_RESULT
        end
end

В ходе экспериментов для подключения к БД был получен такой конфиг dns.ini для работы с MySQL:
Универс|DRIVER=MySQL ODBC 5.2 Unicode Driver;NO_SSPS=1;MULTI_STATEMENTS=1;AUTO_RECONNECT=1;LOG_QUERY=0;IGNORE_SPACE=1;COMPRESSED_PROTO=1;NO_PROMPT=1;CHARSET=cp1251;DATABASE=marcsql;SERVER=192.168.4.26;PORT=4040;UID=marcsql;PASSWORD=password;
Описание некоторых опций:
  • NO_SSPS=1; - Включение подстановок на стороне клиента, а не сервера (т.е. запросы в которых есть знаки "?").
  • COMPRESSED_PROTO=1; - Включение сжатия (немного повышается скорость работы с большими результатами запросов).
  • NO_PROMPT=1; - Отключение окна запроса, при переподключении к БД.
  • CHARSET=cp1251; - Кодировка в которой будет идти обмен между сервером и клиентом (программа для Windows и работает в cp1251).
  • BASE=marcsql; - Имя базы.
  • SERVER=192.168.4.26; - Адрес сервера MySQL-Proxy.
  • PORT=4040; - Порт на котором работает MySQL-Proxy.
  • UID=marcsql; - Логин, для подключения к БД.
  • PASSWORD=password; - Пароль, для подключения к БД.
Но на этом рано останавливаться, нужно еще привести в порядок запросы в файлах программы да и самой программе объяснить, что мы будем использовать MySQL, а не MS Access: Добавляем в конец информацию о MySQL в bin/db.ini:
[Mysql]

ScriptPath=..\sql\Mysql
CreateTempTable=CREATE TABLE &Table&TabSuf(DOC_ID INTEGER PRIMARY KEY)
DictQuery=SELECT TERM,CNT FROM &Table
В файле DbmsParams.ini:
[Mysql]

$VARCHAR=VARCHAR
$COUNTER=INT AUTO_INCREMENT
$DOUBLE=FLOAT
$LONGTEXT=TEXT
$LONGBINARY=TEXT
$MIDTEXT=TEXT
$TEXT=TEXT
$DBPREF_=marcsql.
$COLUMN=
$TOP1000=
$ALTERCOLUMN=ALTER COLUMN
Добавляем информацию о возрастном маркере в EditMap.ini:
[333a]
EditForm=TECombo
ComboValues=0+  Для дошкольного возраста,6+  Для младшего школьного возраста,12+ Для среднего школьного возраста,16+ Для старшего школьного возраста,18+ Для взрослых
TagValues=Для дошкольного возраста,Для младшего школьного возраста,Для среднего школьного возраста,Для старшего школьного возраста,Для взрослых
Separator=,
OnlyFormEdit=Yes
DefaultMenu=NO

[200e]
EditForm=TECombo
ComboValues=[0+],[6+],[12+],[16+],[18+]
TagValues=[0+],[6+],[12+],[16+],[18+]
Separator=,
OnlyFormEdit=Yes
DefaultMenu=NO
Добавляем редактор LibreOffice в файле marc.ini в секцию [Editors]:
[Editors]

LibreOffice=swriter.exe
Изменяем файл phase.ini под потребности нашей школы:
[Книги]

CreateTags=245anpbco,100ae,700ae,653a,520a,020ac,090ax,084a,110a,260abc,440a,650a,200e,300ab,333a,952be,526cde,250a,998а,773b,773d,773t,773g,013ddee
EditTags=245,100,700,653,520,020,090,084,110,200,260,440,650,300,333,952,526,250,998,773
ViewTags=100a,100e,700a,700e,245a,245b,245o,245p,245n,260a,260b,260c,300a,300b,333a,440a,020a,020c,650a,090a,090x,084a
ShowAllTags=YES
RecType=a
BibLevel=m
В файле RdrData.ini, в секции [Common] исправляем запрос LastReaderQuery:
LastReaderQuery=SELECT RDR_ID FROM &ReadersPrefREADERS ORDER BY LEN(RDR_ID) DESC, RDR_ID DESC LIMIT 1
Теперь SQL файлы, заходим в каталог sql:
Была проблема при удалении записей из таблиц словарей, исправляется в файле delidx.sql: Ищем строку:
DELETE FROM &Table WHERE CNT=0;
Заменяем её на:
DELETE FROM &Table WHERE CNT<=0;
Исправляем проблему с удалением данных из таблицы METAIDX ищем в файле dropdict.sql строку:
DELETE FROM METAIDX WHERE NAME='&Table.TERM'
Заменяем её на:
DELETE FROM `METAIDX` WHERE `NAME` = '&Table.`TERM`';
DELETE FROM `METAIDX` WHERE `NAME` = '&Table.TERM';
Теперь создаем каталог Mysql и копируем все файлы из каталога Access в созданный каталог Mysql (напоминаю, мы должны быть в каталоге sql). Другими словами мы должны получить копию папки sql/Acess, но по адресу sql/Mysql. И приводим в порядок файлы в каталоге sql/Mysql: Файл crdict.sql приводим к такому виду:
INSERT INTO METAIDX(`NAME`,`TYPE`,`MAXLEN`,`TAGS`,`CAPTION`,`SEP`) VALUES('&Table.`TERM`','&Type',&MaxLen,'&Taglist','&Caption','&Sep');

CREATE TABLE &Table (
 `IDX_ID` INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
 `TERM` VARCHAR(&MaxLen),
 `CNT` INTEGER);

CREATE TABLE `&TableX` (
 `IDX_ID` INTEGER NOT NULL,
 `DOC_ID` INTEGER NOT NULL,
 FOREIGN KEY(`IDX_ID`) REFERENCES `&Table`(`IDX_ID`));

CREATE INDEX &TableXB ON &TableX(`DOC_ID`);
CREATE INDEX &TableXC ON &TableX(`IDX_ID`);
Файл rebuild.sql приводим к такому виду:
DROP TABLE IF EXISTS `IDXTEMP`;

CREATE TABLE `IDXTEMP` (`DOC_ID` INTEGER, &Term Text);
$BUILD;
$Инициализация таблицы индексов;
DELETE FROM &TableX;
DELETE FROM &Table;
$Заполнение таблицы индексов;
INSERT INTO &Table(&Term,CNT) SELECT &Term, Count(&Term) FROM IDXTEMP GROUP BY &Term;
$Заполнение таблицы перекрестных ссылок;
INSERT INTO &TableX(IDX_ID,DOC_ID) SELECT &Table.IDX_ID,IDXTEMP.DOC_ID FROM &Table,IDXTEMP
WHERE IDXTEMP.&Term=&Table.&Term;
$Удаление временной таблицы;
DROP TABLE IDXTEMP;
На этом изменения в файлах программы окончены. Пришло время конвертировать базу, я конвертировал при помощи BullZip Access To MySQL[6], на выходе получил .sql файл, который был скопирован на сервер и залит в БД. На этом все.

1. Reserved Words in MySQL 5.0
2. Download MySQL Proxy
3. Download Connector/ODBC
4. 20.1 – Pattern-Matching Functions
5. MySQL On air. Мониторим SQL запросы
6. Access To MySQL
7. MySQL и MarcSQL
8. Версия АИБС "МАРК-SQL" для школьных библиотек находится в свободном доступе для российских школ.

1 комментарий:

GTFXR1ffEyGy комментирует...

We suggest trying elsewhere for your on-line on line casino entertainment if you can’t locate a licence number. If you suspect you studied} another player on a playing web site just isn't over 18, let the site know via email or reside chat. The state of affairs on the other aspect of the ocean was much less complicated until the creation of Las Vegas happened. Bets have been before that placed primarily in old style bars, which were not a pleasant place thecasinosource.com for novices and inexperienced players. Gambling could be addictive, so please play responsibly and moderately. Please go to the Responsible Gaming web page for more info.

Отправить комментарий