Страница 1 из 1

Работа с MySQL

СообщениеДобавлено: 12 окт 2008 11:37
Deniska
Eggdrop - это хорошо, но возможность хранения данных только в текстовых файлах уже не то. На данный момент большие объемы данных куда выгоднее хранить в подходящих СУБД - что и делается в большинстве программ.
В данном случае мы рассмотрим СУБД MySQL как наиболее распространенную и, поэтому, наиболее удобную для рядового пользователя.
В стандартной поставке бота нет никаких средств для работы с подобными источниками данных, но эта проблема устранена сторонними разработчиками.

mysql.mod
Сайт проекта: http://barkerjr.net/irc/eggdrop/modules/
Документация: http://wiki.barkerjr.net/wiki/MySQL_Module
Текущая версия: 0.6
Скачать: mysql.mod (win) mysql.mod (unix)
Установка
Eggdrop: Скопировать mysql.mod в папку src/mod, набрать make config, make, make install.
Поместить mysql.so в папку eggdrop/modules, загрузить модуль в eggdrop.conf командой loadmodule mysql.
Windrop: Поместить mysql.dll в папку eggdrop/modules, загрузить модуль в eggdrop.conf командой loadmodule mysql.
Команды
mysql_connect <база> <хост> [пользователь] [пароль] [сокет|порт]
Инициализирует подключение к базе данных. Если хост указан как `localhost', подключение будет осуществлено через сокет, а не по TCP порту. Сокет это путь к UNIX сокету, например /tmp/mysql.sock.

mysql_close
Закрывает текущее подключение к базе данных, освобождая используемую память.

mysql_query <запрос>
Выполняет SQL запрос и возвращает результат в виде списка. Символ конца запроса (";" - точка с запятой) автоматически дописывается в конце SQL запроса.

mysql_escape [байт] <строка>
Делает строку безопасной для запросов к MySQL. Добавляет обратные слэши(экранирует бэкслешами "\") перед одинарными кавычками, удваивает бэкслеши и т.п. Указывайте аргумент "байт" только если вы работаете с бинарными данными. Не корректное использование команды вызовет падение бота или хуже.

mysql_errno
Возвращает код последней случившейся ошибки. Список кодов ошибок доступен на: http://dev.mysql.com/doc/refman/5.0/en/error-handling.html

mysql_ping
Проверяет установлено ли подключение к серверу. Если подключение упало - будет осуществлена автоматическая попытка восстановить подключение.

mysql_connectioninfo
Если подключение установлено - возвращает список их имени базы данных, хоста, пользователя и порта/сокета.

mysql_insert_id
Возвращает ID из последнего INSERT.

mysql_connected
Возвращает true, если подключение установлено, false если нет.
Внимание: результат может быть не правильный.

mysql_affected_rows
Возвращает число записей, измененных/задействованных последним запросом

FastBase MySQL
Сайт проекта: http://www.fastbase.co.nz/fbsql/index.html
Документация: http://www.fastbase.co.nz/fbsql/fbsql.html
Текущая версия: 1.06
Скачать: fbsql.dll (win32) fbsql.c + Makefile (unix)
Этот модуль не является модулем Eggdrop - это расширение самого TCL. Проект, как и mysql.mod, так же заброшен, но модуль, как ни странно, работает под Windows, работа под UNIX - не тестировалась.
Установка
Eggdrop:
Скомпилировать fbsql.so из исходника fbsql.c. Скопировать fbsql.so, например, в папку modules. Загружать расширение командой "load fbsql.so".
Windrop:
Скопировать fbsql.dll в папку modules, необходимую версию libmySQL.dll(идёт в стандартной поставке клиента MySQL) в ту же папку, загрузить расширение командой "load fbsql.dll".
Команды
load <fbsql.dll/fbsql.so>
Команда загружает расширение fbsql и добавляет в интерпретатор TCL 6 новых команд: sql sql1 sql2 sql3 sql4 sql5. Все 6 команд абсолютно одинаковы, но они независимы друг от друга и, поэтому, могут быть использованы для доступа к разным серверам, базам или к разным результатам запросов.
sql connect [хост] [пользователь] [пароль] [база данных] [порт]
Подключается к указанному хосту (по умолчанию localhost) используя указанное имя пользователя (по умолчанию имя пользователя в системе) и пароль (если указан).
Возможность указывать хост и порт добавлена в версии 1.06. Возможность указания имени базы данных при подключении исключило необходимость использования "sql selectdb".
sql selectdb <база данных>
Использовать указанную базу данных (на UNIX системах - имя регистрозависимо).
sql disconnect
Отключиться от MySQL сервера.
sql version
Возвращает строку с информацией о FBSQL. Например, "FastBase MySQL Interface for Tcl; version 1.06".
sql [query] <запрос>
Выполняет SQL запрос, опция "query" не обязательна. Если SQL запрос возвращает результат (SELECT, DESCRIBE, SHOW, EXPLAIN), тогда возвращаемым значением будет список, где каждый элемент является так же списком, содержащим поля. Если SQL выражение не имеет возвращаемого значения (UPDATE, INSERT, DELETE), тогда и команда не имеет возвращаемого значения. Смотрите sql startquery для расширенных настроек.
sql numrows
Возвращает число строк, запрошенных последним запросом. Если последний запрос был UPDATE - команда вернет число измененных строк.
sql startquery <запрос> [-huge] [-array имя]
Выполняет SQL запрос, но не возвращает никаких данных. Выражение должно возвращать какие-нибудь значения иначе возникнет ошибка. Чтобы получить данные используйте sql fetchrow, а для прекращения запроса - sql endquery.
Опция -huge обозначает, что результат запроса может быть очень большим и, поэтому, он не будет сохранен в памяти. Эту команду нужно использовать осторожно, так как по документации MySQL функция mysql_use_result() выставляет READ LOCK на используемые в запросе таблицы до тех пор, пока запрос не будет завершен, поэтому вы не сможете использовать INSERT, UPDATE или DELETE на запрашиваемых таблицах.
Опция -array имя означает, что sql fetchrow должен присвоить значения полей ассоциативному массиву с указанным именем, то есть "set name(FIELD_NAME) $column_value" для каждого поля, где name - имя ассоциативного массива, FIELD_NAME - имя поля из таблицы в базе данных, $column_value - значение поля.
sql fetchrow
Возвращает следующую строку из результатов (см sql startquery). Если строк больше нет - возвращается пустое значение {}. Если sql startquery была вызвана с опцией -array имя, возвращаемое значение будет именем ассоциативного массива. Если опция array не была использована, тогда команда возвращает список со значениями.
sql endquery
Прекращает запрос, инициированный sql startquery. Обычно, она выполняется, если sql fetchrow возвращает пустую строку(закончились результаты запроса), но так же может быть без проблем использована и до этого.
Примеры
Использование простых SQL запросов
Код: Выделить всё
 load fbsql.dll
 sql connect 192.168.3.8 root ""
 sql selectdb test
 foreach row [sql "SELECT NUMBER, NAME FROM CUSTOMER ORDER BY NAME"] {
 set number [lindex $row 0]
 foreach row [sql "SELECT DATE, REF, TOTAL FROM TRAN WHERE CUSTOMER_NO = $customer(NUMBER) ORDER BY DATE, REF"] {
 set tran(DATE) [lindex $row 0]
 set tran(REF) [lindex $row 1]
 set tran(TOTAL) [lindex $row 2]
 # process transaction record ...
 }
 }
 sql disconnect

Использование startquery/fetchrow/endquery
Код: Выделить всё
 load fbsql.dll
 sql connect 192.168.3.8 root "" test
 sql2 connect 192.168.3.8 root "" test
 sql startquery "SELECT NUMBER, NAME FROM CUSTOMER ORDER BY NAME" -array customer
 while {[sql fetchrow] != ""} {
 sql2 startquery "SELECT * FROM TRAN WHERE CUSTOMER_NO = $customer(NUMBER) ORDER BY DATE, REF" -array tran
 while {[sql2 fetchrow] != ""} {
 # tran() array contains one element for each field (note: in this example we retrieved all fields)
 # process transaction record ...
 }
 sql2 endquery
 }
 sql endquery
 sql disconnect
 sql2 disconnect


mysqlTcl
Сайт проекта: http://www.xdobry.de/mysqltcl/
Документация: http://www.xdobry.de/mysqltcl/mysqltcl.html
Текущая версия: 3.05
Скачать: mysqltcl 3.03 (win) mysqltcl 3.05 (unix)
mysqlTcl является расширением TCL. К счастью, проект жив, дата релиза последней версии - 04.2008. Это расширение обладает куда большим, по сравнению с двумя другими интерфейсами работы с MySQL, функционалом.
Установка
Eggdrop:
Скомпилировать mysqltcl, скопировать libmysqltcl.so в папку modules, загрузить его командой "load libmysqltcl.so".
Windrop:
Скопировать libmysqltcl.dll в папку modules, скопировать туда же нужную версию libmySQL.dll, загрузить mysqltcl командой "load libmysqltcl.dll". Загружать libmySQL.dll не требуется.
Команды
Всего в mysqltcl есть 33 команды, перевод документации будет позже. Оригинал информации о командах можно посмотреть в официальной документации.

Заключение
Модуль для бота mysql.mod не всегда корректно работает с ботом Windrop и позволяет использовать только 1 подключение одновременно, что исключает возможность использовать два различных скрипта, использующих MySQL, да и вообще уменьшает возможности для манёвра. Набор возможных функций весьма не велик, да и те ( mysql_connected - конкретный пример привел Eternal + упоминается в описании модуля ) работают не всегда корректно. 3 место за старательность и за "нативность" по отношению к боту.
Расширение FBSQL для TCL - уже на порядок лучше. По-прежнему бедный синтаксис, но поддержка до 6 возможных подключений. Всё еще не то, но 2е место за несколько одновременных подключений и стабильность работы на разных платформах.
И, наконец, MySQLTCL. Все функции объявлены в отдельном пространстве имён - mysql - что, конечно же, является хорошим тоном. Богатый синтаксис, достаточный для написания скриптов различной функциональности. Не ограниченное число одновременных подключений. И, опять-таки, стабильность в работе под различными платформами. Несомненно - первое место. Использую его сам и рекомендую другим.

Re: Работа с MySQL

СообщениеДобавлено: 13 окт 2008 21:10
tvrsh
Несколько примеров работы с mysql.mod (http://barkerjr.net/irc/eggdrop/modules/)

Загрузка модуля:
TCL: [ Скачать ] [ Скрыть ]
        namespace eval database {
           
               # -- Mysql Info
           
               variable dbhost "127.0.0.1"
               variable dbuser "root"
               variable dbpass "secretpass"
               variable dbname "userlist"
               variable dbconnect ""
           
               # Leave dbconnect empty!
           
               # --- Module
           
               loadmodule mysql
           
               bind evnt - "init-server" [namespace current]::dbconnect
           
           }


Соединение с базой:
TCL: [ Скачать ] [ Скрыть ]
           proc database::dbconnect init-server {
               putlog "Connecting to MySQL Server:"
               if {[catch { set database::dbconnect [mysql_connect $database::dbname $database::dbhost $database::dbuser $database::dbpass] } error]} {
                   putlog "MySQL Error:"
                   foreach x [split $error \n] {
                       putlog "$x"
                   }
                   putlog "End of error."
               } else {
                   putlog "Connected to MySQL."
                   putlog "Database: $database::dbname"
                   mysql_query "CREATE TABLE IF NOT EXISTS `userlist` ( `nickname` varchar(100) NOT NULL, `hostname` varchar(100) NOT NULL )"
           
               }
           }


Проверка на наличие юзера в базе:
TCL: [ Скачать ] [ Скрыть ]
           proc isadded {nick} {
               set nick_ident *!*@[lindex [split [getchanhost $nick] "@"] 1]
               if {[mysql_query "SELECT `nickname` FROM `userlist` WHERE `hostname` = '[mysql_escape $nick_ident]'"] == ""} {
                   return "0"
               } else {
                   return "1"
               }
           }

Вернет 0 если юзер не добавлен и 1 если успешно добавлен.

Добавление юзера в базу:
TCL: [ Скачать ] [ Скрыть ]
           proc addnick {nick} {
               set nick_ident *!*@[lindex [split [getchanhost $nick] "@"] 1]
               if {[isadded $nick] == "1"} {
                   return "allready added"
               } else {
                   mysql_query "INSERT INTO `userlist` ( nickname , hostname  ) VALUES ( '[mysql_escape $nick]' , '[mysql_escape $nick_ident]'  )"
                   return "added you in the tabel"
               }
           }


Получаем хост ника добавленного в базу:
TCL: [ Скачать ] [ Скрыть ]
           proc hostname {nick} {
               set nick_ident *!*@[lindex [split [getchanhost $nick] "@"] 1]
               if {[set hostname1 [mysql_query "SELECT `hostname` FROM `userlist` WHERE `hostname` = '[mysql_escape $nick_ident]'"]] == ""} {
                   return "0"
               } else {
                   return "[join $hostname1]"
               }
           }

Вернет 0 если юзер не добавлен.

Удаление юзера из базы:
TCL: [ Скачать ] [ Скрыть ]
           proc delnick {nick} {
               set nick_ident *!*@[lindex [split [getchanhost $nick] "@"] 1]
               if {[isadded $nick] == "0"} {
                   return "didn`t found $nick in the database"
               } else {
                   mysql_query "DELETE FROM `userlist` WHERE `nickname` = '[mysql_escape $nick]' AND `hostname` = '[mysql_escape $nick_ident]';"
                   return "Deleted you from database"
               }
           }


Теперь вы имеете представление о соединении с базой, добавлении/удалении/поиска в базе.

Вольный перевод поста http://tclhelp.net/unb/227