Автор: Алексей Паутов.
Источник: RussianLDP:MySQL
Имеется список всех системных переменных, которые используются MySQL непосредственно или косвенно. Большинство их также может быть найдено в других местах в этом руководстве.
Обратите внимание, что любые параметры в командной строке будут иметь приоритет над значениями, определенными в файлах конфигурации и системных переменных, а значения в файлах конфигурации всегда имеют приоритет над значениями в системных переменных.
DBI_USER | Заданный по умолчанию пользователь для интерфейса Perl DBI. |
DBI_TRACE | Используется при трассировке Perl DBI. |
HOME | Заданный по умолчанию путь для файла
хронологии mysql , обычно $HOME/.mysql_history. |
LD_RUN_PATH | Используется, чтобы определить, где
находится Ваша библиотека libmysqlclient.so . |
MYSQL_DEBUG | Опции трассировки при отладке. |
MYSQL_HISTFILE | Путь к файлу хронологии
mysql . |
MYSQL_HOST | Заданное по умолчанию имя хоста,
используемое подсказкой командной строки mysql . |
MYSQL_PWD | Заданный по умолчанию пароль при
соединении с mysqld . Обратите внимание, что использование этой
возможности задания пароля опасно! |
MYSQL_TCP_PORT | Заданный по умолчанию порт TCP/IP. |
MYSQL_UNIX_PORT | Сокет по умолчанию. Используется
для связи с localhost . |
PATH | Используется оболочкой для поиска программ и утилит пакета MySQL. |
TMPDIR | Каталог, где будут созданы временные таблицы или файлы. |
TZ | Это должно быть установлено к Вашей зоне местного времени. Подробности в разделе "11.4.6 Проблемы часового пояса". |
UMASK_DIR | Создание каталога пользователя будет
выполнено с данной маской прав доступа. Обратите внимание, что это значение
будет использовано в операции AND с UMASK ! |
UMASK | То же самое, но для создания файлов. |
USER | Заданный по умолчанию пользователь в
Windows, чтобы использовать при соединении с mysqld .
|
Перед отправкой отчета об ошибке или вопроса сделайте следующее:
Если Вы не можете найти ответ в руководстве или архиве, проконсультируйтесь с Вашим локальным экспертом MySQL. Если Вы все еще не можете найти ответ на Ваш вопрос, читайте следующий раздел относительно того, как послать запрос на mysql@lists.mysql.com.
Написание хорошего отчета об ошибке требует немало терпения, но при выполнении этого экономится много времени Вам и всем окружающим. Хороший отчет об ошибке, содержащий полный случай теста для ошибки, делает весьма вероятным скорейшее исправление проблемы. Этот раздел поможет Вам написать Ваш отчет так, чтобы Вы не тратили впустую Ваше время, выполняя действия, которые не могут ничем помочь.
Пользуйтесь скриптом mysqlbug
, чтобы генерировать отчет об
ошибке (или отчет относительно любой проблемы), если возможно. Сам
mysqlbug
может быть найден в каталоге scripts в
дистрибутиве исходного кода или (для двоичного дистрибутива) в каталоге
bin под Вашим каталогом установки MySQL. Если Вы не можете
использовать mysqlbug
, Вы должны все же включать всю необходимую
информацию, перечисленную в этом разделе.
Скрипт mysqlbug
помогает Вам сгенерировать отчет, определяя
многое из следующей информации автоматически, но если кое-что важное
отсутствует, пожалуйста, включите это в Ваше сообщение! Пожалуйста, читайте
этот раздел тщательно и удостоверьтесь, что вся информация, описанная здесь,
включена в Ваш отчет.
Нормальное место, чтобы сообщить ошибки и проблемы:
mysql@lists.mysql.com. Если Вы
можете создать случай теста, который ясно показывает ошибку, Вы должны его
послать на bugs@lists.mysql.com.
Обратите внимание, что в этом списке Вы должны только регистрировать полный
повторимый отчет ошибки, использующий скрипт mysqlbug
. Если Вы
работаете под Windows, Вы должны включить описание операционной системы и
версии MySQL. Предпочтительно, Вы должны проверить проблему при использовании
последнего устойчивого дистрибутива или версии для разработчика. Любой должен
быть способен повторить ошибку, используя только mysql test<script
на включенном случае теста или выполнить скрипт, который включен в
отчет ошибки. Все ошибки, зарегистрированные в списке bugs
,
будут исправлены или зарегистрированы в следующем выпуске MySQL! Если имеются
только маленькие изменения кода, в этом списке может быть опубликован патч.
Не забудьте, что можно ответить на сообщение, содержащее слишком много информации, но не на то, в котором полезных данных очень мало. Часто люди опускают факты потому, что они думают, что они знают причину проблемы и считают, что некоторые важнейшие детали не имеют значения. Хороший принцип: если Вы находитесь в сомнении относительно установления чего-либо, устанавливайте это! Это намного ускорит и упростит работу всем остальным.
Наиболее общие ошибки состоят в том, что люди не указывают номер версии MySQL или ОС (включая ее версию!), на которой работают. Это очень важная информация, и в 99 случаях из 100 отчет об ошибке без нее бесполезен! Часто спрашивают об ошибках, которые есть в старых версиях, но их уже нет в новых. Обновляйте софт, меньше будет проблем! Иногда ошибка платформно-зависимая, в таких ситуациях почти невозможно установить что-нибудь без того, чтобы знать операционную систему и номер версии платформы.
Не забудьте также обеспечивать информацию относительно Вашего компилятора, если это связано с проблемой. Часто люди находят ошибки в компиляторах и считают, что это проблемы MySQL. Большинство компиляторов вечно находятся в состоянии разработки и совершенствования. Чтобы определить, зависит или нет Ваша проблема от компилятора, авторы должны знать, какой именно компилятор используется. Обратите внимание, что каждая проблема компиляции должна быть расценена как отчет об ошибке и сообщена соответственно.
Самые лучшие отчеты такие, которые включают полный пример, показывающий как воспроизвести ошибку или проблему.
Если программа производит сообщение об ошибках, очень важно включить сообщение в Ваш отчет! Если мы пробуем искать данные из архива, используя сведения по этой программе лучше, чтобы присланное сообщение об ошибках точно соответствовало тому, которое программа производит. Вы никогда не должны пробовать запомнить то, что было в сообщении об ошибке, вместо этого скопируйте и вставьте сообщение в Ваш отчет!
Пожалуйста, не забудьте, что многие из тех, кто будет читать Ваш отчет,
применяют монитор в режиме с 80 символами в строке. Следовательно, при
изготовлении отчетов и примеров с использованием клиента mysql
Вы должны использовать опцию --vertical
(или завершать команду
комбинацией символов \G
) для вывода, который не превысит
доступную ширину для такого дисплея (например, инструкция EXPLAIN
SELECT
, подробности ниже).
Пожалуйста, включите следующую информацию в Ваш отчет:
mysqladmin
version
. mysqladmin
может быть найден в каталоге
bin под каталогом установок MySQL.
uname -a
.
mysqld
рухнул, Вы должны также сообщить запрос, который
потерпел крах. Вы можете обычно найти его, запуская
mysqld
с включеным протоколированием.
mysqldump --no-data db_name tbl_name1 tbl_name2 ...
. Это очень
простой и мощный способ получить информацию относительно любой таблицы в базе
данных, которая поможет создать ситуацию, соответствующую той, что у Вас.
SELECT
Вы должны всегда включать вывод
EXPLAIN SELECT ...
и по крайней мере число строк, которые
производит инструкция SELECT
. Большее количество информации,
которую Вы даете относительно Вашей ситуации, делает более вероятным, что
кто-то сможет помочь Вам! Например, следующее представляет собой пример очень
хорошо составленного отчета об ошибке (это должно быть, конечно, создано с
помощью скрипта mysqlbug
). Обратите внимание на использование
признака конца оператора \G
для инструкций, чья ширина вывода
иначе превысила бы 80 символов:
mysql> SHOW VARIABLES; mysql> SHOW COLUMNS FROM ...\G < Вывод SHOW COLUMNS> mysql> EXPLAIN SELECT ...\G < Вывод EXPLAIN> mysql> FLUSH STATUS; mysql> SELECT ...; < Короткая версия вывода из SELECT, включая время, затраченное на обработку запроса> mysql> SHOW STATUS; < Вывод SHOW STATUS>
mysqladmin variables
extended-status processlist
, чтобы обеспечить некоторую информацию о
раболте Вашей системы.
mysqldump
, и создать файл README, который
описывает Вашу проблему. Создайте сжатый архив Ваших файлов, используя
tar
и gzip
(или zip
), и передайте его
по ftp
на
ftp://support.mysql.com/pub/mysql/secret. Затем пошлите короткое описание
проблемы на bugs@lists.mysql.com.
ftp
на
ftp://support.mysql.com/pub/mysql/secret. Если данные совершенно
секретны, используйте другие имена, но это крайние меры.
mysqld
, и что Вы используете, чтобы выполнить любые программы
клиента MySQL. Параметры к программам mysqld
и
mysql
, а также скрипту configure
, часто являются
ключами к решениям и очень нужны. Во всяком случае включить их не помешает.
Если Вы используете любые модули, типа Perl или PHP, пожалуйста, включите
также номера их версий.
mysqlaccess
, mysqladmin reload
и все сообщения об
ошибках, которые Вы получили при попытке подключить! Когда Вы проверяете Ваши
привилегии, Вы должны сначала выполнить mysqlaccess
. После этого
выполните mysqladmin reload version
и попробуйте соединиться с
программой, которая создает проблему. Команда mysqlaccess
есть в
каталоге bin под каталогом установки MySQL.
parse
error
), пожалуйста, проверьте Ваш синтаксис очень тщательно! Если Вы
не можете найти что-то неправильное в нем, чрезвычайно вероятно, что Ваша
текущая версия MySQL просто не поддерживает запрос, который Вы используете.
Если Вы применяете самую свежую версию, и руководство на
http://www.mysql.com/documentation/manual.php не покрывает синтаксис,
который Вы применили, значит MySQL не поддерживает Ваш запрос. Если
руководство покрывает синтаксис, который Вы используете, но Вы имеете старую
версию MySQL, Вы должны проверить хронологию изменения MySQL, чтобы увидеть,
когда синтаксис был реализован. В этом случае следует обновить версию.
myisamchk
или
CHECK TABLE
и REPAIR TABLE
.
mysqld
никогда не должен разрушить таблицу,
если ничто не уничтожило его посреди модификации. Если Вы можете найти
причину слета mysqld
, это сильно облегчит работу.
Направьте отчет на адрес соответствующей рассылки. Может кто-то еще испытал (и возможно решил) такую проблему. Если Вы подписаны на поддержку, пишите на mysql-support@mysql.com.
Когда ответы посланы Вам индивидуально, а не списку рассылки, считается хорошим тоном суммировать ответы и послать резюме в список рассылки, чтобы все могли с ним ознакомиться и решить свои проблемы.
Если Вы полагаете, что Ваш ответ представляет широкий интерес, Вы можете отправить его в список рассылки вместо того, чтобы ответить лично индивидууму, который Вас спросил. Пожалуйста, удостоверьтесь, что Ваш ответ не дублирует другой.
Попробуйте суммировать существенную часть вопроса в Вашем ответе, не надо цитировать все первоначальное сообщение. Пожалуйста, не отправляйте сообщения почты из Вашего браузера с включенным режимом HTML! Много пользователей не читают почту в браузере.
Version 2, June 1991
Copyright © 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and modification follow.
9.4 NO WARRANTY
If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found.
one line to give the program's name and a brief idea of what it does. Copyright (C) yyyy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w and show c; they could even be mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the program, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice
This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
Version 2.1, February 1999
Copyright © 1991, 1999 Free Software Foundation, Inc. 59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some specially designated software--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
We call this license the Lesser General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a ``work based on the library'' and a ``work that uses the library''. The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
9.6 NO WARRANTY
If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the ``copyright'' line and a pointer to where the full notice is found.
one line to give the library's name and an idea of what it does. Copyright (C) year name of author This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your school, if any, to sign a ``copyright disclaimer'' for the library, if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. signature of Ty Coon, 1 April 1990 Ty Coon, President of Vice
That's all there is to it!
Эта глава описывает API, доступные для MySQL, где получить, как использовать их и так далее. C API наиболее подробно рассмотрен, поскольку был разработан авторами MySQL и послужил основой для большинства других API.
PHP представляет собой серверный, встроенный в HTML, скриптовый язык, который может использоваться, чтобы создать динамическую веб-страницу. Это содержит поддержку обращений к нескольким базам данных, включая MySQL. PHP может быть выполнен как отдельная программа или компилироваться как модуль для использования с веб-сервером Apache.
Дистрибутивы и документация доступны на web-сайте PHP.
-lz
в конце строки для компоновки с -lmysqlclient
.Два комплекта API доступны в каталоге MySQL Contrib.
Вы можете компилировать исходники MySQL для Windows с помощью Borland C++ 5.02. Исходники для Windows включают только проекты для Microsoft VC++, для Borland C++ Вы должны сделать файлы проекта самостоятельно.
Одна известная проблема с Borland C++ состоит в том, что этот компилятор
использует иное выравнивание структуры, чем VC++. Это означает, что Вы
столкнетесь с проблемами, если попробуете использовать заданную по умолчанию
библиотеку libmysql.dll
(которая компилировалась с VC++) с
Borland C++. Вы можете сделать одно действие из следующего перечня решений,
чтобы избежать этой проблемы.
mysql_init()
с NULL
в качестве
параметра, не размещая предварительно структуру MYSQL.Имеются два официально поддерживаемых драйвера JDBC для MySQL (mm driver и Reisin JDBC driver) плюс еще куча неофициальных, но на них я не буду останавливаться. Вы можете скачать копию mm driver с http://mmmysql.sourceforge.net или с http://www.mysql.com/Downloads/Contrib. Reisin driver есть на http://www.caucho.com/projects/jdbc-mysql/index.xtp. Ознакомьтесь с любой документацией по JDBC и собственной документацией драйвера для получения сведений по MySQL-специфическим свойствам.
Каталог MySQL Contrib хранит интерфейс с языком Python, написанный Joseph Skinner.
Вы можете также использовать интерфейс Python для iODBC, чтобы обратиться к серверу MySQL (пакет mxODBC).
Есть пакет Tcl at binevolve. Кроме того, каталог Contrib включает интерфейс с Tcl, основанный на msqltcl 1.50.
Каталог MySQL Contrib включает драйвер для языка Eiffel, написанный Michael Ravits.
Код C API распространяется в комплекте с MySQL. Он включен в библиотеку
mysqlclient
и позволяет программам на C обращаться к базе данных.
Многие клиенты в дистрибутиве исходного кода MySQL написаны на C. Если Вы
ищете примеры, которые показывают, как использовать C API, посмотрите код
этих клиентов. Их можно найти в каталоге clients
дистрибутива
исходного кода MySQL.
Большинство других клиентских API (кроме поддержки Java) использует
библиотеку mysqlclient
, чтобы связаться с сервером MySQL. Это
означает, что, например, Вы можете воспользоваться большинством системных
переменных, которые используются другими программами потому, что реально они
вызваны из библиотеки.
Пользователь имеет максимальный размер буфера связи. Размер буфера, который распределен первоначально (16 килобайт), автоматически увеличивается до максимального размера (максимум 16 мегабайт). Поскольку размеры буфера растут только по запросу, просто увеличивая заданное по умолчанию максимальное ограничение, Вы не заставите большее количество ресурсов использоваться. Эта проверка размера обычно применяется в сложных ситуациях.
Буфер связи должен быть достаточно большим, чтобы хранить одиночную
инструкцию SQL (для трафика "клиент-на сервер") и одну строку возвращенных
данных (для трафика "сервер-на-клиент"). Буфер связи каждого потока будет
динамически расширен до максимального ограничения, чтобы обработать любой
запрос или строку. Например, если Вы имеете значения BLOB
,
которые содержат до 16M данных, Вы должны иметь ограничение буфера связи
по крайней мере в 16M (на клиенте и на сервере сразу). Заданный по умолчанию
максимум пользователя равен 16M, но заданный по умолчанию максимум сервера
равен всего 1M. Вы можете увеличивать это, меняя значение параметра
max_allowed_packet
при запуске сервера.
Сервер MySQL сокращает каждый буфер связи до
net_buffer_length
байт после каждого запроса. Для клиентуры
размер буфера, связанного с подключением, не будет уменьшен, пока подключение
не будет закрыто.
Для программирования с потоками, обратитесь к разделу "2.8 Как делать поточные клиенты". Для создания автономной прикладной программы, которая включает клиент и сервер в той же самой программе (и не связывается с внешним сервером MySQL) обратитесь к разделу "2.9 libmysqld, библиотека встроенного сервера MySQL".
MYSQL
MYSQL_RES
SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
). Информация, возвращенная из запроса, названа набором
результатов в остатках от этого раздела.
MYSQL_ROW
mysql_fetch_row()
.
MYSQL_FIELD
MYSQL_FIELD
для каждого поля, неоднократно вызывая
mysql_fetch_field()
. Значения полей не являются частью этой
структуры, они содержатся в структуре MYSQL_ROW
.
MYSQL_FIELD_OFFSET
mysql_field_seek()
. Смещения представляют
собой номера полей внутри строки, начиная с нуля.
my_ulonglong
mysql_affected_rows()
, mysql_num_rows()
и
mysql_insert_id()
. Этот тип обеспечивает диапазон от
0
до 1.84e19
. На некоторых системах попытка
печатать значение типа my_ulonglong
не будет работать. Чтобы
отпечатать такое значение, преобразуйте его к типу unsigned long
и используйте формат вывода %lu
. Например:
printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result));
Структура MYSQL_FIELD
содержит члены, перечисленные ниже:
char * name
char * table
table
представлено пустой строкой.
char * def
mysql_list_fields()
.
enum enum_field_types type
type
может быть один из следующего:
Значение Type | Используемый тип |
FIELD_TYPE_TINY | TINYINT |
FIELD_TYPE_SHORT | SMALLINT |
FIELD_TYPE_LONG | INTEGER |
FIELD_TYPE_INT24 | MEDIUMINT |
FIELD_TYPE_LONGLONG | BIGINT |
FIELD_TYPE_DECIMAL | DECIMAL или
NUMERIC |
FIELD_TYPE_FLOAT | FLOAT |
FIELD_TYPE_DOUBLE | DOUBLE или
REAL |
FIELD_TYPE_TIMESTAMP | TIMESTAMP |
FIELD_TYPE_DATE | DATE |
FIELD_TYPE_TIME | TIME |
FIELD_TYPE_DATETIME | DATETIME |
FIELD_TYPE_YEAR | YEAR |
FIELD_TYPE_STRING | Строка (CHAR или
VARCHAR ) |
FIELD_TYPE_BLOB | BLOB или
TEXT (используйте max_length , чтобы определить
максимальную длину поля) |
FIELD_TYPE_SET | SET |
FIELD_TYPE_ENUM | ENUM |
FIELD_TYPE_NULL | NULL |
FIELD_TYPE_CHAR | Не рекомендуется: используйте
FIELD_TYPE_TINY |
IS_NUM()
, чтобы проверить имеет
или нет поле числовой тип. Передайте значение type
в
IS_NUM()
. Вернется TRUE, если поле числовое:
if (IS_NUM(field->type)) printf("Field is numeric\n");
unsigned int length
unsigned int max_length
mysql_store_result()
или mysql_list_fields()
, это
содержит максимальную длину поля. Если Вы используете
mysql_use_result()
, значение этой переменной нулевое.
unsigned int flags
flags
может иметь ноль или большее количество из следующего набора битов:
Значение Flag | Что это значит |
NOT_NULL_FLAG | Поле не может быть
NULL |
PRI_KEY_FLAG | Поле часть первичного ключа |
UNIQUE_KEY_FLAG | Поле часть уникального ключа |
MULTIPLE_KEY_FLAG | Поле часть неуникального ключа |
UNSIGNED_FLAG | Поле имеет атрибут
UNSIGNED |
ZEROFILL_FLAG | Поле имеет атрибут
ZEROFILL |
BINARY_FLAG | Поле имеет атрибут
BINARY |
AUTO_INCREMENT_FLAG | Поле имеет атрибут
AUTO_INCREMENT |
ENUM_FLAG | Поле имеет тип ENUM |
BLOB_FLAG | Поле имеет тип BLOB или
TEXT |
TIMESTAMP_FLAG | Поле имеет тип
TIMESTAMP |
BLOB_FLAG
, ENUM_FLAG
и
TIMESTAMP_FLAG
не рекомендуется потому, что они указывают тип
поля, а не атрибут типа. Предпочтительно проверить
field->type
вместо FIELD_TYPE_BLOB
,
FIELD_TYPE_ENUM
или FIELD_TYPE_TIMESTAMP
. Пример
ниже иллюстрирует типичное использование flags
:
if (field->flags & NOT_NULL_FLAG) printf("Field can't be null\n");Вы можете использовать следующие макрокоманды, чтобы определить булево состояние значения
flags
:
IS_NOT_NULL(flags) | Истина, если это поле
определено как NOT NULL |
IS_PRI_KEY(flags) | Истина, если это поле первичный ключ |
IS_BLOB(flags) | Истина, если это поле
BLOB или TEXT |
unsigned int decimals
Функции, доступные в C API, перечислены ниже и описаны более подробно в следующем разделе. Подробности в разделе "2.3 Описание функций C API".
mysql_affected_rows() |
Возвращает число строк измененных последним запросом UPDATE ,
DELETE или INSERT . |
mysql_close() | Закрывает подключение к серверу. |
mysql_connect() | Соединяется с сервером. |
mysql_change_user() | Меняет пользователя и базу данных на открытом подключении. |
mysql_character_set_name() | Возвращает имя заданного по умолчанию набора символов для подключения. |
mysql_create_db() | Создает базу данных.
Аналог команды SQL CREATE DATABASE . |
mysql_data_seek() | Ищет произвольную строку в наборе результатов запросов. |
mysql_debug() | Делает DBUG_PUSH
для заданной строки. |
mysql_drop_db() | Удаляет базу данных. Эта
функция аналогична команде SQL DROP DATABASE . |
mysql_dump_debug_info() | Заставляет сервер писать информацию отладки в файл регистрации. |
mysql_eof() | Определяет, читалась или нет последняя строка набора результатов. |
mysql_errno() | Возвращает код ошибки для вызванной недавно функции MySQL. |
mysql_error() | Возвращает текстовое сообщение об ошибке для вызванной недавно функции MySQL. |
mysql_real_escape_string() | Выходит из специальных символов в строке для использования в инструкции SQL, принимающей во внимание текущий набор символов данного подключения. |
mysql_escape_string() | Выходит из специальных символов в строке для использования в обычной инструкции SQL. |
mysql_fetch_field() | Возвращает тип следующего поля таблицы. |
mysql_fetch_field_direct() | Возвращает тип поля таблицы, по номеру поля. |
mysql_fetch_fields() | Возвращает массив всех структур поля. |
mysql_fetch_lengths() | Возвращает длины всех столбцов в текущей (актуальной) строке. |
mysql_fetch_row() | Выбирает следующую строку из набора результатов. |
mysql_field_seek() | Помещает курсор столбца в определенный параметром столбец. |
mysql_field_count() | Возвращает число столбцов результата для последнего запроса. |
mysql_field_tell() | Возвращает позицию
курсора поля, используемого для последнего вызова
mysql_fetch_field() . |
mysql_free_result() | Освобождает память, используемую набором результатов. |
mysql_get_client_info() | Возвращает информацию о версии программы-клиента. |
mysql_get_host_info() | Возвращает строку, описывающую подключение. |
mysql_get_proto_info() | Возвращает версию протокола, используемую подключением. |
mysql_get_server_info() | Возвращает номер версии сервера. |
mysql_info() | Возвращает информацию относительно недавно выполненного запроса. |
mysql_init() | Получает или инициализирует
структуру MYSQL . |
mysql_insert_id() | Возвращает ID,
сгенерированный для столбца с поддержкой AUTO_INCREMENT
предыдущим запросом. |
mysql_kill() | Уничтожает заданный поток. |
mysql_list_dbs() | Возвращает имена баз данных, соответствующие простому регулярному выражению. |
mysql_list_fields() | Возвращает имена полей, соответствующие простому регулярному выражению. |
mysql_list_processes() | Возвращает список текущих потоков сервера. |
mysql_list_tables() | Возвращает имена таблиц, соответствующие простому регулярному выражению. |
mysql_num_fields() | Возвращает число столбцов в наборе результатов. |
mysql_num_rows() | Возвращает число строк в наборе результатов. |
mysql_options() | Устанавливает опции связи
для вызова mysql_connect() . |
mysql_ping() | Проверяет работает или нет подключение с сервером, повторно соединяется по мере необходимости. |
mysql_query() | Выполняет запрос SQL, определенный как строка с нулевым символом в конце. |
mysql_real_connect() | Соединяется с сервером. |
mysql_real_query() | Выполняет запрос SQL, определенный как рассчитанная строка. |
mysql_reload() | Сообщает, чтобы сервер перезагрузил таблицы предоставления привилегий. |
mysql_row_seek() | Переходит к строке в наборе
результатов, используя значение, возвращенное из
mysql_row_tell() . |
mysql_row_tell() | Возвращает позицию курсора строки. |
mysql_select_db() | Выбирает базу данных. |
mysql_shutdown() | Закрывает сервер. |
mysql_stat() | Возвращает состояние сервера. |
mysql_store_result() | Возвращает полный набор результатов пользователю. |
mysql_thread_id() | Возвращает ID потока. |
mysql_thread_safe() | Возвращает 1, если клиент компилируется как поточно-безопасный. |
mysql_use_result() | Инициализирует копию результата строка в строку. |
Чтобы соединиться с сервером, вызовите mysql_init()
, чтобы
инициализировать драйвер подключения, затем вызовите
mysql_real_connect()
с этим драйвером (наряду с другой
информацией типа hostname, имени пользователя и пароля). При подключении
mysql_real_connect()
устанавливает флажок reconnect
(часть структуры MYSQL) в значение 1
. Этот флажок указывает, что
когда запрос не может выполняться из-за потерянного подключения, надо
попробовать повторно соединиться с сервером перед отказом. Когда Вы закончите
работу с подключением, вызовите mysql_close()
для его закрытия.
В то время как подключение активно, пользователь может посылать запросы
SQL серверу, применяя функции mysql_query()
или
mysql_real_query()
. Различие между ними в том, что
mysql_query()
ожидает, что запрос будет определен как строка с
нулевым символом в конце, в то время как mysql_real_query()
ожидает рассчитанную строку. Если несет в себе двоичные данные (которые сами
по себе могут включать нулевые байты), Вы должны использовать только
mysql_real_query()
.
Для каждого запроса не-SELECT
(например, INSERT
,
UPDATE
, DELETE
), Вы можете выяснить, сколько строк
были изменены, вызывая mysql_affected_rows()
.
Для запросов SELECT
Вы получаете выбранные строки в наборе
результатов. Обратите внимание, что некоторые инструкции подобны
SELECT
в том плане, что они возвращают строки. Сюда входят
SHOW
, DESCRIBE
и EXPLAIN
. Они должны
обработаться тем же самым методом, что и обычный SELECT
.
Имеются два пути для пользователя, чтобы обработать наборы результатов.
Один путь состоит в том, чтобы получить весь набор результатов, вызывая
mysql_store_result()
. Эта функция получает с сервера все строки,
возвращенные запросом и сохраняет их на клиенте. Второй путь инициализировать
построчный набор результатов, вызывая mysql_use_result()
. Эта
функция инициализирует поиск, но фактически не получает никаких строк.
В обоих случаях Вы обращаетесь к строкам, вызывая
mysql_fetch_row()
. В случае mysql_store_result()
mysql_fetch_row()
обращается к строкам, которые уже были выбраны
из сервера. В случае же mysql_use_result()
mysql_fetch_row()
фактически получает строку с сервера
самостоятельно. Информация относительно размера данных в каждой строке
доступна через вызов mysql_fetch_lengths()
.
После того, как Вы закончите работу с набором результатов, вызовите
mysql_free_result()
, чтобы освободить используемую память.
Два механизма поиска дополняют друг друга. Программы пользователя должны
выбрать подход, который является наиболее подходящим для их требований.
Практически же, клиентура имеет тенденцию обычно использовать
mysql_store_result()
.
Преимущество mysql_store_result()
в том, что, поскольку все
строки были переданы пользователю, Вы не только можете обращаться к строкам
последовательно, Вы можете также двигаться обратно в наборе результатов,
используя mysql_data_seek()
или mysql_row_seek()
,
чтобы изменить текущую (актуальную) позицию строки внутри набора результатов.
Вы можете также выяснять, сколько там строк, вызывая
mysql_num_rows()
. С другой стороны, требования к памяти для
mysql_store_result()
могут быть очень высоки для больших наборов
результатов, и Вы, вероятно, столкнетесь с проблемами нехватки памяти.
Преимущество mysql_use_result()
в том, что пользователь
требует меньшего количества памяти для набора результатов потому, что это
поддерживает только одну строку одновременно (и потому, что имеется меньшее
количество дополнительных распределений для заголовков, так что
mysql_use_result()
может быть быстрее). Недостаток: Вы должны
обработать каждую строку быстро, чтобы не держать занятым сервер. Вы не
имеете произвольного доступа к строкам внутри набора результатов (Вы можете
только обращаться к строкам последовательно), и Вы не знаете, сколько строк
находится в наборе результатов, пока Вы не получите их все. Кроме того, Вы
должны принять все строки, даже если Вы определяете в середине поиска, что
уже нашли ту информацию, которую Вы искали.
API позволяет клиентам ответить соответственно на запросы (получая строки
только по мере необходимости) без того, чтобы знать, является или нет запрос
SELECT
. Вы можете делать это, вызывая
mysql_store_result()
после каждого mysql_query()
(или mysql_real_query()
). Если обращение к набору результатов
прошло успешно, запросом был SELECT
, и Вы можете читать строки.
Если произошел сбой, вызовите mysql_field_count()
, чтобы
определить, должен или нет фактически ожидаться результат. Если
mysql_field_count()
возвращает ноль, запрос не возвратил никаких
данных (это показывает, что это был INSERT
, UPDATE
,
DELETE
или что-то в этом роде) и не возвратит строки. Если
mysql_field_count()
отличен от нуля, запрос должен был
возвратить строки, но не сделал этого. Это указывает, что запросом был
SELECT
, который потерпел неудачу.
Вызовы mysql_store_result()
и mysql_use_result()
позволяют Вам получать информацию относительно полей, которые составляют
набор результатов (число полей, их имена, типы и т.п.). Вы можете обращаться
к информации поля последовательно внутри строки, вызывая
mysql_fetch_field()
неоднократно, или по номеру поля внутри
строки, вызывая mysql_fetch_field_direct()
напрямую. Текущая
(актуальная) позиция курсора поля может быть изменена вызовом
mysql_field_seek()
. Установка курсора поля воздействует на
последующие обращения к mysql_fetch_field()
. Вы можете также
получать информацию для полей в любой момент, вызывая
mysql_fetch_fields()
.
Для обнаружения и сообщения об ошибках MySQL обеспечивает доступ к
информации ошибки посредством функций mysql_errno()
и
mysql_error()
. Они возвращают код ошибки или сообщение об ошибке
для последней вызванной функции, позволяя Вам определить, когда ошибка
произошла, и что это было.
В описаниях ниже параметр или значение возврата NULL
означает
NULL
в смысле языка программирования C, а не MySQL-значение
NULL
.
Функции, которые возвращают значение, возвращают указатель или целое
число. Если не определено иное, функции, возвращающие указатель, возвращают
значение не-NULL
, чтобы указать успех, или значение
NULL
, чтобы указать ошибку, а функции, возвращающие число,
возвращают целочисленный ноль, чтобы указать успех, или отличное от нуля
значение, чтобы указать ошибку. Обратите внимание, что "отличное от нуля"
означает только это. Если функциональное описание не говорит иного, не надо
проверять результат на соответствие каким-либл числам, кроме нуля.
if (result) /* правильно */ ... error ... if (result < 0) /* неправильно */ ... error ... if (result == -1) /* неправильно */ ... error ...
Когда функция возвращает ошибку, подраздел Ошибки
описания функции вносит в список возможные типы ошибок. Вы можете выяснить,
который из них произошел, вызывая mysql_errno()
. Представление
строки ошибки может быть получено, вызывая mysql_error()
.
mysql_affected_rows()
my_ulonglong mysql_affected_rows(MYSQL *mysql)
Возвращает число строк, измененных последним UPDATE
,
удаленных последним DELETE
или вставленных последней инструкцией
INSERT
. Может быть вызвана немедленно после
mysql_query()
для UPDATE
, DELETE
или
INSERT
. Для инструкции SELECT
mysql_affected_rows()
работает подобно
mysql_num_rows()
.
Целое число, большее, чем ноль, указывает количество обработанных строк.
Ноль указывает, что никакие записи обработаны не были. -1 указывает, что
запрос возвратил ошибку или то, что для запроса SELECT
mysql_affected_rows()
был вызван до вызова
mysql_store_result()
.
Нет.
mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); printf("%ld products updated",(long) mysql_affected_rows(&mysql));
Если определен флажок CLIENT_FOUND_ROWS
, при соединение с
mysqld
mysql_affected_rows()
возвратит число строк,
согласованных инструкцией WHERE
для UPDATE
.
Обратите внимание, что, когда использована команда REPLACE
,
mysql_affected_rows()
вернет 2 потому, что в этом случае одна
строка была вставлена, а затем дубликат был удален.
mysql_close()
void mysql_close(MYSQL *mysql)
Закрывает предварительно открытое подключение. mysql_close()
также освободит дескриптор подключения, указанный в mysql
, если
дескриптор был распределен автоматически mysql_init()
или
mysql_connect()
.
Нет.
Нет.
mysql_connect()
MYSQL *mysql_connect(MYSQL *mysql, const char *host, const
char *user, const char *passwd)
пытается устанавливать подключение с сервером MySQL на компьютере
host
. mysql_connect()
должна завершиться успешно
прежде, чем Вы сможете выполнить любую из функций API, за исключением
mysql_get_client_info()
.
Значения параметров такие же, как для соответствующих параметров
mysql_real_connect()
с тем различием, что параметр подключения
может быть NULL
. В этом случае C API распределяет память для
структуры подключения автоматически и освобождает ее, когда Вы вызываете
mysql_close()
. Недостаток этого подхода в том, что Вы не можете
получить сообщение об ошибке, если подключение терпит неудачу. Чтобы получать
информацию об ошибке из mysql_errno()
или
mysql_error()
, Вы должны обеспечить имеющий силу указатель
на структуру MYSQL
.
Аналогично mysql_real_connect()
.
Аналогично mysql_real_connect()
.
mysql_change_user()
my_bool mysql_change_user(MYSQL *mysql, const char *user, const
char *password, const char *db)
Меняет пользователя и заставляет базу данных, определенную как
db
, стать заданной по умолчанию (текущей) базой данных на
подключении, определенном mysql
. В последующих запросах эта база
данных будет значением по умолчанию для ссылок на таблицы, которые не
включают явный спецификатор базы данных.
Эта функция представлена в MySQL Version 3.23.3.
mysql_change_user()
терпит неудачу, если указанный
пользователь не может быть использован, или если он не имеет разрешения
использовать эту базу данных. В этом случае пользователь и база данных не
будут изменены вообще.
Параметр db
может быть установлен в NULL
, если
Вы не хотите иметь заданную по умолчанию базу данных.
Ноль для успеха. Отличное от нуля, если произошла ошибка.
Аналогично mysql_real_connect()
.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
ER_UNKNOWN_COM_ERROR
ER_ACCESS_DENIED_ERROR
ER_BAD_DB_ERROR
ER_DBACCESS_DENIED_ERROR
ER_WRONG_DB_NAME
if (mysql_change_user(&mysql, "user", "password", "new_database")) { fprintf(stderr, "Failed to change user. Error: %s\n", mysql_error(&mysql)); }
mysql_character_set_name()
const char *mysql_character_set_name(MYSQL *mysql)
Возвращает заданный по умолчанию набор символов для текущего (актуального) подключения.
Заданный по умолчанию набор символов
Нет.
mysql_create_db()
int mysql_create_db(MYSQL *mysql, const char *db)
Создает базу данных с именем db
.
Ноль, если база данных была создана успешно. Отличное от нуля, если в процессе произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
if (mysql_create_db(&mysql, "my_database")) { fprintf(stderr, "Failed to create new database. Error: %s\n", mysql_error(&mysql)); }
mysql_data_seek()
void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)
Переходит к произвольной строке в наборе результатов запроса. Это требует,
чтобы структура набора результата содержала весь результат запроса, так что
mysql_data_seek()
может использоваться только в конъюнкции с
mysql_store_result()
, но никак не с
mysql_use_result()
.
Смещение должно быть значением в диапазоне от 0 до
mysql_num_rows(result)-1
.
Нет.
Нет.
mysql_debug()
void mysql_debug(char *debug)
Делает DBUG_PUSH
с заданной строкой. Вызов
mysql_debug()
использует библиотеку отладки Fred Fish. Чтобы
использовать эту функцию, Вы должны компилировать библиотеку клиентов так,
чтобы поддерживать отладку.
Нет.
Нет.
Обращение, показанное ниже, заставляет библиотеку клиентов генерировать файл трассировки /tmp/client.trace на машине пользователя:
mysql_debug("d:t:O,/tmp/client.trace");
mysql_drop_db()
int mysql_drop_db(MYSQL *mysql, const char *db)
Удвляет базу данных, упомянутую как параметр db
.
Ноль, если база данных была удалена успешно. Отличное от нуля, если в процессе произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
if (mysql_drop_db(&mysql, "my_database")) fprintf(stderr, "Failed to drop the database: Error: %s\n", mysql_error(&mysql));
mysql_dump_debug_info()
int mysql_dump_debug_info(MYSQL *mysql)
Инструктирует сервер, чтобы писать некоторую информацию отладки в файл регистрации. Отдавший команду пользователь должен иметь привилегию process, чтобы работать.
Ноль, если команда была успешно выполнена. Отличное от нуля, если в процессе произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_eof()
my_bool mysql_eof(MYSQL_RES *result)
mysql_eof()
определяет, читалась или нет последняя
строка набора результатов.
Если Вы приобретаете результат из успешного обращения к
mysql_store_result()
, клиент получает весь набор в одной
операции. В этом случае возврат NULL
из
mysql_fetch_row()
всегда означает, что конец набора результатов
был достигнут и не нужно вызвать mysql_eof()
.
С другой стороны, если Вы используете mysql_use_result()
,
чтобы инициализировать поиск набора результата, строки набора получены с
сервера по одной, поскольку Вы вызываете mysql_fetch_row()
неоднократно. Потому что ошибка может происходить на подключении в течение
этого процесса, значение NULL
из функции
mysql_fetch_row()
не обязательно означает, что конец набора
результатов был достигнут. В этом случае, Вы можете использовать
mysql_eof()
, чтобы определить, что там случилось. Функция
mysql_eof()
возвращает значение, отличное от нуля, если конец
набора результатов был достигнут и ноль, если произошла ошибка.
Исторически mysql_eof()
предшествует стандартной функции
MySQL mysql_errno()
и mysql_error()
. Так как те
функции ошибки обеспечивают ту же самую информацию, их использование
предпочтительнее mysql_eof()
. Фактически, они обеспечивают
большее количество информации потому, что mysql_eof()
возвращает
только булево значение, в то время как функции ошибки указывают причину.
Функция mysql_eof()
возвращает значение, отличное от нуля,
если конец набора результатов был достигнут и ноль, если произошла ошибка.
Нет.
Следующий пример показывает, как Вы могли бы использовать
mysql_eof()
:
mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // Что-то делается с данными } if (!mysql_eof(result)) // mysql_fetch_row() потерпел неудачу из-за ошибки { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); }
Однако, Вы можете достичь того же самого эффекта с помощью стандартных функций обработки ошибок в MySQL:
mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // Что-то делается с данными } if (mysql_errno(&mysql)) // mysql_fetch_row() потерпел неудачу из-за ошибки { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); }
mysql_errno()
unsigned int mysql_errno(MYSQL *mysql)
Для подключения, определенного в mysql
,
mysql_errno()
возвращает код ошибки для вызванной функции
API, которая может сработать нормально или потерпеть неудачу. Значение
возврата 0 означает, что никакой ошибки не произошло. Числа сообщений об
ошибках клиента перечислены в файле заголовка MySQL errmsg.h.
Серверные ошибки перечислены в mysqld_error.h. В дистрибутиве
исходного кода MySQL Вы можете найти полный список сообщений об ошибках и их
кодов в файле Docs/mysqld_error.txt.
Значение кода ошибки. 0, если никакая ошибка не произошла.
Нет.
mysql_error()
char *mysql_error(MYSQL *mysql)
Для подключения, определенного в mysql
,
mysql_error()
возвращает сообщение об ошибках для вызванной
функции API, которая может сработать нормально или потерпеть неудачу. Пустая
строка (""
) вернется, если никакой ошибки не произошло. Это
означает, что следующие тесты эквивалентны:
if (mysql_errno(&mysql)) { // an error occurred } if (mysql_error(&mysql)[0] != '\0') { // an error occurred }
Язык сообщений об ошибках пользователя может быть изменен перекомпиляцией библиотеки клиента MySQL. В настоящее время Вы можете выбирать сообщения об ошибках на нескольких различных языках.
Символьная строка, которая описывает ошибку. Пустая строка, если никакой ошибки не произошло.
Нет.
mysql_escape_string()
Это идентично mysql_real_escape_string()
за исключением того,
что требуется подключение как первый параметр.
mysql_real_escape_string()
обработает строку согласно текущему
(актуальному) набору символов, в то время как
mysql_escape_string()
игнорирует установку charset.
mysql_fetch_field()
MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)
Возвращает определение одного столбца набора результатов как структуру
MYSQL_FIELD
. Вызовите эту функцию неоднократно, чтобы собрать
информацию относительно всех столбцов в наборе результатов.
mysql_fetch_field()
возвращает NULL
, когда все поля
уже обработаны или их не было вовсе.
mysql_fetch_field()
будет сброшен так, чтобы возвратить
информацию относительно первого поля каждый раз, когда Вы выполняете новый
запрос SELECT
. На поле, возвращенное
mysql_fetch_field()
также воздействуют обращения к
mysql_field_seek()
.
Если Вы вызвали mysql_query()
чтобы выполнить
SELECT
на таблице, но не вызвали
mysql_store_result()
, MySQL возвращает заданную по умолчанию
длину blob (8K), если Вы вызываете mysql_fetch_field()
, чтобы
спросить о длине поля типа BLOB
. Размер в 8K выбран потому, что
MySQL не знает максимальную длину для BLOB
. Это должно быть
сделано с перестраиваемой конфигурацией когда-нибудь. Как только Вы получили
набор результатов, field->max_length
хранит длину самого
большого значения для этого столбца в специфическом запросе.
Структура типа MYSQL_FIELD
для текущего (актуального)
столбца. NULL
, если никакие столбцы не обработаны.
Нет.
MYSQL_FIELD *field; while((field = mysql_fetch_field(result))) { printf("field name %s\n", field->name); }
mysql_fetch_fields()
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)
Возвращает массив всех структур MYSQL_FIELD
для набора
результатов. Каждая структура обеспечивает определение поля для одного
столбца набора результатов.
Массив структур MYSQL_FIELD
для всех
столбцов набора результатов.
Нет.
unsigned int num_fields; unsigned int i; MYSQL_FIELD *fields; num_fields = mysql_num_fields(result); fields = mysql_fetch_fields(result); for (i = 0; i < num_fields; i++) { printf("Field %u is %s\n", i, fields[i].name); }
mysql_fetch_field_direct()
MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result,
unsigned int fieldnr)
Получает код поля fieldnr
для столбца внутри набора
результатов, возвращает определение поля столбца как структура
MYSQL_FIELD
. Вы можете использовать эту функцию, чтобы получить
описание для произвольного столбца. Значение fieldnr
должно быть
в диапазоне от 0 до mysql_num_fields(result)-1
.
Структура MYSQL_FIELD
для определенного столбца.
Нет.
unsigned int num_fields; unsigned int i; MYSQL_FIELD *field; num_fields = mysql_num_fields(result); for (i = 0; i < num_fields; i++) { field = mysql_fetch_field_direct(result, i); printf("Field %u is %s\n", i, field->name); }
mysql_fetch_lengths()
unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
Возвращает длины столбцов текущей (актуальной) строки внутри набора
результатов. Если Вы планируете копировать значения поля, эта информация
также полезна для оптимизации потому, что Вы можете избежать вызова
strlen()
. Кроме того, если набор результатов содержит двоичные
данные, Вы должны использовать эту функцию, чтобы определить размер
данных потому, что функция strlen()
возвращает неправильные
результаты для любого поля, содержащего символы пробела.
Длина для пустых столбцов и для столбцов, содержащих значения
NULL
, равна нулю. Чтобы видеть, как отличить эти два случая,
обратитесь к описанию mysql_fetch_row()
.
Массив длинных целых чисел без знака, представляющих размер каждого
столбца (не включая любые символы пробелов в хвосте). NULL
, если
что-то пошло не так.
mysql_fetch_lengths()
имеет силу только для текущей строки
набора результатов. Этот вызов возвращает NULL
, если Вы
вызываете его перед mysql_fetch_row()
или после получения
всех строк в результате.
MYSQL_ROW row; unsigned long *lengths; unsigned int num_fields; unsigned int i; row = mysql_fetch_row(result); if (row) { num_fields = mysql_num_fields(result); lengths = mysql_fetch_lengths(result); for (i = 0; i < num_fields; i++) { printf("Column %u is %lu bytes in length.\n", i, lengths[i]); } }
mysql_fetch_row()
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
Получает следующую строку набора результатов. Когда используется после
mysql_store_result()
, mysql_fetch_row()
возвращает
NULL
, когда не имеется больше строк, чтобы получить. Когда
используется после mysql_use_result()
,
mysql_fetch_row()
вернет NULL
, когда не имеется
больше строк, чтобы получить, или произошла ошибка.
Число значений в строке задано mysql_num_fields(result)
. Если
row
хранит значение возврата от обращения к
mysql_fetch_row()
, указатели на значения меняются с
row[0]
на row[mysql_num_fields(result)-1]
. Значения
NULL
в строке обозначены указателями NULL
.
Длины значений полей в строке могут быть получены, вызывая
mysql_fetch_lengths()
. Пустые поля и поля, содержащие
NULL
имеют длину 0. Вы можете отличать их, проверяя указатель
для значения поля. Если указатель равен NULL
, поле
NULL
, иначе поле пустое.
Структура MYSQL_ROW
для следующей строки. NULL
,
если не имеется больше строк, чтобы получить, или произошла ошибка.
CR_SERVER_LOST
CR_UNKNOWN_ERROR
MYSQL_ROW row; unsigned int num_fields; unsigned int i; num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { unsigned long *lengths; lengths = mysql_fetch_lengths(result); for (i = 0; i < num_fields; i++) { printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); } printf("\n"); }
mysql_field_count()
unsigned int mysql_field_count(MYSQL *mysql)
Если Вы используете версию MySQL ранее, чем Version 3.22.24, Вы должны
вместо этого использовать unsigned int
mysql_num_fields(MYSQL *mysql)
.
Возвращает число столбцов для самого последнего запроса на подключении.
Нормальное использование этой функции: когда
mysql_store_result()
возвращает NULL
(и таким
образом Вы не имеете никакого указателя на набор результатов). В этом случае
Вы можете вызывать mysql_field_count()
, чтобы определить, должен
или нет mysql_store_result()
произвести не пустой результат. Это
позволяет программе пользователя выбрать соответствующее действие без того,
чтобы знать, был или нет запрос SELECT
(или
SELECT
-подобным). Пример, показанный ниже иллюстрирует, как это
может быть выполнено.
Целое число без знака, представляющее число полей в наборе результатов.
Нет.
MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else // query succeeded, process any data returned by it { result = mysql_store_result(&mysql); if (result) // there are rows { num_fields = mysql_num_fields(result); // retrieve rows, then call mysql_free_result(result) } else // mysql_store_result() returned nothing; should it have? { if (mysql_field_count(&mysql) == 0) { // query does not return data // (it was not a SELECT) num_rows = mysql_affected_rows(&mysql); } else // mysql_store_result() should have returned data { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } } }
Вариант: можно заменить mysql_field_count(&mysql)
на
mysql_errno(&mysql)
. В этом случае Вы проверяете
непосредственно для ошибки из mysql_store_result()
вместо
анализа значения mysql_field_count()
на предмет того, является
или нет оператор SELECT
.
mysql_field_seek()
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
MYSQL_FIELD_OFFSET offset)
Устанавливает курсор поля к данному смещению. Следующее обращение к
mysql_fetch_field()
получит определение поля столбца, связанного
именно с этим смещением.
Чтобы перейти к началу строки, передайте 0 как значение
offset
.
Предыдущее значение курсора поля.
Нет.
mysql_field_tell()
MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)
Возвращает позицию курсора поля, используемого для последнего
mysql_fetch_field()
. Это значение может использоваться как
параметр для mysql_field_seek()
.
Текущее смещение курсора поля.
Нет.
mysql_free_result()
void mysql_free_result(MYSQL_RES *result)
Освобождает память, распределенную для набора результатов
mysql_store_result()
, mysql_use_result()
,
mysql_list_dbs()
и другими подобными функциями. Когда Вы
закончили работу с набором результатов, Вы должны освободить память, которую
он использует, вызывая mysql_free_result()
.
Нет.
Нет.
mysql_get_client_info()
char *mysql_get_client_info(void)
Возвращает строку, которая представляет версию клиентской библиотеки.
Символьная строка, которая представляет версию клиентской библиотеки MySQL.
Нет.
mysql_get_host_info()
char *mysql_get_host_info(MYSQL *mysql)
Возвращает строку, описывающую тип используемого подключения, включая имя главного компьютера сервера.
Символьная строка, представляющая имя компьютера и тип подключения.
Нет.
mysql_get_proto_info()
unsigned int mysql_get_proto_info(MYSQL *mysql)
Возвращает код версии протокола, используемой текущим подключением.
Целое число без знака, представляющее версию протокола, используемую текущим (актуальным) подключением.
Нет.
mysql_get_server_info()
char *mysql_get_server_info(MYSQL *mysql)
Возвращает строку, которая представляет номер версии сервера.
Символьная строка, которая представляет номер версии станции.
Нет.
mysql_info()
char *mysql_info(MYSQL *mysql)
Возвращает строку, обеспечивающую информацию относительно недавно
выполненного запроса, но только для инструкций, перечисленных ниже. Для
других инструкций mysql_info()
всегда возвращает
NULL
. Формат строки изменяется в зависимости от типа запроса,
как описано ниже. Числа только иллюстративны: строка будет содержать
значения, соответствующие запросу.
INSERT INTO ... SELECT ...
Records: 100 Duplicates: 0 Warnings: 0
INSERT INTO ... VALUES (...),(...),(...)...
Records: 3 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ...
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE
Records: 3 Duplicates: 0 Warnings: 0
UPDATE
Rows matched: 40 Changed: 40 Warnings: 0
Обратите внимание, что mysql_info()
возвращает значение
не-NULL
для инструкции INSERT ... VALUES
только,
если много списков значений было определено в инструкции.
Символьная строка, представляющая дополнительную информацию относительно
последнего выполненного запроса. NULL
, если никакая информация
не доступна для запроса.
Нет.
mysql_init()
MYSQL *mysql_init(MYSQL *mysql)
Распределяет или инициализирует объект MYSQL
, подходящий для
mysql_real_connect()
. Если mysql
является
указателем NULL
, функция распределяет память, инициализирует и
возвращает новый объект. Иначе объект будет просто инициализирован, и адрес
объекта возвращен. Если mysql_init()
распределяет новый объект,
место будет освобождено, когда будет вызвана mysql_close()
.
Инициализированный дескриптор MYSQL*
. NULL
, если
недостаточно памяти, чтобы распределить и инициализировать новый объект.
В случае недостаточной памяти вернется NULL
.
mysql_insert_id()
my_ulonglong mysql_insert_id(MYSQL *mysql)
Возвращает ID, сгенерированный предыдущим запросом для столбца с
поддержкой AUTO_INCREMENT
. Используйте эту функцию после того,
как Вы выполнили запрос INSERT
для таблицы, которая содержит
поле AUTO_INCREMENT
.
Обратите внимание, что mysql_insert_id()
возвращает
0
, если предыдущий запрос не генерирует значение
AUTO_INCREMENT
. Если Вы должны сохранить значение для
последующего неспешного потребления убедитесь, что вызвали
mysql_insert_id()
немедленно после того запроса,
который генерирует значение.
mysql_insert_id()
модифицируется после инструкций
INSERT
и UPDATE
, которые генерируют значение
AUTO_INCREMENT
, или установки значения столбца с помощью
LAST_INSERT_ID(expr)
.
Также обратите внимание, что значение функции SQL
LAST_INSERT_ID()
всегда содержит самое последнее сгенерированное
значение AUTO_INCREMENT
, и оно не будет сброшено между запросами
потому, что значение этой функции поддерживается сервером.
Значение поля AUTO_INCREMENT
, которое модифицировалось
предыдущим запросом. 0, если не имелось никакого предыдущего запроса на
подключении, или если запрос не модифицировал AUTO_INCREMENT
.
Нет.
mysql_kill()
int mysql_kill(MYSQL *mysql, unsigned long pid)
Просит, чтобы сервер уничтожил поток, определенный как pid
.
Ноль для успеха. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_dbs()
MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)
Возвращает набор результатов, состоящий из имен баз данных на сервере,
которые соответствуют простому регулярному выражению, определенному
параметром wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем базам данных. Вызов
mysql_list_dbs()
подобен выполнению запроса SHOW
databases [LIKE wild]
.
Вы должны освободить набор результатов с помощью
mysql_free_result()
.
Набор результатов MYSQL_RES
для успеха, NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_fields()
MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table,
const char *wild)
Возвращает набор результатов, состоящий из имен полей в данной таблице,
которые соответствуют простому регулярному выражению, определенному
параметром wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем полям. Вызов
mysql_list_fields()
подобен выполнению запроса SHOW
COLUMNS FROM tbl_name [LIKE wild]
.
Обратите внимание, что рекомендуется, чтобы Вы использовали SHOW
COLUMNS FROM tbl_name
вместо mysql_list_fields()
.
Вы должны освободить набор результатов с помощью
mysql_free_result()
.
Набор результатов MYSQL_RES
для успеха. NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_processes()
MYSQL_RES *mysql_list_processes(MYSQL *mysql)
Возвращает набор результатов, описывающий текущие потоки сервера. Это тот
же самый вид информации, что и сообщаемый командой mysqladmin
processlist
или запросом SHOW PROCESSLIST
.
Вы должны освободить набор результатов с помощью
mysql_free_result()
.
Набор результатов MYSQL_RES
для успеха. NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_list_tables()
MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)
Возвращает набор результатов, состоящий из имен таблиц в текущей базе
данных, которые соответствуют простому регулярному выражению, определенному
параметром wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем таблицам. Вызов
mysql_list_tables()
подобен выполнению запроса SHOW
tables [LIKE wild]
.
Вы должны освободить набор результатов с помощью
mysql_free_result()
.
Набор результатов MYSQL_RES
для успеха. NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_num_fields()
unsigned int mysql_num_fields(MYSQL_RES *result)
или
unsigned int mysql_num_fields(MYSQL *mysql)
Вторая форма не работает в MySQL Version 3.22.24 или выше. Чтобы
передавать параметр MYSQL*
, Вы должны использовать
unsigned int mysql_field_count(MYSQL *mysql)
.
Возвращает число столбцов в наборе результатов.
Обратите внимание, что Вы можете получать число столбцов из указателя
набора результатов или от дескриптора подключения. Вы используете дескриптор
подключения, если mysql_store_result()
или
mysql_use_result()
возвращает NULL
(и таким образом
Вы не имеете никакого указателя набора результата). В этом случае Вы можете
вызывать mysql_field_count()
чтобы определить, должен или нет
mysql_store_result()
произвести непустой результат. Это
позволяет программе пользователя выбрать соответствующее действие без того,
чтобы знать, был или нет запрос SELECT
(или
SELECT
-подобным). Пример, показанный ниже иллюстрирует, как это
может быть выполнено.
Целое число без знака, представляющее число полей в наборе результатов.
Нет.
MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else // query succeeded, process any data returned by it { result = mysql_store_result(&mysql); if (result) // there are rows { num_fields = mysql_num_fields(result); // retrieve rows, then call mysql_free_result(result) } else // mysql_store_result() returned nothing; should it have? { if (mysql_errno(&mysql)) { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } else if (mysql_field_count(&mysql) == 0) { // query does not return data // (it was not a SELECT) num_rows = mysql_affected_rows(&mysql); } } }
Вариант (если Вы ЗНАЕТЕ, что ваш запрос должен был возвратить набор
результатов): заменить обращение mysql_errno(&mysql)
на
проверку mysql_field_count(&mysql)
=0.
mysql_num_rows()
my_ulonglong mysql_num_rows(MYSQL_RES *result)
Возвращает число строк в наборе результатов.
Использование mysql_num_rows()
зависит от того, используете
ли Вы mysql_store_result()
или mysql_use_result()
,
чтобы получить набор результатов. Если Вы используете
mysql_store_result()
, mysql_num_rows()
может
быть вызван немедленно. Если Вы используете mysql_use_result()
,
mysql_num_rows()
не будет возвращать правильное значение, пока
все строки в наборе результатов не будут получены.
Число строк в наборе результатов.
Нет.
mysql_options()
int mysql_options(MYSQL *mysql, enum mysql_option option,
const char *arg)
Может использоваться, чтобы установить дополнительные параметры связи и действует на поведение подключения. Эта функция может быть вызвана несколько раз, чтобы установить несколько параметров.
mysql_options()
должна быть вызвана после
mysql_init()
, но перед mysql_connect()
или
mysql_real_connect()
.
Параметр option
представляет собой опцию, которую Вы хотите
устанавливать, arg
задает значение для опции. Если опция целое
число, то arg
должен указывать на значение целого числа.
Возможные значения параметров:
Опция | Тип аргумента | Действие |
MYSQL_OPT_CONNECT_TIMEOUT |
unsigned int * | Время ожидания в секундах. |
MYSQL_OPT_COMPRESS | Не используется | Использовать сжатый протокол клиент-сервер. |
MYSQL_OPT_NAMED_PIPE | Не используется | Использовать именованные каналы, чтобы соединиться с сервером MySQL под NT. |
MYSQL_INIT_COMMAND | char * | Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически выполнена при повторном соединении. |
MYSQL_READ_DEFAULT_FILE | char * |
Читать параметры из указанного файла опций вместо my.cnf. |
MYSQL_READ_DEFAULT_GROUP | char *
| Читать параметры из именованной группы из файла опций
my.cnf или файла, определенного в
MYSQL_READ_DEFAULT_FILE . |
Обратите внимание, что группа client
всегда читается, если Вы
используете MYSQL_READ_DEFAULT_FILE
или
MYSQL_READ_DEFAULT_GROUP
.
Определенная группа в файле опций может содержать следующие параметры:
connect_timeout | Время ожидания в секундах. В Linux это время ожидания также используется для ожидания первого ответа. |
compress | Использовать сжатый протокол клиент-сервер. |
database | Соединиться с этой базой данных, если никакая база данных не была определена в команде подключения. |
debug | Опции для отладки. |
host | Имя сервера по умолчанию. |
init-command | Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически заново выполнена при повторном соединении, если связь прервалась. |
interactive-timeout | Аналогично указанию опции
CLIENT_INTERACTIVE в mysql_real_connect() .
Подробности в разделе "2.3.171 mysql_real_connect() ". |
password | Пароль по умолчанию. |
pipe | Использовать именованные каналы, чтобы соединиться с сервером MySQL, работая под NT. |
port | Порт по умолчанию. |
return-found-rows | Сообщить
mysql_info() о том, что нужно возвратить найденные строки вместо
модифицируемых строк при использовании UPDATE . |
socket | Сокет по умолчанию. |
user | Пользователь по умолчанию. |
Обратите внимание, что timeout
был заменен на
connect_timeout
, но timeout
будет все еще работать
некоторое время для совместимости.
Ноль для успеха. Отличное от нуля, если Вы использовали неизвестную опцию.
MYSQL mysql; mysql_init(&mysql); mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); if (!mysql_real_connect(&mysql,"host","user","passwd", "database",0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); }
Вышеупомянутое запрашивает использовать сжатый протокол клиент-сервер и
читать дополнительные параметры из группы odbc
в файле опций
my.cnf
.
mysql_ping()
int mysql_ping(MYSQL *mysql)
Проверяет работает или нет подключение. В случае неработоспособности будет предпринято автоматическое переподключение.
Эта функция может использоваться клиентом, который долго простаивает, чтобы определить, закрыл или нет сервер подключение, и повторно соединиться с ним в случае необходимости.
Ноль, если подключение работает. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_UNKNOWN_ERROR
mysql_query()
int mysql_query(MYSQL *mysql, const char *query)
Выполняет запрос SQL, указанный строкой с нулевым символом в конце. Запрос
должен состоять из одиночной инструкции SQL. Вы не должны добавлять точку с
запятой (;) или \g
для завершения запроса.
mysql_query()
не может использоваться для запросов, которые
содержат двоичные данные, взамен Вы должны использовать
mysql_real_query()
. Двоичные данные могут содержать в себе
символ \0, который mysql_query()
интерпретирует как
конец строки запроса.
Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы
можете использовать mysql_field_count()
, чтобы проверить это.
Подробности в разделе "2.3.85 mysql_field_count()
".
Ноль, если запрос был успешен. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_real_connect()
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
const char *user, const char *passwd,
const char *db, unsigned int port,
const char *unix_socket,
unsigned int client_flag)
mysql_real_connect()
пытается установить подключение с
сервером MySQL, запущенным на машине host
.
mysql_real_connect()
должен завершиться успешно прежде, чем Вы
сможете выполнить любую из других функций API, за исключением
mysql_get_client_info()
.
Параметры определены следующим образом:
MYSQL
. Перед вызовом mysql_real_connect()
Вы должны
вызвать mysql_init()
, чтобы инициализировать структуру
MYSQL
. Вы можете изменять много параметров подключения через
вызов mysql_options()
. Подробности в
разделе "2.3.159 mysql_options()
".
host
может быть имя или адрес IP. Если это
NULL
или строка localhost
, выполняется подключение
к локальной системе. Если OS поддерживает сокеты (Unix) или именованные
каналы (Windows), именно они используются вместо стека протоколов TCP/IP,
чтобы соединиться с сервером.
user
содержит ID пользователя MySQL. Если
user
равен NULL
, предполагается текущий
пользователь. Под Unix это текущее (актуальное) имя входа в систему. Под
Windows ODBC имя пользователя должно быть определено явно.
passwd
содержит пароль для user
. Если
passwd
равен NULL
, только записи в таблице
user
, которые имеют пустое поле пароля, будут проверены на
соответствие. Это позволяет администратору базы данных устанавливать систему
привилегий MySQL таким способом, которым пользователи получают различные
привилегии в зависимости от того, определили или нет они пароль. ОБРАТИТЕ
ВНИМАНИЕ: Не пытайтесь шифровать пароль перед вызовом
mysql_real_connect()
: шифрование пароля обработано автоматически.
db
задает имя базы данных. Если db
не
NULL
, подключение установит заданную по умолчанию базу данных.
port
не равен 0, значение будет использоваться как
номер порта для подключения по TCP/IP. Обратите внимание, что параметр
host
определяет тип подключения.
unix_socket
не равен NULL
, строка
определяет сокет или именованный канал, который должен использоваться.
Обратите внимание, что параметр host
определяет тип подключения.
client_flag
как правило равно 0, но может быть
установлено к комбинации из следующих флажков в специальных обстоятельствах:
Имя флажка | Что он делает |
CLIENT_COMPRESS | Использовать протокол сжатия. |
CLIENT_FOUND_ROWS | Возвратить число найденных, а не обработанных строк. |
CLIENT_IGNORE_SPACE | Позволить использовать пробелы после имен функций. Делает все зарезервированные слова именами функций. |
CLIENT_INTERACTIVE | Позволить
interactive_timeout секунд (вместо wait_timeout
секунд) бездеятельности перед закрытием подключения. |
CLIENT_NO_SCHEMA | Не позволять синтаксис
db_name.tbl_name.col_name . Это сделано для ODBC. Это заставляет
синтаксический анализатор генерировать ошибку, если Вы используете тот
синтаксис, который является полезным для заманивания в ловушку ошибок в
некоторых программах ODBC. |
CLIENT_ODBC | Работает клиент ODBC. |
CLIENT_SSL | Использовать шифрованный протокол SSL. |
Дескриптор MYSQL*
, если подключение было успешно,
NULL
, если подключение было неудачно. Для успешного подключения,
значение возврата: такое же, как значение первого параметра, если Вы не
передаете NULL
для этого параметра.
CR_CONN_HOST_ERROR
CR_CONNECTION_ERROR
CR_IPSOCK_ERROR
CR_OUT_OF_MEMORY
CR_SOCKET_CREATE_ERROR
CR_UNKNOWN_HOST
CR_VERSION_ERROR
--old-protocol
.
CR_NAMEDPIPEOPEN_ERROR
CR_NAMEDPIPEWAIT_ERROR
CR_NAMEDPIPESETSTATE_ERROR
CR_SERVER_LOST
connect_timeout
> 0 и требуется более, чем
connect_timeout
секунд, чтобы соединиться с сервером, или если
сервер свалился при выполнении init-command
, вернется это.MYSQL mysql; mysql_init(&mysql); mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); if (!mysql_real_connect(&mysql,"host","user","passwd","database", 0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); }
Используя mysql_options()
библиотека клиентов MySQL будет
читать группы [client]
и your_prog_name
в файле
my.cnf
, что гарантирует, что Ваша программа будет работать, даже
если кто-то установил MySQL некоторым ненормативным способом.
Обратите внимание, что на подключение mysql_real_connect()
устанавливает флажок reconnect
(часть структуры MYSQL) в
значение 1
. Этот флажок указывает, что когда запрос не может
выполниться из-за потерянного подключения, надо попробовать повторно
соединиться с сервером перед отказом.
mysql_real_escape_string()
unsigned int mysql_real_escape_string(MYSQL *mysql, char *to,
const char *from,
unsigned int length)
Эта функция используется, чтобы создать допустимую строку, которую Вы можете использовать в инструкции SQL.
Строка в from
бужет закодирована до экранированной строки
SQL, принимая во внимание текущий (актуальный) набор символов подключения.
Результат будет помещен в to
и завершающий байт пустого
указателя допишется автоматически. Символы NUL
(ASCII 0),
\n, \r, \, ',
", а также Control-Z, будуь экранированы.
Строка, указанная в from
должна быть length
байтов длины. Вы должны распределить буфер по крайней мере
length*2+1
байт. В худшем случае каждый символ должен быть
закодирован как использование двух байтов, и Вы нуждаетесь в участке памяти
для завершающего байта пустого указателя. Когда
mysql_escape_string()
завершится, в to
будет
строка с нулевым байтом в конце. Значение возврата: длина закодированной
строки, не включая символ завершения.
char query[1000],*end; end = strmov(query,"INSERT INTO test_table values("); *end++ = '\''; end += mysql_real_escape_string(&mysql, end,"What's this",11); *end++ = '\''; *end++ = ','; *end++ = '\''; end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); *end++ = '\''; *end++ = ')'; if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) { fprintf(stderr, "Failed to insert row, Error: %s\n", mysql_error(&mysql)); }
Функция strmov()
, используемая в примере, включена в
библиотеку mysqlclient
и работает подобно strcpy()
,
но возвращает указатель на завершающий символ первого параметра.
Длина значения, помещенного в to
, не включая
нулевой символ завершения.
Нет.
mysql_real_query()
int mysql_real_query(MYSQL *mysql, const char *query,
unsigned int length)
Выполняет запрос SQL, указанный в query
, который должен быть
строкой длиной в length
байт. Запрос должен состоять из
одиночной инструкции SQL. Вы не должны добавлять точку с запятой
(`;') или \g
для завершения запроса.
Вы должны использовать mysql_real_query()
вместо
mysql_query()
для запросов, которые содержат двоичные данные,
потому, что двоичные данные могут сами содержать символ \0.
Кроме того, mysql_real_query()
быстрее, чем
mysql_query()
потому, что не вызывает strlen()
.
Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы
можете использовать mysql_field_count()
, чтобы проверить это.
Подробности в разделе "2.3.85 mysql_field_count()
".
Ноль, если запрос был успешным. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_reload()
int mysql_reload(MYSQL *mysql)
Просит, чтобы сервер MySQL перезагрузил таблицы предоставления привилегий. Пользователь должен иметь привилегию reload.
Ноль для успеха. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_row_seek()
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
MYSQL_ROW_OFFSET offset)
Устанавливает курсор строки на произвольную строку в наборе результатов
запросов. Это требует, чтобы структура набора результата содержала весь
результат запроса, так что mysql_row_seek()
может использоваться
в конъюнкции только с mysql_store_result()
, но не с
mysql_use_result()
.
Смещение должно быть значением, возвращенным из
mysql_row_tell()
для mysql_row_seek()
. Это значение
не просто номер строки, если Вы хотите перейти к строке внутри набора
результатов, используйте mysql_data_seek()
.
Предыдущее значение курсора строки. Это значение может быть передано
последующему обращению к mysql_row_seek()
.
Нет.
mysql_row_tell()
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)
Возвращает текущую (актуальную) позицию курсора строки для последнего
вызова mysql_fetch_row()
. Это значение может использоваться как
параметр для mysql_row_seek()
.
Вы должны использовать mysql_row_tell()
только после
mysql_store_result()
, но не после
mysql_use_result()
.
Текущее (актуальное) смещение курсора строки.
Нет.
mysql_select_db()
int mysql_select_db(MYSQL *mysql, const char *db)
Заставляет базу данных, определенную через db
, стать заданной
по умолчанию базой данных на подключении, определенном в mysql
.
В последующих запросах эта база данных будет значением по умолчанию для
ссылок на таблицы, которые не включают явный спецификатор базы данных.
mysql_select_db()
терпит неудачу, если связанный пользователь
не имеет прав доступа, чтобы использовать базу данных.
Ноль для успеха. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_shutdown()
int mysql_shutdown(MYSQL *mysql)
Выключает сервер. Связанный пользователь должен иметь привилегии закрытия системы (shutdown).
Ноль для успеха. Отличное от нуля, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_stat()
char *mysql_stat(MYSQL *mysql)
Возвращает символьную строку, содержащую информацию, подобную
обеспечиваемой командой mysqladmin status
. Это включает
uptime в секундах, число работающих потоков, количество запросов,
перезагрузок и открытых таблиц.
Символьная строка, описывающая состояние сервера. NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_store_result()
MYSQL_RES *mysql_store_result(MYSQL *mysql)
Вы должны вызвать mysql_store_result()
или
mysql_use_result()
для каждого запроса, который успешно получает
данные (SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
).
Вы не должны вызывать mysql_store_result()
или
mysql_use_result()
для других запросов, но это не причинит
вреда, если Вы вызываете mysql_store_result()
во всех случаях.
Правда, и эффективности не прибавится... Вы могли обнаружить, что запрос не
имеет набора результатов, проверяя равенство нулю возврата
mysql_store_result()
.
Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы
можете использовать mysql_field_count()
, чтобы проверить это.
Подробности в разделе "2.3.85 mysql_field_count()
".
mysql_store_result()
читает весь результат запроса,
распределяет структуру MYSQL_RES
и помещает
результат в эту структуру.
mysql_store_results()
вернет пустой указатель, если запрос не
возвращал набор результатов вообще (если запрос был, например, инструкцией
INSERT
).
mysql_store_results()
также возвращает пустой указатель, если
чтение набора результатов потерпело неудачу. Вы можете проверить, получили
ли Вы ошибку, проверяя возвращает ли mysql_error()
пустой
указатель. Если mysql_errno()
<> 0, или если
mysql_field_count()
<> 0, значит, ошибочка.
Пустой набор результатов будет возвращен, если не имеется никаких возвращенных строк. Пустой набор результатов отличается от пустого указателя как значение возврата.
Как только Вы вызвали mysql_store_result()
и получили
результат, который не пустой указатель, Вы можете вызывать
mysql_num_rows()
, чтобы выяснить, сколько строк
находится в наборе результатов.
Вы можете вызвать mysql_fetch_row()
, чтобы выбрать строки из
набора результатов, или mysql_row_seek()
и
mysql_row_tell()
, чтобы получить или установить текущую позицию
строки внутри набора результатов.
Вы должны вызвать mysql_free_result()
как только Вы закончите
работу с данным набором результатов.
Структура MYSQL_RES
с результатами. NULL
,
если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
mysql_thread_id()
unsigned long mysql_thread_id(MYSQL *mysql)
Возвращает ID потока текущего (актуального) подключения. Это значение
может использоваться как параметр для mysql_kill()
, чтобы
уничтожить этот поток.
Если подключение потеряно, и Вы повторно соединяетесь через
mysql_ping()
, ID потока изменится. Это означает, что Вы не
должны получить ID потока и хранить его. Надо получать ID по мере надобности.
ID потока текущего (актуального) подключения.
Нет.
mysql_use_result()
MYSQL_RES *mysql_use_result(MYSQL *mysql)
Вы должны вызвать mysql_store_result()
или
mysql_use_result()
для каждого запроса, который успешно получает
данные (SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
).
mysql_use_result()
инициализирует поиск набора результата, но
фактически не читает набор результатов подобно
mysql_store_result()
. Вместо этого, каждая строка должна быть
получена индивидуально, делая обращения к mysql_fetch_row()
. Это
читает результат запроса непосредственно с сервера без того, чтобы сохранить
его во временной таблице или локальном буфере, что несколько быстрее и
использует намного меньше памяти, чем mysql_store_result()
.
Пользователь распределит память только для текущей (актуальной) строки и
буфера связей, который может сам вырасти до max_allowed_packet
.
С другой стороны, Вы не должны использовать
mysql_use_result()
если Вы делаете много обработки для каждой
строки на стороне пользователя, или если вывод послан экрану, на котором
пользователь может напечатать ^S
(приостановить показ данных).
Это свяжет сервер и не даст другим потокам модифицировать любые таблицы, из
которых выбираются данные.
При использовании mysql_use_result()
Вы должны выполнять
mysql_fetch_row()
до тех пор, пока значение не вернется значение
NULL
, иначе невыбранные строки будут возвращены как часть набора
результатов для Вашего следующего запроса. C API выдает ошибку
"Commands out of sync; You can't run this command now
", если Вы
забываете про это!
Вы не можете использовать mysql_data_seek()
,
mysql_row_seek()
, mysql_row_tell()
,
mysql_num_rows()
или mysql_affected_rows()
с
результатом, возвращенным из mysql_use_result()
, и при этом Вы
не можете выдавать другие запросы, пока не закончится
mysql_use_result()
. Однако, после того, как Вы выбрали все
строки, mysql_num_rows()
точно возвратит число выбранных строк.
Вы должны вызвать mysql_free_result()
как только Вы закончили
с этим набором результатов.
Структура MYSQL_RES
. NULL
, если произошла ошибка.
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
Вы должны использовать следующие функции, когда Вы хотите создавать поточного клиента. Подробности в разделе "2.8 Как делать поточного клиента".
my_init()
Эта функция должна быть вызвана однажды в программе перед вызовом любой
функции MySQL. Это инициализирует некоторые глобальные переменные. Если Вы
используете поточно-безопасную библиотеку клиентов, это также вызовет для
этого потока функцию mysql_thread_init()
.
Это автоматически вызвано функциями mysql_init()
,
mysql_server_init()
и mysql_connect()
.
Нет.
mysql_thread_init()
Эту функцию должен запрашивать каждый созданный поток, чтобы инициализировать специфические переменные.
Это автоматически вызвано my_init()
и
mysql_connect()
.
Нет.
mysql_thread_end()
Эта функция должна быть вызвана перед вызовом pthread_exit()
,
чтобы освободить память, распределенную в mysql_thread_init()
.
Обратите внимание, что эта функция не вызывается автоматически библиотекой. Это должно быть вызвано явно, чтобы избежать утечки памяти.
Нет.
Вы должны использовать следующие функции, если Вы хотите, чтобы в Вашей прикладной программе была функциональность встроенного сервера MySQL. Подробности в разделе "2.9 libmysqld, библиотека встроенного сервера MySQL ".
Если программа скомпонована с -lmysqlclient
вместо
-lmysqld
, эти функции не делают ничего. Это делает возможным
выбирать между использованием встроенного и автономного сервера без изменения
какого-либо кода.
mysql_server_init()
void mysql_server_init(int argc, const char **argv,
const char **groups)
Эта функция должна быть вызвана в программе перед вызовом
любой другой функции MySQL. Она запускает сервер и инициализирует все
подсистемы (mysys
, InnoDB и т.д.), используемые сервером. Если
эта функция не была вызвана, программа разрушится.
Параметры argc
и argv
аналогичны параметрам
main()
. Первый элемент argv
игнорируется (он обычно
содержит имя программы). Для удобства argc
может быть
0
, если не имеется никаких параметров командной строки сервера.
Завершаемый символом NULL
список строк в groups
задает то, какие группы в файле опций будут активны. Для удобства
groups
может быть NULL
, тогда будет активна группа
[server]
.
#include <mysql.h> #include <stdlib.h> static char *server_args[] = { "this_program", /* this string is not used */ "--datadir=.", "--set-variable=key_buffer_size=32M" }; static char *server_groups[] = { "server", "this_program_SERVER", (char *)NULL }; int main(void) { mysql_server_init(sizeof(server_args) / sizeof(char *), server_args, server_groups); /* Use any MySQL API functions here */ mysql_server_end(); return EXIT_SUCCESS; }
Нет.
mysql_server_end()
Эта функция должна быть вызвана в программе, в конце. Она завершает сервер.
Нет.
mysql_query()
вызов mysql_store_result()
иногда возвращает NULL?
Когда это случается, это означает, что одно из следующего произошло:
malloc()
(например, если набор результатов
был слишком большой).
INSERT
, UPDATE
или DELETE
).Вы можете всегда проверить, должна или нет инструкция произвести непустой
результат, вызывая mysql_field_count()
. Если
mysql_field_count()
вернет ноль, результат пуст, и последний
запрос был инструкцией, которая не возвращает значения (например,
INSERT
или DELETE
). Если
mysql_field_count()
вернет не ноль, инструкция должна была
произвести не пустой результат.
Вы можете проверить наличие ошибки вызовом mysql_error()
или
mysql_errno()
.
В дополнение к набору результатов, возвращенному запросом, Вы можете также получать следующую информацию:
mysql_affected_rows()
возвращает число строк, на которые
воздействует последний запрос при выполнении INSERT
,
UPDATE
или DELETE
. Исключительная ситуация:
DELETE
используется без предложения WHERE
, таблица
будет пересоздана пустой, что намного быстрее! В этом случае
mysql_affected_rows()
возвращает ноль для числа записей.
mysql_num_rows()
возвращает число строк в наборе
результатов. При использовании mysql_store_result()
mysql_num_rows()
может быть вызван, как только отработает
mysql_store_result()
. При использовании
mysql_use_result()
mysql_num_rows()
может быть
вызван только после того, как Вы выбрали все строки с помощью
mysql_fetch_row()
.
mysql_insert_id()
возвращает ID, сгенерированный последним
запросом, который вставил строку в таблицу с индексом
AUTO_INCREMENT
. Подробности в разделе "2.3.126
mysql_insert_id()
".
LOAD DATA INFILE ...
, INSERT INTO
... SELECT ...
, UPDATE
) возвращают дополнительную
информацию. Результат возвращен через mysql_info()
.
mysql_info()
вернет NULL
если не имеется
никакой дополнительной информации.Если Вы вставляете запись в таблицу, содержащую столбец, который имеет
атрибут AUTO_INCREMENT
, Вы можете получать последнее значение
ID вызовом mysql_insert_id()
.
Вы можете также получать ID, используя функцию
LAST_INSERT_ID()
в строке запроса, которую Вы передаете
mysql_query()
.
Вы можете проверять, используется ли индекс AUTO_INCREMENT
,
выполняя следующий код. Это также проверит, был ли запрос INSERT
с индексом AUTO_INCREMENT
:
if (mysql_error(&mysql)[0] == 0 && mysql_num_fields(result) == 0 && mysql_insert_id(&mysql) != 0) { used_id = mysql_insert_id(&mysql); }
Недавно сгенерированный ID хранится на сервере с привязкой к подключению.
Это не будет изменено другим пользователем. Это не будет даже изменено, если
Вы модифицируете другой столбец AUTO_INCREMENT
не со специальным
значением (то есть значением, которое не NULL
и не
0
).
Если Вы хотите использовать ID, который был сгенерирован для одной таблицы и вставлять его во вторую таблицу, Вы можете использовать инструкции SQL подобно этому:
INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULL INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table
При компоновке с C API следующие ошибки могут происходить на некоторых системах:
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl Undefined first referenced symbol in file floor /usr/local/lib/mysql/libmysqlclient.a(password.o) ld: fatal: Symbol referencing errors. No output written to client
Если это случается на Вашей системе, Вы должны включить математическую
библиотеку, добавляя -lm
к концу строки для компоновки.
Если Вы компилируете MySQL клиентуру, которую вы написали самостоятельно
или получили от третьего лица, программы должны быть скомпонованы, используя
опцию -lmysqlclient -lz
. Вы также должны определить опцию
-L
, чтобы сообщить компоновщику, где найти библиотеку. Например,
если библиотека установлена в /usr/local/mysql/lib, используйте
-L/usr/local/mysql/lib -lmysqlclient -lz
на строке компоновки.
Для клиентуры, которая использует файлы заголовков MySQL, Вы должны
определить опцию -I
, когда Вы компилируете их (например,
-I/usr/local/mysql/include
), чтобы транслятор смог найти файлы.
Самая большая проблема состоит в том, что подпрограммы в net.c,
которые читают из сокетов, не безопасны для прерываний. Это было выполнено с
мыслью о том, что Вы могли бы иметь Вашу собственную функцию, которая может
разорвать длинное чтение на сервер. Если Вы устанавливаете программы
обработки прерывания для SIGPIPE
, обработка сокета должна
быть поточно-безопасной.
В старом двоичном коде библиотеки пользователей обычно не компилируются с опциями для поддержки поточной безопасности (код для Windows по умолчанию компилируются как поточно-безопасный). Более новые двоичные дистрибутивы имеют оба варианта библиотек.
Чтобы сделать поточный клиент, где Вы можете прерывать пользователя
из других потоков и устанавливать времена ожидания при обмене данными с
сервером MySQL, Вы должны использовать библиотеки -lmysys
,
-lstring
и -ldbug
, а также код
net_serv.o
, который использует сервер.
Если Вы не нуждаетесь в прерываниях или временах ожидания, Вы можете
только скомпилировать поточно-безопасную библиотеку пользователей
(mysqlclient_r)
и использовать ее. В этом случае Вы не должны
волноваться относительно объектного файла net_serv.o
или других
библиотек для MySQL.
При использовании поточного клиента, и если Вы хотите использовать времена
ожидания и прерывания, Вы можете использовать код из файла
thr_alarm.c. Если Вы используете подпрограммы из библиотеки
mysys
, Вы должны помнить, что нужно сначала вызвать
my_init()
! Подробности в разделе "2.4
Описание поточных функций C".
Все функции за исключением mysql_real_connect()
по умолчанию
безопасны для потоков. Следующие замечания описывают, как компилировать
безопасную библиотеку клиентов и использовать ее соответственно. Замечания
для mysql_real_connect()
фактически применимы и для
mysql_connect()
.
Чтобы сделать mysql_real_connect()
поточно-безопасной, Вы
должны перетранслировать библиотеку этой командой:
shell> ./configure --enable-thread-safe-client
Это создаст поточно-безопасную библиотеку libmysqlclient_r
.
Вы можете позволять двум потокам совместно использовать то же самое
подключение, пока Вы делаете следующее:
mysql_query()
и mysql_store_result()
другой поток
никогда не использует то же самое подключение.
mysql_store_result()
.
mysql_use_result
, Вы должны
гарантировать, что никакой другой поток не спрашивает что-нибудь относительно
того же самого подключения, пока набор результатов не закрыт.
mysql_query()
и mysql_store_result()
. Когда
mysql_store_result()
готов, блокировка может быть снята, и
другие потоки смогут сделать запрос с того же самого подключения.
pthread_mutex_lock()
и pthread_mutex_unlock()
,
чтобы устанавливать и снимать блокировку mutex.Вы должны знать следующее, если Вы имеете поток, который вызывает функции MySQL, но не создал подключение к базе данных MySQL:
Когда Вы вызываете mysql_init()
или
mysql_connect()
, MySQL создаст специфические переменные для
потока, которые используются библиотекой отладки.
Если Вы имеете в потоке вызов функции MySQL прежде, чем поток вызвал
mysql_init()
или mysql_connect()
, поток не будет
иметь необходимых специфических переменных, и Вы, вероятно, свалите программу
в дамп рано или поздно (скорее рано, чем поздно). Чтобы работать спокойно,
надо предпринять следующее:
my_init()
в начале Вашей программы, если она
вызывает любую другую функцию MySQL, перед вызовом
mysql_real_connect()
.
mysql_thread_init()
в драйвере потока перед вызовом
любой функции MySQL.
mysql_thread_end()
перед вызовом
pthread_exit()
. Это освободит память, используемую
специфическими переменными MySQL.Вы можете получать некоторые ошибки из-за неопределенных символов при
компоновке Вашего клиента с mysqlclient_r
. В большинстве случаев
это потому, что Вы не включили библиотеки потоков в строку компоновки.
Библиотека встроенного сервера MySQL делает возможным выполнить полнофункциональный сервер MySQL внутри прикладной программы. Основные выгоды: увеличивается быстродействие и упрощается управление.
libmysqld
В настоящее время, все библиотеки должны быть явно перечислены при
компоновке с -lmysqld
. В будущем mysql_config
--libmysqld-libs
назовет библиотеки, чтобы делать этот проще. Также,
все библиотеки будут, вероятно, включены в libmysqld, чтобы упростить этот
процесс еще сильнее.
Правильные флажки для компиляции и компоновки поточной программы должны использоваться, даже если Вы непосредственно не вызываете никакие функции потоков в Вашем коде.
Эта программа должна работать без любых изменений на Linux или FreeBSD системе. Для других операционных систем будут необходимы маленькие изменения. Этот пример разработан, чтобы дать общее представление о том, как все делать.
Чтобы испытать пример, создайте каталог example в том же самом уровне, где лежит каталог с исходными текстами mysql-4.0. Сохраните в нем файлы example.c и GNUmakefile, после чего выполните GNU make из каталога example.
Файл example.c:
/* * A simple example client, using the embedded MySQL server library */ #include <mysql.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> enum on_error {E_okay, E_warn, E_fail}; static void die(MYSQL *db, char *fmt, ...); MYSQL *db_connect(const char *dbname); void db_disconnect(MYSQL *db); void db_do_query(MYSQL *db, const char *query, enum on_error on_error); const char *server_groups[] = { "test_client_SERVER", "server", NULL }; int main(int argc, char **argv) { MYSQL *one, *two; /* This must be called before any other mysql functions. * * You can use mysql_server_init(0, NULL, NULL), and it will * initialize the server using groups = { "server", NULL }. * * In your $HOME/.my.cnf file, you probably want to put: [test_client_SERVER] language = /path/to/source/of/mysql/sql/share/english * You could, of course, modify argc and argv before passing * them to this function. Or you could create new ones in any * way you like. But all of the arguments in argv (except for * argv[0], which is the program name) should be valid options * for the MySQL server. * * If you link this client against the normal mysqlclient * library, this function is just a stub that does nothing. */ mysql_server_init(argc, argv, server_groups); one = db_connect("test"); two = db_connect(NULL); db_do_query(one, "show table status", E_fail); db_do_query(two, "show databases", E_fail); mysql_close(two); mysql_close(one); /* This must be called after all other mysql functions */ mysql_server_end(); exit(EXIT_SUCCESS); } void die(MYSQL *db, char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); putc('\n', stderr); if (db) db_disconnect(db); exit(EXIT_FAILURE); } MYSQL * db_connect(const char *dbname) { MYSQL *db = mysql_init(NULL); if (!db) die(db, "mysql_init failed: no memory"); mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "simple"); if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0)) die(db, "mysql_real_connect failed: %s", mysql_error(db)); return db; } void db_disconnect(MYSQL *db) { mysql_close(db); } /* * show_query: this code is snagged from mysql.cc; this function * is intended to be used internally to db_do_query() */ static char * show_query(MYSQL *db) { MYSQL_RES *res; MYSQL_FIELD *field; MYSQL_ROW row; char sep[256], *psep = sep; char *is_num = 0; char *err = 0; unsigned int length = 1; /* initial "|" */ unsigned int off; if (!(res = mysql_store_result(db))) return mysql_error(db); if (!(is_num = malloc(mysql_num_fields(res)))) { err = "Не хватило памяти"; goto err; } /* set up */ *psep++ = '+'; while ((field = mysql_fetch_field(res))) { unsigned int len = strlen(field->name); if (len < field->max_length) len = field->max_length; if (len < 2 && !IS_NOT_NULL(field->flags)) len = 2; /* \N */ field->max_length = len + 1; /* bending the API... */ len += 2; length += len + 1; /* " " before, " |" after */ if (length >= 255) { err = "row too long"; goto err; } memset(psep, '-', len); psep += len; *psep++ = '+'; *psep = '\0'; } /* column headings */ puts(sep); mysql_field_seek(res,0); fputc('|',stdout); for (off=0; (field = mysql_fetch_field(res)) ; off++) { printf(" %-*s|",field->max_length, field->name); is_num[off]= IS_NUM(field->type); } fputc('\n',stdout); puts(sep); /* rows */ while ((row = mysql_fetch_row(res))) { (void) fputs("|",stdout); mysql_field_seek(res,0); for (off=0; off < mysql_num_fields(res); off++) { field = mysql_fetch_field(res); printf(is_num[off] ? "%*s |" : " %-*s|", field->max_length, row[off] ? (char*) row[off] : "NULL"); } (void) fputc('\n',stdout); } puts(sep); err: if (is_num) free(is_num); mysql_free_result(res); return err; } void db_do_query(MYSQL *db, const char *query, enum on_error on_error) { char *err = 0; if (mysql_query(db, query) != 0) goto err; if (mysql_field_count(db) > 0) { if ((err = show_query(db))) goto err; } else if (mysql_affected_rows(db)) printf("Affected rows: %lld [%s]\n", mysql_affected_rows(db),query); return; err: switch (on_error) { case E_okay: break; case E_warn: fprintf(stderr, "db_do_query failed: %s [%s]\n", err ? err : mysql_error(db), query); break; case E_fail: die(db, "db_do_query failed: %s [%s]", err ? err : mysql_error(db), query); break; } }
Файл GNUmakefile:
# Set this to your mysql source directory m := ../mysql-4.0 CC := cc CPPFLAGS := -I$m/include -D_THREAD_SAFE -D_REENTRANT CFLAGS := -g -W -Wall LDFLAGS := -static LDLIBS = $(embed_libs) -lz -lm -lcrypt ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null)) # FreeBSD LDFLAGS += -pthread else # Assume Linux LDLIBS += -lpthread endif # Standard libraries embed_libs := \ $m/libmysqld/.libs/libmysqld.a \ $m/isam/libnisam.a \ $m/myisam/libmyisam.a \ $m/heap/libheap.a \ $m/merge/libmerge.a \ $m/myisammrg/libmyisammrg.a # Optionally-built libraries ifneq (,$(shell test -r $m/innobase/usr/libusr.a && echo "yes")) embed_libs += \ $m/innobase/usr/libusr.a \ $m/innobase/odbc/libodbc.a \ $m/innobase/srv/libsrv.a \ $m/innobase/que/libque.a \ $m/innobase/srv/libsrv.a \ $m/innobase/dict/libdict.a \ $m/innobase/ibuf/libibuf.a \ $m/innobase/row/librow.a \ $m/innobase/pars/libpars.a \ $m/innobase/btr/libbtr.a \ $m/innobase/trx/libtrx.a \ $m/innobase/read/libread.a \ $m/innobase/usr/libusr.a \ $m/innobase/buf/libbuf.a \ $m/innobase/ibuf/libibuf.a \ $m/innobase/eval/libeval.a \ $m/innobase/log/liblog.a \ $m/innobase/fsp/libfsp.a \ $m/innobase/fut/libfut.a \ $m/innobase/fil/libfil.a \ $m/innobase/lock/liblock.a \ $m/innobase/mtr/libmtr.a \ $m/innobase/page/libpage.a \ $m/innobase/rem/librem.a \ $m/innobase/thr/libthr.a \ $m/innobase/com/libcom.a \ $m/innobase/sync/libsync.a \ $m/innobase/data/libdata.a \ $m/innobase/mach/libmach.a \ $m/innobase/ha/libha.a \ $m/innobase/dyn/libdyn.a \ $m/innobase/mem/libmem.a \ $m/innobase/sync/libsync.a \ $m/innobase/ut/libut.a \ $m/innobase/os/libos.a \ $m/innobase/ut/libut.a endif ifneq (,$(shell test -r $m/bdb/build_unix/libdb.a && echo "yes")) embed_libs += $m/bdb/build_unix/libdb.a endif # Support libraries embed_libs += \ $m/mysys/libmysys.a \ $m/strings/libmystrings.a \ $m/dbug/libdbug.a \ $m/regex/libregex.a # Optionally built support libraries ifneq (,$(shell test -r $m/readline/libreadline.a && echo "yes")) embed_libs += $m/readline/libreadline.a endif # This works for simple one-file test programs sources := $(wildcard *.c) objects := $(patsubst %c,%o,$(sources)) targets := $(basename $(sources)) all: $(targets) clean: rm -f $(targets) $(objects) *.core
Исходный текст MySQL охвачен GNU GPL. Один результат этого: любая
программа, которая компонуется с libmysqld
и с исходным текстом
MySQL, должна быть выпущена как свободное программное обеспечение (согласно
лицензии, совместимой с GPL).
Авторы поощряют каждого поддерживать свободное программное обеспечение, выпуская код под GPL или совместимой лицензией. Для тех, кто не способен делать это, есть другой вариант: они должны приобрести MySQL у MySQL AB согласно более свободной лицензии.
Mysql++ представляет собой полноценный C++ API для Mysql (а в скором времени и для других баз данных на SQL также). Цель этого API: сделать работу с запросами столь же простой, как работа с другими STL Контейнерами
Последняя версия Mysql++ лежит на web-сайте mysql++ по адресу http://www.mysql.com/download_mysql++.html
Инструкции по присоединению к списку рассылки (и архив списка рассылки) могут быть найдены на домашней страничке Mysql++ по адресу http://www.mysql.com/download_mysql++.html. Если Вы желаете только задать вопрос, можете писать на mysql-plusplus@lists.mysql.com.
Mysql++ API очень сложен и обладает большой мощностью. В этом разделе обеспечивается краткий обзор многих различных компонентов этой библиотеки.
Подобно работе с большинством других SQL API, процесс выполнения запросов тот же самый: 1) Вы открываете подключение, 2) Вы формируете и выполняете запросы, 3) Вы выполняете итерации через набор результатов. Однако имеется много дополнительных функциональных возможностей.
Это тот класс, который обрабатывает подключение к серверу Mysql. Вы всегда нуждаетесь по крайней мере в одном из этих объектов, чтобы делать что-нибудь с сервером. Этот класс может создать отдельный объект запросов или непосредственно выполнять запросы. Отдельный объект запроса является рекомендуемым путем, поскольку это дает Вам гораздо больше мощности.
Этот объект представляет собой рекомендуемый путь выполнения запросов. Это подкласс от strstream, что означает, что Вы можете писать в него данные подобно любому другому потоку. Это сделано, чтобы помочь Вам в гибком и простом формировании запросов.
Вы можете также устанавливать запросы Template с этим классом. Запросы Template представляют собой путь установки запросов с заменяемыми параметрами, которые Вы можете изменять через Вашу программу.
Вы можете также использовать специализированные структуры и даже динамические (на сайте разработчиков они почему-то названы драматическими) наборы результатов, чтобы упростить создание и обработку запросов.
Объект Query возвращает объект с информацией относительно успеха запроса для запросов не-select (запросы, которые не возвращают набор результатов).
Для запросов, которые возвращают набор результатов, имеются два различных пути обработки результатов: в динамическом наборе или в статическом.
Динамический набор результатов представляет собой такой набор результатов, в котором имена столбцов и тип информации столбцов не должны быть определены во времени компиляции. Набор результатов может быть полностью постоянным, в нем жанные будут возвращены Вам в классе constant string link class, частично постоянным, тогда Вы можете изменять данные по одной строке за раз, или полностью переменным, в этом случае Вы можете менять данные как угодно.
Постоянный набор результатов почти аналогичен набору результатов в C API. Он обеспечивает наибольшие функциональные возможности. С этим набором результатов Вы можете выяснять детализированную информацию относительно типа информации, сохраненной в каждом из столбцов. Это также самое быстрое решение потому, что данные не должны быть скопированы вообще.
Частично постоянный набор результатов подобен постоянному набору результатов за исключением того, что Вы можете изменять данные по одной строке за раз. Данные, которые Вы изменяете, фактически копия данных, возвращенных сервером. Это означает, что изменение данных не изменяет фактический набор результатов.
Частично постоянный набор результатов почти то же самое, что и постоянный набор результатов. Единственное различие в том, что когда Вы запрашиваете строку из результата, Вы можете объявить ее изменяемой явно. Это означает, что Вы можете получать некоторые строки как постоянные, а другие как изменчивые.
Полностью изменяемый набор результатов подобен постоянному за исключением того, что данные полностью изменчивы в том смысле, что Вы можете изменять данные в фактическом наборе результатов. Однако, в отличие от первого, этот набор результатов не связан с набором результатов из C API. Взамен это создается копия данных, возвращенных C API в двухмерном векторе. Из-за этого детализированная информация относительно каждого из столбцов в настоящее время не доступна, только имена столбца и тип в C++, который наиболее близко соответствует оригинальному типу из SQL. Кроме того, поскольку это делает копию данных, возвращенных из C API, быстродействие будет чуть пониже.
Строки во всех динамических наборах результатов очень близки к контейнеру произвольного доступа из Standard Template Library (STL). Это означает, что они имеют iterator, который может использоваться для STL-алгоритмов. Имеется несколько специализированных сервисных функций, чтобы помочь в использовании наборов результатов в STL-алгоритмах.
Столбцы во всем динамическом результате также очень близки к контейнеру произвольного доступа из STL. Однако, в дополнение к доступу к столбцам по по их индексным числам, Вы можете также обращаться к столбцам через их имена полей.
Кроме того, поскольку строки и столбцы подобны контейнерам, Вы можете также обрабатывать набор результатов как двумерный массив. Например, Вы можете получить 5-ый элемент в 3-ей строке простым запросом result[3][5]. А так как Вы можете также использовать имена полей, Вы можете написать вместо номера поля его имя, например, result[3]["price"], чтобы получить элемент "price" в 3-ей строке.
Фактические данные, возвращаемые динамическим набором результатов, сохранены в специальной строке подобно классу, которая имеет некоторые дополнительные полезные свойства. А именно: данные столбца автоматически преобразуются во все базисные типы данных, также как некоторые дополнительные типы, которые разработаны, чтобы обработать типы mysql, которые включают типы для обработки дат, времен, наборов и величин со значением null. Если имеется проблема в преобразовании, будет установлена метка предупреждения или возвращена исключительная ситуация в зависимости от того, как пакет настроен. Относительно исключительных ситуаций: MySQL++ поддерживает два различных метода рассмотрения исключительных ситуаций. Первый работает по фиксированному типу, второй (новый) представляет собой стандартный тип C++, использующий метод what(). Выбор методов должен быть выполнен при формировании библиотеки. Если скрипт выбора конфигурации выполнен с опцией -enable-exception, то новый метод будет использоваться. Если никакая опция не обеспечивается, или используется -disable-exception, всегда используется старый метод исключений MySQL++.
Динамические наборы результатов могут даже использоваться, чтобы помочь формировать запросы с помощью некоторого дополнительного метода. Имеются методы для возвратов: 1) Разделенный запятыми список данных (например: 1.5, 10, "Dog", "Brown"), 2) Разделенный запятыми список имен полей (например: age, weight, what, color), 3) Список присваиваний (например: age = 1.5 AND weight = 10 AND what = "Dog" AND color = "Brown").
Изменчивые наборы результатов могут быть созданы так, чтобы Вы могли воспользоваться преимуществом этих методов во вставке данных в базу данных без необходимости писать дополнительные запросы.
Результаты запроса могут также быть сохранены статически в специализированной структуре SQL. Эти структуры затем будут сохранены в некотором STL-контейнере, например, векторе или списке. В отличие от динамических наборов результатов принимается, что программист знает то, что набор результатов собирается вернуть. Из-за этого вся информация относительно столбцов, включая имена, будет потеряна.
Специализированные структуры являются термином C++ structs. Каждый элемент члена сохранен с уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-нибудь еще из STL, чтобы работать с индивидуальными элементами структур. Однако, поскольку эти структуры все равно затем будут сохранены в STL-контейнерах, Вы можете использовать STL-алгоритмы на контейнерах этих структур. Контейнеры представляют строки, а индивидуальные элементы структуры представляют столбцы. Например, Вы можете обращаться к элементу, именованному "price" в третьей строке как к result[3].price. В динамическом наборе результатов то же самое достигается записью result[3]["price"].
Если имеется проблема в преобразовании из набора результатов, возвращенного сервером, к специализированным структурам, возникает исключительная ситуация, которую нужно обработать.
Чтобы помочь в создании запросов, использующих эти специализированные структуры, тот же самый запрос, доступен для применения в динамических наборах результатов. Это включает методы для возврата списков данных.
Этот набор результатов будет выполнен, когда курсоры на стороне сервера будут поддерживаться в MySQL. Но, основываясь на приобретенном знании и опыте при проектирования MySQL++ и MySQLGUI, была сделана предварительная версия. Этот набор результатов полностью динамический в том смысле, что весь набор результатов сохранен в динамическом контейнере C++. Этот контейнер будет только кэшировать набор результатов, и он будет иметь заданный по умолчанию размер. Этот динамический контейнер будет окном в M строк из всего набора результатов в N строк, где N ограничено сервером MySQL. Этот набор результатов будет также полностью динамическим в том смысле, что имена столбцов и тип информации столбцов не должны быть определены во время компиляции. Но все существующие функциональные возможности статических и динамических наборов будут также доступны и в этом наборе. Этот набор будет также иметь методы для модифицирования, удаления и вставки строк, а также ряд специализированных макрокоманд для конструирования классов.
В дополнение к материалу, упомянутому выше, хочу заметить, что есть много универсальных классов, которые могут использоваться с другими программами. Примеры этого включают специальный класс const string, адаптер произвольного доступа, который будет делать контейнер произвольного доступа из класса только с методом size() и определенным оператором subscript ([]), а также универсальный класс запроса SQL, который может использоваться любым SQL C или C++ API.
Начиная с версии 1.7, имеется новое дополнение к библиотекам. Добавилось несколько очень полезных функций для строк STL, которые могут применяться в любом приложении на C++, неважно, скомпоновано оно с MySQL++ или нет. Эти функции содержатся в исходных файлах string_util.hh и string_util.cc.
Это описание, как предполагается, дает Вам начало использования Mysql++ API. Пакет этот сложный, с большим количеством свойств, так что начните с чего-то простого.
Этот учебник предполагает, что Вы знаете C++ довольно хорошо. Считается, что Вы знакомы с исключениями и Standard Template Library (STL).
Все коды примеров формируют полные программы. Однако, чтобы использовать их, Вы должны сначала откомпилировать их, для чего перейдите в каталог с примерами и наберите там make. Затем Вы должны установить базу данных запуском reset-db. Параметры здесь такие:
Когда Вы выполняете программу, Вы должны иметь права доступа с разрешением создавать базы данных. Как только база данных создана, Вы можете использовать другие права доступа для полного доступа к базе данных mysql_cpp_data.
Вы должны также выполнить программу reset-db между примерами, которые изменяют данные, чтобы все работало как надо.
Следующий пример показывает, как открыть подключение, выполнить простой запрос и отобразить результаты. Код может быть найден в файле simple1.cc, который размещен в каталоге примеров пакета.
#include <iostream> #include <iomanip> #include <sqlplus.hh> int main() { Connection con("mysql_cpp_data"); // The full format for the Connection constructor is // Connection(cchar *db, cchar *host="", cchar *user="", cchar *passwd="") // You may need to specify some of them if the database is not on // the local machine or you database username is not the same as your // login name, etc.. Query query = con.query(); // This creates a query object that is bound to con. query << "select * from stock"; // You can write to the query object like you would any other ostrem Result res = query.store(); // Query::store() executes the query and returns the results cout << "Query: " <<query.preview() << endl; // Query::preview() simply returns a string with the current query // string in it. cout << "Records Found: "<< res.size() << endl <<endl; Row row; cout.setf(ios::left); cout << setw(17) << "Item" << setw(4) <<"Num" << setw(7) <<"Weight" << setw(7) <<"Price" << "Date" <<endl << endl; Result::iterator i; // The Result class has a read-only Random Access Iterator for (i = res.begin(); i != res.end(); i++) { row = *i; cout << setw(17) << row[0] << setw(4) << row[1] << setw(7) << row["weight"] << setw(7) <<row[3] << row[4] <<endl; } return 0; }
Этот пример почти подобен предыдущему, однако он использует исключительные ситуации и автоматическое свойство преобразования ColData. Файл с ним назван complic1.cc.
#include <iostream> #include <iomanip> #include <sqlplus.hh> int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); // Here we broke making the connection into two calls. // The first one creates the Connection object with the // use exceptions option turned on and the second one // makes the connection Query query = con.query(); query << "select * from stock"; Result res = query.store(); cout << "Query: " <<query.preview() << endl; cout << "Records Found: "<< res.size() << endl <<endl; Row row; cout.setf(ios::left); cout << setw(17) << "Item" << setw(4) <<"Num" << setw(7) <<"Weight" << setw(7) <<"Price" << "Date" <<endl << endl; Result::iterator i; cout.precision(3); for (i = res.begin(); i != res.end(); i++) { row = *i; cout << setw(17) <<row["item"] << setw(4) <<row[1] << setw(7) << (double)row[2] << setw(7) <<(double)row[3]; Date date = row["sdate"]; // The ColData is implicitly converted to a date here. cout.setf(ios::right); cout.fill('0'); cout << setw(2) <<date.month << "-" << setw(2) << date.day << endl; cout.fill(' '); cout.unsetf(ios::right); } return 0; } catch (BadQuery er) { // handle any connection or // query errors that may come up cerr << "Error: " <<er.error << endl; return -1; } catch (BadConversion er) { // handle bad conversions cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name <<"\"." <<endl; return -1; } }
Все должно быть довольно очевидно. Приведу лишь несколько примечаний относительно исключительных ситуаций:
Следующий пример показывает, как получить некоторую базисную информацию относительно полей, включая имя поля и тип SQL. Файл назван fieldinfo1.cc.
#include <iostream> #include <iomanip> #include <sqlplus.hh> int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock"; Result res = query.store(); cout << "Query: " <<query.preview() << endl; cout << "Records Found: "<< res.size() << endl <<endl; cout << "Query Info:\n"; cout.setf(ios::left); for (unsigned int i = 0; i < res.size(); i++) { cout << setw(2) << i << setw(15) << res.names(i).c_str() << setw(15) << res.types(i).sql_name() << setw(20) << res.types(i).name() << endl; } cout << endl; if (res.types(0) == typeid(string)) cout << "Field 'item' is of an sql type which most closely resembles a\n" << "the c++ string type\n"; if (res.types(1) == typeid(short int)) cout << "Field 'num' is of an sql type which most closely resembles a\n" << "the c++ short int type\n"; else if (res.types(1).base_type() == typeid(short int)) cout << "Field 'num' base type is of an sql type which most closely \n" << "resembles a the c++ short int type\n"; return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << endl; return -1; } catch (BadConversion er) { cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." << endl; return -1; } }
Следующий пример показывает довольно интересное понятие, известное как Specialized SQL Structures (SSQLS). Имя файла для этого кода: custom1.cc.
#include <iostream> #include <iomanip> #include <vector> #include <sqlplus.hh> #include <custom.hh> sql_create_5 (stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate) // this is calling a very complex macro which will create a custom // struct "stock" which has the variables: // string item // int num // ... // Date sdate // defined as well methods to help populate the class from a mysql row // among other things that I'll get too in a latter example int main () { try { Connection con (use_exceptions); con.connect ("mysql_cpp_data"); Query query = con.query (); query << "select * from stock"; vector < stock > res; query.storein (res); // this is storing the results into a vector of the custom struct // "stock" which was created my the macro above. cout.setf (ios::left); cout << setw (17) << "Item" << setw (4) << "Num" << setw (7) << "Weight" << setw (7) << "Price" << "Date" << endl << endl; cout.precision(3); vector <stock>::iterator i; for (i = res.begin (); i != res.end (); i++) { cout << setw (17) << i->item.c_str () << setw (4) << i->num << setw (7) << i->weight << setw (7) << i->price << i->sdate << endl; } return 0; } catch (BadQuery er) { // handle any connection // or query errors that may come up cerr << "Error: " << er.error << endl; return -1; } catch (BadConversion er) { // we still need to cache bad conversions incase something goes // wrong when the data is converted into stock cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." << endl; return -1; } }
Как Вы можете видеть, SSQLS очень мощная штука.
SSQLS может также использоваться, чтобы добавить данные в таблицу. Имя файла для этого кода: custom2.cc.
#include <iostream> #include <vector> #include <sqlplus.hh> #include <custom.hh> #include "util.hh" sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate) int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); stock row; /* row.item = "Hot Dogs"; row.num = 100; row.weight = 1.5; row.price = 1.75; row.sdate = "1998-09-25"; */ row.set("Hot Dogs", 100, 1.5, 1.75, "1998-09-25"); // populate stock query.insert(row); // form the query to insert the row // the table name is the name of the struct by default cout << "Query : " << query.preview() << endl; // show the query about to be executed query.execute(); // execute a query that does not return a result set print_stock_table(query); // now print the new table; } catch (BadQuery er) { cerr << "Error: " <<er.error << endl; return -1; } catch (BadConversion er) { cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." <<endl; return -1; } }
Так как этот пример изменяет данные, Вы должны выполнить программу reset-db после работы примера.
Очень просто изменять данные с помощью SSQLS. Имя файла: custom3.cc.
#include <iostream> #include <vector> #include <sqlplus.hh> #include <custom.hh> #include "util.hh" // util.hh/cc contains the print_stock_table function sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, Date, sdate) int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock where item = \"Hotdogs' Buns\" "; Result res = query.store(); if (res.empty()) throw BadQuery("Hotdogs' Buns not found in table, run reset-db"); stock row = res[0]; stock row2 = row; row.item = "Hotdog Buns"; // now change item query.update(row2, row); // form the query to replace the row // the table name is the name of the struct by default cout << "Query : " << query.preview() << endl; // show the query about to be executed query.execute(); // execute a query that does not return a result set print_stock_table(query); // now print the new table; } catch (BadQuery er) { cerr << "Error: " << er.error << endl; return -1; } catch (BadConversion er) { cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." << endl; return -1; } }
Когда Вы выполняете пример, обратите внимание, что в предложении where проверено только поле item. Не забудьте выполнить reset-db после работы этого примера.
SSQLS могут также быть сделаны less-than-comparable. Это означает, что структуры могут сортироваться и сохраняться в наборах результатов как показывается в следующем примере. Имя файла: custom4.cc.
#include <iostream> #include <iomanip> #include <vector> #include <sqlplus.hh> #include <custom.hh> sql_create_5(stock, 1, 5, string,item, int,num, double,weight, double,price, Date,sdate) int main() { try { // its in one big try block Connection con(use_exceptions); con.connect("mysql_cpp_data"); Query query = con.query(); query << "select * from stock"; set <stock> res; query.storein(res); // here we are storing the elements in a set not a vector. cout.setf (ios::left); cout << setw (17) << "Item" << setw (4) << "Num" << setw (7) << "Weight" << setw (7) << "Price" << "Date" << endl << endl; // Now we we iterate through the set. // Since it is a set the list will // naturally be in order. set <stock>::iterator i; cout.precision(3); for (i = res.begin (); i != res.end (); i++) { cout << setw (17) << i->item.c_str () << setw (4) << i->num << setw (7) << i->weight << setw (7) << i->price << i->sdate << endl; } i = res.find(stock("Hamburger Buns")); if (i != res.end()) cout << "Hamburger Buns found. Currently " << i->num << " in stock.\n"; else cout << "Sorry no Hamburger Buns found in stock\n"; // Now we are using the set's find method to find out how many // Hamburger Buns are in stock. return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << endl; return -1; } catch (BadConversion er) { cerr << "Error: Tried to convert \"" << er.data << "\" to a \"" << er.type_name << "\"." << endl; return -1; } }
При начале разработки MySQl++ 1.6 авторы представили три новых примера, чья цель состоит в том, чтобы показать некоторых из самых сильных свойств MySQL++, а также обеспечить решение некоторых из наиболее частых проблем. Эти примеры иллюстрируют превосходство C++ над другими существующими языками.
Поскольку эти примеры предполагаются к активному использованию (и применяются многими пользователями), константы, которые могут отличаться в разных ситуациях, были сгруппированы, чтобы упростить редактирование. Также, все эти примеры содержат полную ошибку, проверяющую код. Это один из тех редких случаев, в которых обработка исключительной ситуации, принятая в С++, полностью применена в MySQL++.
Эта функция появилась в MySQL version 3.23, но многие пользователи все еще используют старые версии. Пример показывает несколько свойств MySQL++. Эта программа требует одного параметра, который является полным путевым именем для двоичного файла.
#include <sys/stat.h> #include <fstream> #include <mysql++> extern int errno; const char MY_DATABASE[]="telcent"; const char MY_TABLE[]="fax"; const char MY_HOST[]="localhost"; const char MY_USER[]="root"; const char MY_PASSWORD[]=""; const char MY_FIELD[]="fax"; // BLOB field int main(int argc, char *argv[]) { if (argc < 2) { cerr << "Usage: load_file full_file_path" << endl<< endl; return -1; } Connection con(use_exceptions); try { con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); ostrstream strbuf; ifstream In (argv[1],ios::in| ios::binary); struct stat for_len; if ((In.rdbuf())->is_open()) { if (stat (argv[1],& for_len) == -1) return -1; unsigned int blen = for_len.st_size; if (!blen) return -1; char *read_buffer= new char[blen]; In.read(read_buffer,blen); string fill(read_buffer,blen); strbuf << "INSERT INTO " << MY_TABLE <<" (" << MY_FIELD << ") VALUES(\"" << escape << fill << "\")"; query.exec(strbuf.str()); delete[] read_buffer; } else cerr << "Your binary file " << argv[1] << "could not be open, errno = " << errno; return 0; } catch (BadQuery er) { cerr << "Error: " <<er.error << " " <<con.errnum() << endl; return -1; } }
Одно из свойств, которое отображается в этом примере, манипулятор escape. Хотя автоматическое цитирование и экранирование появилось в версии 1.6, это применимо только к классам ColData, так как они содержат информацию о типе данных. Авторы пакета могли бы также делать цитирование и экранировку на общей строке типа данных, но требуется просмотреть всю строку, чтобы выявить все места, где нужна экранировка служебных символов. Поскольку это свойство замедлит код, оно не реализовано.
Этот пример также очень короткий. Рассмотрим функцию, которую он выполняет. Хотя с версии 3.23.3 имеется команда для сброса данных из столбцов BLOB в двоичный файл, эта программа может использоваться не только клиентами, все еще использующими старые версии, но и теми, кто не хочет сбрасывать картинку на диск.
#include <sqlplus.hh> #define MY_DATABASE "telcent" #define MY_TABLE "fax" #define MY_HOST "localhost" #define MY_USER "root" #define MY_PASSWORD "" #define MY_FIELD "fax" // BLOB field #define MY_KEY "datet" // PRIMARY KEY int main (int argc, char *argv[]) { if (argc < 2) { cerr << "Usage: cgi_image primary_key_value" << endl<< endl; return -1; } cout << "Content-type: image/jpeg" << endl; Connection con(use_exceptions); try { con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); query << "SELECT" << MY_FIELD << "FROM " << MY_TABLE << " WHERE " << MY_KEY <<" = " << argv[1]; ResUse res = query.use(); Row row=res.fetch_row(); long unsigned int *jj = res.fetch_lengths(); cout << "Content-length:" << *jj << endl<< endl; fwrite(row.raw_data(0),1,*jj,stdout); return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << " " << con.errnum() << endl; return -1; } }
Этот пример показывает обработку двоичных данных в MySQL++, которая появилась в версии 1.6. Гибкое использование потоков допускает легкое использование этого кода во многих прикладных программах.
Об этом свойстве просят многие пользователи, но пока оно не сделано на уровне ядра СУБД, эта программа может использоваться вместо него. Это маленькая программка, которая также показывает некоторые свойства MySQL++.
#include <sqlplus.hh> #define MY_DATABASE "telcent" #define MY_TABLE "nazivi" #define MY_HOST "localhost" #define MY_USER "root" #define MY_PASSWORD "" #define MY_FIELD "naziv" #define MY_QUERY "SELECT URL from my_table as t1, my_table as t2 \\ where t1.field = t2.field" int main (void) { Connection con(use_exceptions); try { ostrstream strbuf; unsigned int i=0; con.real_connect(MY_DATABASE,MY_HOST,MY_USER,MY_PASSWORD,3306, (int)0,60,NULL); Query query = con.query(); query << MY_QUERY; ResUse res = query.use(); Row row; strbuf << "delete from " << MY_TABLE << " where " << MY_FIELD << " in ("; // for UPDATE just replace the above DELETE FROM with UPDATE statement for (;row=res.fetch_row();i++) strbuf << row[0] << ","; if (!i) return 0; string output(strbuf.str()); output.erase(output.size()-1,1); output += ")"; query.exec((const string&)output); // cout << output << endl; return 0; } catch (BadQuery er) { cerr << "Error: " << er.error << " " << con.errnum() << endl; return -1; } }
Пожалуйста, сообщите в поле команды конструкции запроса MY_FIELD список значений для вставки. Значения поля будут цитироваться или нет в зависимости от их типа. Пользователи должны не должны ставить кавычки (или экранировать их символом escape), поскольку это приведет к ошибке. Этот метод требует несколько больше усилий от программиста. Программист может отключать это свойство, устанавливая соответствующую глобальную переменную переменную в false. Этот пример написан для выполнения DELETE. UPDATE требует изменений.
Все пользователи этих примеров должны быть осторожны: еще одна проверка требуется, чтобы выполнить этот запрос безопасно. А именно, в некоторых критических случаях размер запроса может превысить значение max_allowed. Эта проверка должна быть добавлна.
Это только общий обзор того, что SSQLS может делать. Для получения большего количества информации обратитесь к главе 3.7.
Другое мощное свойство Mysql++: можно устанавливать шаблоны запросов. Следующий пример показывает, как использовать их. Этот код представляет собой фактический код используемый, чтобы устанавливать и/или сбрасывать типовую базу данных. Этот код может быть найден в файле reset-db.cc.
#include <iostream> #include <sqlplus.hh> int main (int argc, char *argv[]) { Connection connection(use_exceptions); try { // the entire main block is one big try block; if (argc == 1) connection.connect(""); else if (argc == 2) connection.connect("",argv[1]); else if (argc == 3) connection.connect("",argv[1],argv[2]); else if (argc <= 4) connection.connect("",argv[1],argv[2],argv[3]); // create a new object and connect based on any (if any) arguments // passed to main(); try { connection.select_db("mysql_cpp_data"); } catch (BadQuery er) { // if it couldn't connect to the database assume that it doesn't exist // and try created it. If that does not work exit with an error. connection.create_db("mysql_cpp_data"); connection.select_db("mysql_cpp_data"); } Query query = connection.query(); // create a new query object try { // ignore any errors here we hope to make this simpler soon query.execute("drop table stock"); } catch (BadQuery er) {} query << "create table stock (item char(20) not null, num smallint," << "weight double, price double, sdate date)"; query.execute(RESET_QUERY); // send the query to create the table and execute it. The // RESET_QUERY tells the query object to reset it self after // execution query << "insert into %5:table values (%q0, %q1, %2, %3, %q4)"; query.parse(); // set up the template query we will use to insert the data. The // parse method call is important as it is what lets the query // know that this is a template and not a literal string query.def["table"] = "stock"; // This is setting the parameter named table to stock. query.execute("Hamburger Buns", 56, 1.25, 1.1, "1998-04-26"); query.execute("Hotdogs' Buns",65, 1.1, 1.1, "1998-04-23"); query.execute("Dinner Roles", 75, 0.95, 0.97, "1998-05-25"); query.execute("White Bread", 87, 1.5, 1.75, "1998-09-04"); // The last parameter "table" is not specified here. Thus // the default value for "table" is used which is "stock". } catch (BadQuery er) { // handle any errors that may come up cerr << "Error: " <<er.error << endl; return -1; } }
Этот раздел документирует все классы для внешнего использования. Если некий класс не зарегистрирован здесь, не используйте кго, поскольку он представляет собой метод или класс для внутреннего пользования.
Используется для создания исключительной ситуации, когда происходит плохое преобразование.
Используется, когда значение Null пытаются преобразовать в тип, к которому оно не может быть преобразовано.
Основной обработчик базы данных.
Специальный тип для хранения дат в формате mysql.
Date представляет собой структуру данных для хранения типов дат mysql. Используется в приеме потоков и операциях вставки.
Комбинация из Date и Time для хранения mysql-типа DateTime.
Вектор имен полей.
Вектор типов полей.
Вектор, подобный контейнеру с чистыми данными mysql о поле.
Контейнерный класс для хранения типов с поддержкой null.
Тип нужный, чтобы использовать для параметра поведения для Null.
Тип нужный, чтобы использовать для параметра поведения для Null.
Тип нужный, чтобы использовать для параметра поведения для Null.
Класс для выполнения запросов.
Этот класс подклассифицируется из SQLQuery. Этот класс в отличие от SQLQuery свободно присоединен к объекту Mysql так, чтобы он мог выполнять запросы.
Эта структура хранит информацию относительно успеха запросов, которые не возвращают наборы результатов.
Этот класс обрабатывает набор результатов.
Это также Random Access Container, который не LessThanComparable и не Assignable. Будучи контейнером произвольного доступа (Random Access Container), это может возвращать Random Access Iterator или обратный Random Access Iterator.
Этот класс обрабатывает фактические строки интеллектуальным способом.
Чистый класс запроса.
Это чистый класс запроса. Он используется для того, чтобы формировать запросы, которые планируется послать объекту Connection. Класс Query может использоваться, если Вы желаете также выполнить запросы без того, чтобы посылать их объекту Connection.
Этот класс подклассифицируется из strstream. Это означает, что Вы можете писать в него подобно потоку, чтобы избежать необходимости создавать свой strstream или применять sprintf. Хотя Вы можете читать из запроса (потому, что это поток), это не рекомендуется. Я не могу гарантировать предсказуемость класса. Однако, можно использовать любой из методов потока, чтобы писать в него. Только удостоверьтесь, что буферные точки Вашего запроса записаны прежде, чем Вы попробуете использовать любой из специфических методов SQLQuery, кроме error() и success().
Исключительная ситуация, когда не задано достаточно параметров.
Этот класс хранит значения параметров для заполнения шаблонов запроса.
Специальная строка, которая преобразуется из чего-либо.
Специальный набор для хранения множеств в формате mysql.
Специальный тип для хранения времени в формате mysql.
Специальная строка, которая создана из существующей const char *.
Адаптер контейнера, чтобы сделать контейнер контейнером произвольного доступа (Random Access Container).
Основной класс для автопреобразований данных столбца. Не используйте непосредственно.
Интеллектуальная строка. Это автоматически преобразуется в любой из базисных типов C. Когда используется с двоичными операторами, она автоматически преобразуется в тип, используемый с другой стороны оператора, если это базисный тип. Однако, будьте внимательным при использовании этого с двоичными операторами, так как MysqlStr("12.86")+2 вернет 14, поскольку 2 является целым числом. Если это мешает, определите макрос NO_BINARY_OPERS для отмены такого поведения. Этот класс также имеет некоторую базисную информацию относительно типа данных, сохраненных в нем. Не используйте этот класс непосредственно. Используйте вместо этого typedef ColData или MutableColData.
Класс, который хранит базисную информацию типа для ColData.
Следующие манипуляторы изменяют только следующий элемент направо от них в цепочке <<. Они могут использоваться с любым ostream (который включает SQLQuery и Query, поскольку они также ostream) или с SQLQueryParms. Когда используются с SQLQueryParms, они отменят любой набор параметров настройки шаблона запросов для этого элемента.
Это свойство можно выключить, установив в Вашем коде переменную dont_quote_auto в значение true.
Идея шаблонов сводится к тому, чтобы оснастить запрос такими параметрами для вызова, которые могут быть изменены между обращениями без необходимости преобразовывать сам запрос.
Чтобы установить шаблон запроса, просто создайте обычным порядком нормальный запрос, например:
query << "select (%2:field1, %3:field2) from stock where %1: wheref = %q0:what"А затем выполните метод Query::parse(). Например:
query.parse()
Шаблон выглядит примерно так:
select (%2:field1, %3:field2) from stock where %1:wheref = %q0:what
Числа представляют номер элемента в структуре SQLQueryParms (рассмотрена чуть ниже).
Формат параметров подстановки:
%(modifier)##(:name)(:)
Здесь Modifier может быть любым из следующего перечня:
``:name'' представляет собой факультативное имя, которое помогает в заполнении SQLQueryParms. Имя может содержать любые алфавитно-цифровые символы или символ подчеркивания. Если Вы используете имя, и должны ввести двоеточие, введите их два последовательно. Первый символ закончит имя, так что второй не будет обработан.
Параметры могут заданы когда запрос выполнен, или раньше срока, используя заданные по умолчанию параметры.
Чтобы определять параметры, когда Вы хотите выполнять запрос, просто используйте Query::store(const SQLString &parm0, [..., const SQLString &parm11]) (или выражение Query::use или Query::execute). Здесь определение parm0 соответствует параметру 0 и так далее. Отсчет идет с нуля, так что первый параметр на самом деле нулевой. Вы можете определять от 1 до 12 различных параметров. Например:
Result res = query.store("Dinner Roles", "item", "item", "price")Для описанного в разделе 3.6.2 шаблона запроса это выведет:
select (item, price) from stock where item = " Dinner Roles"Причина того, почему я не сделал шаблон более логическим:
select (%0:field1, %1:field2) from stock where %2: wheref = %q3:whatСтанет очевидным быстрее.
Вы можете также устанавливать параметры по одному посредством общего члена данных def. Чтобы сменить значения def, просто используйте подстановочные оператора. Вы можете обратиться к параметрам по номерам или по их именем. Например:
query.def[0] = "Dinner Roles"; query.def[1] = "item"; query.def[2] = "item"; query.def[3] = "price";Как и другой вариант:
query.def["what"] = "Dinner Roles"; query.def["wheref"] = "item"; query.def["field1"] = "item"; query.def["field2"] = "price";Имеют тот же самый эффект.
Как только все параметры установлены, просто выполните запрос так, как выполнили бы запрос без всяких шаблонов. Например так:
Result res = query.store()
Вы можете также объединять использование установки параметров во время выполнения и использование объекта def, просто применяя расширенную форму Query::store (можно также use или execute) без необходимых определенных параметров. Например:
query.def["field1"] = "item"; query.def["field2"] = "price"; Result res1 = query.store("Hamburger Buns", "item"); Result res2 = query.store(1.25, "price");Сохранит такой запрос:
select (item, price) from stock where item = "Hamburger Buns"для res1 и
select (item, price) from stock where price = 1.25для res2.
Поскольку расширенная форма Query::store может работать только с начала списка (по номерам, но не по расположению параметров), более логично было бы сделать так:
select (%0:field1, %1:field2) from stock where %2: wheref = %q3:whatНо такой подход в этом случае не сработает. Более сложный вариант
select (%2:field1, %3:field2) from stock where %1: wheref = %q0:whatвсе же был необходим, чтобы Вы могли определять wheref и what.
Следует, однако, помнить, что Query::store(const char* q) также определена для выполнения запроса q. По этой причине, когда Вы используете Query::store (use или execute), только с одним элементом, и этот элемент const char*, Вы должны явно преобразовать это в SQLString. Например:
Result res = query.store(SQLString("Hamburger Buns")).
Если по некоторым причинам Вы не определяли все параметры при выполнении запроса, и неопределенные параметры не имеют значений по умолчанию, заданных через объект def, объект запроса породит объект исключения SQLQueryNEParms. Вы можете выяснить, что же случилось, проверяя значение SQLQueryNEParms::string. Например:
query.def["field1"] = "item"; query.def["field2"] = "price"; Result res = query.store(1.25);породит исключение SQLQueryNEParms по причине того, что wheref не был опеределен нигде.
В теории эта исключительная ситуация никогда не должна быть вызвана. Если она все же возникла, это, вероятно, логическая ошибка на Вашей стороне (например, как в вышеупомянутом примере).
Специализированные структуры SQL (Specialized SQL Structures, SSQLS) позволяют Вам создавать свои структуры для хранения данных для запросов mysql с дополнительными функциональными возможностями. Эти структуры никоим образом не связаны с контейнерами и типами из Standard Template Library (STL). Это именно структуры (structs). Каждый элемент члена сохранен под уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-то еще из STL, чтобы работать с индивидуальными структурами. Однако Вы можете использовать эти структуры как value_type для контейнеров STL.
Следующая команда создаст базисный запрос mysql для использования с типовой базой данных.
sql_create_basic_5(stock, 0, 0, string, item, int, num, double, weight, double, price, MysqlDate, date)Это установит следующую структуру:
struct stock { stock () {} stock (const MysqlRow &row); set (const MysqlRow &row); string item; int num; double weight; double price; MysqlDate date; };Как Вы можете видеть, ничего фантастического в этих структурах нет. Основное преимущество этой простой структуры: конструктор stock (MysqlRow &row), который позволяет Вам легко заполнять вектор stock таким образом:
vector<stock> result; query.storein(result);Требования заключаются в том, что запрос возвращает элементы в том же самом порядке, в каком Вы определили их в заказной структуре.
Общий формат структур:
sql_create_basic_#(NAME, 0, 0, TYPE1, ITEM1, ... TYPE#, ITEM#)Здесь # является числом переменных в векторе, NAME задает имя структуры, которую Вы желаете создать, TYPE1 определяет имя типа для первого элемента, а ITEM1 представляет собой имя переменной для первого элемента и т.д.
Вы можете также сделать структуру сравнимой, заменяя первый 0 в предыдущем примере на ненулевое значение. Это число сообщает, что если первые n чисел одинаковые, то и две структуры совпадают:
sql_create_basic_5(stock, 1, 0, string, item, int, num, double, weight, double, price, MysqlDate, date)Создаст структуру, где только первый элемент будет проверен, чтобы увидеть являются ли две различных структуры действительно различными. Это также позволяет Вам сравнивать одну структуру с другой основываясь на значении элемента. Если n больше одного, это сравнит структуры в лексикографическом порядке. Например, если n=2, это сначала сравнило бы элемент item, и если он был тот же самый, затем будет сравниваться num. Если num был тот же самый, это объявит две структуры идентичными.
struct stock ( ... stock (const string &p1); set (const string &p1); bool operator == (const stock &other) const; bool operator != (const stock &other) const; bool operator > (const stock &other) const; bool operator < (const stock &other) const; bool operator >= (const stock &other) const; bool operator <= (const stock &other) const; int cmp (const stock &other) const; int compare (const stock &other) const; } int compare (const stock &x, const stock &y);int compare (const stock &x, const stock &y) сравнивает x с y и возвращает значение <0, если x < y, 0 если x=y и значение >0, если x > y. stock::cmp и stock::compare действуют аналогично compare(*this, other).
stock::stock представляет собой конструктор, который установит элемент в p1 и оставит все другие переменные неопределенными. Это полезно для создания временных объектов, чтобы использовать для сравнений подобных такому:
x <= stock("Hotdog")
Поскольку stock объявлена как less-then-comparable, Вы можете сохранять результаты запроса в наборе:
set<stock> result; query.storein(result);Вы можете теперь использовать это подобно любому другому набору, например:
cout << result.lower_bound(stock("Hamburger"))->item << endl;вернет первый элемент набора, который начинается с Hamburger.
Вы можете также теперь использовать любой STL-алгоритм который требует, чтобы все значения были less-then-comparable.
Общий формат таков:
sql_create_base_#(NAME, CMP, 0, TYPE1, ITEM1, ... TYPE#, ITEM#)Здесь CMP сообщает, что если первые cmp переменных являются теми же самыми, то две структуры одинаковы.
Последний ноль в последнем примере предназначен для создания другого конструктора. Замените этот ноль на m, и это создаст конструктор, который заполнит первые n переменных. Например:
sql_create_basic_5(stock, 1, 5, string, item, int, num, double, weight, double, price, MysqlDate, date)Также определит следующее:
struct stock { ... stock(const string&, const int&, const double&, const double&, const MysqlDate&); set(const string&, const int&, const double&, const double&, const MysqlDate&); }
Основной формат для sql_create_basic следующий:
sql_create_basic_#(NAME, CMP, CNST, TYPE1, ITEM1, ..., TYPE#, ITEM#)
Вы можете также определять альтернативный порядок, когда mysql заполняет структуру. Например:
sql_create_basic_c_order_5(stock, 2, 5, MysqlDate, date, 5, double, price, 4, string, item, 1, int, num, 2, double, weight, 3)Это создаст структуру, схожую созданной в предыдущем примере за исключением того, что порядок элементов данных будет иным. С++ использует первые два элемента, чтобы сравнить с группой (date, price). Однако, так как определен заказной порядок, Вы можете использовать тот же самый запрос, чтобы заполнить набор. Это заполнит date 5-ым элементом набора результатов запроса, price соответственно 4-м и так далее.
Таким образом, общий формат для sql_create_basic такой:
sql_create_basic_c_order_#(NAME, CMP, CNST, TYPE1, ITEM1, ORDER1, ... TYPE#, ITEM#, ORDER#)
В дополнение к базисным структурам Вы можете устанавливать расширенные структуры, которые также имеют методы определенные, чтобы помочь в создании запросов и во вставке данных в таблицах. Например:
sql_create_5(stock, 1, 5, string, item, int, num, double, weight, double, price, MysqlDate, date)создаст определение, эквивалентное следующему:
struct stock { ... static char *names[]; static char *table; template <class Manip> stock_value_list<Manip> value_list(cchar *d = ",", Manip m = mysql_quote) const; template <class Manip> stock_field_list<Manip> field_list(cchar *d = ",", Manip m = mysql_do_nothing) const; template <class Manip> stock_equal_list<Manip> equal_list(cchar *d = ",", cchar *e = " = ", Manip m = mysql_quote, ) const; template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,]] bool i1, bool i2 = false, ... , bool i5 = false) const; template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,]] stock_enum i1, stock_enum i2=stock_NULL, ..., stock_enum i5 = stock_NULL) const; template <class Manip> stock_cus_value_list<Manip> value_list([cchar *d, [Manip m,]] vector<bool> *i) const; ...(логический эквивалент для field_list и equal_list)... };value_list() возвращает специальный класс, который при использованни с оператором << в ostream слева вернет разделенный запятыми список правильно цитированных и экранированных значений.
field_list() возвращает специальный класс, который делает то же самое, но возвращает список полей, которые хранит структура. Имена полей не цитируются и не экранируются.
equal_list() возвращает разделенный запятыми список в формате имя поля=значение. Имена полей не цитируются и не экранируются, а значения цитируются и экранируются только по мере надобности. Например:
stock s("Dinner Roles",75,0.95,0.97,"1998-05-25"); cout << "Value List: " << s.comma_list() << endl; cout << "Field List: " << s.field_list() << endl; cout << "Equal List: " << s.equal_list() << endl;вернет нечто вроде следующего: Value List: 'Dinner Roles',75,0.95,0.97,'1998-05-25' Field List: item,num,weight,price,date Equal List: item = 'Dinner Roles',num = 75,weight = 0.95, price = 0.97,date = '1998-05-25' Комбинация списков полей и значений может использоваться для запросов замены или вставки. Например:
query << "insert into stock (" << s.field_list() ") values " << s.value_list();вставит s в таблицу stock.
Вы можете также использовать SQLQuery::insert или SQLQuery::replace (и таким образом вызвать Query::insert или Query::replace), чтобы выполнить ту же самую задачу:
query.insert(s);Это использует s.table для имени таблицы, которое задано по умолчанию в имени структуры.
Вы можете также определять различные разделители "d". Если ни один не определен явно, по умолчанию берется ",". Вы можете использовать разделитель " AND " для equal_list, чтобы помочь в запросах выбора и модификации. Например:
stock s2 = s; s2.item = "6 Dinner Roles"; query << "UPDATE TABLE stock SET " << s2.equal_list() << " WHERE " << s.equal_list(" AND ");будет аналогично запросу:
UPDATE TABLE stock SET item = '6 Dinner Roles',num=75,weight = 0.95, price = 0.97,date = '1998-05-25' WHERE item = 'Dinner Roles' AND num = 75 AND weight = 0.95 AND price = 0.97 AND date = '1998-05-25'который изменит запись в таблице так, чтобы элемент был теперь "6 Dinner Roles" вместо "Dinner Roles".
Вы можете использовать SQLQuery::update (и обратиться таким образом к Query::update) для выполнения той же самой задачи:
stock s2 = s; s2.item = "6 Dinner Roles"; query.update(s,s2);Подобно SQLQuery::insert, это использует s.table для имени таблицы, который задан по умолчанию для имени структуры.
Вы можете также определять манипулятор, который методами c++ цитирует или экранирует значения. Это может быть любой имеющий силу манипулятор потока, который только обрабатывает элемент справа от манипулятора. Списки value_list и equal_list имеют значение по умолчанию escape, а field_list имеет do_nothing. Для equal_list манипулятор обрабатывает только часть value, но не трогает часть field name.
Это может быть полезным при экспорте в файл, где Вы не хотите получить кавычки вокруг строк. Например:
table_out << q.value_list("\ t", mysql_escape) << endl;конкатенирует данные к файлу, который обрабатывается table_out.
Три не базисных формы позволяют Вам определять, которые элементы будут Вам возвращены. Например:
cout << q.value_list(false,false,true,true,false) << endl; cout << q.value_list(stock_weight, stock_price) << endl;Оба варианта вернут:
0.95,0.97bool form ожидает булевы параметры, где каждый бит представляет собой инструкцию, что именно надо показывать. Например:
cout << q.value_list(false,false,true,true) << endl;выведет показанное в предыдущем примере.
list form позволяет Вам определять то, которые элементы будут показываться. Значения enum созданы для каждой переменной с именем структуры плюс символ подчеркивания в качестве префикса, например, item обозначается как stock_item.
Эти формы могут быть полезны в запросах выбора. Например:
query << "SELECT * FROM stock WHERE " << q.equal_list(" AND ",stock_weight,stock_price);произведет такой запрос:
SELECT * FROM stock WHERE weight=0.95 AND price=0.97Который выберет все строки из stock, которые имеют weight и price, заданные в операторе как значение q.
vector form (не показанный выше) позволяет Вам передавать булев вектор, который экономит время, если Вы используете некоторый образец больше, чем однажды. Дело в том, что такой подохд позволяет обойти необходимость создавать вектор из параметров каждый раз. Если a представляет собой булев вектор, то a[0] хранит первую переменную, a[1] соответственно вторую и так далее. Например:
vector<bool> a; a[0] = false; a[1] = false; a[2] = true; a[3] = true; a[4] = false; query << "SELECT * FROM stock WHERE " << q.equal_list(" AND ", a);Произведет тот же самый запрос, что и в вышеупомянутом примере.
Вы можете также определять альтернативные имена поля так:
sql_create_c_names_5(stock, 1, 5, string, item, "item", int, num, "quantity", double, weight, "weight", double, price, "price" MysqlDate, date, "shipment")Когда field_list или equal_list применены, это использует данные имена поля вместо имен переменных. Например:
stock s("Dinner Roles",75,0.95,0.97,"1998-05-25"); cout << "Field List: " << s.field_list() << endl; cout << "Equal List: " << s.equal_list() << endl;вернет нечто вроде:
Field List: item,quantity,weight,price,shipment Equal List: item = 'Dinner Roles',quantity = 75,weight = 0.95, price = 0.97,shipment = '1998-05-25'
Основной формат таков:
sql_create_c_names_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ... TYPE#, ITEM#, NAME#)Здесь NAME1 представляет собой имя первого поля. Все остальное так же, как и в формате sql_create_basic_c_order.
Как в sql_create_basic_c_order Вы можете определять заказной порядок. Основная форма такая:
sql_create_c_order_#(NAME, CMP, CNST, TYPE1, ITEM1, ORDER1, ... TYPE#, ITEM#, ORDER#)Здесь все так же, как и в основном формате sql_create_basic_c_order.
Вы можете также определять заказной порядок и заказные имена поля вместе. Основная форма такая:
sql_create_complete_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ORDER1, ... TYPE#, ITEM#, NAME#, ORDER#)Здесь все так же, как и в основном формате sql_create_c_order и sql_create_c_names.
Вы не можете определять различные имена таблицы в фактическом макрообращении. Имя таблицы используется в SQLQuery::insert, replace и update. Однако Вы можете изменять заданное по умолчанию имя таблицы, которое является тем же самым, что и имя структуры, заменяя ссылку NAME::table() на другую const char *:
stock::table() = "in_stock"Это заменит имя таблицы на "in_stock" в примерах, используемых во всем этом руководстве.
Увидеть фактический код, который используют макро вставки sql++pretty, довольно просто. Например так:
sql++pretty < test.cc | less
Самый лучший способ добавлять функциональные возможности: через наследование. Даже при том, что Вы могли бы вставлять выводимый код из pretty.pl и изменять его, это не рекомендуется делать потому, что это не будет отражать будущие расширения.
Макрокоманды определены для структур длиной до 25 элементов. Если Вы должны использовать больше, надо изменить основной скрипт perl (custom.pl). Этот скрипт на perl используется, чтобы генерировать файл заголовка. Он никоим образом не пробует анализировать код на C++.
Файл заголовка, который строит скрипт custom.pl занимает около мегабайта. Однако, пожалуйста обратите внимание, что заголовочный файл (custom-macros.hh) включает ТОЛЬКО макрокоманды. Так что компилятор должен делать очень малый объем работ при чтении файла.
Также, все включенное макрообращением выполнено таким способом, что Вы можете безопасно включать макрокоманду в файл заголовка и не должны волноваться относительно двойных обращений к функции или чего-то подобного.
По умолчанию Mysql++ API использует как короткие имена без префиксов Mysql или mysql_, так и их длинные версии уже с префиксами Mysql или mysql_. Если это вызывает проблемы, определите макрос MYSQL_NO_SHORT_NAMES перед включением mysql++. После этого в принудительном порядке будут использоваться исключительно длинные имена. Их соответствие коротким такое:
Короткое имя | Длинное имя |
BadQuery | MysqlBadQuery |
Connection | MysqlConnection |
ResNSel | ResNSel |
ResUse | ResUse MysqlResUse |
Result | MysqlRes |
Field | MysqlField |
Fields | MysqlFields |
ResIter | MysqlResIter |
ResultIter | MysqlResIter |
Row | MysqlRow |
MutableRow | MysqlMutableRow |
FieldNames | MysqlFieldNames |
Query | MysqlQuery |
BadConversion | MysqlBadConversion |
ColData | MysqlColData |
MutableColData | MysqlMutableColData |
quote | mysql_quote |
quote_only | mysql_quote_only |
quote_double_only | mysql_quote_double_only |
escape | mysql_escape |
do_nothing | mysql_do_nothing |
ignore | mysql_ignore |
Date | MysqDate |
Time | MysqlTime |
DateTime | MysqlDateTime |
Set | MysqlSet |
Null | MysqlNull |
null_type | mysql_null_type |
null | mysql_null |
NullisNull | MysqlNullisNull |
NullisZero | MysqlNullisZero |
NullisBlank | MysqlNullisBlank |
Сайт языка Lua: http://www.tecgraf.puc-rio.br/lua.
Lua представляет собой ядро языка, которое Вы можете внедрять в Вашу прикладную программу. Это означает, что, помимо синтаксиса и семантики, Lua имеет API, который позволяет прикладной программе обмениваться данными с программами на Lua и расширять Lua функциями на C. В этом смысле, Lua может быть расценен как некий базисный метаязык для формирования проблемно-зависимых языков программирования.
Lua был предоставлен первый приз (технологическая категория) в Second Compaq Award for Research and Development in Computer Science в 1997. Это вознаграждение было объединенным предприятием Compaq Computer Brazil, the Brazilian Ministry of Science and Technology и the Brazilian Academy of Sciences.
Lua использовался во многих различных проектах во всем мире. Краткий перечень есть на http://www.tecgraf.puc-rio.br/lua/uses.html.
Lua объединяет простой процедурный синтаксис (подобный Паскалю) с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua имеет динамические типы, интерпретируется из байт-кода и имеет автоматическое управление памятью.
Lua представляет собой мощный, легкий язык программирования расширений разработанный, чтобы поддерживать общее процедурное программирование для средств описания данных. Lua предназначен, чтобы использоваться как мощный и легкий язык конфигураций для любой программы, которая нуждается в этом, и для расширения прикладных программ. Lua также часто используется как автономный язык общего назначения.
Цели реализации: простота, эффективность, мобильность и низкая объемлющая стоимость. Результат: быстрое ядро языка с маленькими требованиями, что делает его идеальным также и во встроенных системах.
Lua написан как библиотека на C, написан на ANSI C и компилирует неизменяемый на всех известных платформах код. Будучи языком расширений, Lua не имеет никакого понятия главной программы: это работает только как вложение в некую ведущую программу. Эта ведущая программа может вызывать функции, чтобы выполнить часть кода в Lua, может писать и читать переменные Lua, и может регистрировать функции C, которые будут вызваны Lua-кодом. С помощью функций C, Lua может быть расширена, чтобы справиться с широким диапазоном различных областей, таким образом создавая настроенные языки программирования, совместно использующие синтаксические рамки.
Lua свободно доступен для академических и коммерческих целей и может быть скачан с различных сайтов в сети:
Базовые http://www.tecgraf.puc-rio.br/lua сайты: http://csg.uwaterloo.ca/~lhf/lua Зеркала: Brazil: ftp://ftp.tecgraf.puc-rio.br/pub/lua/ Canada: ftp://csg.uwaterloo.ca/pub/lhf/lua/ USA: ftp://ftp.freesoftware.com/pub/languages/lua/ Germany: ftp://ftp.uni-trier.de/pub/languages/lua/ Germany: ftp://ftp.gwdg.de/pub/languages/lua/ Greece: ftp://ftp.ntua.gr/pub/lang/lua/ Japan: ftp://ftp.u-aizu.ac.jp/pub/lang/lua/ Denmark: ftp://ftp.ucore.com/lua/dist
Lua распространяется свободно. Реализация, описанная в этом руководстве, доступна по адресам: http://www.tecgraf.puc-rio.br/lua и ftp://ftp.tecgraf.puc-rio.br/pub/lua.
Lua был разработан и выполнен Waldemar Celes, Roberto Ierusalimschy и Luiz Henrique de Figueiredo. С ними можно входить в контакт по e-mail lua@tecgraf.puc-rio.br.
Шлите Ваши комментарии, вопросы и отчеты об ошибках на lua@tecgraf.puc-rio.br. Для сообщений об ошибках попробуйте также список рассылки lua-l@tecgraf.puc-rio.br. Для получения большего количества информации относительно этого списка, включая инструкции о том, как на него подписаться, обратитесь на http://www.tecgraf.puc-rio.br/lua/lua-l.html.
Lua разработан в TeCGraf, the Computer Graphics Technology Group of PUC-Rio (the Pontifical Catholic University of Rio de Janeiro in Brazil). TeCGraf является лабораторией отдела информатики. Множество индустриальных программ, разработанных в TeCGraf, используют Lua.
Все инструкции в Lua выполнены в глобальной среде. Эта среда будет
инициализирована обращением к lua_open
и сохранится до обращения
к lua_close
или до завершения ведущей программы. В случае
необходимости программист может создавать много независимых глобальных сред и
свободно переключаться между ними.
Глобальная среда может управляться Lua-кодом или ведущей программой, которая может читать и писать глобальные переменные, используя функции API из библиотеки, которая предоставлена Lua.
Глобальные переменные в Lua не должны быть объявлены. Любая переменная считается глобальной, пока не объявлена явно как локальная. Перед первым назначением, значение глобальной переменной nil (это значение по умолчанию может быть изменено, подробности в разделе 4.4.8). Таблица используется, чтобы хранить все глобальные имена и значения (таблицы объясняются в разделе 4.3).
Модуль выполнения Lua назван составной частью. Это просто последовательность инструкций, которые выполнены последовательно. Каждая инструкция может факультативно сопровождаться точкой с запятой:
chunk ::= {stat [`;']}Инструкции описаны в разделе 4.4.4. Запись выше представляет собой обычный расширенный BNF, в котором {a} соответствует 0 или более объектов a [a] означает факультативный a, а (a)+ задает один или большее количество a. Полный синтаксис Lua дан в BNF.
Составная часть (chunk) может быть сохранена в файле или в строке в ведущей программе. Когда chunk выполняется, сначала проводится прекомпиляция в байт-код для реальной машины, а затем инструкции будут выполнены в последовательном порядке, моделируя действительную машину. Все модификации глобальной среды сохраняются после окончания работы кода.
Chunk также может быть прекомпилирован в двоичную форму и сохранен в файле. Подробности есть в описании программы luac. Текстовые файлы с кодом и их двоичные прекомпилированные формы взаимозаменяемы. Lua автоматически обнаруживает тип файла и действует соответственно.
Lua представляет собой dynamically typed language. Это означает, что переменные не имеют типов, а только значения. Следовательно, не имеется никаких определений типов на языке. Все значения несут их собственный тип. Помимо типа все значения также имеют тэг.
Имеются шесть базисных типов в Lua:
nil, number (число),
string (строка),
function (функция),
userdata (пользовательские данные) и
table (таблица). Nil тип значения
nil, чье основное свойство должно отличаться от любого другого
значения. Number представляет реальные (двойная точность с плавающей
запятой) числа, в то время как string имеет обычное значение. Lua
нормально понимает 8-разрядные символы, так что строки могут содержать любой
8-разрядный символ, включая вложенные нули ('\0'
). Подробности в
разделе 4.4.1. Функция type
возвращает
строку, описывающую тип данного значения (подробности в разделе
4.6.1).
Функции рассматриваются как значения первого класса (first-class
values) в Lua. Это означает, что функции могут быть сохранены в
переменных, переданы как параметры другим функциям и возвращены как
результаты. Lua может вызывать и управлять как функциями, написанными на Lua,
так и функциями, написанными на C. Два вида функций могут различаться их
тэгами: все функции Lua имеют тот же самый тэг, и все функции C имеют свой
тэг, который отличается от тэга функций Lua. Функция tag
возвращает тэг данного значения (подробности в разделе
4.6.1).
Тип userdata обеспечивается, чтобы позволить произвольным
C-указателям быть сохраненными в Lua-переменных. Этот тип соответствует
void*
и не имеет никаких предопределенных операций в Lua, за
исключением теста равенства и назначения. Однако, используя методы
тэгов, программист может определять операции для значений
userdata. Подробности в разделе 4.4.8.
Тип table осуществляет ассоциативные массивы, то есть массивы,
которые могут быть индексированы не только числами, а любыми значениями (за
исключением nil). Следовательно, этот тип может использоваться не
только, чтобы представить обычные массивы, но также и символные таблицы,
наборы, записи, графы, деревья и т.д. Таблицы представляют собой основной
механизм, структурирующий данные в Lua. Чтобы представлять записи
(records), Lua использует имя поля как индекс. Язык
поддерживает это представление, обеспечивая a.name
как
синтаксический аналог для a["name"]
. Таблицы могут также нести
методы: поскольку функции представляют собой значения первого
класса, поля таблицы могут содержать функции. Форма t:f(x)
синтаксический аналог для t.f(t,x)
, который вызывает метод
f
из таблицы t
прохождением таблицы непосредственно
как первый параметр (подробности в разделе 4.4.5.9).
Обратите внимание, что таблицы представляют собой объекты, а не значения. Переменные не содержат таблицы, только ссылаются на них. Назначение, обработка параметра и возврат всегда управляют ссылками на таблицы и не подразумевают никакого вида копирования. Кроме того, таблицы должны быть явно созданы прежде, чем используются. Подробности в разделе 4.4.5.7.
Каждый из типов nil, number и string имеет
свой тэг. Вообще, очень многое в Lua построено именно вокруг тэгов. Все
значения каждого из этих типов имеют тот же самый предопределенный тэг. Как
объяснено выше, значения типа function могут иметь два различных
тэга в зависимости от того, являются ли они функциями Lua или функциями C. В
заключение, значения типов userdata и table могут иметь
переменные тэги, назначенные программистом (подробности в разделе
4.4.8). Функция tag
возвращает тэг
данного значения. Пользовательские тэги могут быть созданы функцией
newtag
. Функция settag
используется, чтобы изменить
тэг таблицы (подробности в разделе 4.6.1). Тэг
значений userdata может быть установлен из C (подробности в разделе
4.5.7). Тэги главным образом используются, чтобы выбрать
соответствующие методы тэгов, когда происходят некоторые события.
Методы тэгов представляют собой основной механизм для распространения
семантики Lua (подробности в разделе 4.4.8).
Этот раздел описывает лексику, синтаксис и семантику Lua.
Идентификатором в Lua может быть любая строка символов, цифр и символов подчеркивания, не начинающаяся цифрой. Это совпадает с определением идентификаторов в большинстве языков, за исключением того, что определение символа зависит от текущего региона. Любой символ, который считается алфавитным в текущем языке, может использоваться в идентификаторе. То есть, алфавитные символы берутся из настроек текущей системной локали. Замечу, что для лучшей переносимости программ и их применения в разных регионах лучше все же ограничиться латинским алфавитом, цифрами и символом подчеркивания: они применимы везде. Следующие слова зарезервированы, и не могут использоваться как идентификаторы:
and break do else elseif return end for function if in then local nil not or repeat until while
Lua представляет собой язык, чувствительный к регистру символов:
and является зарезервированным словом, но And и
AND (если региональный язык разрешает) не одно и то же. Значит,
приведенные варианты уже можно использовать как имена переменных. Кроме того,
идентификаторы, начинающиеся с символа подчеркивания, сопровождаемого
прописными буквами (типа _INPUT
) зарезервированы для внутренних
переменных. Их не стоит применять в своих программах.
Следующие строки обозначают другие лексемы (tokens):
~= <= >= < > == = + - * ( ) { } [ ] ; , . .. ... /
Литеральные строки могут быть
разграничены одиночными или двойными кавычками, и могут содержать C-подобные
управляющие последовательности: \a
(bell),
\b
(backspace), \f
(form feed),
\n
(newline), \r
(carriage return),
\t
(horizontal tab), \v
(vertical tab),
\\
(backslash), \"
(double quote),
\'
(single quote), и \
newline (то есть,
наклонная черта влево, сопровождаемая реальным newline, который приводит к
переводу строки). Символ в строке может также быть определен числовым
значением, через управляющую последовательность \
ddd,
где ddd последовательность до трех десятичных цифр. Строки
в Lua могут содержать любое 8-разрядное значение, включая вложенные нули,
которые могут быть определены как \000
.
Литеральные строки могут также быть разграничены парами
[[
... ]]
. Литералы в этой форме в скобках могут
занимать по несколько строк, содержать вложенные пары скобок
[[
... ]]
и не интерпретировать управляющие
последовательности. Эта форма особенно удобна для записи строк, которые
содержат части программы или другие цитируемые строки. Как пример, в системе
использующей ASCII-кодировку, следующие три литерала эквивалентны:
1) "alo\n123\"" 2) '\97lo\10\04923"' 3) [[alo 123"]]
Комментарии начинаются с двойного тире
(--
) и выполняются до конца строки. Кроме того, первая строка
составной части всегда пропущена, если начинается с символа
#
. Это средство позволяет использование Lua как интерпретатора
скриптов в Unix-системах.
Числовые константы могут быть написаны с факультативной целой частью и тоже факультативным дробной частями. Допустимо применение экспоненциальной формы запитси. Примеры имеющих силу числовых констант:
3 3.0 3.1416 314.16e-2 0.31416E1
Lua обеспечивает некоторые автоматические преобразования между значениями
во время выполнения. Любая арифметическая операция, примененная к строке,
пробует преобразовывать эту строку в соответствующее число, следуя обычным
правилам. Наоборот, всякий раз, когда используется число, а ожидается строка,
это число будет преобразовано в строку в приемлемом формате. Формат выбран
так, чтобы преобразование из числа в строку было таким, чтобы обратное
преобразование из строки в число было точным. Таким образом,
преобразование не обязательно генерирует хороший текст для некоторых чисел.
Для полного управления тем, как числа будут преобразованы в строки,
используйте функцию format
(подробности в разделе
4.6.2).
Функции в Lua могут возвращать много значений. Потому, что не имеется никаких объявлений типа когда функция вызвана, система не знает, сколько значений вернется, или сколько параметры требуется. Следовательно, иногда список значений должен быть откорректирован во время выполнения к данной длине. Если имеется большее количество значений, чем необходимы, то лишние значения отбрасываются. Если имеется меньшее количество значений, чем необходимы, то список расширен добавлением потребного количества nil. Эта корректировка происходит в многократных назначениях (подробности в разделе 4.4.4.2) и в обращениях к функции (подробности в разделе 4.4.5.8).
Lua поддерживает почти стандартный набор инструкций, подобных таким же наборам на Pascal или C. Стандартные команды включают присваивание, контроль выполнения и вызовы процедур. Нестандартные команды включают конструкторы таблицы и объявления локальных переменных.
block ::= chunk
Блок может быть явно разграничен:
stat ::= do block endЯвные блоки полезны, чтобы управлять областью видимости (контекстом) локальных переменных. Явные блоки также иногда используются, чтобы добавить возврат или разрывать инструкцию в середине другого блока.
stat ::= varlist1 `=' explist1 varlist1 ::= var {`,' var}Эта инструкция сначала оценивает все значения справа и возможные индексы слева, а затем делает примваивание. Так, код:
i = 3 i, a[i] = 4, 20установит
a[3]
в 20, но не воздействует на a[4]
потому, что i
в a[i]
оценен прежде, чем ему было
присвоено значение 4
. Многократное присваивание может
использоваться, чтобы поменять местами два значения, например:
x, y = y, x
Два списка в многократном присваивании могут иметь различные длины. Перед собственно присваиванием, список значений будет откорректирован к длине списка имеющихся переменных.
Одиночное имя может обозначать глобальную переменную, локальную переменную или формальный параметр:
var ::= name
Квадратные скобки используются, чтобы индексировать таблицу:
var ::= varorfunc `[' exp1 `]' varorfunc ::= var | functioncallvarorfunc должен иметь в качестве результата значение из таблицы, где поле, индексированное значением выражения exp1, получает назначенное ему значение.
Синтаксис var.NAME
представляет собой только синтаксический
аналог для выражения var["NAME"]
:
var ::= varorfunc `.' name
Значение присваиваний, оценок глобальных переменных и индексированных
переменных может быть изменено методами тэгов. Фактически, назначение
x=val
, где x
представляет собой глобальную
переменную, является эквивалентным обращению setglobal("x",val)
,
а присваивание t[i]=val
эквивалентно
settable_event(t,i,val)
. В разделе 4.4.8
есть полное описание этих функций (setglobal
находится в
базисной библиотеке, settable_event используется только
для объяснительных целей).
stat ::= while exp1 do block end stat ::= repeat block until exp1 stat ::= if exp1 then block {elseif exp1 then block} [else block] endВыражение exp1 условия структуры управления может возвращать любое значение. Все значения, отличные от nil, рассматриваются как истина, только nil считается ложью.
Инструкция return используется, чтобы возвратить значения из функции или из chunk. Поскольку функции или составные части могут возвращать больше, чем одно значение, синтаксис для инструкции return:
stat ::= return [explist1]
Инструкция break может использоваться, чтобы завершить выполнение цикла, переходя к следующей инструкции сразу после цикла:
stat ::= breakbreak заканчивает самый внутренний вложенный цикл (while, repeat или for).
По синтаксическим причинам инструкции return и break могут
быть написаны только как последние инструкции блока. Если
действительно необходимо вставить их в середину, надо применить явный
внутренний блок, например, do return end
потому, что теперь
return в самом деле последняя инструкция во внутреннем блоке.
Инструкция for имеет две формы, по одной для чисел и таблиц. Числовая версия цикла for имеет следующий синтаксис:
stat ::= for name `=' exp1 `,' exp1 [`,' exp1] do block endИнструкция for, подобная:
for var = e1 ,e2, e3 do block endявляется заменителем кода:
do local var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3) if not (var and _limit and _step) then error() end while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do block var = var+_step end endОбратите внимание на следующее:
_limit
и _step
являются невидимыми переменными.
Имена здесь даны только для объяснительных целей.
var
внутри блока.
var
локальна для инструкции: Вы не можете
использовать ее значение после окончания работы for.
Таблица для инструкции for пересекает все пары (index,value) данной таблицы. Это имеет следующий синтаксис:
stat ::= for name `,' name in exp1 do block endИнструкция for, подобная:
for index, value in exp do block endравносильна такому коду:
do local _t = exp local index, value = next(t, nil) while index do block index, value = next(t, index) end endОбратите внимание на следующее:
_t
является невидимомй переменномй. Имя здесь дано только
для объяснительных целей.
index
внутри блока.
_t
при работе цикла.
index
и var
локальны для инструкции:
Вы не можете использовать их значения после окончания работы for.
index
или value
, присвойте
их другим переменным перед выходом.
stat ::= functioncallВ этом случае все возвращенные значения утрачены. Обращения к функции объясняются в разделе 4.4.5.8.
stat ::= local declist [init] declist ::= name {`,' name} init ::= `=' explist1Если представлено начальное назначение, то оно имеет ту же самую семантику многократного назначения. Иначе все переменные инициализированы nil.
Сhunk также блок, так что локальные переменные могут быть объявлены снаружи любого явного блока.
Область действия (контекст) локальных переменных начинается после
объявления и продолжается до конца блока. Таким образом, код
local print=print
создает локальную переменную, названную
print
, чье начальное значение будет взято из глобальной
переменной с тем же самым именем.
Базисные выражения в Lua такие:
exp ::= `(' exp `)' exp ::= nil exp ::= number exp ::= literal exp ::= var exp ::= upvalue exp ::= function exp ::= functioncall exp ::= tableconstructor
Доступ к глобальной переменной x
эквивалентен обращению
getglobal("x")
, а доступ к индексированной переменной
t[i]
эквивалентен обращению к gettable_event(t,i)
.
Подробности в разделе 4.4.8, там есть описания этих
функций (getglobal
находится в базисной библиотеке).
Нетерминальный exp1 используется, чтобы указать, что значения, возвращенные выражением должны быть откорректированы к одному значению:
exp1 ::= exp
+
(сложение), -
(вычитание), *
(умножение), /
(деление), ^
(возведение в степень),
а также унарный -
(обращение знака числа). Если операнды числа
или строки, которые могут быть преобразованы в числа, (согласно правилам,
данным в разделе 4.4.2), то все операции за
исключением возведения в степень имеют обычное значение. Иначе будет вызван
соответствующий метод тэга. Возведение в степень всегда вызывает метод тэга.
Стандартная математическая библиотека переопределяет этот метод для чисел,
давая ожидаемое значение (подробности в разделе 4.6.3).
== ~= < > <= >=Эти операторы возвращают nil как ложь, или любое другое значение (но не nil) в качестве истины.
Равенство (==
) сначала сравнивает тэги операндов. Если они
различны, то результатом будет nil. Иначе сравниваются их значения.
Числа и строки сравниваются обычным способом. Таблицы, userdata, и функции
сравниваются как ссылки, то есть две таблицы рассматриваются равными только,
если они реально та же самая таблица. Оператор ~=
прямо
противоположен оператору равенства (==
).
Правила преобразования из раздела 4.4.2
НЕ применяются к сравнениям равенства. Таким образом,
"0"==0
вернет false, а t[0]
и
t["0"]
обозначают различные записи в таблице.
Операторы порядка работают следующим образом. Если оба параметра числа, то они сравниваются также. Иначе, если оба параметра строки, то их значения сравниваются, используя лексикографический порядок. Во всех остальных ситуациях будет вызван метод lt тэга (подробности в разделе 4.4.8).
and or notПодобно структурам управления, все логические операторы рассматривают nil как false (ложь), а все остальное как истину (true).
Оператор конъюнкции and
вернет nil, если первый
параметр nil, иначе это возвращает второй параметр. Оператор
дизъюнкции or
вернет первый параметр, если он отличается от
nil, в противном случае это возвращает второй параметр. Операторы
and
и or
используют
краткое вычисление, то есть второй операнд оценен только в случае
необходимости. Имеются две полезных идиомы в Lua, которые используют
логические операторы. Первая идиома:
x = x or vКоторая является эквивалентной:
if x == nil then x = v endЭта идиома устанавливает
x
к значению по умолчанию
v
, когда x
не установлен.
Вторая идиома такая:
x = a and b or cКоторая должна читаться как
x=(a and b) or c
.
Эта идиома эквивалентна:
if a then x = b else x = c endПри условии, что
b
не nil.
and or < > <= >= ~= == .. + - * / not - (unary) ^Все двоичные операторы ассоциативны слева, кроме возведения в степень, который является ассоциативным справа. Прекомпилятор может перестраивать порядок оценки ассоциативных операторов (типа
..
или
+
), пока эти оптимизация не изменяют нормальные результаты.
Однако, эти оптимизация могут изменять некоторые результаты, если Вы
определяете не ассоциативные методы тэгов для этих операторов.
tableconstructor ::= `{' fieldlist `}' fieldlist ::= lfieldlist|ffieldlist|lfieldlist `;' ffieldlist|ffieldlist `;' lfieldlist lfieldlist ::= [lfieldlist1] ffieldlist ::= [ffieldlist1]
Форма lfieldlist1 используется, чтобы инициализировать списки:
lfieldlist1 ::= exp {`,' exp} [`,']Выражения в списке назначены последовательным числовым индексам, начиная с 1 (но не с 0!). Например, код:
a = {"v1", "v2", 34}является эквивалентным коду:
do local temp = {} temp[1] = "v1" temp[2] = "v2" temp[3] = 34 a = temp end
Форма ffieldlist1 инициализирует другие поля в таблице:
ffieldlist1 ::= ffield {`,' ffield} [`,'] ffield ::= `[' exp `]' `=' exp | name `=' expНапример такая запись:
a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c}эквивалентна такому коду:
do local temp = {} temp[f(k)] = g(y) temp.x = 1 -- or temp["x"] = 1 temp.y = 3 -- or temp["y"] = 3 temp[0] = b+c a = temp endВыражения, подобные
{x=1, y=4}
фактически синтаксический
аналог для выражения вида {["x"]=1, ["y"]=4}
.
Обе формы могут иметь факультативную конечную запятую и могут использоваться в том же самом конструкторе, разделенные точкой с запятой. Например, все формы ниже правильны:
x = {;} x = {"a", "b",} x = {type="list"; "a", "b"} x = {f(0), f(1), f(2),; n=3,}
functioncall ::= varorfunc argsСначала вычисляется varorfunc. Если значение имеет тип function, то эта функция будет вызвана с данными параметрами. Иначе вызывается метод function тэга, имея первым параметром значение varorfunc с перечисленными затем первоначальными параметрами обращения. Подробности в разделе 4.4.8.
Форма
functioncall ::= varorfunc `:' name argsМожет использоваться, чтобы вызвать methods. Обращение
v:name(...)
синтаксически аналогично
v.name(v, ...)
, за исключением того, что v
будет
оценен только однажды. Параметры имеют следующий синтаксис:
args ::= `(' [explist1] `)' args ::= tableconstructor args ::= literal explist1 ::= {exp1 `,'} expВсе выражения параметра оценены перед обращением. Обращение в форме
f{...}
синтаксически аналогично f({...})
, то есть
список параметров представляет собой одиночную новую таблицу. Обращение в
форме f'...'
(f"..."
или f[[...]]
)
синтаксически аналогично f('...')
, то есть список параметров
представляет собой одиночную строку литералов.
Потому, что функция может возвращать любое число результатов, число результатов должно быть откорректировано прежде, чем они используются. Если функция вызвана как инструкция, то список возврата откорректирован к 0, таким образом отбрасывая все возвращенные значения. Если функция вызвана в месте, которое нуждается в одиночном значении (синтаксически обозначенном нетерминальным exp1), то список возврата откорректирован к 1, таким образом отбрасывая все возвращенные значения, но не первый. Если функция вызвана в месте, которое может использовать много значений (синтаксически обозначено нетерминальным exp), то никакая корректировка не будет сделана. Единственные места, которые могут обрабатывать много значений, это последние (или единственные) выражения в присваивании, в списке параметров или в инструкции return. Имеются примеры:
f() -- 0 результатов g(f(), x) -- f() 1 результат g(x, f()) -- g получает x и все значения, возвращенные f() a,b,c = f(), x -- f() скорректирован к 1 результату (и c получает nil) a,b,c = x, f() -- f() 2 результата a,b,c = f() -- f() 3 результата return f() -- возвращает все значения, возвращенные f() return x,y,f() -- вернет a, b и все, что вернет f()
Синтаксис для определения функций такой:
function ::= function `(' [parlist1] `)' block end stat ::= function funcname `(' [parlist1] `)' block end funcname ::= name | name `.' name | name `:' nameИнструкция
function f () ... endявляется только синтаксическим аналогом для
f = function () ... endа инструкция
function v.f () ... endявляется синтаксическим аналогом для
v.f = function () ... end
Функциональное определение представляет собой выполнимое выражение, чье значение имеет тип function. Когда Lua прекомпилирует chunk, все функциональные тела также прекомпилируются. Затем, всякий раз, когда Lua выполняет функциональное определение верхние переменные (upvalues) фиксируются, и функция выполняется. Этот функциональный образец (или замкнутое выражение) представляет собой конечное значение выражения. Различные образцы той же самой функции могут иметь различные верхние переменные.
Параметры действуют как локальные переменные, инициализированные со значениями параметра:
parlist1 ::= `...' parlist1 ::= name {`,' name} [`,' `...']Когда функция вызвана, список параметров будет откорректирован к длине списка параметров, если функция не vararg-функция, которая обозначена тремя точками (`
...
') в конце списка параметра. Функция vararg
не корректирует список параметров, вместо этого она собирает все лишние
параметры в неявный параметр, названный arg.
Значением arg
является таблицы из n
полей, чьим
значением является число параметров дополнительного пространства и сами эти
параметры, перечисленные в полях 1, 2, ..., n
.
Как пример, рассмотрите следующие определения:
function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 endИмеем следующее отображение параметров:
ВЫЗОВ ПАРАМЕТРЫ f(3) a=3, b=nil f(3, 4) a=3, b=4 f(3, 4, 5) a=3, b=4 f(r(), 10) a=1, b=10 f(r()) a=1, b=2 g(3) a=3, b=nil, arg={n=0} g(3, 4) a=3, b=4, arg={n=0} g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2} g(5, r()) a=5, b=1, arg={2, 3; n=2}
Результаты возвращены, используя инструкцию return. Если управление достигает конца функции без того, чтобы столкнуться с инструкцией return, то функция будет завершена без результатов.
Синтаксис
funcname ::= name `:' nameиспользуется для определения методов, то есть функции, которые имеют неявный дополнительный параметр self .
Инструкция
function v:f (...) ... endявляется только синтаксическим аналогом для
v.f = function (self, ...) ... endОбратите внимание, что функция получает дополнительный формальный параметр
self
.
Функциональное тело может обратиться к собственным локальным переменным (которые включают и параметры), а также к глобальным переменным, пока они не затенены локальными переменными с тем же самым именем. Функция не может обращаться к локальной переменной из функции включения, так как такие переменные больше не могут существовать, когда функция вызвана. Однако, функция может обращаться к значению локальной переменной из функции включения, используя upvalues, чей синтаксис:
upvalue ::= `%' name
upvalue подобен переменному выражению, но его значение закрепляется, когда функция, в которой он появляется запускается. Имя, используемое в upvalue, может быть именем любой переменной, видимой в том месте, где функция определена, то есть пригодны глобальные переменные и локальные переменные. Обратите внимание, что, когда upvalue таблица, только ссылка на эту таблицу (которая и является значением upvalue) закрепляется, а содержание самой таблицы может быть изменено по желанию. Использование значений таблицы как upvalues представляет собой методику для наличия перезаписываемого но частного состояния, приложенного к функциям.
Имеются некоторые примеры:
a,b,c = 1,2,3 -- глобальные переменные local d function f (x) local b = {} -- x и b локальны для f, b затеняет глобальную b local g = function (a) local y -- a и y локальны для g p = a -- OK, доступ к локальной a p = c -- OK, доступ к глобальной c p = b -- ERROR: невозможен доступ к переменной вне зоны видимости p = %b -- OK, доступ к замороженной b (локальная f) %b = 3 -- ERROR: нельзя менять upvalue %b.x = 3 -- OK, изменение содержимого таблицы p = %c -- OK, доступ к замороженному значению глобальной c p = %y -- ERROR: `y' невидима, где `g' определена p = %d -- ERROR: `d' невидима, где `g' определена end -- g end -- f
Поскольку Lua язык расширений, все действия Lua начинаются из
C-кода в ведущей программе, вызывающей функцию из Lua-библиотеки. Всякий раз,
когда ошибка происходит в течение Lua-трансляции или выполнения, вызывается
функция _ERRORMESSAGE
и затем
соответствующая функция из библиотеки (lua_dofile
,
lua_dostring
, lua_dobuffer
или
lua_call
) завершена, возвращая условие ошибки.
Ошибки распределения памяти представляют собой исключительную ситуацию из
предыдущего правила. Когда происходит сбой распределения памяти, Lua не может
выполнить функцию _ERRORMESSAGE
. Так что, для этого вида ошибки,
Lua не вызывает функцию _ERRORMESSAGE
. Вместо этого
соответствующая функция из библиотеки немедленно завершится со специальным
кодом ошибки (LUA_ERRMEM
). Это и другие коды ошибки определено в
заголовочном файле lua.h
, подробности в разделе
4.5.8.
Единственный параметр _ERRORMESSAGE
: строка, описывающая
ошибку. Заданное по умолчанию определение для этого: обращение к функции
_ALERT
, которая печатает сообщение на
stderr
. Стандартная библиотека ввода-вывода переопределяет
_ERRORMESSAGE
и использует средства отладки, чтобы печатать
некоторую дополнительную информацию, типа расположения обращений в стеке.
Lua-код может явно генерировать ошибку, вызывая функцию
error
(подробности в разделе 4.6.1).
Lua-код может перехватить ошибку, используя обращение к функции
call
(подробности в разделе 4.6.1).
Lua обеспечивает мощный механизм, чтобы расширить семантику, названный методами тэгов. Это определенная программистом функция, которая вызвана в специфических точках в течение выполнения программы Lua, позволяя программисту изменить стандартное поведение Lua в этих точках. Каждая из этих точек названа событием (event).
Метод тэга для некоего специфического события выбран согласно тэгу
значения. Функция settagmethod изменяет
метод тэга, связанный с данной парой (tag, event). Первый параметр
представляет собой тэг, второй строку (имя события), а третий параметр
(функция) задает новый метод или nil, чтобы восстановить заданное по
умолчанию поведение для пары. Функция settagmethod
возвращает
предыдущий метод тэга для этой пары. Функция-компаньон
gettagmethod получает тэг и имя события и
возвращает текущий метод, связанный с парой.
Методы тэгов вызваны при соответствующих событиях, которые
идентифицированы данными именами. Семантика методов лучше объяснена функцией
Lua, описывающей поведение интерпретатора в каждом событии. Эта функция не
только показывает, когда метод вызван, но также параметры, результаты и
заданное по умолчанию поведение. Код, показанный здесь, только иллюстративен:
реальное поведение сложно закодировано в интерпретаторе и намного более
эффективно, чем это моделирование. Все функции, используемые в этих
описаниях (rawget
, tonumber
, call
и
т.д.), описаны подробно в разделе 4.6.1.
+
применяется
к не числовым операндам.
Функция getbinmethod
ниже определяет, как Lua выбирает метод
для двоичной операции. Сначала Lua пробует первый операнд. Если тэг не
определяет метод для операции, то Lua пробует второй операнд. Если это также
терпит неудачу, то Lua получает метод из тэга 0.
function getbinmethod (op1, op2, event) return gettagmethod(tag(op1), event) or gettagmethod(tag(op2), event) or gettagmethod(0, event) endПри использовании этой функции, метод события ``add'' такой:
function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- both operands are numeric return o1+o2 -- '+' here is the primitive 'add' else -- at least one of the operands is not numeric local tm = getbinmethod(op1, op2, "add") if tm then -- call the method with both operands and an extra -- argument with the event name return tm(op1, op2, "add") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end end
-
применяется
к не числовым операндам. Поведение подобно событию ``add''.
*
применяется
к не числовым операндам. Поведение подобно событию ``add''.
/
применяется
к не числовым операндам. Поведение подобно событию ``add''.
^
(возведение
в степень) применяется к числовым операндам.
function pow_event (op1, op2) local tm = getbinmethod(op1, op2, "pow") if tm then -- call the method with both operands and an extra -- argument with the event name return tm(op1, op2, "pow") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end
-
применяется к не числовому операнду.
function unm_event (op) local o = tonumber(op) if o then -- operand is numeric return -o -- '-' here is the primitive 'unm' else -- the operand is not numeric. -- Try to get a tag method from the operand; -- if it does not have one, try a "global" one (tag 0) local tm = gettagmethod(tag(op), "unm") or gettagmethod(0, "unm") if tm then -- call the method with the operand, nil, and an extra -- argument with the event name return tm(op, nil, "unm") else -- no tag method available: default behavior error("unexpected type at arithmetic operation") end end end
<
.
function lt_event (op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 < op2 -- numeric comparison elseif type(op1) == "string" and type(op2) == "string" then return op1 < op2 -- lexicographic comparison else local tm = getbinmethod(op1, op2, "lt") if tm then return tm(op1, op2, "lt") else error("unexpected type at comparison"); end end endДругие операторы порядка используют этот метод согласно обычным эквивалентностям:
a>b <=> b<a a<=b <=> not (b<a) a>=b <=> not (a<b)
function concat_event (op1, op2) if (type(op1) == "string" or type(op1) == "number") and (type(op2) == "string" or type(op2) == "number") then return op1..op2 -- primitive string concatenation else local tm = getbinmethod(op1, op2, "concat") if tm then return tm(op1, op2, "concat") else error("unexpected type for concatenation") end end end
newtag
. Обратите
внимание, что тэг представляет собой текущее
значение глобальной переменной.
function getglobal (varname) -- access the table of globals local value = rawget(globals(), varname) local tm = gettagmethod(tag(value), "getglobal") if not tm then return value else return tm(varname, value) end endФункция
getglobal
определена в базисной библиотеке.
function setglobal (varname, newvalue) local oldvalue = rawget(globals(), varname) local tm = gettagmethod(tag(oldvalue), "setglobal") if not tm then rawset(globals(), varname, newvalue) else tm(varname, oldvalue, newvalue) end endФункция
setglobal
определена в базисной библиотеке.
function gettable_event (table, index) local tm = gettagmethod(tag(table), "gettable") if tm then return tm(table, index) elseif type(table) ~= "table" then error("indexed expression not a table"); else local v = rawget(table, index) tm = gettagmethod(tag(table), "index") if v == nil and tm then return tm(table, index) else return v end end end
function settable_event (table, index, value) local tm = gettagmethod(tag(table), "settable") if tm then tm(table, index, value) elseif type(table) ~= "table" then error("indexed expression not a table") else rawset(table, index, value) end end
function function_event (func, ...) if type(func) == "function" then return call(func, arg) else local tm = gettagmethod(tag(func), "function") if tm then for i=arg.n,1,-1 do arg[i+1] = arg[i] end arg.n = arg.n+1 arg[1] = func return call(tm, arg) else error("call expression not a function") end end end
function gc_event (obj) local tm = gettagmethod(tag(obj), "gc") if tm then tm(obj) end endВ цикле уборки мусора методы тэгов для userdata вызываются в порядке, обратном созданию тэгов, то есть первые методы, которые будут вызваны, связаны с последним тэгом, созданным в программе. Кроме того, в конце цикла Lua делает эквивалент обращения
gc_event(nil)
.lua.h
.
Даже когда используем термин "функция", любое средство в API можно обеспечить как макрокоманду. Все такие макрокоманды используют каждый из параметров точно однажды и не генерируют скрытые побочные эффекты.
Библиотека Lua полностью повторно используема: она не имеет никаких
глобальных переменных. Все состояние интерпретатора Lua (глобальные
переменные, стек, методы тэгов и т.д.) сохранено в динамически распределенной
структуре типа
lua_State
. Это состояние должно быть передано как первый
параметр каждой функции в библиотеке (за исключением lua_open
).
Перед вызовом любой функции API, Вы должны создать состояние вызовом:
lua_State *lua_open (int stacksize);Единственный параметр этой функции: размер стека для интерпретатора. Каждое обращение к функции нуждается в одной позиции стека для каждого параметра, локальной переменной и временного значения, плюс по одной позиция для бухгалтерии. Стек должен также иметь приблизительно 20 позиций дополнительного пространства доступными. Для очень маленьких реализаций, без применения рекурсивных функций, размер стека в 100 должен быть достаточным. Если параметр
stacksize
равен 0, то используется заданный
по умолчанию размер в 1024.
Чтобы освободить состояние, созданное lua_open
, вызовите:
void lua_close (lua_State *L);Эта функция уничтожает все объекты в данной среде Lua (вызывая соответствующие методы тэгов для уборки мусора, если они есть) и освобождает всю динамическую память, используемую этим состоянием. Обычно Вы не должны вызвать эту функцию потому, что все ресурсы естественно освобождены, когда Ваша программа заканчивается. С другой стороны, долго работающие программы должны бы освобождать ресурсы как только они становятся ненужными, чтобы не становиться слишком большими.
За исключением lua_open
все функции в Lua API нуждаются в
состоянии как в первом параметре.
Lua использует стек (stack), чтобы передавать значения в и из C. Каждый элемент в этом стеке представляет значение Lua (nil, число, строка).
Для удобства большинство операций запроса в API не следует за строгой
дисциплиной стека. Вместо этого они могут обратиться к любому элементу в
стеке, используя индекс: положительный индекс представляет абсолютную позицию
стека (начиная с 1, а не с 0, как в C). Отрицательный индекс представляет
смещение от верхней части стека. Более определенно, если стек имеет
n элементов, индекс 1 представляет первый элемент (то есть, первый
элемент, помещенный в стек), а индекс n представляет последний
элемент. Индекс -1 также представляет последний элемент (то есть,
элемент наверху), и индекс -n представляет первый элемент. Мы говорим,
что индекс имеет силу, если он находится между 1 и верхней частью стека (то
есть, если 1 <= abs(index) <= top
).
В любое время Вы можете получать индекс верхнего элемента вызовом:
int lua_gettop (lua_State *L);Потому, что начало индексов в 1, результат
lua_gettop
равно
числу элементов в стеке (0 стало быть означает пустой стек).
Когда Вы взаимодействуете с Lua API, Вы ответственны за контроль переполнения стека. Функция
int lua_stackspace (lua_State *L);возвращает число доступных позиций стека. Всякий раз, когда Lua вызывается C, это гарантирует, что по крайней мере
LUA_MINSTACK
позиций все
еще доступны. LUA_MINSTACK
определен в файле заголовка
lua.h
и по крайней мере 16, так что Вы должны позаботиться о
месте в стеке только, когда Ваш код имеет циклы, помещающие элементы в стек.
Большинство функций запроса принимает как индексы любое значение внутри
доступного места в стеке. Такие индексы названы приемлемыми индексами
. Более формально можно определять приемлемый индекс таким образом:
(index < 0 && abs(index) <= top) ||
(index > 0 && index <= top + stackspace)
Обратите внимание, что 0 не является приемлемым индексом.
void lua_settop(lua_State *L, int index); void lua_pushvalue(lua_State *L, int index); void lua_remove(lua_State *L, int index); void lua_insert(lua_State *L, int index);
lua_settop
принимает любые приемлемые индексы или 0 и
устанавливает верхнюю часть стека к этому индексу. Если новая верхняя часть
больше, чем старая, то новые элементы заполнены nil. Если
index
равен 0, то все элементы из стека будут удалены. Полезная
макрокоманда, определенная в API:
#define lua_pop(L,n) lua_settop(L, -(n)-1)выталкивает
n
элементов из стека.
lua_pushvalue
помещает в стек копию элемента в
данном индексе. lua_remove
удаляет элемент в данной позиции,
сдвигая элементы вверх от этой позиции, чтобы заполнить промежуток.
lua_insert
перемещает верхний элемент в данную позицию, сдвигая
элементы вверх от позиции на открытое место. Эти функции принимают только
имеющие силу индексы. Как пример, если стек хранит значения (снизу вверх)
10 20 30 40 50
:
lua_pushvalue(L, 3) --> 10 20 30 40 50 30 lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30 lua_remove(L, -3) --> 10 20 30 40 30 30 lua_remove(L, 6) --> 10 20 30 40 30 lua_insert(L, 1) --> 30 10 20 30 40 lua_insert(L, -1) --> 30 10 20 30 40 (никакого эффекта нет) lua_settop(L, -3) --> 30 10 20 lua_settop(L, 6) --> 30 10 20 nil nil nil
Чтобы проверять тип элемента стека, следующие функции доступны:
int lua_type(lua_State *L, int index); int lua_tag(lua_State *L, int index); int lua_isnil(lua_State *L, int index); int lua_isnumber(lua_State *L, int index); int lua_isstring(lua_State *L, int index); int lua_istable(lua_State *L, int index); int lua_isfunction(lua_State *L, int index); int lua_iscfunction(lua_State *L, int index); int lua_isuserdata(lua_State *L, int index);Эти функции могут быть вызваны с любым приемлемым индексом.
lua_type
возвращает одну из следующих констант, согласно типу
данного объекта: LUA_TNIL
, LUA_TNUMBER
,
LUA_TSTRING
, LUA_TTABLE
,
LUA_TFUNCTION
, LUA_TUSERDATA
. Если индекс не имеет
силу (то есть, если та позиция стека пуста), то lua_type
возвращает LUA_TNONE
. Эти константы могут быть преобразованы в
строки с помощью вызова:
const char *lua_typename(lua_State *L, int t);здесь
t
представляет собой тип, возвращенный
lua_type
. Строки, возвращаемые lua_typename
:
"nil"
, "number"
, "string"
,
"table"
, "function"
, "userdata"
и
"no value"
,
lua_tag
возвращает тэг значения или LUA_NOTAG
для не имеющего силу индекса.
Функция lua_is*
возвращает 1, если объект совместим с данным
типом, и 0 в противном случае. Всегда возвращается 0 для не имеющего силу
индекса. lua_isnumber
принимает числа и числовые строки.
lua_isstring
берет строки и числа и lua_isfunction
воспринимает функции Lua и C. Чтобы различать между функциями Lua и функциями
C, Вы должны использовать lua_iscfunction
. Чтобы различать между
числами и числовыми строками, Вы можете использовать lua_type
.
API также имеет функции, чтобы сравнить два значения в стеке:
int lua_equal(lua_State *L, int index1, int index2); int lua_lessthan(lua_State *L, int index1, int index2);Эти функции эквивалентны их дубликатам в Lua. Определенно,
lua_lessthan
эквивалентна lt_event
. Обе функции
возвращают 0, если любой из индексов не имеет силу.
Чтобы транслировать значение в стеке к специфическому типу C, Вы можете использовать следующие функции преобразования:
double lua_tonumber(lua_State *L, int index); const char *lua_tostring(lua_State *L, int index); size_t lua_strlen(lua_State *L, int index); lua_CFunction lua_tocfunction(lua_State *L, int index); void *lua_touserdata(lua_State *L, int index);Эти функции могут быть вызваны с любым приемлемым индексом. Когда вызваны с не имеющим силу индексом, они действуют так, как будто переданное им значение имело неправильный тип.
lua_tonumber
преобразовывает значение в данном индексе к
числу с плавающей запятой. Это значение должно быть числом или строкой,
обратимой в число (подробности в разделе 4.2). Иначе
lua_tonumber
возвращает 0.
lua_tostring
преобразовывает значение Lua в строку
(const char*
). Это значение должно быть числом или строкой,
иначе будет возвращен NULL
. Эта функция возвращает указатель на
строку внутри Lua-среды. Эти строки всегда имеют ноль ('\0'
)
после их последнего символа (как в C), но могут содержать другие ноли в их
теле. Если Вы не знаете, может ли строка содержать ноли, Вы должны
использовать lua_strlen
, чтобы получить фактическую длину.
Потому, что Lua имеет мусороуборщик, не имеется никакой гарантии, что
указатель, возвращенный lua_tostring
, будет иметь силу после
того, как соответствующее значение удалено из стека.
lua_tocfunction
преобразовывает значение в стеке к функции C.
Это значение должно быть функцией C, иначе lua_tocfunction
возвращает NULL
. Тип lua_CFunction
рассмотрен более
подробно в отдельном разделе 5.13.
lua_touserdata
преобразовывает значение в void*
.
Это значение должно иметь тип userdata, иначе
lua_touserdata
вернет NULL
.
API имеет следующие функции, чтобы поместить значения C в стек:
void lua_pushnumber(lua_State *L, double n); void lua_pushlstring(lua_State *L, const char *s, size_t len); void lua_pushstring(lua_State *L, const char *s); void lua_pushusertag(lua_State *L, void *u, int tag); void lua_pushnil(lua_State *L); void lua_pushcfunction(lua_State *L, lua_CFunction f);Эти функции получают значение C, преобразовывают его в соответствующее значение Lua, и помещают результат в стек. В частности,
lua_pushlstring
и lua_pushstring
делают
внутреннюю копию данной строки. lua_pushstring
может
использоваться только, чтобы поместить соответствующие C-строки (то есть,
такие строки, которые заканчиваются нолем и не содержат вложенные ноли),
иначе Вы должны использовать более общую функцию
lua_pushlstring
, которая принимает явный размер данных.
Lua использует два числа, чтобы управлять совокупностью мусора. Одно число рассчитывает, сколько байтов динамической памяти Lua использует, а другое задает порог. Это внутренний счетчик байтов, сохраняемый Lua не полностью аккуратно: это может отклоняться на 10% от реального положения дел в памяти. Когда число байтов пересекает порог, Lua выполняет цикл зачистки мусора, который исправляет память и стирает оттуда все отработавшие свое, но забытые там объекты (то есть объекты, больше доступные из Lua). Счетчик байтов будет исправлен, а затем порог сброшен к двойному значению счетчика байтов.
Вы можете обращаться к текущим значениям этих двух чисел через следующие функции:
int lua_getgccount (lua_State *L); int lua_getgcthreshold (lua_State *L);Оба возвращают их соответствующие значения в килобайтах. Вы можете изменять пороговое значение с помощью:
void lua_setgcthreshold (lua_State *L, int newthreshold);Снова значение
newthreshold
задано в килобайтах. Когда Вы
вызываете эту функцию, Lua устанавливает новый порог и проверяет счетчик
байтов. Если новый порог меньше, чем счетчик байтов, то Lua немедленно
выполняет уборку мусора. После нее новый порог будет установлен
согласно предыдущему правилу.
Если Вы хотите изменять поведение коллектора мусора адаптивно, Вы можете использовать метод тэга мусоросборщика для nil, чтобы установить ваш собственный порог (метод тэга будет вызван после того, как Lua сбрасывает порог).
Поскольку userdata представляют собой объекты, функция
lua_pushusertag
может создавать новые userdata. Если Lua
имеет userdata с данным значением (void*
) и тэг, то этот объект
размещен. Иначе создается новый userdata с данным значением и тэгом. Если эта
функция вызвана с тэгом, равным LUA_ANYTAG
, то Lua пробует находить любой объект userdata с данным значением,
независимо от его тэга. Если не имеется никакого userdata с этим значением,
то новый объект будет создан с тэгом, равным 0.
Userdata может иметь различные тэги, чья семантика известна только ведущей программе. Тэги создаются функцией:
int lua_newtag (lua_State *L);Функция
lua_settag
меняет тэг объекта в верхней части стека (без
того, чтобы получить его):
void lua_settag (lua_State *L, int tag);Объект должен быть userdata или таблицей, данный тэг должен быть значением, созданным с помощью функции
lua_newtag
.
int lua_dofile(lua_State *L, const char *filename); int lua_dostring(lua_State *L, const char *string); int lua_dobuffer(lua_State *L, const char *buff, size_t size, const char *name);Эти функции возвращают 0 в случае успеха, или один из следующих кодов ошибки, если они терпят неудачу:
_ERRORMESSAGE
(подробности в разделе 4.4.7).
_ERRORMESSAGE
. Для таких ошибок Lua не вызывает
_ERRORMESSAGE
снова, чтобы избежать циклов.
lua_dofile
). В этом случае Вы можете проверять
errno
, вызывая strerror
или perror
,
чтобы сообщить пользователю, что пошло неправильно.lua.h
.
Когда функция lua_dofile
вызвана с параметром
NULL
, она выполняет поток stdin
.
lua_dofile
и lua_dobuffer
способны выполнить
прекомпилируемые объекты кода. Они автоматически обнаруживают, является ли
кусок кода текстовым или двоичным, и загружают его соответственно.
lua_dostring
выполняет только исходный текст, заданный в
простой текстовой форме.
Третий параметр для lua_dobuffer
задает имя chunk, который
используется сообщениях об ошибках и отладочных сообщениях. Если имя
name
равно NULL
, то Lua дает заданное по умолчанию
имя этому chunk.
Эти функции помещают в стек любые значения, в конечном счете возвращенные
кодом. Код может возвращать любое число значений; Lua соблюдает осторожность,
в том плане, что эти значения вписываются в размер стека, но после обращения
ответственность переходит к Вам. Если Вы должны поместить другие элементы
после вызова любой из этих функций, и Вы хотите работать спокойно, Вы должны
или проверить место в стеке с помощью lua_stackspace
, или
удалять возвращенные элементы из стека (если Вы не нуждаетесь в них).
Например, следующий код загружает код в файле и отбрасывает все результаты,
возвращенные этим кодом:
{ int oldtop = lua_gettop(L); lua_dofile(L, filename); lua_settop(L, oldtop); }
Чтобы прочитать значение глобальной переменной Lua, надо:
void lua_getglobal (lua_State *L, const char *varname);Это помещает в стек значение данной переменной. Как в Lua эта функция может вызывать метод тэга для события getglobal. Чтобы читать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют
lua_rawget
над таблицей глобальных переменных.
Чтобы записать значение в глобальнукю переменную:
void lua_setglobal (lua_State *L, const char *varname);Это извлекает из стека значение, которое будет сохранено в данной переменной. Как в Lua эта функция может вызывать метод тэга для события setglobal. Чтобы устанавливать реальное значение глобальной переменной без того, чтобы вызывать любой метод тэга, используют
lua_rawset
над таблицей
глобальных переменных (подробности приведены ниже).
Все глобальные переменные сохраняются в обычной Lua-таблице. Вы можете получать ее вызовом:
void lua_getglobals (lua_State *L);Это помещает текущую (актуальную) таблицу глобальных переменных в стек. Чтобы устанавливать другую таблицу глобальных переменных, используйте вызов:
void lua_setglobals (lua_State *L);Таблица, которую нужно использовать, извлекается из стека.
Чтобы читать значение в таблице, таблица должна находиться где-нибудь в стеке. Теперь вызовите
void lua_gettable (lua_State *L, int index);где
index
относится к таблице. lua_gettable
извлекает ключ из стека и возвращает (через стек) содержание таблицы для
заданного ключа. Как в Lua эта операция может вызывать метод тэга для
события gettable. Получать реальное значение любого ключа таблицы, без того,
чтобы вызывать любой метод тэга, можно, используя
void lua_rawget (lua_State *L, int index);
Чтобы сохранять значение в таблицу, которая находится где-нибудь в стеке, Вы помещаете ключ и значение в стек (именно в этом порядке!), а затем вызываете такое обращение:
void lua_settable (lua_State *L, int index);здесь
index
относится к таблице. lua_settable
извлекает из стека ключ и значение. Как и все в Lua, эта операция может
вызывать метод тэга для события settable. Чтобы устанавливать реальное
значение любого индекса таблицы без того, чтобы вызывать любой метод тэга,
используют raw-версию:
void lua_rawset (lua_State *L, int index);
В заключение, еще одна функция
void lua_newtable (lua_State *L);создает новую, пустую, таблицу и помещает ее в стек.
void lua_rawgeti(lua_State *L, int index, int n); void lua_rawseti(lua_State *L, int index, int n); int lua_getn(lua_State *L, int index);
lua_rawgeti
получает значение энного элемента таблицы в
позиции index
стека.
lua_rawseti
устанавливает значение энного элемента таблицы в
позиции index
стека к значению наверху стека.
lua_getn
возвращает число элементов в таблице в позиции
index
. Это число представляет собой значение поля n
таблицы, если это имеет числовое значение, или самый большой числовой индекс
со значением non-nil в таблице.
Функции, определенные в Lua (и функции C, зарегистрированные в Lua), могут быть вызваны из ведущей программы. Это выполнено, используя следующий протокол: сначала, функция, которая будет вызвана, помещена в стек, затем, параметры функции помещены в прямом порядке, то есть первый параметр помещен в стек первым. В заключение, функция вызвана:
int lua_call (lua_State *L, int nargs, int nresults);Эта функция возвращает те же самые коды ошибки, что и
lua_dostring
и другие (подробности в разделе
4.5.8). Если Вы хотите исследовать ошибку, вместо того, чтобы возвратить
код ошибки, используйте:
void lua_rawcall(lua_State *L, int nargs, int nresults);
В обеих функциях nargs
задает число параметров, которые Вы
поместили в стек. Все параметры и функциональное значение берутся из стека,
а функциональные результаты помещены туда. Число результатов будет
откорректировано до nresults
, если nresults
не
LUA_MULTRET. В этом случае все
результаты функции будут помещены в стек. Функциональные результаты помещены
в прямом порядке (первый результат и помещен первым), чтобы после обращения
последний результат оказался на самой вершине стека.
Следующий пример показывает, как ведущая программа может делать эквивалент коду на Lua:
a,b = f("how", t.x, 4)Here it is in C:
lua_getglobal(L, "t"); /* глобальная `t' (потом пригодится) */ lua_getglobal(L, "f"); /* функция, которая будет вызвана */ lua_pushstring(L, "how"); /* 1-ый параметр */ lua_pushstring(L, "x"); /* помещает в стек строку `x' */ lua_gettable(L, -4); /* помещает в стек результат t.x (2-ой аргумент) */ lua_pushnumber(L, 4); /* 3-ий параметр */ lua_call(L, 3, 2); /* вызывает функцию с 3 параметрами и 2 результатами */ lua_setglobal(L, "b"); /* устанавливает глобальную переменную `b' */ lua_setglobal(L, "a"); /* устанавливает глобальную переменную `a' */ lua_pop(L, 1); /* удаляет из стека `t' */Обратите внимание, что код выше сбалансированный: в конце стек обратен к первоначальной конфигурации. Это считается хорошей практикой.
Некоторые специальные функции Lua имеют собственные интерфейсы C. Ведущая программа может генерировать ошибку Lua, вызывая функцию:
void lua_error (lua_State *L, const char *message);Эта функция никогда не возвращает ничего. Если
lua_error
вызвана из функции C, которая была вызвана из Lua, то соответствующий блок
кода Lua завершается так, как будто ошибка произошла внутри кода Lua. Иначе
вся ведущая программа завершается обращением exit(EXIT_FAILURE)
.
Перед завершением выполнения, сообщение message
будет передано
функции драйвера ошибки _ERRORMESSAGE
. Если message
равно NULL
, то _ERRORMESSAGE
не вызывается.
Методы тэгов могут быть изменены с
void lua_settagmethod (lua_State *L, int tag, const char *event);Второй параметр задает тэг, а третий представляет собой имя события. Новый метод берется из стека. Чтобы получить текущее (актуальное) значение метода тэга используйте функцию
void lua_gettagmethod(lua_State *L, int tag, const char *event);
Также возможно копировать все методы из одного тэга в другой:
int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);Эта функция вернет
tagto
.
Вы можете пересекать таблицу с функцией:
int lua_next (lua_State *L, int index);здесь
index
относится к таблице, которая будет пересечена.
Функция берет ключ из стека и помещает туда пару "значение-ключ" из таблицы
(следующую после данного ключа). Если не имеется больше элементов, то функция
возвращает 0 (и не помещает в стек ничего). Типичный пример использования
выглядит следующим образом:
lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { /* `key' is at index -2 and `value' at index -1 */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); /* removes `value'; keeps `index' for next iteration */ }
void lua_concat (lua_State *L, int n);конкатенирует
n
значений сверху стека, извлекает их и оставляет
результат наверху. Здесь n
должно быть по крайней мере равно 2.
Конкатенация выполнена по правилам обычной семантики Lua
#define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) /* const char *n; */ /* lua_CFunction f; */Которая получает имя, которое функция будет иметь в Lua, и указатель на функцию. Этот указатель должен иметь тип
lua_CFunction
,
который определен так;
typedef int (*lua_CFunction) (lua_State *L);То есть, это указатель на функцию с целочисленным результатом и одиночным параметром, Lua-средой.
Чтобы связываться правильно с Lua, функция C должна следовать следующему протоколу, который определяет путь, которым параметры и результаты переданы: функция C получает параметры от Lua в стеке, в прямом порядке (первый параметр помещен первым). Чтобы возвращать значения Lua, функция C только помещает их в стек в прямом порядке и возвращает число результатов. Подобно функции Lua, функция C, вызванная Lua, может возвращать много результатов.
Как пример, следующая функция получает переменное число числовых параметров, а возвращает их среднее и сумму:
static int foo (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ double sum = 0; int i; for (i = 1; i <= n; i++) { if (!lua_isnumber(L, i)) lua_error(L, "incorrect argument to function `average'"); sum += lua_tonumber(L, i); } lua_pushnumber(L, sum/n); /* первый результат */ lua_pushnumber(L, sum); /* второй результат */ return 2; /* сколько всего результатов */ }Эта функция может быть зарегистрирована в Lua как
average
таким вызовом:
lua_register(L, "average", foo);
Когда функция C создана, возможно сопоставить с ней некоторые upvalues, таким образом создавая замкнутое выражение C; эти значения будут переданы функции всякий раз, когда она вызвана, как обычные параметры. Чтобы сопоставить upvalues с функцией C, сначала эти значения должны быть помещены в стек. Затем функция
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);используется, чтобы поместить функцию C в стек с параметром
n
означающим, сколько upvalues должно быть связан с функцией (эти upvalues
берутся из стека). Фактически, макрокоманда lua_pushcfunction
определена как lua_pushcclosure
с n
установленным в
0. Затем, всякий раз, когда функция C вызвана, эти upvalues вставлены как
последние параметры функции, после фактических параметров,
переданных в обращении. Это избавляет от необходимости выяснять, сколько
параметров было передано фактически. Так i-th upvalue находится в
стеке в индексе i-(n+1), где n задает номер upvalues.
Для большего количества примеров функций C и замкнутых выражений изучите
файлы lbaselib.c
, liolib.c
,
lmathlib.c
и lstrlib.c
в дистрибутиве Lua.
Если C-код должен хранить значение Lua вне продолжительности жизни функции C, то надо создать ссылку к значению. Функции, чтобы управлять ссылками, следующие:
int lua_ref(lua_State *L, int lock); int lua_getref(lua_State *L, int ref); void lua_unref(lua_State *L, int ref);
lua_ref
выталкивает значение из стека, создает ссылку к нему
и возвращает эту ссылку. Для значения nil ссылка всегда
LUA_REFNIL
. lua.h
также
определяет константу LUA_NOREF
, которая
отличается от любой имеющей силу ссылки. Если lock
не равно 0,
то объект блокирован: это означает, что объект не будет обработан
мусоросборщиком. Разблокированные ссылки могут быть удалены в порядке уборки
мусора на общих основаниях.
Всякий раз, когда вызванный объект необходим в C, обращение к
lua_getref
помещает тот объект в стек; если объект был убран,
lua_getref
вернет 0 (и не поместит ничего в стек).
Когда ссылка больше не нужна, ее надо освободить вызовом
lua_unref
.
При своем запуске Lua регистрируют таблицу в позиции LUA_REFREGISTRY. К этому можно обращаться через макрокоманду:
#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)Эта таблица может использоваться C-библиотеками как общий механизм системного реестра. Любая C-библиотека может сохранять данные в этой таблице, пока она выбирает ключ регистрации, отличный от других библиотек.
Стандартные библиотеки обеспечивают полезные функции, которые выполнены непосредственно через стандартный API. Следовательно, они не так уж и необходимы для самого языка, а обеспечиваются как отдельные C-модули. В настоящее время, Lua имеет следующие стандартные библиотеки:
lua_baselibopen
, lua_strlibopen
,
lua_mathlibopen
и lua_iolibopen
, которые объявлены
в файле заголовков lualib.h
.
Базисная библиотека обеспечивает некоторые основные функции для Lua.
Следовательно, если Вы не включаете эту библиотеку в Вашей прикладной
программе, Вы должны тщательно проверить, должны ли Вы обеспечить какую-то
альтернативную реализацию для некоторых средств. Например, без функции
_ERRORMESSAGE
Lua не способен показать сообщения об ошибках.
_ALERT
. Следовательно, программа может
назначать другую функцию к этой переменной, и изменять путь, которым такие
сообщения показываются (например, для систем без stderr
).
v
равен
nil. Эта функция эквивалентна следующей функции Lua:
function assert(v, m) if not v then m = m or "" error("assertion failed! " .. m) end end
func
с параметрами, заданными таблицей
arg
. Обращение эквивалентно
func(arg[1], arg[2], ..., arg[n])где
n
представляет собой результат getn(arg)
. Все
результаты из func
просто возвращены call
.
По умолчанию, если ошибка происходит в течение обращения к
func
, она объясняется подробно. Если строка mode
включает "x"
, то обращение защищено. В этом режиме
обращение к функции не call
не объясняет ошибку подробно,
независимо от того, что случается в течение обращения. Вместо этого, это
возвращает nil, чтобы сообщить об ошибке (помимо вызова
приспособленного драйвера ошибки).
Если errhandler
обеспечивается, функция ошибки
_ERRORMESSAGE
временно установлена к errhandler
на время выполнения func
. В частности, если
errhandler
равен nil, никакие сообщения об ошибках не
будут выданы в течение выполнения вызванной функции вообще.
Устанавливает порог для мусоросборщика в данное значение (в Kbytes).
Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет
уборку мусора в памяти. Если limit
отсутствует, значением по
умолчанию является ноль (таким образом уборка мусора запустится сразу).
tagto
.
dofile
выполняет содержание стандартного ввода
(stdin
). Если имеется любая ошибка, dofile
вернет
nil. Иначе это возвращает значения, возвращенные кодом, или значение
не-nil, если блок кода не возвращает никаких значений. Это выдает
ошибку, когда вызвано не со строчным параметром.
dostring
вернет nil. Иначе это возвращает значения,
возвращенные кодом, или значение не-nil, если код не возвращает
никакие значения. Факультативный параметр chunkname
имя кода,
используемого для информации об ошибках и отладочных сообщений.
lua_dofile
, lua_dostring
,
lua_dobuffer
или lua_callfunction
, в Lua:
dofile
, dostring
или call
в защищенном
режим). Если message
равно nil, то драйвер ошибки не
будет вызван. Функция error
никогда ничего не возвращает.
func
над всеми элементами таблицы
table
. Для каждого элемента, функция вызвана с индексом и
соответствующим значением как параметрами. Если функция возвращает любое
значение не-nil, то цикл завершается, и это значение будет возвращено
как конечное значение foreach
. Эта функция могла бы быть
определена в Lua так:
function foreach (t, f) for i, v in t do local res = f(i, v) if res then return res end end endПоведение
foreach
неопределено, если Вы изменяете
таблицу t
в ходе работ.
func
над числовыми индексами таблицы
table
. Для каждого индекса функция вызвана с индексом и
соответствующим значением как параметрами. Индексы обрабатываются в
последовательном порядке, от 1 до n
, где n
представляет собой результат getn(table)
. Если функция
возвращает любое значение не-nil, то цикл прерывается, а это значение
будет возвращено как конечное значение foreachi
. Эта функция
могла бы быть определена в Lua таким образом:
function foreachi (t, f) for i=1,getn(t) do local res = f(i, t[i]) if res then return res end end end
name
задает имя переменной.
n
полей с числовым значением, это количество и будет размером
таблицы. Иначе размером является самый большой числовой индекс со значением
не-nil в таблице. Эта функция могла бы быть определена в Lua так:
function getn (t) if type(t.n) == "number" then return t.n end local max = 0 for i, _ in t do if type(i) == "number" and i>max then max=i end end return max end
table
задан, то это также устанавливает его как новую
таблицу глобальных переменных.
next
вернет
следующий индекс таблицы и значение, связанное с индексом. Когда вторым
параметром является nil, next
вернет первый индекс
таблицы и связанное значение. При вызове с последним индексом или с
nil в пустой таблице, next
вернет nil. Если второй
параметр отсутствует, то это интерпретируется как указание nil.
Lua не имеет никакого объявления полей: семантически не имеется никакого
различия между полем, не представленным в таблице, или полем со значением
nil. Следовательно, next
рассматривает только поля со
значениями не-nil. Порядок, в котором индексы перечислены, не
определен даже для числовых индексов. Чтобы обработать таблицу в числовом
порядке, надо использовать функцию foreachi.
Поведение next
неопределено, если Вы изменяете
таблицу в ходе работ.
tostring
. Эта функция не предназначена для
форматируемого вывода, ее следует рассматривать только как быстрый способ
показать значение, например для отладки.
table[index]
без того, чтобы вызвать
любой метод тэга. Таблица должна быть задана как table
, а
index
представляет собой любое значение, отличное от nil.
table[index]
в
value
без того, чтобы вызвать любой метод тэга. Параметр
table
должен быть таблицей, index
представляет
собой любое значение, отличное от nil, а value
задает
любое значение Lua.
tag
) должен быть
значением, созданным через newtag
. settag
вернет
значение первого параметра (таблицу). Для безопасности ведущих программ
невозможно изменить тэг userdata прямо из Lua.
newmethod
равно nil, то
settagmethod
восстанавливает заданное по умолчанию поведение для
данного события. Эта функция не может использоваться, чтобы установить метод
для события gc. Такие методы могут управляться только C-кодом.
table[1]
и помещаются в table[n]
, где
n
представляет собой результат getn(table)
. Если
comp
задан, то это должно быть функцией, которая получает два
элемента таблицы и возвращает истину (то есть значение, отличное от
nil), когда первый меньше, чем второй (так, чтобы not
comp(a[i+1], a[i])
был истиной после сортировки). Если
comp
не задано, то вместо этого используется стандартный
оператор <
языка Lua.
Алгоритм сортировки неустойчив (то есть элементы, рассматриваемые как равные, могут изменить свои относительные позиции после сортировки).
tonumber
вернет это число, иначе это
всегда возвращает nil.
Факультативный параметр определяет ядро, чтобы интерпретировать цифру. Ядром может быть любое целое число между 2 и 36 включительно. В базах более, чем 10, символ A (заглавные или строчные буквы) представляет 10, B соответствует 11 и так далее до символа Z, соответствующему 35. В ядре 10 (значение по умолчанию) число может иметь десятичную часть, также как и факультативную часть экспоненты. В других базах только целые числа без знака.
format
.
Вставляет значение элемента value
в позицию pos
таблицы, сдвигая другие элементы в случае необходимости на открытое место.
Значение по умолчанию для pos
равно n+1
, где
n
является результатом getn(table)
так, чтобы
обращение tinsert(t,x)
вставило x
в конец таблицы
t
. Эта функция также устанавливает или увеличивает поле
n
таблицы, превращая его в n+1
. Эта функция
эквивалентна следующей функции Lua, за исключением того, что доступ к таблице
прямой (без методов тэгов):
function tinsert (t, ...) local pos, value local n = getn(t) if arg.n == 1 then pos, value = n+1, arg[1] else pos, value = arg[1], arg[2] end t.n = n+1; for i=n,pos,-1 do t[i+1] = t[i] end t[pos] = value end
Удаляет из таблицы table
элемент в позиции pos
,
сдвигая в случае необходимости другие элементы, чтобы закрыть образовавшуюся
дырку. Возвращает значение удаленного элемента. Значение по умолчанию для
pos
равно n
, где n
является
результатом getn(table)
, чтобы обращение tremove(t)
удалило последний элемент из таблицы t
. Эта функция также
устанавливает поле n
таблицы в значение n-1
.
Эта функция эквивалентна следующей функции Lua, за исключением того, что доступ к таблице прямой (без использования методов тэгов):
function tremove (t, pos) local n = getn(t) if n<=0 then return end pos = pos or n local value = t[pos] for i=pos,n-1 do t[i] = t[i+1] end t[n] = nil t.n = n-1 return value end
"nil"
(строка, а не значение nil!),
"number"
, "string"
, "table"
,
"function"
и "userdata"
.
s
. Если i
отсутствует, то принято 1.
i
может быть отрицателен.
Числовые коды не обязательно переносимы между платформами.
Числовые коды не обязательно переносимы между платформами.
pattern
в
s
. Если это найдено, strfind
вернет индексы
s
, где эти вхождения начинаются и заканчивается, иначе это
возвращает nil. Если образец определяет набор данных (подробности в
описании gsub
ниже), зафиксированные строки возвращены как
дополнительные результаты. Факультативный числовой параметр init
определяет, где запустить поиск: значение по умолчанию 1, и оно может быть
отрицательным. Четвертый факультативный аргумент plain
выключает
средства поиска образца, так что функция просто ищет подстроку без символов в
pattern
, обрабатываемых особым образом. Обратите внимание, что
если задана опция plain
, должна быть задана и init
.
""
) имеет
длину 0. Вложенные ноли в строке считаются, так что строка
"a\000b\000c"
имеет длину 5 символов.
n
копий строки
s
.
s
,
начинающегося в i
и продолжающейся до j
.
i
и j
могут быть отрицательными, Если
j
отсутствует, то оно считается равным -1 (длине строки).
В частности, обращение strsub(s,1,j)
возвращает префикс
s
длиной j
, а вызов strsub(s, -i)
вернет суффикс s
длиной i
.
printf
в C. Единственное различие состоит в
том, что параметры *
, l
, L
,
n
, p
и h
тут не работают, зато имеется
дополнительная опция q
. Опция q
форматирует строку
в форме, подходящей, чтобы безопасно читаться обратно Lua интерпретатором.
Строка записана между двойными кавычками, а все двойные кавычки и спецсимволы
будут правильно экранированы при записи. Например, обращение
format('%q', 'a string with "quotes" and \n new line')произведет такую строку:
"a string with \"quotes\" and \ new line"
Преобразования могут применяться к энному параметру в списке параметров
вместо следующего неиспользуемого параметра. В этом случае символ
%
заменен последовательностью %d$
, где
d
десятичная цифра в диапазоне [1,9], определяет позицию
параметра в списке. Например, обращение
format("%2$d -> %1$03d", 1, 34)
выдаст результат
"34 -> 001"
. Тот же самый параметр может использоваться
больше, чем в одном преобразовании.
Опции c
, d
, E
, e
,
f
, g
, G
, i
,
o
, u
, X
и x
все ожидают
число как параметр, в то время как q
и s
ожидают
строку. Модификатор *
может применяться, формируя
соответствующую строку формата. Например, "%*g"
может соответствовать "%"...что-то-внутри..."g"
.
Ни строка формата, ни значения строки, которые нужно форматировать с
%s
, не могут содержать вложенные ноли. Но %q
обрабатывает значения строк с вложенными нолями.
s
, в которой все местонахождения образца
pat
были заменены строкой замены, определенной в
repl
. Функция gsub
также возвращает, как второе
значение, общее количество сделанных замен.
Если repl
является строкой, то значение используется для
замены как есть. Любая последовательность в repl
в форме
%n
с n
от 1 до 9 предназначена для
n-й зафиксированной подстроки.
Если repl
представляет собой функцию, то эта функция будет
вызвана каждый раз, когда соответствие происходит, со всеми зафиксированными
подстроками, переданными как параметры. Если значение, возвращенное этой
функцией, является строкой, то это используется как строка для замены, иначе
берется пустая строка.
Последний факультативный параметр n
ограничивает максимальное
число замен. Например, когда n
равно 1, только первое
местонахождение pat
будет обработано.
Имеются некоторые примеры:
x = gsub("hello world", "(%w+)", "%1 %1") --> x="hello hello world world" x = gsub("hello world", "(%w+)", "%1 %1", 1) --> x="hello hello world" x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1") --> x="world hello Lua from" x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv) --> x="home = /home/roberto, user = roberto" (for instance) x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring) --> x="4+5 = 9" local t = {name="lua", version="4.0"} x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end) --> x="lua - 4.0" t = {n=0} gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end) --> t={"first", "second", "word"; n=3}
^$()%.[]*+-?
.
Представляет непосредственно символ x.
%
, когда символ применен в образце.
char-set
. Диапазон символов может быть определен, отделяя
конечные символы диапазона тире (-
). Все классы
%
x, описанные выше, могут также использоваться как
компоненты в char-set. Все другие символы в char-set представляются как есть.
Например, [%w_]
(или [_%w]
) представляет все
алфавитно-цифровые символы плюс символ подчеркивания, [0-7]
представляет восьмеричные цифры, а [0-7%l%-]
представляет
восьмеричные цифры плюс символы строчных букв плюс символ тире.
Взаимодействие между диапазонами и классами не определено. Следовательно,
образцы, подобные [%a-z]
или [a-%%]
не
имеют никакого значения.
char-set
, где char-set
интерпретируется как выше.Для всех классов, представляемых одиночными символами (%a
,
%c
, ...), соответствующая прописная буква представляет
дополнение класса. Например, %S
представляет все не пробелы.
Определения символа, пробела и т.д. зависят от текущего региона. В
частности, класс [a-z]
не может быть эквивалентен
%l
. Вторая форма должна быть предпочтительней для переносимости.
*
, что
соответствует 0 или большему количеству повторений символов в классе. Эти
элементы повторения будут всегда соответствовать самой
длинной возможной последовательности.
+
, что
соответствует 1 или большему количеству повторений символов в классе. Эти
элементы повторения будут всегда соответствовать самой
длинной возможной последовательности.
-
, что
также соответствует 0 или большему количеству повторений символов в классе.
В отличие от *
, элементы повторения будут всегда соответствовать
самой короткой возможной последовательности.
?
, что
соответствует 0 или 1 местонахождению символа в классе.
%b()
соответствует выражениям со
сбалансированными круглыми скобками.^
) в начале образца закрепляет
соответствие в начале подчиненной строки. $
в конце образца
закрепляет соответствие в конце подчиненной строки. В других позициях
^
и $
не имеют никакого специального значения и
представляются как есть.
"(a*(.)%w(%s*))"
, часть
соответствия строки "a*(.)%w(%s*)"
сохранена как первый
сбор данных (а, следовательно, имеет номер 1), символьное соответствие
.
зафиксировано с номером 2, а часть, соответствующая
%s*
, конечно, имеет номер 3.
Образец не может содержать вложенные ноли. Используйте вместо этого
%z
.
Эта библиотека предоставляет интерфейс к некоторым функциям стандартной
математической библиотеки C. Кроме того, это регистрирует метод тэга для
двоичного оператора ^
, который возвращает x^y, когда
применяется к числам x^y
.
Библиотека обеспечивает следующие функции:
abs acos asin atan atan2 ceil cos deg exp floor log log10 max min mod rad sin sqrt tan frexp ldexp random randomseedПлюс глобальная переменная PI. Большинство из них представляют собой только интерфейсы к функциям в C-библиотеке, за исключением того, что для тригонометрических функций все углы выражены в градусах, а не в радианах. Функции
deg
и
rad
могут использоваться для того, чтобы преобразовывать данные
между радианами и градусами.
Функция max
возвращает максимальное значение числовых
параметров. Точно так же min
вычисляет минимум. Обе они могут
использоваться с 1, 2 или большим количеством параметров.
Функции random
и randomseed
представляют собой
интерфейсы к простому генератору случайных чисел, предоставляемому ANSI C
(соответвенно функции rand
и srand
). Не может быть
дпно никаких гарантий касательно их статистических свойств. Функция
random
при вызове без параметров возвращает псевдослучайное
вещественное число в диапазоне [0,1). При вызове с параметром
n, random
вернет псевдослучайное целое число в диапазоне
[1,n]. При вызове с двумя параметрами l и u,
random
вернет псевдослучайное целое число в диапазоне
[l,u]. Границы всегда входят в диапазон.
Все операции ввода-вывода в Lua реализованы через два
дескриптора файла, по одному на ввод и
вывод. Эти дескрипторы сохранены в двух глобальных переменных Lua, названных
_INPUT
и _OUTPUT
. Глобальные переменные
_STDIN
, _STDOUT
и _STDERR
инициализированы с описателями файлов для
stdin
, stdout
и stderr
. Первоначально
Initially, _INPUT=_STDIN
и _OUTPUT=_STDOUT
.
Дескриптор файла представляет собой объект userdata, содержащий поток
файла (FILE*
) с отличительным тэгом, созданным
библиотекой ввода-вывода (I/O).
Если иное не установлено, все функции I/O возвращают nil на сбое и некоторое значение, отличное от nil, при успехе.
Эта функция открывает файл в режиме, определенном в строке
mode
. Это возвращает новый дескриптор файла или, в случае
ошибок, nil плюс строку, описывающую ошибку. Эта функция не изменяет
_INPUT
или _OUTPUT
.
Строка mode
может быть любой из следующего списка:
mode
может также иметь в конце b
, что
необходимо в некоторых системах, чтобы открыть файл в двоичном режиме. Эта
строка аналогична той, что используется в стандартной функции C
fopen
.
Эта функция закрывает файл. Это не изменяет
_INPUT
или _OUTPUT
.
Эта функция может быть вызвана двумя путями. Когда она вызвана с именем
файла, открывает именованный файл, устанавливает дескриптор как значение
_INPUT
и возвращает это значение. Это не закрывает текущий файл
input. При вызове без параметров, она закрывает файл _INPUT
и
восстанавливает stdin
как значение _INPUT
. Если эта
функция где-то не сработала, она возвращает nil плюс строку описания.
Если filename
начинается с символа трубопровода
|
, открывается поточный ввод через
функцию popen. Не все системы его выполняют.
Кроме того, число файлов, которые могут быть открыты в то же самое время,
обычно ограничивается и зависит от системы.
Эта функция может быть вызвана двумя путями. Когда она вызвана с именем
файла, открывает именованный файл, устанавливает дескриптор как значение
_OUTPUT
и возвращает это значение. Это не закрывает текущий
выходной файл. Обратите внимание, что если файл уже существует, то он
будет полностью уничтожен этой операцией. Когда функция вызвана без
параметров, она закрывает файл _OUTPUT
и восстанавливает
stdout
как значение _OUTPUT
. В случае ошибки
функция возвращает nil плюс строку, описывающую ошибку.
Если filename
начинается с символа трубопровода
|
, открывается поточный ввод через
функцию popen. Не все системы его выполняют.
Кроме того, число файлов, которые могут быть открыты в то же самое время,
обычно ограничивается и зависит от системы.
Открывает файл, именованный filename
и устанавливает это как
значение _OUTPUT
. В отличие от операции writeto
,
эта функция не стирает предыдущее содержание файла, вместо этого все, что
пишется в файл, будет конкатенировано к концу. Если эта функция получила
сбой, она вернет nil плюс строку, описывающую ошибку.
Удаляет файл с данным именем. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.
Переименовывает файл name1
в name2
. Если эта
функция получила сбой, она вернет nil плюс строку с описанием ошибки.
Сохраняет любые записанные данные в заданный файл. Если
filehandle
не определен, то flush
сбросит на диск
все открытые файлы. Если эта функция получила сбой, она вернет nil
плюс строку с описанием ошибки.
Получает позицию файла, измеряемую в байтах от начала файла, и меняет ее
на позицию, данную смещением offset
плюс ядром, определенным
как строка whence
следующим образом:
seek
возвращает конечную позицию файла,
измеряемую в байтах от начала файла. Если эта функция получила сбой, она
вернет nil плюс строку, описывающую эту ошибку.
Значение по умолчанию для whence
равно cur
, а
для offset
это 0. Следовательно, вызов seek(file)
возвращает текущую позицию файла без того, чтобы изменить это. Вызов
seek(file, "set")
устанавливает позицию на начало файла (и
возвращает 0), а seek(file, "end")
устанавливает позицию в конец
файла и возвращает его размер.
Возвращает строку с именем файла, которое может безопасно использоваться для временного файла. Файл должен быть явно открыт перед использованием и удален, когда больше не нужен.
Читает файл _INPUT
или filehandle
, если этот
параметр задан, согласно данным форматам, которые определяют, что читать. Для
каждого формата, функция возвращает строку или число с прочитанными данными
или nil, если не может читать данные с определенным форматом. Когда
вызвана без форматов, эта функция использует заданный по умолчанию формат,
который читает следующую строку.
Доступные форматы такие:
Пишет значение каждого из параметров в файл _OUTPUT
или в
filehandle
, если этот параметр задан. Параметры должны быть
строками или числами. Чтобы писать другие значения, используйте
tostring
или format
перед write
.
Если эта функция нарвалась на ошибку, она вернет nil и строку с
описанием данной ошибки.
Возвращает приближение количество времени CPU, используемое программой (в секундах).
Возвращает строку, содержащую дату и время, форматируемую согласно
данному формату format
. Формат задается по тем же самым
правилам, что и в функции ANSI C strftime
. Когда вызвана без
параметров, возвращает приемлемое представление даты и времени, которое
зависит от ведущей системы и от текущего региона.
Эта функция эквивалентна функции C system
. Это передает
команду command
, которая будет выполнена оболочкой операционной
системы. Возвращает код состояния, который является зависимым от системы.
Вызывает C-функцию exit
с факультативным кодом завершения
программы code
. Значение по умолчанию для code
:
код успешного завершения.
Возвращает значение системной переменной процесса varname
или nil, если эта переменная не определена.
Эта функция предоставляет интерфейс к функции ANSI C
setlocale
. locale
представляет собой строку,
определяющую регион, category
факультативная строка,
описывающая которую категорию изменить: "all"
,
"collate"
, "ctype"
, "monetary"
,
"numeric"
или "time"
, заданная по умолчанию
категория: "all"
. Функция возвращает имя нового региона или
nil, если этот запрос не может быть выполнен.
Lua не имеет никаких встроенных средств отладки. Вместо этого, это
предлагает специальный интерфейс, посредством функций и обработчиков
прерываний, который позволяет создание различных видов отладчиков,
профилировщиков и других инструментальных средств, которые нуждаются во
внутренней информации из интерпретатора. Этот интерфейс объявлен в
файле заголовков luadebug.h
.
Основная функция, чтобы получить информацию относительно стека интерпретатора:
int lua_getstack (lua_State *L, int level, lua_Debug *ar);Это заполняет части структуры
lua_Debug
с идентификацией
записи активации функции, выполняющейся в заданном уровне. Уровень
0 текущая функция управления, в то время как уровень n+1 функция,
которая вызвала уровнем n. Обычно lua_getstack
вернет 1,
когда вызвана с уровнем больше, чем глубина стека, она возвращает 0.
Структура lua_Debug
используется,
чтобы нести различные части информации относительно активной функции:
typedef struct lua_Debug { const char *event; /* "call", "return" */ int currentline; /* (l) */ const char *name; /* (n) */ const char *namewhat; /* (n) поля, глобальные и локальные переменные, методы тэгов */ int nups; /* (u) количество upvalues */ int linedefined; /* (S) */ const char *what; /* (S) "Lua" функция, "C" функция, Lua "main" */ const char *source; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ ... } lua_Debug;
lua_getstack
заполняет только одну из частей этой структуры для
будущего использования. Чтобы заполнить другие поля lua_Debug
полезной информацией, надо вызвать:
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);Эта функция возвращает 0 на ошибке (например, недопустимая опция в
what
). Каждый символ в строке what
указывает
некоторые поля ar
, которые будет заполнены, как обозначено
символом в круглых скобках в определении lua_Debug
:
S
заполняет поле исходником (source
),
linedefined
и what
, l
заполняет поле
текущей строкой (currentline
) и так далее. Кроме того,
f
помещает в стек функцию, которая работает в данном уровне.
Чтобы добираться до информации относительно функции, которая не активна
(то есть она не в стеке), Вы помещаете функцию в стек и начинаете строку
what
с символа >
. Например, чтобы знать, в
которой строке функция f
была определена, Вы можете писать:
lua_Debug ar; lua_getglobal(L, "f"); lua_getinfo(L, ">S", &ar); printf("%d\n", ar.linedefined);Поля
lua_Debug
имеют следующее значение:
source
как раз и
будет этой строкой, а если функция была определена в файле,
source
начинается с @
, а дальше имя файла.
source
, чтобы использоваться в
сообщениях об ошибке.
"Lua"
, если это функция Lua, "C"
, если
это функция C или "main"
, если это основная часть chunk.
currentline
установлен в -1.
lua_getinfo
проверяет,
является ли данная функция методом тэга или значением глобальной переменной.
Если данная функция представляет собой метод тэга, name
указывает на имя события. Если данная функция является значением глобальной
переменной, то name
указывает на имя переменной. Если данная
функция не является ни методом тэга, ни глобальной переменной, то
name
установлен в NULL
.
namewhat
равен "global"
. Если функция метод тэга,
namewhat
равен "tag-method"
, иначе
namewhat
равен ""
(пустой строке).
Для манипулирования локальными переменными luadebug.h
использует индексы: первый параметр или локальная переменная имеет индекс 1 и
так далее до последней активной локальной переменной.
Следующие функции позволяют манипулировать локальными переменными данной активной записи.
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);Параметр
ar
должен быть имеющей силу записью активации,
заполненной предыдущим обращением к lua_getstack
или данный как
параметр обработчика прерываний. Функция lua_getlocal
получает
индекс локальной переменной (n
), помещает значение в стек и
возвращает имя. Для lua_setlocal
Вы помещаете новое значение в
стек, а функция назначает это значение переменной и возвращает имя. Обе
функции возвращают NULL
при сбое. Это случается, если заданный
индекс больше, чем число активных локальных переменных.
Как пример, следующая функция вносит в список имена всех локальных переменных функции в данном уровне стека:
int listvars (lua_State *L, int level) { lua_Debug ar; int i = 1; const char *name; if (lua_getstack(L, level, &ar) == 0) return 0; /* failure: no such level in the stack */ while ((name = lua_getlocal(L, &ar, i++)) != NULL) { printf("%s\n", name); lua_pop(L, 1); /* remove variable value */ } return 1; }
Lua-интерпретатор предлагает два обработчика прерываний для целей отладки: call и line. Оба обработчика имеют тот же самый тип:
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);Вы можете устанавливать их со следующими функциями:
lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);Обработчик прерываний заблокирован, когда значение
NULL
, что и
является начальным значением обоих обработчиков прерываний. Функции
lua_setcallhook
и lua_setlinehook
устанавливают
соответствующие обработчики прерываний и возвращают их предыдущие значения.
Обработчик прерываний call вызван всякий раз, когда интерпретатор вызывает
или оставляет функцию. Поле события event
записи ar
имеет строки "call"
или "return"
. Этот
ar
может затем использоваться в обращениях для
lua_getinfo
, lua_getlocal
и
lua_setlocal
, чтобы получить большее количество информации
относительно функции и управлять локальными переменными.
Обработчик прерываний line вызван каждый раз, когда интерпретатор изменяет
строку кода, которую выполняет. Поле event
в ar
имеет строку "line"
, а поле currentline
хранит код
строки. Вы можете использовать этот ar
в других
обращениях к отладочному API.
В то время как Lua управляет обработчиком прерываний, это отключает другие обращения к обработчикам прерываний. Следовательно, если обработчик прерываний вызывает Lua, чтобы выполнить функцию или chunk, это выполнение идет без обращений к обработчикам прерываний.
Библиотека ldblib
обеспечивает функциональные возможности
интерфейса отладки программам Lua. Если Вы хотите использовать эту
библиотеку, Ваша ведущая прикладная программа должна открыть ее вызовом
lua_dblibopen
.
Вы должны проявить большую осторожность при использовании этой библиотеки. Функции, обеспеченные здесь, должны использоваться исключительно для отладки и подобных задач (например, профилирования). Пожалуйста, сопротивляйтесь искушению использовать их как обычный инструмент программирования. Они медленны и нарушают некоторые аспекты языка (например, секретность локальных переменных). Как общее правило, если Ваша программа не нуждается в этой библиотеке, не открывайте ее вообще.
Эта функция возвращает таблицу с информацией относительно функции. Вы
можете давать функцию непосредственно, или Вы можете давать число как
значение function
, что означает функциональное управление в
уровне стека function
. Уровень 0 считается текущей функцией
(непосредственно getinfo
), уровень 1: функция, которая вызвала
getinfo
и так далее. Если function
представляет
собой число большее, чем число активных функций, то getinfo
сразу вернет nil.
Возвращенная таблица содержит все поля, возвращенные
lua_getinfo
со строкой what
описывающий, что
нужно получить. Значение по умолчанию для what
: нужно получить
всю доступную информацию.
Например, выражение getinfo(1,"n").name
вернет имя текущей
функции, если приемлемое имя может быть найдено, и
getinfo(print)
возвращает таблицу со всей доступной информацией
относительно функции print
.
Эта функция возвращает имя и значение локальной переменной с индексом,
local
на уровне level
стека. Первый параметр или
локальная переменная имеет индекс 1 и так далее до последней активной
локальной переменной. Функция вернет nil, если не имеется никакой
локальной переменной с данным индексом, и поднимает ошибку когда вызвана с
level
вне диапазона. Вы можете вызывать getinfo
,
чтобы проверить, имеет ли этот уровень силу.
Эта функция назначает значение value
локальной переменной
с индексом local
функции на уровне level
стека.
Функция вернет nil, если не имеется никакой локальной переменной с
данным индексом, и поднимает ошибку когда вызвана с уровнем
level
вне диапазона.
Устанавливает функциональный обработчик прерываний hook
как обработчик прерываний call. Этот обработчик прерываний будет вызван
каждый раз при начале и завершении интерпретации функции. Единственный
параметр на обработчик прерываний call: имя события ("call"
или
"return"
). Вы можете вызывать getinfo
с уровнем 2,
чтобы получить большее количество информации относительно функции
(уровень 0 соответствует функции getinfo
, а уровень 1 задает
функцию обработчика прерываний. Когда вызвана без параметров, эта функция
выключает обработчики прерываний call. setcallhook
вернет
старый обработчик прерываний.
Устанавливает функциональный обработчик прерываний hook
как
обработчик прерываний line. Этот обработчик прерываний будет вызван каждый
раз, когда интерпретатор изменяет обрабатываемую строку кода. Единственный
параметр на обработчике прерываний line: код строки, которую интерпретатор
собирается выполнять. Когда вызвана без параметров, эта функция выключает
обработчики прерываний line. Вызов setlinehook
возвращает
старый обработчик прерываний.
Хотя Lua был разработан как язык расширений, чтобы быть вложенным в
ведущую программу на C, это часто используется как автономный язык.
Интерпретатор для Lua, как автономного языка, называется просто
lua
. Эта программа может быть вызвана с любой
последовательностью следующих параметров:
stdin
как файл.
lua_close
после обработки всех параметров.
stat
.
filename
с параметрами для таблицы arg
.
var
в строку "value"
.
filename
.lua
ведет себя как
lua -v -i
, когда stdin
представляет собой терминал,
или аналогично lua -
в противном случае.
Все параметры обработаны по порядку, за исключением -c
.
Например, обращение, подобное:
$ lua -i a=test prog.luaСначала взаимодействует с пользователем до
EOF
в
stdin
, затем установит a
в "test"
и
в заключение выполнит файл prog.lua
. Здесь под $
понимается подсказка оболочки. Ваша подсказка может быть иной.
Когда используется опция -f filename, все параметры в командной
строке переданы программе Lua filename
в таблице, названной
arg
. В этой таблице поле n
получает индекс
последнего параметра, а поле 0 получает "filename"
. Например,
$ lua a.lua -f b.lua t1 t3интерпретатор сначала выполняет файл a.lua, затем создает таблицу:
arg = {"t1", "t3"; n = 2, [0] = "b.lua"}а в заключение выполняет файл b.lua. Автономный интерпретатор также обеспечивает функцию
getargs
,
которая может использоваться, чтобы обратиться ко всем параметрам
командной строки. Например, если Вы вызываете Lua строкой:
$ lua -c a bто обращение к
getargs
в a
или в b
возвратит такую таблицу:
{[0] = "lua", [1] = "-c", [2] = "a", [3] = "b", n = 3}
В интерактивном режиме может быть написана многострочная инструкция. Для
этого надо заканчивать промежуточные строки наклонной чертой влево
(\
). Если глобальная переменная
_PROMPT определена как строка, то ее значение используется как
подсказка. Следовательно, подсказка может быть изменена непосредственно в
командной строке. Например:
$ lua _PROMPT='myprompt> ' -iИли в программе Lua, назначая новое значение переменной
_PROMPT
.
В Unix Lua-скрипты могут быть переделаны в выполнимые программы, используя
chmod +x
и форму #!
как в
#!/usr/local/bin/lua
или #!/usr/local/bin/lua -f
,
чтобы получить другие параметры.
Авторы пакета хотели бы поблагодарить CENPES/PETROBRAS, который, совместно с TeCGraf, использовал ранние версии этой системы и дал ценные комментарии. Авторы также хотели бы отблагодарить Carlos Henrique Levy за найденное имя для проекта. Lua на португальском означает луну.
Lua 4.0 представляет собой значительное изменение языка. Была проделана большая работа, чтобы избежать несовместимости с предыдущими общими версиями Lua, но некоторые различия нужно представлять. Есть список несовместимостей.
$debug
, $if
, ...) удалены.
f(g(x))
,
все возвращаемые значения из g
переданы как параметры
f
. Это случается только, когда g
последний или
единственный параметр для f
.
next
или foreach
таблица не может изменяться.
rawgettable
и rawsettable
теперь
переименованы соответственно в rawget
и rawset
.
foreachvar
, nextvar
,
rawsetglobal
и rawgetglobal
устаревшие. Вы
можете получать их функциональные возможности, используя операции таблицы
с таблицей глобальных переменных, возвращаемой globals
.
setglobal
и sort
больше не возвращают значение.
Вызов type
больше не возвращает второе значение.
p
в функции call
устарела.chunk ::= {stat [`;']} block ::= chunk stat ::= varlist1 `=' explist1
| functioncall
| do block end
| while exp1 do block end
| repeat block until exp1
| if exp1 then block {elseif exp1 then block} [else block] end
| return [explist1]
| break
| for `name' `=' exp1 `,' exp1 [`,' exp1] do block end
| for `name' `,' `name' in exp1 do block end
| function funcname `(' [parlist1] `)' block end
| local declist [init] funcname ::= `name' | `name' `.' `name' | `name' `:' `name' varlist1 ::= var {`,' var} var ::= `name' | varorfunc `[' exp1 `]' | varorfunc `.' `name' varorfunc ::= var | functioncall declist ::= `name' {`,' `name'} init ::= `=' explist1 explist1 ::= {exp1 `,'} exp exp1 ::= exp exp ::= nil | `number' | `literal' | var | function | upvalue
| functioncall | tableconstructor | `(' exp `)' | exp binop exp | unop exp functioncall ::= varorfunc args | varorfunc `:' `name' args args ::= `(' [explist1] `)' | tableconstructor | `literal' function ::= function `(' [parlist1] `)' block end parlist1 ::= `...' | `name' {`,' `name'} [`,' `...'] upvalue ::= `%' `name' tableconstructor ::= `{' fieldlist `}' fieldlist ::= lfieldlist | ffieldlist | lfieldlist `;' ffieldlist | ffieldlist `;' lfieldlist lfieldlist ::= [lfieldlist1] ffieldlist ::= [ffieldlist1] lfieldlist1 ::= exp {`,' exp} [`,'] ffieldlist1 ::= ffield {`,' ffield} [`,'] ffield ::= `[' exp `]' `=' exp | `name' `=' exp binop ::= `+' | `-' | `*' | `/' | `\^{ ' | `..'
| `<' | `<=' | `>' | `>=' | `==' | `\ { '=}
| and | or} unop ::= `-' | not
arguments могут быть параметрами, назначениями или именами файлов. Они будут обработаны слева направо.
Параметры начинаются с тире (-) и описаны ниже.
Назначение представляет собой параметр формы a=b, который назначает b глобальной переменной a. Обратите внимание, что никакие кавычки не нужны вокруг строки, если она не содержит пробелы или другие символы, специальные для оболочки. Вообще, Вы должны быть внимательны при использовании кавычек и пробелов в командной строке потому, что они обычно обрабатываются оболочкой непосредственно.
Если параметр не является ни опцией, ни назначением, то это имя файла, который затем будет загружен и выполнен.
Если никакие параметры не заданы, то принято -v -i, когда стандартный ввод представляет собой терминал, в противном случае используется -.
Тире (-) загрузить стандартный ввод как файл, то есть не в интерактивном режиме, даже когда стандартный ввод является терминалом.
-c Закрыть Lua перед выходом.
-e "stat" выполнить инструкцию stat. Вы должны цитировать stat, если она содержит пробелы или кавычки.
-f "file" собрать все последующие параметры как строку в глобальную таблицу arg, а затем выполнить файл file. Параметры в arg начинаются с 0, который содержит строку file. Индекс последнего параметра сохранен в arg.n.
-i ввести интерактивный режим, показывая подсказку. В этом режиме lua читает строки из стандартного ввода и выполняет их как они читаются. Каждая строка должна содержать полную инструкцию. Чтобы записать инструкцию, охватывающую несколько строк, закончите каждую строку наклонной чертой влево (\). Показываемая подсказка представляет собой значение глобальной переменной _PROMPT, если это значение строка. Чтобы изменить подсказку, задайте нужное значение _PROMPT. Вы можете делать это после вызова интерпретатора или в командной строке с помощью "_PROMPT=\'lua: \'". Обратите внимание на потребность в кавычках потому, что строка содержит пробел. Заданная по умолчанию подсказка: >.
-q ввести интерактивный режим, но не показывая подсказку.
-sn установить размер стека в n. Если представлено, это должно быть первой опцией. Обратите внимание, что n находится в том же самом параметре, что и -s. Например, чтобы определить размер стека в 2000, используйте -s2000.
-v вывести информацию о версии.
Основные преимущества прекомпилированных программ: они быстрее при загрузке, исходный текст защищен от изменений пользователя и недоступно обнаружение ошибок синтаксиса.
Прекомпиляция не подразумевает более быстрое выполнение потому, что в Lua блоки всегда компилируются в байт-код прежде, чем выполняются. luac просто позволяет этому байт-коду быть сохраненным в файле.
luac производит одиночный выходной файл, содержащий байт-код для всех заданных исходных файлов. По умолчанию выходной файл именован luac.out, но Вы можете изменять это опцией -o.
Двоичные файлы, созданные luac, переносимы на любую архитектуру с тем же самым размером слова. Это означает, что двоичные файлы, созданные на 32-разрядной платформе (типа Intel) могут читаться без изменений на другой 32-разрядной платформе (типа Sparc), даже если порядок байт различен. С другой стороны, двоичные файлы, созданные на 16-разрядной платформе, не могут читаться на 32-разрядной платформе.
В командной строке Вы можете смешивать текстовые файлы, содержащие код на Lua, и двоичные файлы, содержащие прекомпилированные блоки. Это полезно: чтобы объединить несколько прекомпилированных блоков даже с различных (но совместимых) платформ в один блок.
Вы можете использовать "-", чтобы указать stdin как исходный файл.
Внутренний формат двоичных файлов, произведенных luac, может изменяться, когда выпущена новая версия Lua. Так что храните исходные файлы всех прекомпилированных программ Lua.
Параметры должны быть отделены друг от друга. -l производит распечатку компилируемого байт-кода для виртуальной машины Lua. Если никакие файлы не даны, то luac загружает luac.out и вносит в список его полное содержание.
-o "file" выводит данные в file вместо значения по умолчанию luac.out. Выходной файл может быть исходным файл потому, что все файлы загружены прежде, чем выходной файл записан.
-p загружают файлы, но не генерируют никакой выходной файл. Использован главным образом для проверки синтаксиса или тестирования прекомпиляции: разрушенные файлы, вероятно, сгенерируют ошибки, когда будут загружены. Для полного теста целостности используйте опцию -t.
-s убирает отладочную информации перед записью выходного файла. Это экономит некоторое место в очень больших блоках, но если ошибки происходят при управлении ими, то сообщения об ошибках не смогут содержать полную информацию о том, что случилось.
-t выполняет полный тест целостности прекомпилированного кода. Код, который признает нормальным этот тест, полностью безопасен в том смысле, что это не будет разрывать интерпретатор. Однако, не имеется никакой гарантии, что такой код делает что-нибудь полезное. Если никакие файлы не заданы, то luac загружает luac.out и проверяет его содержимое.
-v выводит сведения о версии.
luac.out представляет собой заданный по умолчанию выходной файл
lua(1)
http://www.tecgraf.puc-rio.br/lua.
Сообщения пакета об ошибках должны быть самодостаточными.
R. Ierusalimschy, L. H. de Figueiredo и W. Celes ( lua@tecgraf.puc-rio.br).
Построение Lua на системах Unix очень просто:
Ниже приведены инструкции для пользователей систем Windows и Macintosh.
Если make выполнилась без проблем, Вы получите:
Это единственные каталоги, в которых Вы нуждаетесь для разработки.
Man-страницы для lua и luac в nroff и html, а также справочное описание в html помещаются в ./doc, некоторый типовой код в ./test, а некоторые полезные дополнения в ./etc. Вы не нуждаетесь в этих каталогах для разработки.
Изучите также README-файлы в различных подкаталогах. Удобная отправная точка: ./doc/readme.html.
Если вызов make ничего хорошего не сделал, пожалуйста, сообщите на lua@tecgraf.puc-rio.br. Если Вы делаете изменения для config или в файлах Makefile, пожалуйста, пошлите их туда же.
Если Вы управляете Linux, сделайте make so после успешного выполнения make. Это создаст общедоступные библиотеки в ./lib. Вероятно, лучше формировать общедоступные библиотеки прежде, чем выполнять make install.
Если Вы хотите переделать интерпретатор и транслятор так, чтобы использовать общедоступные библиотеки, то выполните также make sobin.
Вы, возможно, должны включить lib в системную переменную LD_LIBRAY_PATH, чтобы компоновать программы, которые используют общедоступные библиотеки, если Вы не помещаете их в официальные места с помощью make install.
Формирование общедоступных библиотек в других системах подобно этому, но детали отличаются. Вы будете должны поправить несколько деталей в Makefile на верхнем уровне дерева кода.
Команды для формирования Lua на Mac или Windows-машине зависят от специфического компилятора, который Вы используете. Самый простой путь состоит в том, чтобы создать папку со всеми файлами .c и .h. Затем создайте проекты для основной библиотеки, стандартной библиотеки, интерпретатора и прекомпилятора следующим образом:
core lib: lapi.c lcode.c ldebug.c ldo.c lfunc.c lgc.c llex.c lmem.c lobject.c lparser.c lstate.c lstring.c ltable.c ltests.c ltm.c lundump.c lvm.c lzio.c standard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.c interpreter: core lib, standard lib, lua.c compiler: core lib, dump.c luac.c opt.c print.c stubs.c
Конечно, чтобы использовать Lua как разделяемую библиотеку, Вы должны знать, как создавать и использовать библиотеки с Вашим компилятором и в Вашей операционной системе.
cd sql tar zxf /download/mylua.tar.gz cd .. ./configure --enable-assembler --prefix=/usr/local/mysql \ --enable-assembler --with-mysqld-ldflags="-L/usr/src/lua/lib \ -llua -llualib"
mysql mysql mysql< SELECT user,host FROM user PROCEDURE("/usr/src/mysql/sql/count.lua")
MySQLdb представляет собой поточно-совместимый интерфейс с популярной СУБД MySQL, который обеспечивает Python API для баз данных. Здесь рассматривается его версия 0.9.1 (автор Andy Dustman, andy@dustman.net). Пакет распространяется по лицензии GPL и доступен для закачки с http://sourceforge.net/projects/mysql-python. Цели проекта:
Требования:
Python 1.5.2 или выше:
Distutils 1.0.2 или выше:
MySQL 3.22.19 или выше.
Первое, что Вы будете делать, редактирование скрипта setup.py. Имеются некоторые переменные, которые сообщают где искать MySQL include-файлы и библиотеки. Значения корректны для стандартной установки MySQL в Red Hat Linux (6.2) RPM. Если Вы имеете другую платформу, Вы должны будете вычислить нужные значения самостоятельно. Вам почти никогда не придется изменять это. Если Вы имеете старую версию distutils (до 1.0.2), обновитесь или удалите параметры, относительно которых система возражает.
Обратите внимание, что недавние двоичные дистрибутивы с www.mysql.com включают два набора библиотек пользователей: mysqlclient и mysqlclient_r. Последний хранит поточно-безопасные библиотеки, так что используйте именно его, если потоки Вам нужны.
Если Вы имеете динамические библиотеки пользователей (в Linux .so-файлы), они будут использоваться по умолчанию. Если они не в Вашем стандартном пути загрузчика, Вы должны будете установить или откорректировать системную переменную LD_LIBRARY_PATH (в Linux) или ту, которую Ваша платформа требует. Иначе Вы можете скорректировать setup.py, чтобы компоновать со статической библиотекой. Если Вы используете стандартный пакет RPM, с этим не должно быть особых проблем.
ПРЕДУПРЕЖДЕНИЕ: Если Вы используете двоичный пакет Zope, Вы нуждаетесь в выполнении скрипта setup.py программой python из Zope. Иначе Zope (ZMySQLDA) не может найти _mysql.
Если Вы предпочитаете RPM, Вы можете использовать команду bdist_rpm с setup.py. Это только формирует RPM, но не устанавливает его.
Этот модуль должен быть совместим с более старым интерфейсом, написанным Joe Skinner. Однако, старая версия:
MySQLdb полностью новый модуль, распространяемый бесплатно согласно GNU Public License. Никакой код из той версии не используется в MySQLdb.
Этот модуль разработан на RedHat Linux (в настоящее время 7.1) для Intel.
Это должно формироваться без больших трудностей на большинстве платформ,
используя скрипт setup.py
. Возможно этот модуль работает и под
MacOS X. Вы нуждаетесь в пакете Distutils, который поставляется с Python 2.0.
Если Вы не имеете его (то есть Вы имеете Python 1.5.2), Вы можете скачать
пакет с сайта www.python.org.
Windows не поддерживаемая платформа. Однако, скрипт
setup.py
по сообщениям работает нормально.
MySQLdb требует Python 1.5.2 или новее. Более ранние версии не будут
работать потому, что MySQL нужна поддержка для C long long
. Если
Вы имеете более раннюю версию Python, обновитесь хотя бы до 1.5.2. Текущая
разработка выполнена в Python 2.1, но старый Python 1.5.2 все еще будет
поддержан в обозримом будущем.
Гарантируется работа версии 3.22.32 и выше. Некоторые старые версии могут работать, если Вы имеете старшую версию, Вы должны серьезно подумать об апгрейде в целях исправления ошибок и дыр в защите.
MySQL-3.22 имеет проблему при попытке вставить значения TIME
с дробными секундами. Значения, подобные 12:56:13.00, возвращены как
344:13:00, очевидно интерпретируя первоначальный ввод как 12 дней, 56 часов,
13 минут и 0 секунд (12 дней и 56 часов=344 часа). Чтобы избежать этой
проблемы, используйте тип DateTimeDelta
.
MySQLdb поддерживает транзакции, если их поддерживает сервер. Но
не гарантирует, что транзакции будут работать. Для этого Вы должны
использовать транзакционно-безопасную таблицу (TST). Текущие TST: BDB и
InnoDB. Таблицы GEMINI намечены для MySQL-4.0. Обратите внимание, что MySQL
функционирует в режиме AUTOCOMMIT
по умолчанию, и MySQLdb
считает, что AUTOCOMMIT
включен. Чтобы изменить это, используйте
инструкции SQL SET AUTOCOMMIT=0
.
Если Вы имеете установленный пакет mx.DateTime , MySQLdb использует его для связанных с датой объектов. Иначе они будут возвращены как строки. Вы можете также изменять словарь преобразования типов, чтобы возвратить их как другие объектные классы.
MySQLmodule, старый интерфейс MySQL, разработанный Joe Skinner, является
также интерфейсом C/Python. MySQL
, C-часть, имеет интерфейс,
подобный perl DBI. Кроме того, имеется часть Python, Mysqldb
,
которая обеспечивает интерфейс DB API v1.0, написанный James Henstridge.
MySQLdb-0.2.2 и выше включает CompatMysqldb
, который является
адаптацией Mysqldb
к _mysql
. Это должно
рассмотреться экспериментальным решением.
Напротив, C-часть MySQLdb, _mysql
, разработана в соответствии
с MySQL C API объектно-ориентированным способом. MySQLdb
обеспечивает интерфейс DB API v2.0, который имеет некоторые отличия от
v1.0, в частности такие изменения:
Действие | Mysqldb | MySQLdb |
Соединение | db=Mysqldb.Mysqldb("db@host user pass")
|
db=MySQLdb.connect(db='db', host='host', user='user',
passwd='pass') |
Неявный курсор | db.execute(SQL) |
Неявные курсоры удалены из DB API v2.0. Всегда используйте
c=db.cursor() |
Строка выборок как словарь | c.fetchDict() ,
ключи: "table.column" |
Не стандарт: альтернативный класс DictCursor предоставляет
интерфейс словаря, ключи являются "column" или "table.column
, если имеются два столбца с одним именем. Используйте SQL-оператор
AS для переименования полей. |
Транзакции | db.commit() и
db.rollback() мирно сосуществуют вместе и тихо не делают ничего
(опасно!) |
db.commit() и db.rollback() работают, если
сервер MySQL может выполнять транзакции, иначе db.rollback()
всегда терпит неудачу. |
Был написан пакет ZMySQLDA для использования с MySQLdb. Это адаптируется из ZOracleDA Digital Creations разработчиков системы Zope.
FAQ доступны на http://dustman.net/andy/python/MySQLdb/faq/MySQLdb-FAQ.html.
Если Вы хотите писать прикладные программы, которые переносимы между
базами данных, избегайте использовать этот модуль непосредственно. Модуль
_mysql
обеспечивает интерфейс, который обычно осуществляет MySQL
C API. Для получения большего количества информации обратитесь к документации
на пакет MySQL. Документация для этого модуля преднамеренно слаба потому, что
Вы, вероятно, должны использовать более высокий уровень (модуль MySQLdb).
MySQL C API был обернут объектно-ориентированным способом. Единственные
MySQL структуры данных, которые выполнены в данном интерфейсе, это
MYSQL
(дескриптор подключения базы данных) и
MYSQL_RES
(дескриптор результата). Вообще, любая функция,
которая берет как параметр MYSQL *mysql
, теперь представляет
собой метод объекта подключения, и любая функция, которая берет
MYSQL_RES *result
, теперь метод объекта результата. Функции, не
требующие ни одной структуры MySQL, выполнены как функции в модуле. Функции,
требующие какую-то из других структур данных MySQL, вообще не выполнены. Во
всех случаях префикс mysql_
удален из имени. Большинство
перечисленных методов conn
также доступно как методы объекта
MySQLdb Connection. Их использование не переносимо между базами данных.
C API | _mysql |
mysql_affected_rows() |
conn.affected_rows() |
mysql_close() | conn.close() |
mysql_connect() | _mysql.connect()
|
mysql_data_seek() | result.data_seek()
|
mysql_debug() | _mysql.debug() |
mysql_dump_debug_info |
conn.dump_debug_info() |
mysql_escape_string() |
_mysql.escape_string() |
mysql_fetch_row() | result.fetch_row()
|
mysql_get_client_info() |
_mysql.get_client_info() |
mysql_get_host_info() |
conn.get_host_info() |
mysql_get_proto_info() |
conn.get_proto_info() |
mysql_get_server_info() |
conn.get_server_info() |
mysql_info() | conn.info() |
mysql_insert_id() | conn.insert_id()
|
mysql_list_dbs() | conn.list_dbs()
|
mysql_list_fields() | conn.list_fields()
|
mysql_list_processes() |
conn.list_processes() |
mysql_list_tables() | conn.list_tables()
|
mysql_num_fields() | result.num_fields()
|
mysql_num_rows() | result.num_rows()
|
mysql_options() | _mysql.connect()
|
mysql_ping() | conn.ping() |
mysql_query() | conn.query() |
mysql_real_connect() | _mysql.connect()
|
mysql_real_query() | conn.query()
|
mysql_real_escape_string() |
conn.escape_string() |
mysql_row_seek() | result.row_seek()
|
mysql_row_tell() | result.row_tell()
|
mysql_select_db() | conn.select_db()
|
mysql_stat() | conn.stat() |
mysql_store_result() | conn.store_result()
|
mysql_thread_id() | conn.thread_id()
|
mysql_use_result() | conn.use_result()
|
CLIENT_* | MySQLdb.constants.CLIENT.*
|
CR_* | MySQLdb.constants.CR.* |
ER_* | MySQLdb.constants.ER.* |
FIELD_TYPE_* |
MySQLdb.constants.FIELD_TYPE.* |
FLAG_* | MySQLdb.constants.FLAG.*
|
Допустим, что Вы хотите использовать _mysql
.
Имеются некоторые примеры.
Самое простое подключение к базе данных:
import _mysql db=_mysql.connect()
Это создает подключение к серверу MySQL на локальной машине, используя
стандартый сокет UNIX, Ваше имя входа в систему (из системной переменной
USER), пустой пароль и не применяет команду USE
. Возможно, это
будет работать у Вас, если Вы установили файл конфигурации (~/.my.cnf
). Но скорее всего Вы должны обеспечить большее количество информации:
db=_mysql.connect("localhost","joebob","moonpie","thangs")
Это создает подключение к серверу MySQL на локальной машине, используя TCP на стандартном порте (3306), имя пользовател joebob, пароль moonpie и выбирает начальную базу данных thangs.
Конечно, Вы должны использовать TCP, если работаете с удаленной системой.
Здесь я не рассмотрел часть параметров connect()
, и Вы обратите
внимание, что, если Вы используете позиционные параметры, настроить связь по
TCP не так-то просто. Кроме того, сокеты UNIX быстрее. Я предпочитаю
использовать параметры ключевого слова:
db=_mysql.connect(host="localhost",user="joebob", passwd="moonpie",db="thangs")Это делает точно то же, что делал последний пример, но проще для чтения. Теперь, если Вы действительно хотели использовать сокет UNIX, и Ваше имя входа в систему joebob, Вы могли бы сократить этот пример до:
db=_mysql.connect(passwd="moonpie",db="thangs")Имеются некоторые другие параметры, которые Вы можете использовать, и большинство их не так уж и необходимо, кроме одного, о котором чуть ниже. Во всем остальном обратитесь к встроенной документации. Модуль Python 2.1
pydoc
представляет собой хороший справочник.
Теперь Вы имеете открытое подключение db
и хотите сделать
запрос. Не имеется никаких курсоров в MySQL и никакой подстановки параметров,
так что Вы должны передать полную строку запроса db.query()
:
db.query("""SELECT spam, eggs, sausage FROM breakfast WHERE price < 5""")Не имеется никакого значения возврата, но исключительные ситуации могут быть вызваны. Исключительные ситуации определены в отдельном модуле,
_mysql_exceptions
, но _mysql
экспортирует их.
Читайте спецификацию DB API
(http://www.python.org/topics/database/DatabaseAPI-2.0.html), чтобы выяснить
то, чем они являются, или Вы можете использовать MySQLError
.
В этой точке Ваш запрос был выполнен, и Вы должны получить результаты. Вы имеете два параметра:
r=db.store_result() # ...или... r=db.use_result()Оба метода возвращают объект результата. В чем же разница? А в том, что
store_result()
возвращает весь набор результатов пользователю
немедленно. Если Ваш набор результатов действительно большой, это станет
проблемой. Один путь обхода этого состоит в том, чтобы добавить предложение
LIMIT
к Вашему запросу, чтобы ограничить число возвращенных
строк. Но можно использовать use_result()
, который хранит набор
результатов на сервере и посылает его построчно, когда Вы выбираете. Это
связывает ресурсы сервера и подключение: Вы не можете делать больше запросов,
пока Вы не выбрали все строки. Вообще я рекомендую использовать
store_result()
, если Ваш набор результатов не огромен, и Вы не
можете использовать LIMIT
.
Теперь для фактического получения реальных результатов надо:
>>> r.fetch_row() (('3','2','0'),)Первая вещь, которую Вы должны знать:
fetch_row()
берет
некоторые дополнительные параметры. Первый задает, сколько строк
(maxrows
) должны быть возвращены. По умолчанию, это возвращает
одну строку. Это может возвращать меньшее количество строк, чем Вы просите,
но никогда не больше. Если Вы устанавливаете maxrows=0
, это
возвращает все строки набора результатов. Если Вы когда-либо получаете пустой
набор, значит Вы исчерпали строки.
Второй параметр (how
) сообщает как строка должна
представиться. По умолчанию, это ноль, что означает вернуть как набор.
how=1
значит вернуть данные как словарь, где ключи представляют
собой имена столбца или table.column
, если имеются два столбца с
тем же самым именем. how=2
аналогично how=1
, кроме
того, что ключи всегда table.column
, это для
совместимости со старым модулем Mysqldb
.
Другая причуда: известно, что обрабатываются числовые столбцы, почему они
возвращены как строки? Потому, что MySQL возвращает все данные как строки
просто по определению и ожидает, что Вы преобразуете их непосредственно. Как
я понимаю, все данные в базе хранятся именно как строки, как бы они не
выглядели снаружи. Это было бы реальной проблемой, но фактически
_mysql
может делать это для Вас. MySQLdb
делает это
для Вас сам. Чтобы иметь автоматическое выполненное преобразование типов, Вы
должны создать словарь конвертера типов и передать его в
connect()
как параметр ключевого слова conv
.
Ключи в conv
должны быть типами столбцов MySQL, которые в C
API являются FIELD_TYPE_*
. Вы можете получать эти значения так:
from MySQLdb.constants import FIELD_TYPE
По умолчанию любой тип столбца, который не может быть найден в
conv
, возвращен как строка, которая пригодна для самых разных
применений. Для наших целей нужно:
my_conv = {FIELD_TYPE.LONG: int}Это означает, если это
FIELD_TYPE_LONG
, обработать это
встроенной int()
. Обратите внимание, что
FIELD_TYPE_LONG
представляет собой столбец INTEGER
,
который соответствует C long
, который является также типом,
используемым для нормального целого числа в Python. Но остерегайтесь: если
это столбец UNSIGNED INTEGER
, это может вызвать переполнение. По
этой причине MySQLdb
фактически использует long()
,
чтобы сделать преобразование.
Затем, если Вы используете
db=_mysql.connect(conv=my_conv...)
, результаты возвратятся в
виде ((3, 2, 0),)
, который является тем, что и ожидается.
MySQLdb представляет собой тонкую обертку на Python вокруг
_mysql
. MySQLdb делает его
совместимым с интерфейсом Python DB API (version 2). В действительности код,
который осуществляет API, находится в _mysql
ради эффективности.
Только несколько высокопоставленных функций и атрибутов определены внутри MySQLdb.
mysql_options()
перед соединением.
Обратите внимание, что некоторые параметры должны быть определены как
параметры ключевого слова! Значение по умолчанию для каждого параметра: NULL
или 0, зависит от типа. Важные параметры:
MySQLdb.converters.conversions
.
mysql_options()
.
mysql_options()
.
cursor()
, если не
перекрыт. Значение по умолчанию: MySQLdb.cursors.Cursor
. Это
должно быть параметром ключевого слова.Протокол MySQL не может обрабатывать много потоков, использующих то же
самое подключение, сразу. Более ранние версии MySQLdb использовали
блокировку, чтобы достигнуть threadsafety=2. Несмотря на то, что это не
должно активно использовать стандартный класс Cursor (который используется в
mysql_store_result()
), это усложнено SSCursor (который
используется в mysql_use_result()
. Здесь Вы должны
гарантировать, что все строки прочитались прежде, чем другой запрос сможет
быть выполнен. Это далее усложнено добавлением транзакций, начинающихся
когда курсор выполняет запрос, и завершающихся выполнением
COMMIT
или ROLLBACK
объектом Connection. Два потока
не могут совместно использовать подключение, в то время как транзакция
происходит, в дополнение к неспособности совместно использовать его в течение
выполнения запроса. К сожалению, это чрезмерно усложнило код.
Общий результат этого: совместно не используйте подключения разными потоками. Это не стоит прилагаемых усилий и в результате, вероятно, причинит вред эффективности, так как сервер MySQL выполняет отдельный поток для каждого подключения. Вы можете, конечно, делать кэширование подключений через специальный пул, и давать подключения с одним потоком одновременно. Если Вы позволяете двум потокам использовать подключение одновременно, библиотека пользователей MySQL, вероятно, будет сваливаться.
Примечание о совместимости: старые версии MySQLmodule используют подобную схему задания параметра, но требуют, чтобы кавычки были помещены вокруг строк формата, которые будут содержать строки, даты и подобные символьные данные. Это не требуется для MySQLdb. Рекомендуется, чтобы %s (но не '%s') использовался для всех параметров, независимо от типа. Интерфейс выполняет все необходимое цитирование сам.
FIELD_TYPE.*
) к
вызываемым объектам Python (обычно функциям), которые преобразовываются из
строк в нужные типы. Это инициализировано с приемлемыми значениями по
умолчанию для большинства типов. При создании объекта Connection Вы можете
передать Ваш собственный словарь конвертера типа как параметр ключевого
слова. Иначе это использует копию MySQLdb.converters.conversions
.
Словарь включает некоторые из функций модуля DateTime
, если это
доступно. Несколько ненормативных типов возвращены как строки,
Начиная с MySQL-3.23, MySQL поддерживает различные наборы символов на
клиенте и сервере, а также новую функцию цитирования
mysql_real_escape_string()
. Это требует, чтобы функция
цитирования строки была методом, связанным с объектом connection. MySQLdb
обрабатывает это для Вас автоматически. Однако, если Вы чувствуете
потребность сделать что-то особое со строками, Вы должны изменить словарь
после открытия подключения.
Объекты Connection возвращены функцией connect()
.
NotSupportedError
.
Примечание совместимости: старые версии MySQLmodule определяют этот метод, так что он не далет ничего. Это опасное поведение, поскольку успешная обратная перемотка указывает, что текущая транзакция отменена.
Cursor
.
begin()
для его
временного отключения. AUTOCOMMIT продолжит работу после следующего вызова
commit()
или rollback
.ProgrammingError
. Если Вы используете
курсоры стороны сервера, очень важно
закрыть курсор, когда Вы с ним закончили, но перед созданием нового курсора.
AUTO_INCREMENT
,
вставленное в базу данных.
Warning
. Если Вы
используете класс курсора без предупреждений, рекомендую проверять
info(). Подробности в документации MySQL на mysql_info()
.
Метод connect()
работает почти также, как и с
_mysql
:
import MySQLdb db=MySQLdb.connect(passwd="moonpie",db="thangs")Чтобы выполнить запрос, Вы сначала нуждаетесь в курсоре, а затем Вы можете выполнять запросы на нем.
c=db.cursor() max_price=5 c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (max_price,))
В этом примере max_price=5
. Почему затем в строке
использована опция %s
? Потому, что MySQLdb преобразует это в
литеральное значение SQL, которое является строкой '5'. Когда это закончено,
запрос будет фактически таким: "...WHERE price < 5".
Так, а теперь результаты:
>>> c.fetchone() (3L, 2L, 0L)В отличие от примера с
_mysql
, это возвращает одиночный блок
результатов, который является строкой, и значения правильно преобразованы.
Как упомянуто ранее, в то время как столбец MySQL INTEGER транслируется в
Python integer, UNSIGNED INTEGER может вызвать переполнение, так что эти
значения преобразованы в Python long integer. До Python 1.6 long integer
сохраняли L, когда были преобразованы в строки с помощью
str()
. В 1.6 и позже str()
не включает L. Конечно,
L всегда выводится при использовании repr()
.
Когда Вы закончили работу с транзакцией, Вы должны выполнить
db.commit()
или db.rollback()
. Если сервер и
таблицы не поддерживает транзакции, commit()
будет работать, но
rollback()
вызовет исключительную ситуацию. Обратите внимание,
что это методы connection, а не cursor, даже при том, что
транзакция запускается через c.execute(...)
.
Если Вы хотели получить большее количество строк, Вы могли бы использовать
c.fetchmany(n)
или c.fetchall()
. На
c.fetchmany(n)
параметр n
факультативный и имеет
значение по умолчанию c.arraysize
(обычно 100). Оба этих метода
возвращают последовательность строк, или пустую последовательность, если
строки уже кончились.
Обратите внимание, что в отличие от вышеупомянутого,
c.fetchone()
вернет None
, когда не имеется больше
строк для выборки.
Единственный другой метод, который Вы, очень вероятно, используете, это многострочная вставка:
c.execute("""INSERT INTO breakfast (name, spam, eggs, sausage, price) VALUES (%s, %s, %s, %s, %s)""", [ ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ), ("Not So Much Spam Plate", 3, 2, 0, 3.95 ), ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )])
Здесь мы вставляем три строки по пять значений в каждой. Обратите
внимание, что имеется смесь типов (строки, int, float), хотя все еще
используется только %s
. А также обратите внимание, что включили
только строки формата для одной строки. MySQLdb выбирает и дублирует их
для каждой строки.
Базы данных, даже SQL-базы данных, изменяются по возможностям очень сильно
и могут иметь ненормативные свойства. DB API делает хорошую работу по
обеспечению приемлемо переносимого интерфейса, но некоторых методов там нет.
Специфические параметры для connect()
полностью зависимы от реализации.
Если Вы полагаете, что Ваша прикладная программа должна выполниться на нескольких различных базах данных, автор рекомендует следующий подход, основанный на персональном опыте: пишите упрощенный API для Вашей прикладной программы, который осуществляет специфические запросы и операции, которые Ваша прикладная программа должна выполнить. Выполните этот API как основной класс, который должен иметь немного зависимостей от базы данных, а затем получите подкласс, который осуществляет необходимые зависимости. Таким образом, перенос Вашей прикладной программы к новой базе данных должен быть относительно простым вопросом создания нового подкласса для базы данных.
В качестве примера рекомендую изучить модуль SQLDict (http://dustman.net/andy/python), который позволяет стандартным запросам работать, используя объект, который напоминает словарь, а также читать и писать определяемые пользователем дополнительные объекты.
Поскольку объекты MySQLdb Connection и Cursor написаны на Python, Вы можете легко получать Ваши собственные подклассы. Имеются несколько классов Cursor в MySQLdb.cursors:
mysql_store_result()
,
чтобы получить результат запроса. Весь набор результатов сохранен
на стороне пользователя.
mysql_use_result()
,
чтобы получить результат запроса. Набор результатов сохранен на стороне
сервера и передается построчно.
AS
CursorWarningMixIn, CursorStoreResultMixIn,
CursorTupleRowsMixIn
и BaseCursor
, то есть он создает
исключительную ситуацию Warning
, использует
mysql_store_result()
и возвращает строки как блоки.
Cursor
за исключением того, что возвращает
строки как словари.
Cursor
, но использует
CursorUseResultMixIn
. Используйте только, если Вы имеете дело с
потенциально большими наборами результатов.
SSCursor
за исключением того, что возвращает
строки как словари.
_mysql.so
Имеются некоторые общие ошибки, которые случаются в ходе построения
пакета. Этот раздел покрывает только проблемы UNIX/Linux, поскольку я не
делаю пакетов под Windows. Файлы типа .so
представляют собой
динамические библиотеки в Linux и большинстве других вариантов UNIX. Windows
использует расширение .dll
.
Вы имеете динамические библиотеки MySQL, и по умолчанию Ваш компилятор
линкует _mysql.so
с ними, но они не в пути загрузчика, когда Вы
запускаете Python. Вы имеете два базисных параметра:
/etc/ld.so.conf
или Вы можете добавить каталог к системной переменной
LD_LIBRARY_PATH
перед запуском Python.
LD_LIBRARY_PATH=/path/to/mysql/libs python ... # Bourne-ish shell
PyLong_FromUnsignedLongLong()
сначала появляется в
Python 1.5.2, так что Вы компонуете с более старой версией. Вы можете также
иметь больше, чем одну установленную версию. Получите Python 1.5.2 (а лучше
посвежее) с python.org.
Библиотеки пользователей MySQL-3.23 требуют libz для сжатия gzip. Скрипт setup.py должен бы добавить это автоматически.
Путь для include-файлов (-I) к Вашим MySQL include-файлам ошибочен.
Поправьте скрипт setup.py. Другой вариант: Вы не имеете набора разработчика
для MySQL. Если Вы используете Red Hat RPM, Вы нуждаетесь в RPM-пакете
MySQL-devel
, чтобы откомпилировать _mysql.so
.
Однако, если Вы компонуетесь со статическими библиотеками MySQL, Вы можете
устанавливать _mysql.so
на системе, которая не имеет библиотек
пользователей MySQL (libmysqlclient
).
А я не использую Windows. Скрипт setup.py, как предполагается, работает. Может также быть связь с каким-либо сторонним пакетом.
Вероятно, Вы установили двоичную версию Zope, которая приходит со своим собственным интерпретатором Python. Вы должны компилировать MySQLdb с той специфической установкой Python. Выясните, где находятся двоичные модули python и используйте это, чтобы выполнить setup.py.
Вообще-то они должны быть преобразованы в длинные целых числа, чтобы
избежать переполнения на столбцах UNSIGNED INT. Решения: используйте атрибут
fmt=%d
на элементах dtml-var
или поставьте
Zope 2.4, который приходит с Python 2.1, который не добавляет L.
Z метода SQL имеют параметр max_rows
. Если это установлено к
значению, отличному от нуля, ZMySQLDA автоматически добавляет предложение
LIMIT к инструкции SELECT. Это сильно повышает эффективность, особенно, если
набор результатов мог бы быть большим. Если это сталкивается с чем-то,
установите max_rows
в ноль, и это не будет добавлять предложение
LIMIT. В частности, Вы, вероятно, должны будете сделать это при вставке строк
со столбцами AUTO_INCREMENT, поскольку обычно Вы используете
SELECT, чтобы получить LAST_INSERT_ID(), а LIMIT может блокировать это.
MySQLdb представляет собой модуль, соответствующий спецификации Python Database API 2.0 (http://www.python.org/topics/database/DatabaseAPI-2.0.html), так что Вы должны быть знакомы с этой спецификацией. Здесь указаны отличия: http://dustman.net/andy/python/MySQLdb/doc/MySQLdb.html.
MySQLdb теперь поддерживает транзакции, если сервер поддерживает транзакционно-безопасные таблицы (TST), и Вы используете их. Если Ваш сервер не поддерживает их, rollback всегда будет терпеть неудачу потому, что система не в состоянии выполнить Ваши инструкции. Даже если Ваш сервер поддерживает транзакционно-безопасные таблицы, rollback будет терпеть неудачу, если Вы изменили любую не-TST таблицу.
cursor.commit()
, который пытается завершить транзакцию
всегда работает нормально потому, что MySQL по существу всегда в
режиме auto-commit mode (если Вы не его не выключили).
С одной стороны, никак. Не делайте этого, если Вы можете избежать этого. Ваша программа не будет переносима к другим базам данных.
Но если Вас эта переносимость не интересует, то почти все специальные обращения API выполнены в объекте _mysql, и объект связи в MySQLdb может также вызывать их.
Хорошо, это может быть необходимо в каком-то случае. ZMySQLDA делает это потому, что Zope-модуль ZRDB сам по себе API, а слишком много уровней API имеют тенденцию к разброду и шатанию. С этим поделать что-либо трудно. Кроме того, было фактически довольно просто сделать это именно таким способом, да и эффективность малость повысилась.
Эти файлы генерируют MEX-функции Matlab, которые могут использоваться, чтобы обратиться к базе данных MySQL из пакета Matlab (разработчик: MathWorks, http://www.mathworks.com).
Оригинальный интерфейс был написан Kimmo Uutela (Kimmo.Uutela@hut.fi,
http://boojum.hut.fi/~kuutela) и изменен John Fisher
(jfisher@are.berkeley.edu). Затем он был перенесен под Windows Brian
Shand (bshand@dip5.ee.uct.ac.za). Функции нуждаются в библиотеке
mysqlclient
(public domain, входит в дистрибутив MySQL).
Этот интерфейс был протестирован на Linux с Matlab 6 и на HP-UX с Matlab 5
и 6, но он работает и на других вариантах UNIX с модификациями в
Makefile
. Интерфейс был также протестирован под Windows NT 4.0.
Вы должны иметь уже установленные Matlab и MySQL. Для Windows я
использовал Microsoft Visual C++ 5.0, библиотеку клиентов MySQL из пакета
winclients-3.22.14.zip
и Cygwin GNU Make. Более поздние версии
библиотеки клиентов MySQL должны работать и с VC++ 6. Для UNIX использовался
GCC. Скопируйте правильную версию Makefile
:
cp Makefile.hpux Makefile # Для HP-UX cp Makefile.linux Makefile # Для Linux copy Makefile.win32 Makefile # Для Windows
Проверьте координаты библиотек и каталог назначения в первых строках
Makefile
. Затем откомпилируйте Mex:
gmake
Проверьте библиотеку и инсталлируйте файлы:
gmake test gmake install
Библиотека mysqlclient
должна компилироваться как
position-независимый код. На HP-UX это может быть выполнено параметром
компиляции +z
, на Linux надо
использовать параметр -fPIC
.
Чтобы использовать интерфейс в Linux с Matlab 5, Вы должны иметь
библиотеку libmysqlclient
, совместимую с libc5
. В
некоторых случаях Вы можете столкнуться с необходимостью явно добавить
библиотеку libgcc
к библиотекам системы. Правильное имя
находится с помощью locate libgcc.a
.
Могут иметься проблемы с использованием различных версий MySQL DLL одновременно. Должно быть возможно использовать последнюю версию DLL с Visual C++ 5.0. При установке DLL скопирована в двоичный каталог Matlab так, чтобы она была легко доступна в пути поиска файлов, когда это необходимо.
Будут установлены две команды Matlab:
HOST
от имени
пользователя USER
с паролем доступа PASSWD
.
fn1,fn2,...
NULL
возвращен как
пустая двойная матрица. Следующие типы будут возвращены как
double
: DECIMAL, TINY, SHORT, LONG, FLOAT, DOUBLE,
LONGLONG, INT24
. Все типы BLOB
будут возвращены как
векторы uint8
. Другие типы данных будут возвращены как строки.
Этот раздел документирует интерфейс Perl DBI
. Вышеупомянутый
интерфейс ранее был назван mysqlperl
. Ныне рекомендуемым
является DBI
/DBD
, так что mysqlperl
здесь не рассматривается.
DBI
с DBD::mysql
DBI
представляет собой универсальный интерфейс для многих баз
данных. Это означает, что Вы можете написать скрипт, который работает с
многими серверами баз данных без изменений. Вы нуждаетесь в драйвере базы
данных (DBD) для каждого типа базы данных. Для MySQL этот драйвер назван
DBD::mysql
.
Для получения большего количества информации относительно Perl5 DBI,
пожалуйста, посетите Web-страницу DBI
и прочтите документацию на
ней по адресу
http://www.symbolstone.org/technology/perl/DBI/index.html.
Для получения большего количества информации относительно объектно-ориентированного программирования (OOП) как оно определено в Perl5, обратитесь по адресу http://language.perl.com/info/documentation.html.
Обратите внимание, что, если Вы хотите использовать транзакции с Perl, Вы
должны иметь Msql-Mysql-modules
версии 1.2216 или новее.
Инструкции по установке поддержки MySQL Perl даны в разделе "M.2 Установка Perl".
DBI
Портируемые методы DBI
connect | Устанавливает подключение к серверу. |
disconnect | Закрывает подключение к серверу. |
prepare | Готовит инструкцию SQL для выполнения. |
execute | Выполняет подготовленные инструкции. |
do | Готовит и выполняет инструкцию SQL. |
quote | Цитирует строку или значения
BLOB , которые будут вставлены. |
fetchrow_array | Выбирает следующую строку как массив полей. |
fetchrow_arrayref | Выбирает следующую строку как массив ссылок на поля. |
fetchrow_hashref | Выбирает следующую строку как ссылку на hashtable. |
fetchall_arrayref | Выбирает все данные как массив массивов. |
finish | Заканчивает инструкцию и позволяет системе освободить ресурсы. |
rows | Возвращается число строк, на которые воздействовал данный запрос. |
data_sources | Возвращает массив баз данных, доступных на localhost. |
ChopBlanks | Указывает методам
fetchrow_* урезать ли пробелы. |
NUM_OF_PARAMS | Число параметров в подготовленной инструкции. |
NULLABLE | Которые столбцы могут быть
NULL . |
trace | Выполнить трассировку для отладки. |
MySQL-специфичные методы
insertid | Последнее занчение
AUTO_INCREMENT . |
is_blob | Которые столбцы являются значениями
BLOB . |
is_key | Которые столбцы являются ключами. |
is_num | Которые столбцы являются числовыми. |
is_pri_key | Которые столбцы являются первичными ключами в данной таблице. |
is_not_null | Которые столбцы не могут быть
NULL . |
length | Максимально возможные размеры столбца. |
max_length | Максимальные размеры столбца, фактически представленные в результате. |
NAME | Имена столбцов. |
NUM_OF_FIELDS | Число возвращенных полей. |
table | Имена таблицы в возвращенном наборе. |
type | Все типы столбцов. |
Методы Perl описаны более подробно в следующих разделах. Переменные, используемые для значений возврата метода, имеют эти значения:
$dbh
$sth
$rc
$rv
Портируемые методы DBI
connect($data_source, $username, $password)
connect
, чтобы сделать подключение к базе с
источником данных. Значение $data_source
должно начинаться с
DBI:driver_name:
. Пример connect
с драйвером
DBD::mysql
:
$dbh = DBI->connect("DBI:mysql:$database", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname", $user, $password); $dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", $user, $password);Если имя пользователя и/или пароль не определены,
DBI
использует
значения системных переменных DBI_USER
и DBI_PASS
соответственно. Если Вы не определяете hostname, по умолчанию берется
localhost
. Если Вы не определяете номер порта, это выставляется
в порт MySQL по умолчанию (3306). Начиная с Msql-Mysql-modules
Version 1.2009, значение $data_source
позволяет модификаторы:
mysql_read_default_file=file_name
mysql_read_default_group=group_name
[client]
. Если опция mysql_read_default_group
определена, группой в файле опций будет [group_name]
.
mysql_compression=1
mysql_socket=/path/to/socket
DBI
, Вы можете брать их из
пользовательского файла опций ~/.my.cnf переделав
connect
следующим образом:
$dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf", $user, $password);Это обращение будет читать параметры, определенные для группы
[client]
в файле опций. Если Вы хотите сделать то же самое, но
опции брать из секции [perl]
, Вы могли бы использовать это:
$dbh = DBI->connect("DBI:mysql:$database" . ";mysql_read_default_file=$ENV{HOME}/.my.cnf" . ";mysql_read_default_group=perl", $user, $password);
disconnect
disconnect
отсоединяет дескриптор базы данных от
собственно базы данных. Это надлежит сделать перед завершением программы:
$rc = $dbh->disconnect;
prepare($statement)
($sth)
, который Вы можете использовать,
чтобы вызвать метод execute
. Обычно Вы обрабатываете инструкции
SELECT
(а также SELECT
-подобные инструкции, вроде
SHOW
, DESCRIBE
и EXPLAIN
) посредством
prepare
и execute
. Например так:
$sth = $dbh->prepare($statement) or die "Can't prepare $statement: $dbh->errstr\n";
execute
execute
выполняет подготовленную инструкцию. Для
инструкций не-SELECT
, execute
возвращает число
строк, на которые воздействовал оператор. Если ни на какие строки метод не
воздействовал, он вернет 0E0
, который Perl обрабатывает как
ноль, но расценивает как истину. Если происходит ошибка, execute
вернет undef
. Для инструкций SELECT
execute
только запускает запрос SQL в базе данных. Вы должны
использовать один из методов fetch_*
, описанных ниже, чтобы
получить сами данные. Пример:
$rv = $sth->execute or die "can't execute the query: $sth->errstr;
do($statement)
do
готовит и выполняет инструкцию SQL и возвращает
число строк , на которые воздействовал оператор. Если ни на какие строки
метод не воздействовал, он вернет 0E0
, который Perl обрабатывает
как ноль, но расценивает как истину. Если происходит ошибка, do
вернет undef
. Этот метод вообще используется для инструкций
не-SELECT
, которые не могут быть подготовлены заранее (из-за
ограничений драйвера) или тех инструкций, которые не должны быть выполнены
больше, чем однажды (вставки, удаления и т.п.). Например:
$rv = $dbh->do($statement) or die "Can't execute $statement: $dbh- >errstr\n";Вообще инструкция do НАМНОГО быстрее, чем prepare/execute для инструкций, которые не содержат параметров.
quote($string)
quote
используется, чтобы обойти любые специальные
символы, содержащиеся в строке, и добавить требуемые внешние метки
цитирования. Конкретный пример:
$sql = $dbh->quote($string)
fetchrow_array
while(@row = $sth->fetchrow_array) { print qw($row[0]\t$row[1]\t$row[2]\n); }
fetchrow_arrayref
while($row_ref = $sth->fetchrow_arrayref) { print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); }
fetchrow_hashref
while($hash_ref = $sth->fetchrow_hashref) { print qw($hash_ref->{firstname}\t$hash_ref->{lastname}\t\ $hash_ref-> title}\n); }
fetchall_arrayref
my $table = $sth->fetchall_arrayref or die "$sth->errstr\n"; my($i, $j); for $i (0 .. $#{$table}) { for $j (0 .. $#{$table->[$i]}) { print "$table->[$i][$j]\t"; } print "\n"; }
finish
$rc = $sth->finish;
rows
SELECT
через execute
. Пример:
$rv = $sth->rows;
NULLABLE
NULL
. Пример:
$null_possible = $sth->{NULLABLE};
NUM_OF_FIELDS
SELECT
или SHOW FIELDS
. Вы можете использовать это
для проверки, возвратила ли инструкция результат: нулевое значение указывает
на инструкцию не-SELECT
, типа INSERT
,
DELETE
или UPDATE
. Например:
$nr_of_fields = $sth->{NUM_OF_FIELDS};
data_sources($driver_name)
localhost
. Например:
@dbs = DBI->data_sources("mysql");
ChopBlanks
fetchrow_*
конечные пробелы из возвращенных ими значений. Пример:
$sth->{'ChopBlanks'} =1;
trace($trace_level)
trace($trace_level, $trace_filename)
trace
включает или отключает трассировку. Когда он
вызывается как метод класса DBI
, это воздействует на трассировку
для всех дескрипторов. Когда он вызывается как метод базы данных или
инструкции, это воздействует на трассировку для данного дескриптора и любых
будущих потомков дескриптора. Установка $trace_level
равным 2
обеспечивает детализированную информацию. Установка $trace_level
в 0 отключает трассировку. Вывод идет на стандартный вывод ошибки по
умолчанию. Если $trace_filename
определен, файл будет открыт в
режиме дополнения, и вывод для всех прослеженных дескрипторов будет записан в
этот файл. Например:
DBI->trace(2); # Трассировать все DBI->trace(2,"/tmp/dbi.out"); # Регистрировать все в /tmp/dbi.out $dth->trace(2); # Трассировать этот дескриптор базы данных $sth->trace(2); # Трассировать этот операторный дескрипторВы можете также допускать трассировку
DBI
, устанавливая
системную переменную DBI_TRACE
. Установка ее к числовому
значению эквивалентна вызову DBI->(value)
. Установка ее к
имени пути эквивалентна вызову DBI->(2,value)
.MySQL-специфичные методы
Методы, показанные ниже, MySQL-специфические, а не часть стандарта
DBI
. Несколько из них теперь осуждаются: is_blob
,
is_key
, is_num
, is_pri_key
,
is_not_null
, length
, max_length
и
table
. Где существуют варианты в стандарте DBI
, они
обязательно отмечены ниже:
insertid
AUTO_INCREMENT
, новые
значения будут сохранены здесь. Пример:
$new_id = $sth->{insertid};Как вариант, Вы можете использовать
$dbh->{'mysql_insertid'}
.
is_blob
BLOB
. Так, например:
$keys = $sth->{is_blob};
is_key
$keys = $sth->{is_key};
is_num
$nums = $sth->{is_num};
is_pri_key
$pri_keys = $sth->{is_pri_key};
is_not_null
NULL
:
$not_nulls = $sth->{is_not_null};Метод
is_not_null
осуждается, предпочтительно использовать
атрибут NULLABLE
(описанный выше) потому, что это стандарт DBI.
length
max_length
length
указывает максимальные возможные размеры, которые
каждый столбец может иметь (как объявлено в описании таблицы). Массив
max_length
указывает максимальные размеры, фактически
представленные в таблице. Пример:
$lengths = $sth->{length}; $max_lengths = $sth->{max_length};
NAME
$names = $sth->{NAME};
table
$tables = $sth->{table};
type
$types = $sth->{type};
DBI
/DBD
Вы можете использовать команду perldoc
, чтобы получить
большее количество информации относительно DBI
:
perldoc DBI perldoc DBI::FAQ perldoc DBD::mysql
Вы можете также использовать инструментальные средства
pod2man
, pod2html
и им подобные, чтобы
транслировать справочник к другим форматам.
Вы можете находить последнюю информацию по DBI
на
Web-странице DBI
по адресу
http://www.symbolstone.org/technology/perl/DBI/index.html.
Perl-поддержка для MySQL обеспечивается посредством интерфейса
пользователя DBI
/DBD
. Подробности в разделе
"8 MySQL Perl API". Код пользователя Perl
DBD
/DBI
требует Perl Version 5.004 или выше.
Интерфейс не будет работать, если Вы имеете старую версию!
MySQL Perl-поддержка также требует, чтобы Вы установили MySQL-поддержку программирования пользователя. Если Вы установили MySQL из файлов RPM, программы пользователя находятся в клиентском RPM, но поддержка программирования пользователя находится в RPM для разработчика. Удостоверьтесь, что Вы в самом деле установили последний RPM.
Начиная с Version 3.22.8, поддержка Perl поставляется отдельно от главного дистрибутива MySQL. Если Вы хотите устанавливать поддержку Perl, нужные файлы можно найти на http://www.mysql.com/Downloads/Contrib.
Дистрибутивы Perl поставляются как сжатые архивы в формате
tar
и имеют имена подобные MODULE-VERSION.tar.gz, где
MODULE
представляет собой имя модуля, а VERSION
задает номер версии. Вы должны получить пакеты Data-Dumper
,
DBI
и Msql-Mysql-modules
и устанавливать их в этом
порядке. Процедура установки показывается ниже. Показанный пример подходит
для модуля Data-Dumper
, но процедура та же самая для всех трех
нужных Вам модулей:
shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -Эта команда создаст каталог под именем Data-Dumper-VERSION.
shell> cd Data-Dumper-VERSION
shell> perl Makefile.PL shell> make shell> make test shell> make install
Команда make test
важна потому, что она проверяет что модуль
работает. Обратите внимание, что когда Вы выполняете эту команду в течение
установки Msql-Mysql-modules
, чтобы проверить код интерфейса,
сервер MySQL должен работать, или тест будет терпеть неудачу.
Стоит пересобрать и повторно установить Msql-Mysql-modules
всякий раз, когда Вы устанавливаете новый выпуск MySQL, особенно, если Вы
обращаете внимание на нехорошие признаки типа того, что все Ваши скрипты
DBI
после апгрейда MySQL падают.
Если Вы не имеете права установить модули Perl в системный каталог, или чтобы установить локальные модули Perl, следующая ссылка может помочь:
http://www.iserver.com/support/contrib/perl5/modules.html
Смотрите под заголовком Installing New Modules that Require
Locally Installed Modules
.
Чтобы установить модуль MySQL DBD
под ActiveState Perl под
Windows, Вы должны сделать следующее:
set HTTP_proxy=my.proxy.com:3128
C:\> c:\perl\bin\ppm.pl
DBI
:
ppm> install DBI
install ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
Вышеупомянутое должно работать по крайней мере с ActiveState Perl Version 5.6.
Если Вы не можете заставить это работать, Вы должны взамен установить драйвер MyODBC и соединяться с сервером MySQL через ODBC:
use DBI; $dbh=DBI->connect("DBI:ODBC:$dsn","$user","$password") || die "Got error $DBI::errstr when connecting to $dsn\n";
Дистрибутив MySQL Perl включает в себя DBI
,
DBD:MySQL
и DBD:ODBC
.
C:
, чтобы получился
каталог вида C:\PERL.
perl
выполнением команды
perl -v
в DOS shell.DBI
/DBD
Если Perl сообщает, что не может найти модуль ../mysql/mysql.so, то проблема, вероятно, в том что Perl не может найти общедоступную библиотеку libmysqlclient.so.
Вы можете исправить это любым из следующих методов:
Msql-Mysql-modules
командой
perl Makefile.PL -static -config
вместо
perl Makefile.PL
.
libmysqlclient.so
в каталог, где размещены другие
Ваши общедоступные библиотеки (вероятно, это /usr/lib или
/lib).
LD_RUN_PATH
.Если Вы получаете следующие ошибки из DBD-mysql
, Вы,
вероятно, используете gcc
(или используете старый двоичный
дистрибутив, собранный с помощью gcc
):
/usr/bin/perl: can't resolve symbol '__moddi3' /usr/bin/perl: can't resolve symbol '__divdi3'
Добавьте -L/usr/lib/gcc-lib/... -lgcc
к команде компоновки,
когда библиотека mysql.so собрана (проверьте вывод из
make
для mysql.so, когда Вы компилируете клиента Perl).
Опция -L
должна определить имя пути каталога, где файл
libgcc.a размещен на Вашей системе.
Другой причиой этой проблемы может быть то, что Perl и MySQL не вместе
компилируются gcc
. В этом случае, Вы можете устранить
несоответствие, компилируя оба пакета gcc
.
Если Вы получаете следующую ошибку из Msql-Mysql-modules
,
когда Вы выполняете тесты:
t/00base............install_driver(mysql) failed: Can't load '../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql: ../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: uncompress at /usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
Это означает, что Вы должны включить библиотеку сжатия -lz в строку компновки. Это может сделать следующее изменение в файле lib/DBD/mysql/Install.pm:
$sysliblist .= " -lm"; надо поменять на $sysliblist .= " -lm -lz";
После этого, Вы ДОЛЖНЫ выполнить make realclean и затем продолжить установку с самого начала.
Если Вы хотите использовать Perl-модуль на системе, которая не
поддерживает динамическую связь (подобно SCO), Вы можете сгенерировать
статическую версию Perl, которая включает DBI
и
DBD-mysql
. Соберите версию Perl с модулем DBI
и
установите поверх текущей версии Perl. Затем Вы используете это, чтобы
сформировать версию Perl, которая дополнительно имеет встроенный код
DBD
, и вот ее-то и надо установить как окончательную.
На SCO Вы должны иметь следующий набор системных переменных:
shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/libили
shell> LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib shell> LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib shell> MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:/usr/skunk/man:
Сначала, создайте Perl, который включает статически связанный
DBI
, применяя эти команды в каталоге, где размещен Ваш
дистрибутив пакета DBI
:
shell> perl Makefile.PL -static -config shell> make shell> make install shell> make perl
Затем Вы должны установить новый Perl. Вывод из make perl
укажет точную команду make
, которую Вы должны выполнить, чтобы
осуществить установку. На SCO это make -f Makefile.aperl inst_perl
MAP_TARGET=perl
.
Затем используйте только что созданный Perl, чтобы создать другой Perl,
который также включает и статически связанный модуль DBD::mysql
этими командами в каталоге, где размещен Ваш дистрибутив
Msql-Mysql-modules
:
shell> perl Makefile.PL -static -config shell> make shell> make install shell> make perl
В заключение Вы должны установить этот новый Perl. Снова вывод из команды
make perl
указывает команду, которую Вам надлежит использовать
для выполнения установки.
Есть два способа добавить новую функцию в MySQL:
CREATE FUNCTION
и DROP FUNCTION
.
Подробности в разделе "9.1.1 Синтаксис
CREATE FUNCTION/DROP FUNCTION
".
mysqld
и становятся
доступными на постоянной основе.Каждый метод имеет свои проблемы:
Независимо от метода, который Вы используете, чтобы добавить новые
функции, они могут использоваться точно так же как местные функции типа
ABS()
или SOUNDEX()
.
CREATE FUNCTION/DROP FUNCTION
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
Определяемые пользователем функции (user-definable function, UDF)
представляют собой способ расширить MySQL новой функцией, которая работает
подобно местным (встроенным) функциям MySQL типа ABS()
или
CONCAT()
.
AGGREGATE
новая опция для MySQL Version 3.23. Функция с
AGGREGATE
работает точно так же, как и встроенная функция
GROUP
, подобно SUM
или COUNT()
.
CREATE FUNCTION
сохраняет имя функции, тип и общедоступное
библиотечное имя в таблице mysql.func
системы. Вы должны иметь
привилегии insert и delete для базы данных
mysql
, чтобы создавать и удалять функции.
Все активные функции перезагружаются при каждом запуске сервера, если Вы
не запускаете mysqld
с опцией --skip-grant-tables
.
В этом случае инициализация пропущена, и UDF станут недоступны. Активная
функция представляет собой такую функцию, которая была загружена с помощью
CREATE FUNCTION
, но не была удалена через
вызов DROP FUNCTION
.
По поводу правил написания определяемых пользователем функций отсылаю Вас
к разделу "9.1 Добавление новой
функции, определяемой пользователем в MySQL". Для работы механизма UDF
функции должны быть написаны на C или C++, Ваша операционная система должна
поддерживать динамическую загрузку, и mysqld
должен быть
откомпилирован динамически (не статически).
Для работы механизма UDF функции должны быть написаны на C или C++, а Ваша операционная система должна поддерживать динамическую загрузку. Дистрибутив исходников MySQL включает файл sql/udf_example.cc, который определяет 5 новых функций. Консультируйтесь с этим файлом, чтобы видеть, как работают соглашения о вызовах UDF.
Чтобы mysqld
мог использовать UDF, Вы должны конфигурировать
MySQL с опцией --with-mysqld-ldflags=-rdynamic
. Причина этого
в том, что на многих платформах (включая Linux) Вы можете загружать
динамическую библиотеку (вызовом dlopen()
) из статически
скомпонованной программы, которая собрана с опцией
--with-mysqld-ldflags=-all-static
, но если Вы хотите
использовать UDF, который должен обратиться к символам из
mysqld
(подобно примеру methaphone
в
sql/udf_example.cc, который использует
default_charset_info
), Вы должны компоновать программу с
-rdynamic
. Подробности на man dlopen
.
Для каждой функции, которую Вы хотите использовать в инструкциях SQL, Вы
должны определить соответствующую функцию на C или на C++. В обсуждении ниже
имя ``xxx'' используется для имени функции примера. Здесь XXX()
(верхний регистр) указывает SQL-обращение к функции, и xxx()
(нижний регистр) указывает C/C++-обращение к функции.
Функции, которые Вы пишете на C/C++ для реализации интерфейса с
XXX()
:
xxx()
(обязательна)
SQL-тип | C/C++-тип |
STRING | char * |
INTEGER | long long |
REAL | double |
xxx_init()
(опциональна)
xxx()
. Это может использоваться
для:
XXX()
.
REAL
) максимального количества
десятичных чисел.
NULL
.xxx_deinit()
(опционально)
xxx()
. Это должно освободить
любую память, распределенную функцией инициализации.Когда инструкция SQL вызывает XXX()
, MySQL вызывает функцию
инициализации xxx_init()
, чтобы позволить ей выполнить любую
требуемую настройку, типа проверки параметра или распределения памяти. Если
xxx_init()
возвращает ошибку, инструкция SQL будет прервана с
сообщением об ошибке, причем главная и деинициализационная функции не будут
вызваны, что стоит иметь в виду при распределении памяти. Иначе основная
функция xxx()
будет вызвана один раз для каждой строки. После
того, как все строки были обработаны, вызывается функция
xxx_deinit()
, так что она может выполнить требуемую очистку.
Все функции должны быть безопасны для потоков (не только основная функция,
но и остальные: инициализация и деинициализация идут в поточном режиме!). Это
означает, что Вам не позволят распределить любые глобальные или менять
статические переменные! Если Вы нуждаетесь в памяти, Вы должны распределить
ее в xxx_init()
и непременно освободить в
xxx_deinit()
.
Основная функция должна быть объявлена как показано ниже. Обратите
внимание, что тип возврата и параметры отличаются в зависимости от того,
объявите ли Вы тип возврата функции SQL XXX()
как
STRING
, INTEGER
или REAL
в
вызове CREATE FUNCTION
:
Для функций типа STRING
:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
Для функций типа INTEGER
:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Для функций типа REAL
:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Функции инициализации и деинициализации объявлены подобно этому:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
Параметр initid
передан всем трем функциям. Он указывает на
структуру UDF_INIT
, которая используется, чтобы передать
информацию между функциями. Члены структуры UDF_INIT
перечислены
ниже. Функция инициализации должна заполнить любые члены, которые она желает
изменить. Чтобы использовать значение по умолчанию для члена, оставьте его
неизменным. Перейдем к описанию:
my_bool maybe_null
xxx_init()
должна установить maybe_null
в
1
, если xxx()
может возвращать NULL
.
Значение по умолчанию 1
, если любой из параметров объявлен
как maybe_null
.
unsigned int decimals
1.34
, 1.345
и 1.3
,
значением по умолчанию будет 3, поскольку 1.345
имеет 3 десятичных цифры.
unsigned int max_length
initid->decimals
. Для числовых функций длина включает любой
знак или десятичные символы отметки.
char *ptr
initid->ptr
, чтобы
передать распределенную память между функциями. В xxx_init()
как
обычно распределите память и назначьте ее этому указателю:
initid->ptr=allocated_memory;В
xxx()
и xxx_deinit()
обратитесь к
initid->ptr
, чтобы использовать или освободить память.Параметр args
указывает на структуру UDF_ARGS
,
члены которой приведены ниже:
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type
STRING_RESULT
, INT_RESULT
и
REAL_RESULT
. Чтобы удостовериться, что параметры имеют данный
тип и возвращают ошибку, если они к нему не принадлежат, проверьте массив
arg_type
в функции инициализации. Например:
if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; }Вы можете использовать функцию инициализации, чтобы установить элементы
arg_type
к типам, которые Вы хотите получить. Это заставляет
MySQL привести параметры к тем типам для каждого обращения к
xxx()
. Например, чтобы определить первые два элемента как строку
и число, сделайте следующее в xxx_init()
:
args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args
args->args
сообщает информацию функции инициализации
относительно общего характера параметров, с которыми Ваша функция была
вызвана. Для постоянного параметра (константы) i
args->args[i]
указывает на значение параметра. Для
непостоянного параметра args->args[i]
равно 0
.
Постоянный параметр представляет собой выражение, которое использует только
константы, типа 3
, 4*7-2
или
SIN(3.14)
. Непостоянный параметр представляет собой выражение,
которое обращается к значениям, которые могут изменяться, типа имени столбца
или функций, которые вызваны с непостоянными параметрами. Для каждого
обращения основной функции args->args
хранит фактические
параметры, которые переданы для в настоящее время обрабатываемой строки.
Функции могут обратиться к параметру i
следующим образом:
STRING_RESULT
, данный как указатель строки
плюс длина, позволяет обработку двоичных данных или данных произвольной
длины. Содержание строки доступно как args->args[i]
, а длина
строки как args->lengths[i]
. Вы не должны считать, что
строка завершается нулевым символом.
INT_RESULT
Вы должны привести
args->args[i]
к типу long long
:
long long int_val; int_val = *((long long*) args->args[i]);
REAL_RESULT
Вы должны привести
args->args[i]
к типу double
:
double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths
lengths
указывает
максимальную длину строки для каждого параметра. Для каждого обращения к
основной функции lengths
хранит фактические длины любых
строковых параметров, которые переданы для строки, обрабатываемой в настоящее
время. Для параметров типов INT_RESULT
или
REAL_RESULT
lengths
хранит максимальную длину
параметра (как для функции инициализации).Функция инициализации возвратит 0
, если никакая ошибка не
произошла, и 1
в противном случае. Если ошибка происходит,
xxx_init()
должна сохранить сообщение об ошибке с нулевым
символом в конце в параметре message
. Сообщение будет возвращено
пользователю. Буфер сообщений имеет длину в MYSQL_ERRMSG_SIZE
символов, но Вы должны попробовать сохранить сообщение в 80 символах так,
чтобы это удовлетворило ширине стандартного экрана терминала.
Значение возврата основной функции xxx()
зависит от типа. Для
функций типов long long
и double
оно представляет
собой собственно функциональное значение. Строковые функции должны возвратить
указатель на результат и сохранить длину строки в параметрах
length
. Здесь result
представляет собой буфер
длиной в 255 байт. Установите их к содержанию и длине значения. Например:
memcpy(result, "result string", 13); *length=13;
Если Ваши функции строки должны возвратить строку длиннее, чем 255 байт,
распределите память для результата через malloc()
в функции
xxx_init()
или в xxx()
, а затем освободите память в
xxx_deinit()
. Вы можете сохранять распределенную память в слоте
ptr
структуры UDF_INIT
для повторного использования
в будущем обращении xxx()
. Подробности в разделе
"9.1.2.1 Соглашения о вызове UDF
".
Чтобы указывать значение возврата NULL
в основной функции,
установите is_null
в 1
:
*is_null=1;
Чтобы указать возврат ошибки в основной функции, установите параметр
ошибки (error
) в значение 1
:
*error=1;
Если xxx()
устанавливает *error
в 1
для любой строки, функциональное значение NULL
для текущей
строки и для любых последующих строк, обработанных инструкцией, в которой
вызывалась XXX()
. Причем, xxx()
не будет даже
запрашиваться для последующих строк. ПРИМЕЧАНИЕ: В MySQL до
версии 3.22.10 Вы должны установить *error
и
*is_null
:
*error=1; *is_null=1;
Файлы, выполняющие UDF, должны компилироваться и устанавливаться на сервере. Этот процесс описан ниже для примерного UDF-файла udf_example.cc, который включен в дистрибутив исходников MySQL. Этот файл содержит следующие функции:
metaphon()
возвращает мета-строку для строкового
параметра. Это похоже на soundex, но больше заточено под английский.
myfunc_double()
возвращает сумму ASCII-значений символов в
параметрах, поделенную на сумму длин этих параметров.
myfunc_int()
возвращает сумму длин параметров.
sequence([const int])
возвратит последовательность,
начинающуюся с заданного числа или с 1, если никакого числа задано не было.
lookup()
возвращает IP-адрес.
reverse_lookup()
возвращает hostname для IP-адреса. Функция
может быть вызвана со строкой "xxx.xxx.xxx.xxx"
или с 4 числами.
Динамически загружаемый файл должен компилироваться как разделяемый объектный файл, используя команду:
shell> gcc -shared -o udf_example.so myfunc.cc
Вы можете легко выяснять правильные параметры компилятора для Вашей системы, запуская такую команду в каталоге sql Вашего дерева исходных текстов MySQL:
shell> make udf_example.o
Вы должны выполнить команду компиляции, подобную одной из тех, что
отображает make
, за исключением того, что Вы должны удалить
опцию -c
близко к концу строки и добавить
-o udf_example.so
в самый конец строки. На некоторых системах
удалять -c
не надо, пробуйте.
Как только Вы скомпилируете общедоступный объект, содержащий UDF, Вы
должны установить его и сообщить MySQL о расширении функциональности.
Компиляция общедоступного объекта из udf_example.cc производит файл
с именем udf_example.so (точное имя может изменяться от платформы к
платформе). Скопируйте этот файл в некоторый каталог, где ищет файлы
ld
, например, в /usr/lib. На многих системах Вы можете
устанавливать системную переменную LD_LIBRARY
или
LD_LIBRARY_PATH
, чтобы указать каталог, где Вы имеете Ваши файлы
функции UDF. Руководство на dlopen
сообщает Вам, которую
переменную Вы должны использовать на Вашей системе. Вы должны установить это
в mysql.server
или в safe_mysqld
и перезапустить
mysqld
.
После того, как библиотека установлена, сообщите mysqld
относительно новых функций этими командами:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
Функции могут быть удалены, используя DROP FUNCTION
:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;
Инструкции CREATE FUNCTION
и DROP FUNCTION
модифицируют системную таблицу func
в базе данных
mysql
. Имя функции, тип и общедоступное библиотечное имя будут
сохранено в таблице. Вы должны иметь привилегии insert и
delete для базы данных mysql
, чтобы создавать и
удалять свои функции.
Вы не должны использовать CREATE FUNCTION
, чтобы добавить
функцию, которая уже была создана. Если Вы должны повторно установить
функцию, сначала удалите ее через вызов DROP FUNCTION
и затем
повторно установите ее с помощью CREATE FUNCTION
. Вы должны
сделать это, например, если Вы откомпилировали новую версию Вашей функции,
чтобы mysqld
обновил используемую им версию. Иначе сервер
продолжит применять старую версию.
Активные функции будут перезагружены при каждом перезапуске сервера, если
Вы не запускаете mysqld
с опцей --skip-grant-tables
.
В этом случае инициализация UDF будет пропущена, а UDF-функции станут
недоступными. Активная функция представляет собой функцию, загруженную через
CREATE FUNCTION
, но не удаленную DROP FUNCTION
.
Процедура для добавления новой встроенной функции описана ниже. Обратите внимание, что Вы не можете добавлять встроенные функции к двоичному дистрибутиву потому, что процедура включает изменение исходного текста MySQL. Вы должны скомпилировать MySQL самостоятельно из исходников. Также обратите внимание, что, если Вы мигрируете на другую версию MySQL (например, когда новая версия выпущена), Вы будете должны повторить процедуру с новой версией.
Чтобы добавить новую встроенную функцию MySQL, нужно:
sql_functions[]
.
sql_functions[]
и добавить
функцию, которая создает функциональный объект, в item_create.cc.
Смотрите "ABS"
и create_funcs_abs()
как пример.
Если функциональный прототип усложнен (например, берет переменное число
параметров), Вы должны добавить две строки к sql_yacc.yy. Каждая
указывает символ препроцессора, который yacc
должен определить
(это должно быть добавлено в начале файла). Затем определите функциональные
параметры и добавьте элемент с этими параметрами для правила синтаксического
анализа simple_expr
. Для примера, проверьте все местонахождения
ATAN
в sql_yacc.yy, чтобы увидеть, как это выполнено.
Item_num_func
или Item_str_func
, в зависимости от
того, возвращает ли Ваша функция число или строку.
double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)Если Вы наследуете Ваш объект от любого из стандартных элементов (подобно
Item_num_func
, Вы, вероятно, должны только определить одну из
вышеупомянутых функций и позволить родительскому объекту заботиться о других
функциях. Например, класс Item_str_func
определяет функцию
val()
, которая выполняет atof()
на значении,
возвращенном ::str()
.
void Item_func_newname::fix_length_and_dec()Эта функция должна по крайней мере вычислить
max_length
, исходя
из данных параметров. max_length
задает максимальное число
символов, которое функция может возвращать. Эта функция должна также
установить maybe_null=0
, если основная функция не может
возвращать значение NULL
. Функция может проверить, способен ли
любой из параметров возвращать NULL
, проверяя переменную
параметров maybe_null
. Вы можете изучить
Item_func_mod::fix_length_and_dec
в качестве типичного примера
того, как все это сделать.Все функции должны быть поточно-безопасными (другими словами, не используйте любые глобальные или статические переменные в функциях без того, чтобы защитить их через mutex).
Если Вы хотите возвращать NULL
из ::val()
,
::val_int()
или ::str()
Вы должны установить
null_value
в 1 и вернуть из функции 0.
Для объектной функции ::str()
имеются некоторые
дополнительные хитрости, которые надо знать:
String *str
обеспечивает буфер строки, который
может использоваться, чтобы хранить результат. Для получения большего
количества информации относительно типа String
обратитесь к
файлу sql_string.h.
::str()
должна возвратить строку, которая хранит
результат, или (char*) 0
, если результатом является
NULL
.
В MySQL Вы можете определять процедуру на C++, которая может обращаться и
изменять данные в запросе прежде, чем они отправятся к пользователю.
Модификация может быть выполнена на уровне строки или GROUP BY
.
Авторы пакета создали процедуру примера в MySQL Version 3.23, чтобы показать Вам, что там может быть выполнено.
Дополнительно авторы рекомендуют Вам посмотреть файл mylua, который Вы
можете найти в каталоге Contrib. Вы можете использовать язык LUA, чтобы
загрузить процедуру в mysqld
прямо во время выполнения.
analyse([max elements,[max memory]])
Эта процедура определена в sql/sql_analyse.cc. Она исследует результат, полученный из Вашего запроса, и возвращает анализ результатов:
max elements
(по умолчанию 256) задает максимальное
число разных значений, которые analyse
заметит в столбце. Это
используется, чтобы проверить оптимальность применения типа ENUM
.
max memory
(по умолчанию 8192) задает максимум памяти,
которую analyse
должен распределить на столбец при попытке найти
все отличные значения.SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
На сегодняшний день единственной документацией для этого является исходный код пакета.
Вы можете найти всю информацию относительно процедур, исследуя файлы:
Эта глава описывает много вещей, которые Вы должны знать при работе на коде MySQL. Если Вы планируете способствовать MySQL разработке, иметь доступ к коду отлаживаемых версий или хотите только следить за разработкой, поставьте дерево исходников для разработки. Если Вы заинтересованы внутренней организацией MySQL, Вы должны также подписаться на специальный список рассылки internals@lists.mysql.com.
Сервер MySQL создает следующие потоки:
process_alarm()
, чтобы завершить подключения,
которые были неактивны слишком долго.
mysqld
компилируется с -DUSE_ALARM_THREAD
,
специализированный поток, который обрабатывает тревоги, будет создан. Это
используется только на некоторых системах, где имеются проблемы с
sigwait()
, или если есть недостатки в применении кода
thr_alarm()
в прикладной программе без специализированного
потока обработки сигнала.
--flush_time=#
, будет создан еще
один специализированный поток, который сбрасывает таблицы на диск.
INSERT
DELAYED
, получает собственный поток.
--master-host
, будет запущен поток
репликации, чтобы читать и применять модификации с главного сервера.mysqladmin processlist
показывает только подключения, потоки
репликации и INSERT DELAYED
.
До недавнего времени основной набор теста был основан на составляющих
собственность данных заказчика и по этой причине не был публично доступен.
Единственный публично доступная часть процесса тестирования состояла из теста
crash-me
, эталонного теста Perl DBI/DBD, находящегося в каталоге
sql-bench
, и разнообразных тестов, размещенных в каталоге
tests
. Отсутствие стандартизированного публично доступного
набора тестов сделало трудным для пользователей и разработчиков тестирование
кода MySQL. Чтобы исправить эту ситуацию, авторы пакета создали совершенно
новую систему тестов, которая теперь включена в исходные и двоичные
дистрибутивы, начиная с Version 3.23.29.
Текущий набор тестов не проверяет все в MySQL, но должен охватить наиболее очевидные ошибки в обработка кода SQL, OS/library проблемы и тестирование репликации. Конечная цель состоит в том, чтобы иметь тесты, покрывающие 100% кода. Вы можете предоставить тесты, которые исследуют функциональные возможности, критичные для Вашей системы, поскольку это гарантирует, что все будущие выпуски MySQL будут хорошо работать с Вашими прикладными программами.
Система теста состоит из интерпретатора языков тестов
(mysqltest
), скрипта оболочки, чтобы выполнить все тесты
(mysql-test-run
), фактических случаев тестов, написанных на
специальном языке тестов и их ожидаемых результатов. Чтобы выполнить набор
теста на Вашей системе после построения, введите make test
или
mysql-test/mysql-test-run
из корневого каталога исходных
текстов. Если Вы установили двоичный дистрибутив, перейдите в корень
установки (например, /usr/local/mysql
) и скомандуйте
scripts/mysql-test-run
. Все тесты должны выполниться. Если этого
не произошло, пропобуйте выяснить почему и сообщите о проблеме, если это
ошибка в пакете MySQL.
Если Вы имеете копию mysqld
на машине, где Вы хотите
выполнить набор тестов, Вы не должны останавливать ее, если она не использует
порты 9306
и 9307
. Если один из этих портов
применяется, Вы должны отредактировать mysql-test-run
и изменить
значения главного или подчиненного порта к тому, которое является доступным.
Вы можете запустить индивидуально каждый тест командой
mysql-test/mysql-test-run test_name
.
Если один тест свалился, проверьте работу mysql-test-run
с
опцией --force
, чтобы проверить, сбоят ли любые другие тесты.
Вы можете использовать язык mysqltest
, чтобы писать Ваши
собственные случаи теста. К сожалению, авторы пакета еще не написали полную
документацию для него. Вы можете, однако, рассматривать текущие случаи теста
и использовать их как пример. Следующие пункты должны помочь Вам:
mysql-test/t/*.test
;
)
инструкции и подобен вводу клиента командной строки mysql
.
Инструкция по умолчанию: запрос, который будет послан серверу MySQL, если он
не распознан как внутренняя команда (например, sleep
).
SELECT
, SHOW
, EXPLAIN
и прочие, нужно
предварить указанием @/path/to/result/file
. Файл должен
содержать ожидаемые результаты. Простой способ генерировать файл результата
состоит в том, чтобы выполнить mysqltest -r <
t/test-case-name.test
из каталога mysql-test
, а затем
отредактировать сгенерированные файлы результата, если необходимо
скорректировать их к ожидаемому выводу. В этом случае будьте очень осторожны
относительно добавления или удаления любых невидимых символов. Если Вы должны
вставить строку, удостоверьтесь, что поля отделяются позициями табуляции, и
имеется табуляция в конце. Вы можете использовать od -c
, чтобы
удостовериться, что Ваш текстовый редактор не добавляет что-нибудь
неожиданное в течение процесса редактирования.
mysql-test/r
и назвать их как
test_name.result
. Если тест производит больше, чем один
результат, Вы должны использовать test_name.a.result
,
test_name.b.result
и так далее.
--error error-number
. Здесь error-number может быть списком
возможных кодов ошибок, отделяемых запятыми (,
).
source include/master-slave.inc;
. Чтобы
переключаться между главной и подчиненной системами, используйте
connection master;
и connection slave;
. Если Вы
должны делать что-то на альтернативном подключении, Вы можете сделать
подключение connection master1;
для главной и
connection slave1;
для подчиненной системы.
let $1=1000; while ($1) { # Выполняем здесь запрос. dec $1; }
sleep
. Она поддерживает доли секунды, так что Вы можете указать
sleep 1.3;
, например, чтобы бездействовать 1.3 секунды.
mysql-test/t/test_name-slave.opt
. Для главной системы поместите
их в файл mysql-test/t/test_name-master.opt
.
Если Ваша версия MySQL не выполняет набор тестов, Вы должны сделать так:
mysqlbug
, чтобы
разработчики могли получить информацию относительно Вашей
системы и версии MySQL.
mysql-test-run
и
содержание всех .reject
файлов в каталоге
mysql-test/r
.
cd mysql-test mysql-test-run --local test-nameЕсли это терпит неудачу, то сконфигурируйте MySQL с опцией
--with-debug
и выполните mysql-test-run
с опцией
--debug
. Если это также терпит неудачу, закачайте файл
трассировки var/tmp/master.trace на
ftp://support.mysql.com/pub/mysql/secret, чтобы авторы могли исследовать это.
Пожалуйста, не забудьте также включить полное описание Вашей системы, версию
mysqld и параметры компиляции.
mysql-test-run
с опцией
--force
, чтобы увидеть, имеется ли любой другой тест, который
тоже терпит неудачу.
Result length mismatch
или
Result content mismatch
, это означает, что вывод теста не
соответствовал точно ожидаемому выводу. Это может быть ошибкой в MySQL, или
дело в том, что Ваша версия mysqld производит малость иные результаты при
некоторых обстоятельствах. Неудачные результаты теста будут помещены в файл с
тем же самым основным именем, что и файл результата, но с расширением
.reject
. Если Ваш случай теста терпит неудачу, Вы должны
сравнить два файла. Если Вы не можете увидеть, чем они отличаются, исследуйте
их с помощью od -c
и проверьте их длины.
mysql-test/var/log
для выяснения того, что не так.
mysql-test-run
с опциями --gdb
и/или
--debug
. Если Вы не компилировали MySQL для отладки, вероятно,
стоит сделать это. Только определите параметр --with-debug
для вызова configure
!Это MySQL Ruby API. Он отвечает за реализацию ряда функций, аналогичных MySQL C API.
Для исправной работы интерфейса требуются, как минимум:
Автор: TOMITA Masahiro (tommy@tmtm.org, http://www.tmtm.org/mysql).
Сначала введите команды:
# ruby extconf.rb # make
Скрипт extconf.rb понимает следующие опции:
Теперь введите команду:
# ruby -I. ./test.rb hostname user passwd
Скрипт test.rb имеет несколько аргументов: имя хоста сервера MySQL, имя пользователя MySQL и его пароль.
Теперь введите команду:
# make install
Если Вы получили ошибку, например, libmysqlclient not found, при тестировании, следует в явном виде задать каталог библиотек в вызове make:
# env LD_RUN_PATH=каталог_с_libmysqlclient.so # make
Если используется статическая библиотека libmysqlclient.a, понадобятся некоторые дополнительные библиотеки. Подправьте скрипт extconf.rb и включите в нем "have_library('m')" и "have_library('z')".
Имена методов базируются на C API без префикса mysql_. Если метод породил некую ошибку, возникает исключительная ситуация MysqlError. Загрузка модуля mysql выполняется указанием require "mysql".
Класс Mysql. Методы:
Объектные методы:
Объектные переменные:
Класс MysqlRes. Методы:
Итераторы:
Класс MysqlField. Объектные переменные (только для чтения):
Объектные методы в классе:
Класс MysqlError. Объектные переменные (только для чтения):
MyC представляет собой набор простых подпрограмм C, предназначенных, чтобы сделать создание прикладных программ для использования с базой данных MySQL проще, особенно для тех, кто знаком с Microsoft DAO engine model (используемой в пакетах Microsoft Access и Microsoft Visual Basic).
MyC использует подобную модель, чтобы обратиться к данным внутри базы данных: OpenDatabase, чтобы открыть базу данных, OpenRecordset, чтобы открыть набор результатов, Move, чтобы двигаться внутри набора результатов, AddNew/Edit и Update/Delete, чтобы добавлять, редактировать или удалять данные внутри базы данных.
Текущей версией MyC является 0.0.1 ALPHA.
MyC не предназначен, чтобы открывать больше, чем один набор результатов за раз. Поддержка нескольких наборов результатов будет в следующем выпуске.
Если набор результатов не имеет уникального ключа, связанного с каждой записью, то Delete() удалит только первое соответствие названной записи. Это отличие от модели DAO, в которой удаляется только в настоящий момент указанная запись, неважно первая она или нет.
Сейчас MyC работает только под Linux, но планируется перенос на другие версии UNIX. Попыток переноса на платформу Windows не было.
Никаких тестов на утечки памяти пока не проводилось для MyC.
Пожалуйста не забудьте, что этот код ALPHA, так что он постоянно будет меняться. В коде почти наверняка есть ошибки, так что будьте осторожны с применением его в ответственных участках своих программ. У автора все работает должным образом, должно бы и у Вас работать, но никаких гарантий пока дать не могу.
Автор этого пакета: Ed Carp. Связаться с ним можно по erc@pobox.com. Есть и веб-страница www.pobox.com/~erc. Он технический администратор и коммерческий программный разработчик, с обширным опытом в управлении проектами от начала до конца, а также в разработке программ на C и VB.
В настоящее время все подпрограммы MyC включены в один файл заголовков database.h. Имя этого файла не критическое и может быть изменено в любое время, чтобы удовлетворить потребности специфического проекта.
Этот файл должен быть включен первым, также нужно включить stdio.h и stdlib.h. Если директива #define MYC_DEBUG помещена перед включением database.h, то обширный код отладки будет записан в поток stderr.
Программы MyC компилируются аналогично любым другим программам, использующим MySQL C API.
При вызове OpenDatabase() с именем базы данных, которая будет открыта, именем хоста, именем пользователя и паролем функция инициализирует прикладную программу и открывает выбранную базу данных. EOF возвращен при сбое, NULL возвращен при успехе.
Вызов OpenRecordset() со строкой представляющей собой корректный запрос SQL, открывает набор результатов, который содержит результаты запроса. OpenRecordset() возвращает EOF при ошибке и NULL при успехе. Число записей в наборе результатов может быть получено вызовом RecordCount(), который возвращает число записей в наборе результатов как целое число без знака.
Набор результатов может быть пройден и изучен с помощью вызовов MoveNext, MovePrev, MoveFirst и MoveLast, которые перемещают в следующий, предыдущий, первый и в последний результат в наборе результатов соответственно. Если набор результатов некорректен, эти подпрограммы возвращают значение EOF, иначе они возвращают NULL.
К данным в текущей строке в наборе результатов можно обращаться, вызывая GetField или GetFieldN. GetField вызывается с именем поля как параметр и возвращает символьный указатель на данные или символьный указатель на EOF в случае сбоя. GetFieldN работает подобным способом, за исключением того, что GetFieldN вызывается с номером желательного поля (отсчет начинается с 0).
Данные могут быть записаны в таблицу одним из двух путей: вызовом OpenRecordset() с запросом INSERT INTO или UPDATE (или любой другой имеющей силу в этом отношении инструкцией SQL), или использованием встроенных функций AddNew или Edit.
AddNew() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к Update() генерирует инструкцию SQL INSERT INTO. Точно так же Edit() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к функции Update() сгенерирует инструкцию SQL UPDATE.
Чтобы устанавливать индивидуальные поля используются SetField, SetFieldN или SetFieldB. SetField вызывается с двумя параметрами: именем поля, которое будет установлено, и значением для него. Точно так же вызывается и SetFieldN, но первый параметр задает номер поля, а не его имя. SetFieldB используется с двоичными данными, и преобразует двоичные данные и NULL в форму, которая может быть сохранена. Обратите внимание, что SetFieldB перезаписывает указанные строки. Никакого средства пока не сделано для преобразования чистых двоичных данных, хотя можно вызывать mysql_escape_string() и передавать возвращенный указатель функциям SetField или SetFieldN.
Важно обратить внимание, что SetField и подобные подпрограммы сохраняют только указатель на данные, которые будут записаны, а не сами данные.
В конце концов поля установлены, Update() вызван с именем таблицы, которую нужно модифицировать. Update() вернет EOF при ошибке или NULL при успехе.
После того, как данные добавлены или модифицированы в таблице, иногда полезно иметь текущий (актуальный) набор записей, отражающий измененные данные. Вызов Refresh() заново выполнит запрос, выполненный последним OpenRecordset() (до 4096 байт) и эквивалентен вызову OpenRecordset(), за исключением того, что текущая строка та же, что и перед вызовом Refresh().
Вызов Delete() с именем таблицы удалит текущую строку из таблицы. Если имеются строки с двойными данными, только первая строка будет удалена.
В настоящее время поддерживаются следующие информационные подпрограммы, RecordCount(), FieldCount(), AbsolutePosition() и RecordsetEOF(). RecordCount возвращает целое число без знака, указывающее текущее число записей в наборе результатов. FieldCount возвращает число полей в строке набора результатов. FieldValue вызывается с номером поля и возвращает его значение, в то время как FieldName тоже вызывается с номером поля, но возвращает уже его имя. AbsolutePosition возвращает номер строки текущей строки в наборе результатов. RecordsetEOF возвращает TRUE, если не имеется никаких имеющих силу записей в наборе результатов, или если текущая строка в конце или начале набора результатов, и никаких имеющих силу записей не осталось, чтобы прочитать их из набора записей. MoveLast и MoveFirst устанавливают RecordsetEOF в TRUE.
Прикладные программы очень просто писать с MyC. В следующих примерах существует таблица test в базе данных mysql, а в ней есть 5 записей заданных следующим образом:
+--------+-----+ | name | num | +--------+-----+ | item 0 | 0 | | item 1 | 1 | | item 2 | 2 | | item 3 | 3 | | item 4 | 4 | +--------+-----+
Предположим, например, что прикладная программа должна сделать запрос к базе данных и записать все данные в поток stdout:
#include "database.h" main () { int i; OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("select * from test"); while(RecordsetEOF () != EOF) { for (i = 0; i < FieldCount(); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0); }
Немного более сложный пример иллюстрирует добавление, изменение и удаление данных. Этот пример будет формировать таблицу test, вносить в список все данные в таблице, затем просматривать таблицу, заменяя item 3 на item 5 и попутно удаляя item 4:
#include "database.h" main () { int i; char buf[10], buf2[5]; OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("delete from test"); CloseRecordset(); OpenRecordset("select * from test"); for (i = 0; i < 5; i++) { AddNew(); sprintf(buf, "item %d", i); sprintf(buf2, "%d", i); SetField("name", buf); SetField("num", buf2); Update("test"); } Refresh(); MoveFirst(); while (RecordsetEOF () != EOF) { for (i = 0; i < FieldCount (); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } MoveFirst (); while (RecordsetEOF () != EOF) { printf ("Looking at '%s'\n", GetField ("name")); if (strcmp(GetField("name"), "item 3") == 0) { puts("Changing data"); Edit(); SetField("name", "item 5"); Update("test"); } if (strcmp(GetField("name"), "item 4") == 0) { puts("Deleting data"); Delete("test"); } MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0); }
Версия v0.1 (19-Feb-2000). Автор: Satish (spitfire@pn3.vsnl.net.in). Лицензия: Feel free to use/copy/modify/add bugs/find bugs, but keep the author informed.
Это C++ библиотека для сервера MySQL. Разработчик данного пакета искал библиотеку C++, которая может создавать и работать с Data Access Objects. Он натолкнулся на программное обеспечение, написанное Roland Hanel (MySQL C++) и Ed Carp (MyC). Но MyC написан на чистом C и не может создавать объект в истинном смысле. Также это не может создавать и работать с несколькими наборами результатов. На основе этих пакетов была написан пакет MyDAO ver 0.1.
dbconnect class: Один объект подключения должен быть создан. Это ответственно за соединение с сервером MySQL и открытие базы данных. Свойства:
Методы:
Пример:
dbconnect MyConnect; char host[]="localhost"; char port[]="3306"; char name[]="satish"; char pwd[]=""; char db[]="orders"; MyConnect.Connect(host, port, name, pwd); if (MyConnect.Connected) cout << "Connected" << endl; else { cout << "Connection failed" << endl; return; } if (!MyConnect.OpenDB(db)) { cout << "Can not open selected database" << endl; return; } else { cout << "Opened datbase: " << db << endl; // open recorset(s)... // Manipulate data... } MyConnect.Disconnect();
recordset class: Любое количество наборов результатов может быть создано из этого класса. Он имеет много свойств для простого манипулирования данными.
Свойства:
Методы:
Пример 1:
// Продолжение примера из dbconnect. // Откроем таблицу заказчиков (customers) и распечатаем // все записи из нее. recordset MySet; char sql[]="SELECT * FROM customers"; MySet.OpenRecordset(MyConnect.DBase, sql); if (MySet.EOR && MySet.BOR){ cout << "No records found" << endl; return; } else { // Show number of records cout << "No. of records: " << MySet.RecordCount << endl; // Show all records while (!MySet.EOR) { cout << MySet.GetField("or_id") << "\t"; cout << MySet.GetField("customers") << "\t"; cout << MySet.GetField("city") << endl; MySet.MoveNext(); } }
Пример 2:
// Добавление новой строки в таблицу заказчиков. MySet.AddNew(); MySet.SetField("cs_id", "7"); MySet.SetField("name", "Satish"); MySet.SetField("city", "Pune"); MySet.Update(""); // where не используется! MySet.Refresh(); // Сделаем изменения видимыми.
Пример 3:
// Изменение имени заказчика. MySet.Edit(); MySet.SetField("cs_id", "7"); MySet.SetField("name", "Suresh"); MySet.SetField("city", "Pune"); MySet.Update("or_id=7"); // where здесь необходимо использовать. MySet.Refresh(); // Сделаем изменения видимыми.
Пример 4:
// Удаление записи. MySet.Delete("name='Suresh'"); MySet.Refresh(); // Сделаем изменения видимыми.
Пример 5:
// Закроем набор результатов после употребления. Это ОБЯЗАТЕЛЬНО! MySet.CloseRecordset();
Что еще надо сделать:
Этот модуль включает объект TMySQLServer, полученный из стандартного класса Delphi 5 TCustomConnection.
Компонент: TMySQLServer
Типы: TMySQLServerLoginEvent
Подпрограммы: MYSQLError
Описание
TMySQLServer представляет собой основной компонент в наборе TMySQLComponent. TMySQLServer используется, чтобы обработать фактические подключения к серверу MySQL, используя стандартные функции из libmysql.dll. Большую часть времени Вы будете использовать только один компонент сервера, зато много компонентов TMySQLDatasets.
Важно обратить внимание на то, что есть только одно физическое подключение к серверу MySQL. Все наборы данных, приложенные к этому TMySQLServer, используют это подключение или породят собственные подключения, использующие те же самые параметры настройки TMySQLServer.
Помимо этих функций, этот компонент имеет много полезных свойств и функций, чтобы создавать, удалять, использовать базы данных, получать информацию о версии, собирать списки баз данных, таблиц, полей и т. д.
Свойства
AfterConnect!AL("AfterConnect_Property") AfterDisconnect!AL("AfterDisconnect_Property") BeforeConnect!AL("BeforeConnect_Property") BeforeDisconnect!AL("BeforeDisconnect_Property") Build ClientVersion Compression Connected!AL("Connected_Property") DatabaseName Host IdleTimer Info IntVer LoginPrompt Major Minor Params Password Port Protocol ServerVersion UserName
Методы
Create!AL("Create_Method") Destroy!AL("Destroy_Method") AllocConnection ExecSQL FormatIdentifier FormatIdentifiers SelectDatabase Server CreateDatabase DropDatabase FreeConnection GetDatabaseNames GetFieldNames GetTableNames RegisterClient!AL("RegisterClient_Method") Reload SendEvent UnRegisterClient!AL("UnRegisterClient_Method")
События
Key events OnIdleTimer OnLogin
Цель
Обеспечить все приложенные наборы данных физическими подключениями к серверу MySQL, используя стандартную библиотеку libmysql.dll. Это основной компонент в наборе TMySQLComponent.
Свойство Build
Применимо к TMySQLServer
Определение
property Build : word;
Описание
Сервер формирует версию как слово, например, 32
Read-only
Свойство ClientVersion
Применимо к TMySQLServer
Определение
property ClientVersion : string;
Описание
Используемая версия клиентской разделяемой библиотеки libmysql.dll.
Read-only
Свойство Compression
Применимо к TMySQLServer
Определение
property Compression : boolean;
Описание
Определяет протокол сжатия, используемый при связи с сервером MySQL.
Свойство DatabaseName
Применимо к TMySQLServer
Определение
property DatabaseName : string;
Описание
Получает или определяет текущую (актуальную) базу данных для этого подключения.
Свойство Host
Применимо к TMySQLServer
Определение
property Host : string;
Описание
Получает или определяет имя хоста, используемое при создании новых подключений.
Свойство IdleTimer
Применимо к TMySQLServer
Определение
property IdleTimer : longword;
Описание
Получает или определяет актуальное время неактивности (тайм-аут), позволенное для этого подключения. Подключение автоматически будет пересоздано после того, как это время закончится, а связь еще нужна.
Свойство Info
Применимо к TMySQLServer
Определение
property Info : string;
Описание
Более подробная информация о сервере.
Read-only
Свойство IntVer
Применимо к TMySQLServer
Определение
property IntVer : longword;
Описание
Версия сервера как слово, например, 32306.
Read-only
Свойство LoginPrompt
Применимо к TMySQLServer
Определение
property LoginPrompt;
Описание
Если установлено в True, это учитывает настроенный диалог подсказки MySQL входа в систему, который будет появляться каждый раз, когда устанавливается связь с этим сервером.
Свойство Major
Применимо к TMySQLServer
Определение
property Major : word;
Описание
Старшая часть версии сервера как слово, например, 3
Read-only
Свойство Minor
Применимо к TMySQLServer
Определение
property Minor : word;
Описание
Младшая часть версии сервера как слово, например, 22
Read-only
Свойство Params
Применимо к TMySQLServer
Определение
property Params : TStrings;
Описание
Стандартные параметры, используемые для сервера событием OnLogin. Могут быть изменены во время выполнения.
Свойство Password
Применимо к TMySQLServer
Определение
property Password : string;
Описание
Получает или определяет текущий пароль, используемый при создании нового подключения.
Свойство Port
Применимо к TMySQLServer
Определение
property Port : word;
Описание
Получает или определяет текущий порт, используемый при связи с сервером.
Свойство Protocol
Применимо к TMySQLServer
Определение
property Protocol : string;
Описание
Используемый протокол связи: TCP/IP, Pipes и т.д.
Read-only
Свойство ServerVersion
Применимо к TMySQLServer
Определение
property ServerVersion : string;
Описание
Версия сервера MySQL в виде строки.
Read-only
Свойство UserName
Применимо к TMySQLServer
Определение
property UserName : string;
Описание
Получает или определяет текущее имя пользователя, используемое при создании нового подключения.
Метод AllocConnection
Применим к TMySQLServer
Определение
function AllocConnection : PMYSQL;
Описание
Распределяет новое подключение для TMySQLServer и TMySQLDatasets, используя текущие параметры настройки Username, Password, Port и прочие.
Это внутренне используемый метод, обычно он используется только порожденными классами TMySQLServer.
Метод ExecSQL
Применим к TMySQLServer
Определение
function ExecSQL(SQL : string) : boolean;
Описание
Используя подключение, выполнит любую инструкцию SQL на сервере.
Метод FormatIdentifier
Применим к TMySQLServer
Определение
function FormatIdentifier(Value : string) : string;
Описание
Форматирует идентификатор Value, используя информацию о версии сервера. Например, "Table 1" превратится в "`Table 1`".
Метод FormatIdentifiers
Применим к TMySQLServer
Определение
function FormatIdentifiers(const Value : string) : string;
Описание
Форматирует идентификаторы, полученные в строке Value, используя информацию о версии сервера. Например, "Table 1#10#13Table2#10#13Table 3" превратится в "`Table 1`,Table 2,`Table 3`".
Метод SelectDatabase
Применим к TMySQLServer
Определение
function SelectDatabase(Conn : PMYSQL; DB : string) : boolean;
Описание
Для данного подключения выбирает текущую (актуальную) базу данных, то есть действует аналогично команде "USE Database;". Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Метод Server
Применим к TMySQLServer
Определение
function Server : PMYSQL;
Описание
Представляет собой указатель на текущее потоковое подключение к серверу. Это может использоваться со всеми стандартными функциями mysql_, найденными в библиотеке libmysql.dll. Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Метод CreateDatabase
Применим к TMySQLServer
Определение
procedure CreateDatabase(Value : string);
Описание
При использовании подключения к серверу создает новую базу данных, то есть работает аналогично инструкции "CREATE Database;".
Метод DropDatabase
Применим к TMySQLServer
Определение
procedure DropDatabase(Value : string);
Описание
При использовании текущего подключения к серверу удаляет указанную базу данных, то есть работает аналогично инструкции "DROP Database;".
Метод FreeConnection
Применим к TMySQLServer
Определение
procedure FreeConnection(var Value : PMYSQL);
Описание
Освобождает активное подключение.
Метод GetDatabaseNames
Применим к TMySQLServer
Определение
procedure GetDatabaseNames(List : TStrings);
Описание
Заполняет список со всеми именами баз данных, найденными на сервере. Замечание: в этом списке не будут перечислены те базы данных, на которых Вы не имеете никаких привилегий.
Метод GetFieldNames
Применим к TMySQLServer
Определение
procedure GetFieldNames(const DatabaseName, TableName : string; List : TStrings);
Описание
Заполняет cписок всеми именами полей для таблицы TableName из базы данных DatabaseName с сервера.
Метод GetTableNames
Применим к TMySQLServer
Определение
procedure GetTableNames(const DatabaseName : string; List : TStrings);
Описание
Заполняет cписок всеми именами таблиц из базы данных DatabaseName.
Метод Reload
Применим к TMySQLServer
Определение
procedure Reload;
Описание
Перезагружает права доступа на сервере, то есть работает как команда "RELOAD;"
Метод SendEvent
Применим к TMySQLServer
Определение
procedure SendEvent(Connecting : Boolean);
Описание
Используется, чтобы разъединить все наборы данных, если сервер завершается. Это внутренне используемый метод. Обычно он применяется только классами, порожденными от TMySQLServer.
Событие OnIdleTimer
Применимо к TMySQLServer
Определение
property OnIdleTimer : TNotifyEvent;
Описание
Это событие происходит, когда заканчивается время ожидания подключения.
Событие OnLogin
Применимо к TMySQLServer
Определение
property OnLogin : TMySQLServerLoginEvent;
Описание
Это событие происходит прежде, чем подключение будет сделано, чтобы позволить Вам изменять свойства Params.
Тип TMySQLServerLoginEvent
Модуль MySQLServer
Определение
type TMySQLServerLoginEvent = procedure(Server : TMySQLServer; LoginParams : TStrings); of object;
Описание
Это событие происходит до установки связи с сервером MySQL. Список строк LoginParams в настоящее время поддерживает только два ключевых слова в форме: USERNAME=root, PASSWORD=.
Процедура MYSQLError
Модуль MySQLServer
Определение
procedure MYSQLError(MySQLHandle : PMySQL=nil; ErrNo : integer=-1; Msg : string=''; IntVer : longword=32100);
Описание
Универсальная функция создания исключительной ситуации, предоставляет зависящую от версии информацию относительно последней ошибки MySQL.
Этот модуль содержит все классы необходимые, чтобы поддерживать основной класс TMySQLDataset.
Компонент: TMySQLDataset.
Типы: TMySQLEvent, TMySQLLocateOptions.
Константы: DefaultMacroChar='|', DefaultTermChar=';'.
TMySQLDataset
Модуль: MySQLDataset.
Описание
Это основной класс, используемый в Вашей прикладной программе. Он был назван именно Dataset, а не Query или Table потому, что он может легко использоваться как стандартный TTable или TQuery. Поскольку этот класс связывается и работает с сервером MySQL, он делает доступными для использования все инструкции SQL. По умолчанию используется концепция макросов (Macros) в командах SQL. Эти макрокоманды очень легко могут быть заблокированы или удалены из значения по умолчанию SQL.
Кроме того, являясь прямым поточным подключением к серверу MySQL, класс был получен непосредственно из TDataset и таким образом поддержан всеми компонентами для работы с базами данных, включая TDatasource. Этот компонент имеет все стандартные свойства и методы.
Из-за отсутствия поддержки курсоров на стороне сервера в MySQL, этот компонент полагается на хорошо разработанные таблицы по умолчанию, то есть Ваши таблицы должны по крайней мере иметь первичный ключ. Если Вы отменяете заданные по умолчанию инструкции SQL, Вы можете сами определять, когда, что и над чем будет выполнено.
Компонент TMySQLDataset
Свойства
Active!AL("Active_Property") AffectedRows AfterCancel!AL("AfterCancel_Property") AfterClose!AL("AfterClose_Property") AfterDelete!AL("AfterDelete_Property") AfterEdit!AL("AfterEdit_Property") AfterInsert!AL("AfterInsert_Property") AfterOpen!AL("AfterOpen_Property") AfterPost!AL("AfterPost_Property") AfterRefresh!AL("AfterRefresh_Property") AfterScroll!AL("AfterScroll_Property") BeforeCancel!AL("BeforeCancel_Property") BeforeClose!AL("BeforeClose_Property") BeforeDelete!AL("BeforeDelete_Property") BeforeEdit!AL("BeforeEdit_Property") BeforeInsert!AL("BeforeInsert_Property") BeforeOpen!AL("BeforeOpen_Property") BeforePost!AL("BeforePost_Property") BeforeRefresh!AL("BeforeRefresh_Property") BeforeScroll!AL("BeforeScroll_Property") AllFieldValues CachedUpdates DatabaseName FieldName Filter Filtered MacroChar MacroCount Macros MacrosEnabled MasterFields MasterSource MultiKeyFields MySQLFields MySQLRecords MySQLTables PrimaryKeyFields ReadOnly RealSQL Records Server ShareConnection SQL SQLBatch SQLDelete SQLInsert SQLUpdate TableName UniqueKeyFields
Методы
Create!AL("Create_Method") Destroy!AL("Destroy_Method") BookmarkValid!AL("BookmarkValid_Method") CompareBookmarks!AL("CompareBookmarks_Method") CreateBlobStream!AL("CreateBlobStream_Method") EscapeStr ExecBatch ExecSQL ExecSQLBatch GetFieldData!AL("GetFieldData_Method") GetMacroValue HexStr Locate!AL("Locate_Method") LocateRecord LocateRecordOption Lookup!AL("Lookup_Method") MacroByName ParseSQL QuoteStr ClearMacros ConnectEvent
События
OnCalcFields!AL("OnCalcFields_Event") OnDeleteError!AL("OnDeleteError_Event") OnEditError!AL("OnEditError_Event") OnExecSQL OnNewRecord!AL("OnNewRecord_Event") OnPostError!AL("OnPostError_Event")
Свойство AffectedRows
Применимо к TMySQLDataset
Определение
property AffectedRows : string;
Описание
Число строк, на которые воздействует последняя инструкция SQL, которая будет выполнена. Только для Run-time. Read-only.
Свойство CachedUpdates
Применимо к TMySQLDataset
Определение
property CachedUpdates : boolean;
Описание
Установка этого свойства в True заставит все инструкции SQL, SQLUpdate, SQLInsert, SQLDelete и SQLBatch кэшироваться на локальной системе и реально выполняться только тогда, когда методы Close или Refresh в очередной раз обращаются к этому набору данных.
Свойство DatabaseName
Применимо к TMySQLDataset
Определение
property DatabaseName : string;
Описание
В настоящее время выбранная база данных, устанавливая это свойство вызовет "USE Database" на активной поточной связи этого набора данных с сервером MySQL. Это значение заменит все макросы $DATABASENAME в Ваших запросах SQL.
Свойство FieldName
Применимо к TMySQLDataset
Определение
property FieldName : string;
Описание
В настоящее время выбранное имя поля (возможно, нескольких полей). Это может содержать список полей, разделенных запятыми, и необязательный первичный ключ для текущей (актуальной) таблицы. Это заменит все макросы $FIELDNAME в Ваших запросах SQL.
Свойство AllFieldValues
Применимо к TMySQLDataset
Определение
property AllFieldValues : boolean;
Описание
Установите это свойство в True, если Вы хотите, чтобы набор данных использовал "show columns from table", чтобы получить расширенную информацию относительно каждого поля, например, значения по умолчанию, перечни допустимых значений для полей типов ENUM и SET и так далее.
Свойство MacroChar
Применимо к TMySQLDataset
Определение
property MacroChar : Char;
Описание
Текущий (актуальный) символ, используемый для определенных макрокоманд в Ваших инструкциях SQL.
Свойство Filter
Применимо к MySQLDataset
Определение
property Filter : string;
Описание
Установите это свойство к любому имеющему силу определению MySQL WHERE, например, AccountName like "J%". Это значение будет автоматически включено в макрокоманду $WHERE, если Filtered установлено в значение True.
Свойство MacroCount
Применимо к TMySQLDataset
Определение
property MacroCount : Word;
Описание
Число существующих макрокоманд. Только Run-time. Read-only.
Свойство Filtered
Применимо к TMySQLDataset
Определение
property Filtered : boolean;
Описание
Установите это свойство в True, если Вы хотите, чтобы текущий (актуальный) Filter применялся со следующей командой Open к набору данных.
Свойство MasterFields
Применимо к TMySQLDataset
Определение
property MasterFields : string;
Описание
Установите это свойство к любой имеющей силу комбинации Name=Value так, чтобы получилась пара DetailField=MasterField, например, MasterFields:='AccountID=AccountID,AccountName=FirstName', или используйте компоновку, чтобы связать Ваш набор данных с полями MasterSource.
AccountID и AccountName берутся из текущего детального набора данных, а AccountID и Firstname берутся из главного набора данных, определенного свойством MasterSource.
Поля, определенные свойством MasterFields, автоматически анализируются и будут вставлены в предложение $WHERE, набор данных будет закрыт и вновь открыт, уже используя новую инструкцию SQL, которая отразит изменения в наборе данных MasterSource.
Свойство Macros
Применимо к TMySQLDataset
Определение
property Macros : TMySQLMacros;
Описание
TParams представляет собой совокупность макрокоманд, найденных в инструкциях SQL.
Свойство MasterSource
Применимо к TMySQLDataset
Определение
property MasterSource : string;
Описание
Установите это свойство к любому имеющему силу доступному источнику данных. Если это свойство установлено, оно автоматически модифицирует подробный набор данных для макроса $WHERE, когда происходят изменения в наборе данных.
Свойство MacrosEnabled
Применимо к TMySQLDataset
Определение
property MacrosEnabled : boolean;
Описание
Если установлено в True, допускает использование макрокоманд в Ваших инструкциях SQL.
Свойство MultiKeyFields
Применимо к TMySQLDataset
Определение
property MultiKeyFields : string;
Описание
Список строк всех полей, которые являются частью ключа, доступного в текущем (актуальном) наборе результатов. Только Run-time. Read-only.
Свойство MySQLFields
Применимо к TMySQLDataset
Определение
property MySQLFields : TStringList;
Описание
Список строк всех полей, используемых в текущем наборе результатов. Только Run-time. Read-only.
Свойство MySQLRecords
Применимо к TMySQLDataset
Определение
property MySQLRecords : TList;
Описание
Необработанные записи из текущего (актуального) набора результатов. Только Run-time. Read-only.
Свойство MySQLTables
Применимо к TMySQLDataset
Определение
property MySQLTables : TStringList;
Описание
Список всех таблиц, используемых в текущем наборе результатов. Только Run-time. Read-only.
Свойство PrimaryKeyFields
Применимо к TMySQLDataset
Определение
property PrimaryKeyFields : string;
Описание
Строковый список всех полей первичных ключей, доступных в текущем наборе результатов. Только Run-time. Read-only.
Свойство ReadOnly
Применимо к TMySQLDataset
Определение
property ReadOnly : boolean;
Описание
Изменение этого свойства включит или отключит редактирование текущего наборе результатов.
Свойство RealSQL
Применимо к TMySQLDataset
Определение
property RealSQL : string;
Описание
Последняя полная инструкция SQL, которая будет послана серверу MySQL. Только Run-time. Read-only.
Свойство Records
Применимо к TMySQLDataset
Определение
property Records[Index : Integer] : PRecInfo;
Описание
Необработанные записи текущего набора результатов. Только Run-time. Read-only.
Свойство Server
Применимо к MySQLDataset
Определение
property Server : TMySQLServer;
Описание
TMySQLServer, используемый этим набором данных.
Свойство ShareConnection
Применимо к TMySQLDataset
Определение
property ShareConnection : boolean;
Описание
Если True, этот набор данных совместно использует поточное подключение, обеспеченное TMySQLServer с TMySQLServer.
Обратите внимание: Соблюдайте осторожность при использовании этого, так как каждый набор данных может использовать любую базу данных, но разделяемое подключение может использовать в один момент времени только единственную базу данных. Если выставить значение в False, этот набор данных будет иметь собственное поточное подключение к серверу MySQL, организованное TMySQLServer. Все операции будут локальными и не смогут влиять на другой экземпляр TMySQLDataset или TMySQLServer.
Свойство SQL
Применимо к TMySQLDataset
Определение
property SQL : TStrings;
Описание
Тип SELECT SQL-запроса. Эти инструкции будут выполнены, каждый раз, когда Вы выполняете операцию Open или Active на наборе данных. Этот набор строк может содержать несколько инструкций, разделеных точкой с запятой (;). Последняя инструкция должна будет произвести набор результатов.
Свойство SQLBatch
Применимо к TMySQLDataset
Определение
property SQLBatch : TStrings;
Описание
Общая команда SQL. Эти инструкции будут выполнены каждый раз, когда Вы выполняете ExecBatch на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLDelete
Применимо к TMySQLDataset
Определение
property SQLDelete : TStrings;
Описание
DELETE-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Delete на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLInsert
Применимо к TMySQLDataset
Определение
property SQLInsert : TStrings;
Описание
INSERT-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Insert или Append на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство SQLUpdate
Применимо к TMySQLDataset
Определение
property SQLUpdate : TStrings;
Описание
UPDATE-тип SQL-команды. Эти инструкции будут выполнены каждый раз, когда Вы выполняете Edit и Post на наборе данных. Этот список строк может содержать несколько инструкций, разделеных точкой с запятой (;).
Свойство TableName
Применимо к TMySQLDataset
Определение
property TableName : string;
Описание
Имя в настоящее время выбранной таблицы. Это заменит макросы $TABLENAME в Ваших инструкциях SQL.
Свойство UniqueKeyFields
Применимо к TMySQLDataset
Определение
property UniqueKeyFields : string;
Описание
Список всех уникальных полей, используемых в текущем наборе результатов. Только Run-time. Read-only.
Метод EscapeStr
Применимо к TMySQLDataset
Определение
function EscapeStr(const Value : string) : string;
Описание
Создает экранированную строку для сервера MySQL, используя функцию mysql_escape_string.
Метод ExecBatch
Применимо к TMySQLDataset
Определение
function ExecBatch : boolean;
Описание
Выполняет инструкции SQLBatch, использующие подключение набора данных и текущие параметры настройки.
Метод ExecSQL
Применимо к TMySQLDataset
Определение
function ExecSQL(SQL : string; EnableMacros, Cached : boolean) : boolean;
Описание
Выполнит любую инструкцию SQL, использующую подключение набора данных. Если EnableMacros равно True, SQL будет анализироваться, используя макрокоманды. Если Cached равно True, SQL-запрос будет послан серверу со следующим обращением к методу Close или Refresh.
Метод ExecSQLBatch
Применимо к TMySQLDataset
Определение
function ExecSQLBatch(SQL : TStrings; EnableMacros, Cached, AutoRefresh : boolean): boolean;
Описание
Выполнит любую инструкцию SQL, использующую подключение набора данных. Если EnableMacros равно True, SQL будет анализироваться, используя макрокоманды. Если Cached равно True, SQL-запрос будет послан серверу со следующим обращением к методу Close или Refresh. AutoRefresh не используется.
Метод GetMacroValue
Применимо к TMySQLDataset
Определение
function GetMacroValue(Name : string) : string;
Описание
Возвратит текущее значение макрокоманды Name как строку.
Метод HexStr
Применимо к TMySQLDatasetCVYCG0
Определение
function HexStr(S : PChar; L : longint) : string;
Описание
Применяется для полей типов BLOB и MEMO. Двоичные данные, указанные в S с длиной L возвратятся как строка, наподобие "0x623E63F...".
Метод LocateRecord
Применимо к TMySQLDataset
Определение
function LocateRecord(const KeyFields : string; const KeyValues : Variant; Options : TLocateOptions; SyncCursor : Boolean): Boolean;
Описание
Стандартный метод реализации Locate.
Метод LocateRecordOption
Применимо к TMySQLDatasetCVYCG0
Определение
function LocateRecordOption(const KeyFields : string; const KeyValues : Variant; Options : TLocateOptions; SyncCursor : Boolean; MySQLOptions : TMySQLLocateOptions; var MatchedField : TField) : Boolean;
Описание
Расширенная версия Locate. Это учитывает полный текстовый поиск на всех полях текущего набора результатов. Параметры KeyFields, KeyValues и Options работают так же, как и со стандартным методом Delphi Locate. Если SyncCursor равно True, набор данных будет установлен в первую согласованную запись. MySQLOptions определяет направление и тип поиска. MatchedField возвращает компонент TField, который соответствует критериям. Эта функция вернет True, если соответствие было найдено.
Метод MacroByName
Применим к TMySQLDataset.
Определение
function MacroByName(const Value : string) : TParam;
Описание
Дает Вам доступ во время выполнения ко всем макрокомандам, используемым в любых инструкциях SQL. TMySQLDataset может применяться без того, чтобы использовать любую макрокоманду.
Макросы
Макросы дают возможность Вам что-то задать в Вашем SQL-запросе однажды, а затем факультативно устанавливать части инструкций SQL позже.
Рассмотрим такую SQL-команду:
"select * from |$TABLENAME |JOIN |WHERE |GROUPBY |ORDER |LIMIT;"
Эта инструкция имеет 6 определенных макрокоманд, первая специальна, но посмотрим на макрос |WHERE.
По умолчанию это будет пустая строка, если не задано иное. Но если Вы факультативно хотите устанавливать это, Вы можете:
A) Используя Object Inspector:
Выбрать макрос, нажать на WHERE и ввести значение, подобно "WHERE AccountID=1".
Теперь закройте и снова откройте набор данных, текст будет помещен в Вашу инструкцию SQL и послан на сервер без того, чтобы заменить SQL-свойство.
B) В коде указать:
MySQLDataset1.MacroByName('WHERE').AsString := 'WHERE AccountID=1';
MySQLDataset1.Open;
В обоих случаях заключительная инструкция SQL, посланная серверу, будет выглядеть следующим образом:
"select * from Accounts WHERE AccountID=1;"
Вы можете устанавливать макрокоманды, даже если Ваш набор данных открыт. Они будут использоваться только, если инструкция SQL должна анализироваться и выполняться снова.
ОБРАТИТЕ ВНИМАНИЕ: Макрокоманды чувствительны к регистру!
Имеются несколько специальных макрокоманд, которые являются доступными для использования, но если Вы устанавливаете значение для них, это не будет иметь эффекта для результата заключительной инструкции SQL, поскольку все эти макрокоманды автоматически модифицируются и устанавливаются во время выполнения. Все они начинаются со знака $:
$RELOAD
Вызовет перезагрузку набора данных MySQLServer, результат этой макрокоманды: пустая строка.
$DATABASENAME
Будет заменен свойством DatabaseName Вашего MySQLDataset.
$TABLENAME
Будет заменен свойством TableName Вашего MySQLDatasset.
$FIELDNAME
Будет заменен первым полем в свойстве FieldName Вашего MySQLDataset. Разделитель ";" или ",".
$FIELDS
Будет заменен постоянными полями набора данных (поля, которые Вы определили двойным нажатием на Ваш набор данных). Если таких полей нет, макрос будет заменен на * (звездочку).
$WHERE
Будет заменен комбинацией свойств MasterFields и Filter. Например, если MasterFields установлен в "AccountID=AccountID" и Filter равен "AccountName like "J%", то результатом будет WHERE (AccountID=1) and (AccountName like "J%").
$MODIFIED$FIELDS&VALUES
Будет заменен изменяемыми полями текущей записи, результат примерно таков:
FieldName1="Value1",FieldName2="Value2",...
Обратите внимание: значения экранируются, пустые поля будут равны NULL, типы BLOB будут равняться 0x874365837546.
$UNMODIFIED$FIELDS&VALUES
Будет заменен неизменяемыми полями текущей записи, результат примерно таков: FieldName1="Value1",FieldName2="Value2",....
$MODIFIED$FIELD$NAMES
Будет заменен именами изменяемых полей текущей записи, результат примерно таков: FieldName1,FieldName2,....
$UNMODIFIED$FIELD$NAMES
Будет заменен именами неизменяемых полей текущей записи, результат примерно таков: FieldName1,FieldName2,....
$MODIFIED$FIELD$VALUES
Будет заменен значениями изменяемых полей текущей записи, результат примерно таков: "FieldValue1","FieldValue2",....
$UNMODIFIED$FIELD$VALUES
Будет заменен значениями неизменяемых полей текущей записи, результат примерно таков: "FieldValue1","FieldValue2",....
$OLD$FIELDS&VALUES
Будет заменен всеми полями в текущем наборе результатов и значениями для предыдущих значений текущей записи, результат напомнит: (FieldName1="Value1") and (FieldName2="Value2") and ....
$FIELDNAMES&VALUES
Будет заменен всеми свойствами FieldName (разделенными ";" или ","), именами полей и значениями для текущей записи, результат напомнит: (FieldName1="Value1") and (FieldName2="Value2") and ....
$PRIMARYFIELDS&VALUES
Будет заменен всеми полями первичного ключа в текущем наборе результатов и значениями для текущей записи, результат примерно такой: (FieldName1="Value1") and (FieldName2="Value2") and ....
ОБРАТИТЕ ВНИМАНИЕ: Если не имеется никаких полей первичного ключа в текущем результате, эта макрокоманда возвратит поля и значения для макроса $OLD$FIELDS&VALUES.
$UNIQUEFIELDS&VALUES
Будет заменен всеми уникальными полями в текущем наборе результатов и значениями для текущей записи, результат примерно такой: (FieldName1="Value1") and (FieldName2="Value2") and ....
$MULTIFIELDS&VALUES
Будет заменен всеми полями, которые являются частями составного ключа в текущем наборе результатов и значениями для текущей записи, результат будет примерно таким: (FieldName1="Value1") and (FieldName2="Value2") and ... .
$FIELDNAMES&VALUES$COMMA
Будет заменен всеми именами полей из свойства FieldName (разделенными ; или ,) и значениями для текущей записи: FieldName1="Value1",FieldName2="Value2",....
$FIELDNAME$VALUE
Будет заменен первым полем в свойстве FieldName текущей записи MySQLDataset: "FieldValue1".
YourFieldNameHere
Будет заменен полем, имя которого определено значением текущей записи. Регистр не имеет значения: "FieldValue1".
$OLD$YourFieldNameHere
Будет заменен полем, имя которого определено предыдущим значением текущей записи. Регистр не имеет значения: "FieldOldValue1".
Например, если Вы должны модифицировать запись в наборе результатов: update mytable set AccountName="abc" where AccountName="cba", Вы изменяете свойство SQL на update mytable set AccountName=|AccountName where AccountName=|$OLD$AccountName.
$PROMPT$Caption$PromptName$DefaultValue$PasswordChar
Запросит Вашего конечного пользователя на предмет значения, которое будет вставлено в sql-запрос. Параметры:
Caption: факультативный заголовок для диалога
PromptName: факультативное имя запрашиваемого значения
DefaultValue: факультативное значение по умолчанию
PasswordChar: факультативный парольный символ, например, *
Если макрокоманды не соответствуют никакому из этих специальных имен, то Macro.AsString используется, чтобы заменить макрокоманду в SQL, например:
MySQLDataset1.MacroByName('WHERE').AsString := 'WHERE AccountID=1'; MySQLDataset1.Open;
Следующее предстваляет собой пример инструкций SQL из фактических программ:
SQL Property: Select
select * from |$TABLENAME WHERE AccountType LIKE "%Employee%"
SQLInsert Property: Insert
use MYSQL; insert into USER set host="%",user=|ACCOUNTNAME, password=PASSWORD(|$PROMPT$Password$$*), select_priv="Y",insert_priv="Y",update_priv="Y", delete_priv="Y", reload_priv="Y"; use |$DATABASENAME; insert into |$TABLENAME set |$MODIFIED$FIELDS&VALUES; |$RELOAD;
SQLUpdate Property: Update
use MYSQL; update user set user=|ACCOUNTNAME where user=|$OLD$ACCOUNTNAME; use |$DATABASENAME; update |$TABLENAME set |$MODIFIED$FIELDS&VALUES where |$FIELDNAME=|$FIELDNAME$VALUE; |$RELOAD;
SQLDelete Property: Delete
use MYSQL; delete from user where user=|ACCOUNTNAME; use |$DATABASENAME; delete from |$TABLENAME where |$FIELDNAME=|$FIELDNAME$VALUE; |$RELOAD;
Cascading deletes made easy:
delete from |$TABLENAME where |$FIELDNAMES&VALUES; //Master table delete from devices where |$FIELDNAMES&VALUES; // Detail table
Метод ParseSQL
Применим к TMySQLDataset
Определение
function ParseSQL(SQL : string) : string;
Описание
Анализирует строку SQL, извлекает и добавлет все найденные макрокоманды.
Метод QuoteStr
Применим к TMySQLDataset
Определение
function QuoteStr(const S : string) : string;
Описание
Создает цитированную строку, например, "string" превратится в "`string`".
Метод ClearMacros
Применим к TMySQLDataset
Определение
procedure ClearMacros;
Описание
Очищает все установленные значения для существующих макрокоманд.
Метод ConnectEvent
Применим к TMySQLDataset
Определение
procedure ConnectEvent(Sender : TObject; Connecting : Boolean);
Описание
Позволяет набору данных знать то, что делает TMySQLServer. Это обычно используется только внутреннее между набором данных и TMySQLServer.
Событие OnExecSQL
Применимо к TMySQLDataset
Определение
property OnExecSQL : TMySQLEvent;
Описание
Это событие происходит только прежде, чем инструкция SQL будет послана серверу MySQL. SQL содержит полный SQL-запрос, который, возможно, изменен или продолжен, в зависимости от того, была ли эта инструкция выполнена или нет. Удобно для отладки.
Тип TMySQLEvent
Модуль MySQLDataset
Определение
type TMySQLEvent = procedure(Server: TMySQLDataset; var SQL: string; var Continue: boolean); of object;
Описание
Это событие происходит только прежде, чем инструкция SQL будет послана серверу MySQL. SQL содержит полный SQL-запрос, который, возможно, изменен или продолжен, в зависимости от того, была ли эта инструкция выполнена или нет. Удобно для отладки.
Тип TMySQLLocateOptions
Модуль MySQLDataset
Определение
type TMySQLLocateOptions = set of (loFirst, loNext, loPrior, loLast, loTextSearch, loMatchAll);
Описание
loFirst: вызывает First на наборе данных перед стартом поиска.
loNext: использует Next на наборе данных, чтобы искать вперед.
loPrior: использует Prior на наборе данных, чтобы искать назад.
loLast: вызывает Last на наборе данных перед стартом поиска.
loTextSearch: выполняет текстовый поиск на полях, включенных в search, таким образом, KeyValues должен содержать строку.
loMatchAll: все поля записи должны содержать значение, определенное для поиска в KeyValues.
Пример: свойства сервера
ShowMessage('MySQL server''s properties are:'#13#10+ 'Server version:'+MySQLServer1.ServerVersion+#13#10+ 'Client version:'+MySQLServer1.ClientVersion+#13#10+ 'Protocol:'+MySQLServer1.Protocol+#13#10+ 'Information:'+MySQLServer1.Info+#13#10+ 'Major:'+IntToStr(MySQLServer1.Major)+#13#10+ 'Minor:'+IntToStr(MySQLServer1.Minor)+#13#10+ 'Build:'+IntToStr(MySQLServer1.Build)+#13#10+ 'Complete:'+IntToStr(MySQLServer1.IntVer)+#13#10);
Пример: создание сервера
with TMySQLServer.Create(nil) do try Host := 'localhost'; Username := 'root'; Password := ''; DatabaseName := 'mysql'; LoginPrompt := False; Connected := True; ExecSQL('GRANT SELECT, INSERT, UPDATE, DELETE, RELOAD ON *.* TO 'Admin'@'%''); Reload; CreateDatabase('Test'); DropDatabase('Test'); GetDatabaseNames(List); GetTableNames('mysql',List); GetFieldNames('mysql','user',List); finally Free; end;
Пример: использование MySQLDataset
with TMySQLDataset.Create(nil) do try Server := MySQLServer1; DatabaseName := 'mysql'; TableName := 'user'; Active := True; ExecSQL('GRANT SELECT, INSERT, UPDATE, DELETE, RELOAD ON *.* TO ''Admin''@''%''', True, False); Server.Reload; MacroByName('WHERE').AsString := 'where user=''root'''; Close; Open; ShareConnection := False; Open; // Now the dataset has it's own threaded connection ShareConnection := True; Open; // Now we are back on the TMySQLServer connection ClearMacros; MacroByName('ORDER').AsString := 'order by user'; MacroByName('LIMIT').AsString := 'limit 0,10'; Close; Open; CahcedUpdates := True; // All edits, insert, deletes, updates are now cached Edit; FieldByName('user').AsString := 'test'; Post; Close; // Cached statements flushed CachedUpdates := False; // Statements not cached, sent real-time to server finally Free; end;
Автор: Алексей Паутов. Данный документ подготовлен в рамках некоммерческого проекта RussianLDP:MySQL ( http://www.botik.ru/~rldp/mysql.htm).
Этот модуль был разработан под Linux (RH50), MySQL 3.21.30 и Python 1.5.1. MySQLmodule-1.x основан на mySQLmodule-0.1.4, разработанном:
mySQLmodule-0.1.4 в свою очередь основан на mSQLmodule, разработанном:
Была обнаружена проблема при сохранении строк, содержащих ASCII-ноль (\0) в базе данных MySQL. После расследования в языке Python (который создал первоначальную ошибку), был проверен код mySQLmodule и там найден ряд проблем. Некоторые подпрограммы не освобождают распределенную память, некоторые функции MySQL API не были доступны, и многих разработчиков совершенно не устраивал тот факт, что mySQLmodule возвратит различные структуры данных в зависимости от метода. Так что я переделал код. Так как эти изменения включают изменение в методах Python и значениях возврата, был повышен код версии и изменено имя модуля на MySQL, чтобы оно не столкнулось с оригиналом (mySQL).
Рационально возвратить список списков вместо набора или списка наборов. Не стоит создавать ситуацию, когда подпрограммы доступа к DB занимаются обработкой типа возврата, и стоит предусмотреть возможность изменить данные в возвращенной таблице напрямую.
Data = DBH['select * from MyTable'] if Data: rows = len(Data) cols = len(Data[0]) for i in range(rows): for j in range(cols): if not Data[i][j]: Data[i][j] = DefaultElement() Do_Something(Data)
Никакой потребности усложнять это при наличии наборов внутри внешнего списка нет. Для тех, кто предпочитает словари, метод STH fetchdict() возвратит список словарей. Ключи словаря квалифицированы с соответствующим именем (возможно, не одним) обрабатываемой таблицы.
MySQL MySQLmodule.c -L/usr/local/lib/mysql/ -lmysqlclient \ -I/usr/local/include/mysql
Обратите внимание, что расположение библиотеки MySQL и include-каталога может быть иным на Вашей специфической системе. Вы можете формировать разделяемый модуль (вставкой ниже индикатора shared в файле Setup).
Чтобы формировать динамически загружаемый модуль без доступа к дереву исходников python, используйте:
gcc -shared -I/usr/include/python1.5 -I/usr/local/include/mysql \ MySQLmodule.c -lmysqlclient -L/usr/lib/python1.5/config \ -lpython1.5 -o MySQLmodule.so
Переместите возникающий в результате файл MySQLmodule.so в PYTHONPATH. Замените соответствующие расположения Ваших библиотек и include-файлов.
Обратите внимание, что модуль чувствителен к регистру, и что имя было изменено на MySQL, чтобы не разорвать любой существующий код, который использует старый модуль mySQL.
Модуль MySQL экспортирует следующее:
Обратите внимание: в следующем "таблица" означает "список списков" (за исключением fetchdict). MySQL.connect() вернет дескриптор базы данных (DBH) со следующими методами:
Методы для операторных дескрипторов (STH):
import MySQL DBH = MySQL.connect() # localhost print DBH.listdbs() DBH.selectdb('test') print DBH.serverinfo() print DBH.stat() DBH["create table pytest (x int, y int, s char(20))"] DBH["insert into pytest values (1,2,'abc')"] DBH.do("insert into pytest values (3,4,'def')") STH = DBH.query("insert into pytest values (5,6,'ghi')") print STH.affectedrows() print DBH['select * from pytest'] STH = DBH.query("select * from pytest") print STH.numrows() print STH.fields() print STH.fetchrows(-1) STH.seek(0) print STH.fetchrows(1) print STH.fetchrows(1) STH.seek(0) print STH.fetchrows(2) print STH.fetchrows(2) print STH.numfields() STH.seek(0) print STH.fetchdict(1) print STH.fetchdict() STH = DBH.query("select * from pytest",1) print STH.fetchdict(1) print STH.fetchdict() # compare to previous dicts STH = DBH.query("select * from pytest",1) print STH.fetchrows(1) print STH.eof() print STH.fetchrows() print STH.eof() DBH['drop table pytest']
MySQL предлагает два немного различных пути доступа к данным из базы данных.
Заданный по умолчанию метод в MySQLmodule состоит в том, чтобы использовать хранение на стороне пользователя, то есть все запросы, включая методы курсора (STH), выбирают все данные с сервера. К строкам обращаются через STH.fetchrows(n) или STH.fetchdict(n) индивидуально (n=1), блочно (n>1), все строки забирают одной порцией (n<0) или не обращаются вообще (n=0). STH.numrows() может сообщать после запроса сколько строк находится в результате. STH.seek(k) может использоваться, чтобы обратиться к строкам в произвольном порядке. Недостаток хранения на стороне пользователя состоит в том, что это использует память пользователя, чтобы сохранить все строки. Этот способ учитывает конструкции типа:
STH = DBH.query("select * from Foo") N = STH.numrows() if N > 1000: raise Hell,"You must be joking!" for i in xrange(N): [Data] = STH.fetchdict(1)
Так как пользователь действительно переместил к себе все строки, которые подготовил сервер, все транзакции на этом канале прекратились, и сервер готов принять новые команды. Это также означает, что STH.eof() всегда true (1) для хранения данных на стороне клиента.
Хранение на стороне сервера не требует, чтобы у пользователя было много памяти. Все записи будут перемещены на основании запроса. Однако, этот способ имеет несколько недостатков. Так как теперь возникает возможность того, что пользователь не забрал все строки, каждая новая команда должна проверить, является ли свободным, то есть готов ли он принять новую команду. Если нет, команда должна очистить канал команды, выдавая запросы на чтение в количестве, достаточном, чтобы получить оставшиеся строки. MySQL API 3.21 не предлагает команды abort(). STH.numrows() не знает ничего относительно того, сколько строк были выбраны запросом, так что вышеупомянутый код примера будет падать. STH.numrows() будет, однако, модифицироваться, поскольку строки все-таки читаются, например:
STH = DBH.query("select * from Foo") Data = STH.fetchrows(-1) print "Got",STH.numrows(),"rows." # len(Data) is the same
STH.eof() имеет смысл только при хранении данных на сервере, но даже здесь такой код полезен не всегда:
STH = DBH.query("select 1") print STH.eof() # will print 0 Data = STH.fetchrows(1) # retrieve the row print STH.eof() # still 0 :-( Data = STH.fetchrows(1) # must repeat. Data will be [] print STH.eof() # now we get 1, but we already # knew that we've hit the end
Можно было рассматривать это, как ошибку. STH.seek(k) больше не доступен и создает исключение ("cannot seek on server"), то есть строки должны теперь читаться последовательно.
Хранение на стороне сервера также создает дополнительную нагрузку на сервер. В частности, он должен остаться в контакте с пользователем, пока все строки не будут прочитаны. Так что лучше бы быстро получить все строки и не делать длинную обработку или, что еще хуже, позволять пользователю останавливать поиск (например, нажимая клавиши Ctrl-S в интерактивном интерфейсе).
Для тех, кто не может решить, который метод является более подходящим для прикладной программы, MySQLmodule позволяет смешивать оба метода свободно. Заданное по умолчанию поведение может быть установлено через DBH.selectdb() и может быть изменено для индивидуального курсора (STH). Обратите внимание, что незавершенные запросы будут отменены последующими командами:
STH = DBH.query("select * from Foo",1) # use server side storage Tables = DBH.listtables() # stomp on previous results Data = STH.fetchrows() # nothing here anymore vs. STH = DBH.query("select * from Foo",0) # use client side storage Tables = DBH.listtables() # won't interfere Data = STH.fetchrows() # no problem...
Хранение на стороне сервера также создает более сложный код в MySQLmodule. Обычно при хранении на стороне клиента STH-курсоры независимы от дескриптора базы данных. Немедленно после запроса все данные будут перекачаны клиенту, и пользователь может делать все, что сочтет необходимым с дескриптором DBH. Но при хранении на стороне сервера это становится сложным. С курсорами стороны сервера указатель на дескриптор сохранен в дескрипторе STH. MySQLmodule удостоверится, что этот кусок памяти не освобожден прежде, чем закроются все ожидающие обработки курсоры. Это означает, что mysql_close() не обязательно вызван, если база данных, обрабатываемая DBH, разрушена:
DBH = MySQL.connect() # get a DB handle STH = DBH.query("select 1",1) # server side cursor del DBH # mysql_close() *not* called STH.fetchrows() # will succeed! del STH # now mysql_close() will be called # in DBH_dealloc()
Если Вы должны закрыть дескриптор DB немедленно, используйте DBH.close(). Все дальнейшие попытки работать на этом дескрипторе (даже ожидающие обработки курсоры стороны сервера) получат исключительную ситуацию "... server has gone away". Начиная с того момента, как mySQL не может принимать команды из последовательности, все DBH-методы должны проверить незавершенные STH-курсоры. Чтобы обращаться к ним, дескриптор DBH хранит указатель на STH-курсор.
Следующие инструкции основаны на информации, предоставленной Nigel Head (nhead@houbits.com).
Если что-то пойдет не так, помощь лучше всего поискать в конференции comp.lang.python
TmySQL представляет собой набор классов, которые могут использоваться в delphi наряду с файлом libmysql.dll. Это альтернативный интерфейс, заменяющий собой описанный выше.
Просто распакуйте архив в любой удобный Вам каталог и включите его в соответствующий проект для Delphi.
Требуемый файл libmysql.dll включен в архив (Version 3.22.14-gamma, ее стоит заменить более свежей).
unit MySql; interface uses classes, dialogs, sysutils; type TField = class public Name: String; FieldType: String; Constructor Create(aName: String); end; TFields = class public Constructor Create(res: pmysql_res); Destructor Destroy; override; Function Count: Integer; Property Fields[Index: Integer]: TField read getField; default; Procedure Add(Value: TField); end; TTable = class public Name: String; Fields: TFields; Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; end; TTables = class public Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; Function Count: Integer; Property Tables[Index: Integer]: TTable read getTable; default; Procedure Add(Value: TTable); end; TDatabase = class public Name: String; Selected: Boolean; Tables: TTables; Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; Function Select: Boolean; end; TDatabases = class public Constructor Create(aMySql: pmysql); Destructor Destroy; override; Function Count: Integer; Property Databases[Index: Integer]: TDatabase read getDatabase; default; Procedure Add(Value: TDatabase); end; TRow = class public Constructor Create(aRow: TStringList); Destructor Destroy; override; Function Count: Integer; Property Databases[Index: Integer]: String read getValue; default; Procedure Add(Value: String); end; TRows = class public Constructor Create(res: pmysql_res; Count: Integer); Destructor Destroy; override; Function Count: Integer; Property Rows[Index: Integer]: TRow read getRow; default; Procedure Add(Value: TRow); end; TResult = class public Rows: TRows; Fields: TFields; AffectedRows: Integer; Constructor Create(res: pmysql_res; aMySql: pmysql); Destructor Destroy; override; Function lastError: String; end; TMySql = class public class function ClientVersion: String; constructor CreateConnect(aHost, aUser, aPassword: String; aPort: Integer); destructor Destroy; override; function Connect: Boolean; function Disconnect: Boolean; function Connected: boolean; Property Name: String read getName write setName; Property Host: String read getHost write setHost; Property User: String read getUser write setUser; Property Password: String read getPassword write setPassword; Property Port: Integer read getPort write setPort; function getVersion: String; function getHostInfo: String; function getProtocolVersion: Integer; function getThreadId: Longint; function getStat: String; function getProcesses: TResult; function getDatabases: TDatabases; function Query(sql: String): TResult; function SelectDb(d: String): Boolean; function CreateDb(name: String): Boolean; function DeleteDb(name: String): Boolean; function RefreshGrants: Boolean; end;
Единственный класс, который должен когда-либо создаваться пользователем: TmySQL. Другие будут созданы и разрушены автоматически.
Чтобы создать TmySQL, используйте Create или CreateConnect, который пробует соединиться сразу же.
TmySQL.getDatabases возвращает: TDatabases, TDatabase, TTables, TTable, TFields, TField.
TmySQL.Query и TmySQL.getProcesses возвращают: TResult, TFields, TField, TRows, TRow, String.
Эта программа имеет статус freeware, for personal use.
Для коммерческого использования пакет стоит US$ 20 за лицензию. К тому же, к ней будут приложены все исходные тексты интерфейсного пакета.
С разработчиком можно связаться по адресу:
Hillware I/S Dennis Thrys°e Solvangsvej 6, st, th DK-9000 Aalborg <qabi@mindless.com> http://members.xoom.com/qabi
This product is:
Автор: Roland Haenel (rh@ginster.net). Эта программа является public domain. Распространять и использовать ее можно совершенно свободно.
Это маленькая оболочка для C++, которая написана вокруг базисной клиентской библиотеки mysql. Целью было создание единого универсального интерфейса для следующих баз данных:
Но потому, что mysql намного лучше прочих, контекст этой реализации немного изменился. Теперь стало нужно обеспечить удобный в работе и безопасный интерфейс доступа к mysql.
Программа примера может быть найдена в example.cc. Некоторые слова относительно классов библиотеки:
Класс Database обеспечивает интерфейс связи с базой данных mysqld. Следующие методы выполнены:
#define DB_COMMAND_OK 0 // OK: команда выполнена #define DB_EMPTY_QUERY 1 // Запрос не вернул данных #define DB_TUPLES_OK 2 // Запрос вернул данные #define DB_ERROR 5 // Ошибка в команде #define DB_BAD_RESPONSE 6 // Неправильный ответ сервера #define DB_UNEXPECTED 7 // Непонятная ошибка
![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
YandexMoney: 41001198119846 |
E-gold: 5128052 |
Этот API был определен, чтобы привести к одному знаменателю модули Python,
которые используются, чтобы обратиться к базам данных. Этот документ
описывает Python Database API 2.0. Спецификация интерфейса состоит
из нескольких разделов:
Комментарии и вопросы относительно этой спецификации могут быть направлены
на db-sig@python.org.
Для получения большего количества информации относительно связи с помощью
интерфейса базы данных с Python и о доступных пакетах изучите руководство на
http://www.python.org/topics/database.
Доступ к базе данных сделан доступным через объекты подключения. Модуль
должен обеспечивать конструктор для них:
Эти глобальные переменные модуля должны быть определены:
Совместное использование в вышеупомянутом контексте означает, что два
потока могут использовать ресурс без того, чтобы применять mutex-семафор,
чтобы выполнить блокировку ресурса. Обратите внимание, что Вы не можете
всегда делать внешние ресурсы поточно-безопасными управляя доступом,
использующим mutex: ресурс может полагаться на глобальные переменные или
другие внешние источники данных, которые находятся вне Вашего управления!
Модуль должен делать всю информацию об ошибках доступной через эти
исключительные ситуации или через подклассы от них:
Если база данных не поддерживает функциональные возможности, требуемые
методом, интерфейс должен породить исключительную ситуацию в случае,
если метод используется.
Можно также не реализовывать метод вообще, тогда Python сам сгенерирует
исключительную ситуацию Это размещение наследования исключительной ситуации:
Обратите внимание: значения этих исключительных ситуаций не определены.
Они должны дать пользователю информацию о том, что пошло не так.
Объекты подключения должны отвечать на следующие методы:
Модули баз данных, которые не поддерживают транзакции, должны выполнить
этот метод с не имеющими силу функциональными возможностями.
Параметры конструктора подключения должны быть выполнены как параметры
ключевого слова для более интуитивного использования и следовать
этому порядку параметров:
Например, конструктор подключения мог бы выглядеть следующим образом:
Эти объекты представляют курсор базы данных, который используется, чтобы
управлять контекстом операции выборки.
Объекты курсоров должны отвечать на следующие методы и атрибуты:
Код Ссылка на операцию будет сохраняться курсором. Если тот же самый объект
операции передан снова, то курсор может оптимизировать поведение. Это
наиболее эффективно для алгоритмов, где много раз используется та же самая
операция, но с разными параметрами. Для достижения максимальной эффективности
при многократном использовании операции, самое лучшее использовать метод
setinputsizes(), чтобы определить типы параметра и размеры. Для параметра
допустимо не соответствовать предопределенной информации: реализация должна
это скомпенсировать, возможно, с потерей эффективности.
Параметры могут быть также определены как список, чтобы, например,
вставить много строк в одной операции, но этот вид использования не
рекомендуется: лучше пользуйтесь Модули могут выполнить этот метод, используя многократные обращения к
методу Те же самые комментарии, что касаются Исключительная ситуация Обратите внимание, что имеются сложности с эффективностью, включаемые с
параметром размера. Для достижения оптимальной эффективности, обычно самое
лучшее использовать arraysize.
Этот метод будет переводить курсор к следующему доступному набору,
отбрасывая любые остающиеся строки из текущего (актуального) набора.
Если не имеется больше никаких наборов, метод возвращает
Исключительная ситуация Обратите внимание, что интерфейс может выполнять выборку строки, используя
массивы и другие оптимизацию. Не гарантируется, что обращение к этому методу
только переместит связанный курсор вперед.
Реализации должны отслеживать это значение применительно к методу
Многие базы данных должны иметь ввод в специфическом формате для
связывания с входными параметрами операции. Например, если ввод предназначен
для столбца DATE, то это будет связано с базой данных в специфическом формате
строки. Подобные проблемы существуют для столбцов "Row ID" или больших
двоичных элементов (например, столбцов blob или RAW). Это представляет
проблемы для Python, начиная с параметров для метода без контроля типов
Чтобы преодолеть эту проблему, модуль должен обеспечить конструкторы,
определенные ниже, чтобы создать объекты, которые могут хранить специальные
значения. При передаче к методам курсора, модуль может затем обнаружить
соответствующий тип входного параметра и обработать его соответственно.
Атрибут Модуль экспортирует следующие конструкторы:
SQL-значение NULL представляется на вводе и выводе
как Python Обратите внимание: использование Unix-импульсов сигнала времени для связи
с помощью интерфейса базы данных может вызвать проблемы из-за ограниченного
диапазона даты, который они покрывают.
Python Database API 2.0 представляет несколько важных нововведений по
сравнению с версией 1.0. Некоторые из этих изменений делают невозможным
применять старые скрипты с новой версией DB API.
Хотя спецификация версии 2.0 разъясняет много вопросов, которые были
оставлены открытыми в версии 1.0, некоторые все еще остаются проблемами:
Интерфейс базы данных может поддерживать именованные курсоры, позволяя
задавать методу параметр-строку. Это свойство пока не является частью
спецификации, так как оно сильно усложняет
семантику методов Модуль использует метод Значение передается базе данных напрямую. В практических условиях это
означает, что входное значение непосредственно используется как значение в
операции. Пользователь не должен требоваться, чтобы экранировать значение
так, чтобы оно могло использоваться: значение должно быть равно фактическому
параметру для базы данных.
Атрибут Пользователь имеет максимальный размер буфера связи. Размер буфера,
который распределен первоначально (16 килобайт), автоматически увеличивается
до максимального размера (максимум 16 мегабайт). Поскольку размеры буфера
растут только по запросу, просто увеличивая заданное по умолчанию
максимальное ограничение, Вы не заставите большее количество ресурсов
использоваться. Эта проверка размера обычно применяется в сложных ситуациях.
Буфер связи должен быть достаточно большим, чтобы хранить одиночную
инструкцию SQL (для трафика "клиент-на сервер") и одну строку возвращенных
данных (для трафика "сервер-на-клиент"). Буфер связи каждого потока будет
динамически расширен до максимального ограничения, чтобы обработать любой
запрос или строку. Например, если Вы имеете значения Сервер MySQL сокращает каждый буфер связи до
Структура Функции, доступные в Delphi API, перечислены ниже и описаны более подробно
в следующем разделе. Подробности в разделе "Описание функций Delphi API". Чтобы соединиться с сервером, вызовите В то время как подключение активно, пользователь может посылать запросы
SQL серверу, применяя функции Для каждого запроса не- Для запросов Имеются два пути для пользователя, чтобы обработать наборы результатов.
Один путь состоит в том, чтобы получить весь набор результатов, вызывая
В обоих случаях Вы обращаетесь к строкам, вызывая
После того, как Вы закончите работу с набором результатов, вызовите
Два механизма поиска дополняют друг друга. Программы пользователя должны
выбрать подход, который является наиболее подходящим для их требований.
Практически же, клиентура имеет тенденцию обычно использовать
Преимущество Преимущество API позволяет клиентам ответить соответственно на запросы (получая строки
только по мере необходимости) без того, чтобы знать, является или нет запрос
Вызовы Для обнаружения и сообщения об ошибках MySQL обеспечивает доступ к
информации ошибки посредством функций В описаниях ниже параметр или значение возврата Функции, которые возвращают значение, возвращают указатель или целое
число. Если не определено иное, функции, возвращающие указатель, возвращают
значение не- Когда функция возвращает ошибку, подраздел Ошибки
описания функции вносит в список возможные типы ошибок. Вы можете выяснить,
который из них произошел, вызывая Возвращает число строк, измененных последним Целое число, большее, чем ноль, указывает количество обработанных строк.
Ноль указывает, что никакие записи обработаны не были. -1 указывает, что
запрос возвратил ошибку или то, что для запроса Если определен флажок Обратите внимание, что, когда использована команда Закрывает предварительно открытое подключение. Нет. Пытается устанавливать подключение с сервером MySQL на компьютере
Значения параметров такие же, как для соответствующих параметров
Аналогично Аналогично Меняет пользователя и заставляет базу данных, определенную как
Эта функция впервые была представлена в MySQL Version 3.23.3. Параметр Ноль для успеха. Отличное от нуля, если произошла ошибка. Аналогично Создает базу данных с именем Ноль, если база данных была создана успешно. Отличное от нуля, если в
процессе произошла ошибка. Переходит к произвольной строке в наборе результатов запроса. Это требует,
чтобы структура набора результата содержала весь результат запроса, так что
Смещение должно быть значением в диапазоне от 0 до
Делает Обращение, показанное ниже, заставляет библиотеку клиентов генерировать
файл трассировки /tmp/client.trace на машине пользователя: Удвляет базу данных, упомянутую как параметр Ноль, если база данных была удалена успешно. Отличное от нуля, если в
процессе произошла ошибка. Инструктирует сервер, чтобы писать некоторую информацию отладки в файл
регистрации. Отдавший команду пользователь должен иметь привилегию
process, чтобы работать. Ноль, если команда была успешно выполнена. Отличное от нуля, если в
процессе произошла ошибка. Если Вы приобретаете результат из успешного обращения к
С другой стороны, если Вы используете Исторически Функция Для подключения, определенного в Значение кода ошибки. 0, если никакая ошибка не произошла. Для подключения, определенного в Язык сообщений об ошибках пользователя может быть изменен перекомпиляцией
библиотеки клиента MySQL. В настоящее время Вы можете выбирать сообщения
об ошибках на нескольких различных языках. Символьная строка, которая описывает ошибку. Пустая строка, если никакой
ошибки не произошло. Это идентично Возвращает определение одного столбца набора результатов как структуру
Если Вы вызвали Структура типа Возвращает массив всех структур Массив структур Получает код поля Структура Возвращает длины столбцов текущей (актуальной) строки внутри набора
результатов. Если Вы планируете копировать значения поля, эта информация
также полезна для оптимизации потому, что Вы можете избежать вызова
Длина для пустых столбцов и для столбцов, содержащих значения
Массив длинных целых чисел без знака, представляющих размер каждого
столбца (не включая любые символы пробелов в хвосте). Получает следующую строку набора результатов. Когда используется после
Число значений в строке задано Длины значений полей в строке могут быть получены, вызывая
Структура Если Вы используете версию MySQL ранее, чем Version 3.22.24, Вы должны
вместо этого использовать Возвращает число столбцов для самого последнего запроса на подключении.
Нормальное использование этой функции: когда
Целое число без знака, представляющее число полей в наборе результатов.
Устанавливает курсор поля к данному смещению. Следующее обращение к
Чтобы перейти к началу строки, передайте 0 как значение
Предыдущее значение курсора поля. Возвращает позицию курсора поля, используемого для последнего
Текущее смещение курсора поля. Освобождает память, распределенную для набора результатов
Возвращает строку, которая представляет версию клиентской библиотеки. Символьная строка, которая представляет версию клиентской библиотеки MySQL.
Возвращает строку, описывающую тип используемого подключения, включая имя
главного компьютера сервера. Символьная строка, представляющая имя компьютера и тип подключения. Возвращает код версии протокола, используемой текущим подключением. Целое число без знака, представляющее версию протокола, используемую
текущим (актуальным) подключением. Возвращает строку, которая представляет номер версии сервера. Символьная строка, которая представляет номер версии станции. Возвращает строку, обеспечивающую информацию относительно недавно
выполненного запроса, но только для инструкций, перечисленных ниже. Для
других инструкций Обратите внимание, что Символьная строка, представляющая дополнительную информацию относительно
последнего выполненного запроса. Распределяет или инициализирует объект Инициализированный дескриптор В случае недостаточной памяти вернется Возвращает ID, сгенерированный предыдущим запросом для столбца с
поддержкой Обратите внимание, что Также обратите внимание, что значение функции SQL
Значение поля Просит, чтобы сервер уничтожил поток, определенный как Ноль для успеха. Отличное от нуля, если произошла ошибка. Возвращает набор результатов, состоящий из имен баз данных на сервере,
которые соответствуют простому регулярному выражению, определенному
параметром Вы должны освободить набор результатов с помощью
Набор результатов Возвращает набор результатов, состоящий из имен полей в данной таблице,
которые соответствуют простому регулярному выражению, определенному
параметром Обратите внимание, что рекомендуется, чтобы Вы использовали Вы должны освободить набор результатов с помощью
Набор результатов Возвращает набор результатов, описывающий текущие потоки сервера. Это тот
же самый вид информации, что и сообщаемый командой Вы должны освободить набор результатов с помощью
Набор результатов Возвращает набор результатов, состоящий из имен таблиц в текущей базе
данных, которые соответствуют простому регулярному выражению, определенному
параметром Вы должны освободить набор результатов с помощью
Набор результатов Возвращает число столбцов в наборе результатов. Обратите внимание, что Вы можете получать число столбцов из указателя
набора результатов или от дескриптора подключения. Вы используете дескриптор
подключения, если Целое число без знака, представляющее число полей в наборе результатов.
Возвращает число строк в наборе результатов. Использование Число строк в наборе результатов. Может использоваться, чтобы установить дополнительные параметры связи и
действует на поведение подключения. Эта функция может быть вызвана несколько
раз, чтобы установить несколько параметров. Параметр Возможные значения параметров: Обратите внимание, что группа Определенная группа в файле опций может содержать следующие параметры: Обратите внимание, что Ноль для успеха. Отличное от нуля, если Вы использовали неизвестную опцию.
Проверяет работает или нет подключение. В случае неработоспособности будет
предпринято автоматическое переподключение. Эта функция может использоваться клиентом, который долго простаивает,
чтобы определить, закрыл или нет сервер подключение, и повторно соединиться с
ним в случае необходимости. Ноль, если подключение работает. Отличное от нуля, если произошла ошибка.
Выполняет запрос SQL, указанный строкой с нулевым символом в конце. Запрос
должен состоять из одиночной инструкции SQL. Вы не должны добавлять точку с
запятой (;) или Ноль, если запрос был успешен. Отличное от нуля, если произошла ошибка.
Параметры определены следующим образом: Дескриптор Используя Обратите внимание, что на подключение Эта функция используется, чтобы создать допустимую строку, которую
Вы можете использовать в инструкции SQL. Строка в Строка, указанная в Длина значения, помещенного в Выполняет запрос SQL, указанный в Вы должны использовать Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы
можете использовать Ноль, если запрос был успешным. Отличное от нуля, если произошла ошибка.
Просит, чтобы сервер MySQL перезагрузил таблицы предоставления привилегий.
Пользователь должен иметь привилегию reload. Ноль для успеха. Отличное от нуля, если произошла ошибка. Устанавливает курсор строки на произвольную строку в наборе результатов
запросов. Это требует, чтобы структура набора результата содержала весь
результат запроса, так что Смещение должно быть значением, возвращенным из
Предыдущее значение курсора строки. Это значение может быть передано
последующему обращению к Возвращает текущую (актуальную) позицию курсора строки для последнего
вызова Вы должны использовать Текущее (актуальное) смещение курсора строки. Заставляет базу данных, определенную через Ноль для успеха. Отличное от нуля, если произошла ошибка. Выключает сервер. Связанный пользователь должен иметь привилегии
закрытия системы (shutdown). Ноль для успеха. Отличное от нуля, если произошла ошибка. Возвращает символьную строку, содержащую информацию, подобную
обеспечиваемой командой Символьная строка, описывающая состояние сервера. Вы должны вызвать Вы не должны вызывать Пустой набор результатов будет возвращен, если не имеется никаких
возвращенных строк. Пустой набор результатов отличается от пустого указателя
как значение возврата. Как только Вы вызвали Вы можете вызвать Вы должны вызвать Структура Возвращает ID потока текущего (актуального) подключения. Это значение
может использоваться как параметр для Если подключение потеряно, и Вы повторно соединяетесь через
ID потока текущего (актуального) подключения. Вы должны вызвать С другой стороны, Вы не должны использовать
При использовании Вы не можете использовать Вы должны вызвать Структура Когда это случается, это означает, что одно из следующего произошло: Вы можете всегда проверить, должна или нет инструкция произвести непустой
результат, вызывая Вы можете проверить наличие ошибки вызовом В дополнение к набору результатов, возвращенному запросом, Вы можете также
получать следующую информацию: Если Вы вставляете запись в таблицу, содержащую столбец, который имеет
атрибут Вы можете также получать ID, используя функцию
Вы можете проверять, используется ли индекс Недавно сгенерированный ID хранится на сервере с привязкой к подключению.
Это не будет изменено другим пользователем. Это не будет даже изменено, если
Вы модифицируете другой столбец Если Вы хотите использовать ID, который был сгенерирован для одной
таблицы и вставлять его во вторую таблицу, Вы можете использовать инструкции
SQL подобно этому:
5.7 Спецификация Python Database API 2.0
5.7.1 Интерфейс модулей
'1.0'
и
'2.0'
. Если не задана, предполагается уровень
интерфейса Database API 1.0.
0
Потоки не могут совместно использовать модуль.
1
Потоки могут совместно использовать модуль, но не подключения.
2
Потоки могут совместно использовать модуль и подключения.
3
Потоки могут совместно использовать модуль, курсоры и подключения.
'qmark'
Стиль метки запроса, например, '...WHERE name=?'
'numeric'
Числовой, позиционный стиль, например, '...WHERE name=:1'
'named'
Именованный стиль, например, '...WHERE name=:name'
'format'
Формат кодов ANSI C printf, например, '...WHERE name=%s'
'pyformat'
Расширенные форматные коды языка Python, например, '...WHERE
name=%(name)s' AttributeError
в случае, если метод
запрошен. Это позволяет программисту проверять возможности базы данных,
используя функцию hasattr()
.
StandardError
|__Warning
|__Error
|__InterfaceError
|__DatabaseError
|__DataError
|__OperationalError
|__IntegrityError
|__InternalError
|__ProgrammingError
|__NotSupportedError
5.7.2 Объекты подключения
Error
(или подкласс от нее). То же самое
применяется ко всем объектам курсора, пробующим использовать подключение.
dsn
Источник данных как строка
обязательно user
Имя пользователя как строка
опционально password
Пароль пользователя как строка
опционально host
Имя хоста
опционально database
Имя базы данных
опционально connect(dsn='myhost:MYDB',user='guido',password='234+$')
.
5.7.3 Объекты курсоров
(name, type_code, display_size,
internal_size, precision, scale, null_ok)
. Этот атрибут будет
None
для операций, которые не возвращают строки, или если курсор
не имел операции, вызываемой через метод executeXXX()
.
type_code
может интерпретироваться, сравнивая его с
Type Objects, определенными в разделе ниже.
executeXXX()
(для SQL-инструкций, вроде
select) или затронутых запросом (для SQL-инструкций, подобных
update или insert). Атрибут равен -1 в случае, если никакой
executeXXX()
не выполнился на курсоре.
fetchXXX()
.
Error
(или ее подкласс).
executemany()
.
seq_of_parameters
.
execute()
или используя операции массива, чтобы база
данных обработала всю последовательность в целом в одном обращении.
execute()
, также
применяются к этому методу. Значения возврата не определены.
None
, когда больше
нет доступных данных. Исключительная ситуация Error
(или ее
подкласс) произойдет, если предыдущее обращение к executeXXX()
не производило никакого набора результатов.
arraysize
курсора определяет число строк, которые будут
выбраны. Метод должен пробовать выбирать так много строк, как уаазано
параметром. Если это невозможно из-за определенного числа строк, меньшее
количество строк может быть возвращено.
Error
(или ее подкласс) произойдет,
если предыдущее обращение к executeXXX()
не производило
никакого набора результатов.
Error
(или ее подкласс)
произойдет, если предыдущее обращение к executeXXX()
не
производило никакого набора результатов.
None
. Иначе он возвращает значение true, и последующие обращения
к методам выборки возвратят строки из следующего набора результатов.
Error
(или ее подкласс) произойдет,
если предыдущее обращение к executeXXX()
не производило
никакого набора результатов.
fetchmany()
за раз. Значение по умолчанию 1
(выбрать одиночную строку результатов)
fetchmany()
, но никто не запрещает реально работать с базой
данных каким-либо иным способом. Это может также использоваться в
реализации метода executemany()
.
executeXXX()
к
предопределенным областям памяти для параметров операции. sizes
определен как последовательность: один элемент для каждого входного
параметра. Элемент должен быть Type Object, который соответствует вводу,
который будет использоваться, или это должно быть целым числом, определяющим
максимальную длину параметра строки. Если элемент равен None
, то
никакая предопределенная область памяти не будет зарезервирована для этого
столбца (это полезно, чтобы избегать предопределенных областей для больших
вводов). Метод не является обязательным для использования и реализации.
5.7.4 Типы конструкторов и объектов
executeXXX()
. Когда модуль базы данных видит строковый объект,
он не знает сходу, как с ним быть.
description
объекта курсора возвращает информацию
относительно каждого из столбцов результата запроса. Здесь
type_code
должен быть равен одному из Type Objects,
определенных ниже. Эти самые Type Objects могут быть равны больше, чем одному
коду типа (например, DATETIME может быть равен кодам типа для столбцов даты,
времени и метки времени).
None
.
5.7.5 Хитрости в реализации
import time
def DateFromTicks(ticks):
return apply(Date,time.localtime(ticks)[:3])
def TimeFromTicks(ticks):
return apply(Time,time.localtime(ticks)[3:6])
def TimestampFromTicks(ticks):
return apply(Timestamp,time.localtime(ticks)[:6])
class DBAPITypeObject:
def __init__(self,*values):
self.values = values
def __cmp__(self,other):
if other in self.values:
return 0
if other < self.values:
return 1
else:
return -1
Возникающий в результате объект сравнивается со всеми
значениями, переданными конструктору.
import exceptions
class Error(exceptions.StandardError):
pass
class Warning(exceptions.StandardError):
pass
class InterfaceError(Error):
pass
class DatabaseError(Error):
pass
class InternalError(DatabaseError):
pass
class OperationalError(DatabaseError):
pass
class ProgrammingError(DatabaseError):
pass
class IntegrityError(DatabaseError):
pass
class DataError(DatabaseError):
pass
class NotSupportedError(DatabaseError):
pass
На C Вы можете использовать API
PyErr_NewException(fullname,base,NULL)
, чтобы создать
объекты исключительной ситуации.5.7.6 Изменения при переходе с версии 1.0 на 2.0
Известные проблемы
Замечания
fetchXXX()
.
__getitem__
объекта параметров, чтобы
отобразить позиции (целые числа) или имена (строки) к значениям параметра.
Это учитывает последовательности и отображения, которые нужно
использовать как ввод.
rowcount
может быть реализован так, что модифицирует
значение динамически. Это может быть полезно для баз данных, которые
возвращают используемые значения rowcount
только после первого
обращения к методу fetchXXX()
6 MySQL DELPHI API
BLOB
,
которые содержат до 16M данных, Вы должны иметь ограничение буфера связи
по крайней мере в 16M (на клиенте и на сервере сразу). Заданный по умолчанию
максимум пользователя равен 16M, но заданный по умолчанию максимум сервера
равен всего 1M. Вы можете увеличивать это, меняя значение параметра
max_allowed_packet
при запуске сервера.net_buffer_length
байт после каждого запроса. Для клиентуры
размер буфера, связанного с подключением, не будет уменьшен, пока подключение
не будет закрыто.6.1 Типы данных в DELPHI API
TMYSQL
TMYSQL_RES
SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
). Информация, возвращенная из запроса, названа набором
результатов в остатках от этого раздела.
TMYSQL_ROW
mysql_fetch_row()
.
TMYSQL_FIELD
TMYSQL_FIELD
для каждого поля, неоднократно вызывая
mysql_fetch_field()
. Значения полей не являются частью этой
структуры, они содержатся в структуре TMYSQL_ROW
.
TMYSQL_FIELD_OFFSET
mysql_field_seek()
. Смещения представляют
собой номера полей внутри строки, начиная с нуля.
Tmy_ulonglong
mysql_affected_rows()
, mysql_num_rows()
и
mysql_insert_id()
. Этот тип обеспечивает диапазон от
0
до 1.84e19
. На некоторых системах попытка
печатать значение типа Tmy_ulonglong
не будет работать. Чтобы
отпечатать такое значение, преобразуйте его к типу longint
.TMYSQL_FIELD
содержит члены, перечисленные ниже:
name:pchar;
table:pchar;
table
представлено пустой строкой.
def:pchar;
mysql_list_fields()
.
typ:TFIELD_TYPES;
typ
может быть один из следующего:
Значение Typ Используемый тип
FIELD_TYPE_TINY
TINYINT
FIELD_TYPE_SHORT
SMALLINT
FIELD_TYPE_LONG
INTEGER
FIELD_TYPE_INT24
MEDIUMINT
FIELD_TYPE_LONGLONG
BIGINT
FIELD_TYPE_DECIMAL
DECIMAL
или
NUMERIC
FIELD_TYPE_FLOAT
FLOAT
FIELD_TYPE_DOUBLE
DOUBLE
или
REAL
FIELD_TYPE_TIMESTAMP
TIMESTAMP
FIELD_TYPE_DATE
DATE
FIELD_TYPE_TIME
TIME
FIELD_TYPE_DATETIME
DATETIME
FIELD_TYPE_YEAR
YEAR
FIELD_TYPE_STRING
Строка ( CHAR
или
VARCHAR
)FIELD_TYPE_BLOB
BLOB
или
TEXT
(используйте max_length
, чтобы определить
максимальную длину поля)FIELD_TYPE_SET
SET
FIELD_TYPE_ENUM
ENUM
FIELD_TYPE_NULL
NULL
FIELD_TYPE_CHAR
Не рекомендуется: используйте
FIELD_TYPE_TINY
length:longword;
max_length:longword;
mysql_store_result()
или mysql_list_fields()
, это
содержит максимальную длину поля. Если Вы используете
mysql_use_result()
, значение этой переменной нулевое.
flags:longword;
flags
может иметь ноль или большее количество из следующего набора битов:
Использование Значение Flags Что это значит
NOT_NULL_FLAG
Поле не может быть
NULL
PRI_KEY_FLAG
Поле часть первичного ключа UNIQUE_KEY_FLAG
Поле часть уникального ключа
MULTIPLE_KEY_FLAG
Поле часть неуникального ключа
UNSIGNED_FLAG
Поле имеет атрибут
UNSIGNED
ZEROFILL_FLAG
Поле имеет атрибут
ZEROFILL
BINARY_FLAG
Поле имеет атрибут
BINARY
AUTO_INCREMENT_FLAG
Поле имеет атрибут
AUTO_INCREMENT
ENUM_FLAG
Поле имеет тип
ENUM
BLOB_FLAG
Поле имеет тип BLOB
или
TEXT
TIMESTAMP_FLAG
Поле имеет тип
TIMESTAMP
BLOB_FLAG
, ENUM_FLAG
и
TIMESTAMP_FLAG
не рекомендуется потому, что они указывают тип
поля, а не атрибут типа. Предпочтительно проверить
field.typ
вместо FIELD_TYPE_BLOB
,
FIELD_TYPE_ENUM
или FIELD_TYPE_TIMESTAMP
. Пример
ниже иллюстрирует типичное использование flags
:
if (field.flags & NOT_NULL_FLAG) write("Field can't be null");
Вы можете использовать следующие макрокоманды, чтобы определить булево
состояние значения flags
:
IS_NOT_NULL(flags)
Истина, если это поле
определено как NOT NULL
IS_PRI_KEY(flags)
Истина, если это поле
первичный ключ IS_BLOB(flags)
Истина, если это поле
BLOB
или TEXT
decimals:longword;
6.2 Обзор функций Delphi API
mysql_affected_rows()
Возвращает число строк измененных последним запросом UPDATE
,
DELETE
или INSERT
.mysql_close()
Закрывает подключение к серверу. mysql_connect() Соединяется с сервером.
mysql_change_user() Меняет пользователя и
базу данных на открытом подключении. mysql_create_db() Создает базу данных.
Аналог команды SQL CREATE DATABASE
.mysql_data_seek() Ищет произвольную строку в
наборе результатов запросов. mysql_debug() Делает DBUG_PUSH
для заданной строки.mysql_drop_db() Удаляет базу данных. Эта
функция аналогична команде SQL DROP DATABASE
.mysql_dump_debug_info() Заставляет сервер
писать информацию отладки в файл регистрации. mysql_eof() Определяет, читалась или нет
последняя строка набора результатов. mysql_errno() Возвращает код ошибки для
вызванной недавно функции MySQL. mysql_error() Возвращает текстовое сообщение
об ошибке для вызванной недавно функции MySQL. mysql_real_escape_string() Выходит из
специальных символов в строке для использования в инструкции SQL, принимающей
во внимание текущий набор символов данного подключения. mysql_escape_string() Выходит из специальных
символов в строке для использования в обычной инструкции SQL. mysql_fetch_field() Возвращает тип
следующего поля таблицы. mysql_fetch_field_direct() Возвращает тип
поля таблицы, по номеру поля. mysql_fetch_fields() Возвращает массив
всех структур поля. mysql_fetch_lengths() Возвращает длины всех
столбцов в текущей (актуальной) строке. mysql_fetch_row() Выбирает следующую строку
из набора результатов. mysql_field_seek() Помещает курсор столбца в
определенный параметром столбец. mysql_field_count() Возвращает число
столбцов результата для последнего запроса. mysql_field_tell() Возвращает позицию
курсора поля, используемого для последнего вызова
mysql_fetch_field()
.mysql_free_result() Освобождает память,
используемую набором результатов. mysql_get_client_info() Возвращает
информацию о версии программы-клиента. mysql_get_host_info() Возвращает строку,
описывающую подключение. mysql_get_proto_info() Возвращает версию
протокола, используемую подключением. mysql_get_server_info() Возвращает номер
версии сервера. mysql_info() Возвращает информацию
относительно недавно выполненного запроса. mysql_init() Получает или инициализирует
структуру MYSQL
.mysql_insert_id() Возвращает ID,
сгенерированный для столбца с поддержкой AUTO_INCREMENT
предыдущим запросом.mysql_kill() Уничтожает заданный поток.
mysql_list_dbs() Возвращает имена баз
данных, соответствующие простому регулярному выражению. mysql_list_fields() Возвращает имена полей,
соответствующие простому регулярному выражению. mysql_list_processes() Возвращает список
текущих потоков сервера. mysql_list_tables() Возвращает имена таблиц,
соответствующие простому регулярному выражению. mysql_num_fields() Возвращает число столбцов
в наборе результатов. mysql_num_rows() Возвращает число строк в
наборе результатов. mysql_options() Устанавливает опции связи
для вызова mysql_connect()
.mysql_ping() Проверяет работает или нет
подключение с сервером, повторно соединяется по мере необходимости. mysql_query() Выполняет запрос SQL,
определенный как строка с нулевым символом в конце. mysql_real_connect() Соединяется с сервером.
mysql_real_query() Выполняет запрос SQL,
определенный как рассчитанная строка. mysql_reload() Сообщает, чтобы сервер
перезагрузил таблицы предоставления привилегий. mysql_row_seek() Переходит к строке в наборе
результатов, используя значение, возвращенное из
mysql_row_tell()
.mysql_row_tell() Возвращает позицию
курсора строки. mysql_select_db() Выбирает базу данных.
mysql_shutdown() Закрывает сервер. mysql_stat() Возвращает состояние сервера.
mysql_store_result() Возвращает полный набор
результатов пользователю. mysql_thread_id() Возвращает ID потока.
mysql_thread_safe() Возвращает 1, если
клиент компилируется как поточно-безопасный. mysql_use_result() Инициализирует копию
результата строка в строку. mysql_init()
, чтобы
инициализировать драйвер подключения, затем вызовите
mysql_real_connect()
с этим драйвером (наряду с другой
информацией типа hostname, имени пользователя и пароля). При подключении
mysql_real_connect()
устанавливает флажок reconnect
(часть структуры MYSQL) в значение 1
. Этот флажок указывает, что
когда запрос не может выполняться из-за потерянного подключения, надо
попробовать повторно соединиться с сервером перед отказом. Когда Вы закончите
работу с подключением, вызовите mysql_close()
для его закрытия.
mysql_query()
или
mysql_real_query()
. Различие между ними в том, что
mysql_query()
ожидает, что запрос будет определен как строка с
нулевым символом в конце, в то время как mysql_real_query()
ожидает рассчитанную строку. Если несет в себе двоичные данные (которые сами
по себе могут включать нулевые байты), Вы должны использовать только
mysql_real_query()
.SELECT
(например, INSERT
,
UPDATE
, DELETE
), Вы можете выяснить, сколько строк
были изменены, вызывая mysql_affected_rows()
.SELECT
Вы получаете выбранные строки в наборе
результатов. Обратите внимание, что некоторые инструкции подобны
SELECT
в том плане, что они возвращают строки. Сюда входят
SHOW
, DESCRIBE
и EXPLAIN
. Они должны
обработаться тем же самым методом, что и обычный SELECT
.mysql_store_result()
. Эта функция получает с сервера все строки,
возвращенные запросом и сохраняет их на клиенте. Второй путь инициализировать
построчный набор результатов, вызывая mysql_use_result()
. Эта
функция инициализирует поиск, но фактически не получает никаких строк.mysql_fetch_row()
. В случае mysql_store_result()
mysql_fetch_row()
обращается к строкам, которые уже были выбраны
из сервера. В случае же mysql_use_result()
mysql_fetch_row()
фактически получает строку с сервера
самостоятельно. Информация относительно размера данных в каждой строке
доступна через вызов mysql_fetch_lengths()
.mysql_free_result()
, чтобы освободить используемую память.mysql_store_result()
.mysql_store_result()
в том, что, поскольку все
строки были переданы пользователю, Вы не только можете обращаться к строкам
последовательно, Вы можете также двигаться обратно в наборе результатов,
используя mysql_data_seek()
или mysql_row_seek()
,
чтобы изменить текущую (актуальную) позицию строки внутри набора результатов.
Вы можете также выяснять, сколько там строк, вызывая
mysql_num_rows()
. С другой стороны, требования к памяти для
mysql_store_result()
могут быть очень высоки для больших наборов
результатов, и Вы, вероятно, столкнетесь с проблемами нехватки памяти.mysql_use_result()
в том, что пользователь
требует меньшего количества памяти для набора результатов потому, что это
поддерживает только одну строку одновременно (и потому, что имеется меньшее
количество дополнительных распределений для заголовков, так что
mysql_use_result()
может быть быстрее). Недостаток: Вы должны
обработать каждую строку быстро, чтобы не держать занятым сервер. Вы не
имеете произвольного доступа к строкам внутри набора результатов (Вы можете
только обращаться к строкам последовательно), и Вы не знаете, сколько строк
находится в наборе результатов, пока Вы не получите их все. Кроме того, Вы
должны принять все строки, даже если Вы определяете в середине поиска, что
уже нашли ту информацию, которую Вы искали.SELECT
. Вы можете делать это, вызывая
mysql_store_result()
после каждого mysql_query()
(или mysql_real_query()
). Если обращение к набору результатов
прошло успешно, запросом был SELECT
, и Вы можете читать строки.
Если произошел сбой, вызовите mysql_field_count()
, чтобы
определить, должен или нет фактически ожидаться результат. Если
mysql_field_count()
возвращает ноль, запрос не возвратил никаких
данных (это показывает, что это был INSERT
, UPDATE
,
DELETE
или что-то в этом роде) и не возвратит строки. Если
mysql_field_count()
отличен от нуля, запрос должен был
возвратить строки, но не сделал этого. Это указывает, что запросом был
SELECT
, который потерпел неудачу.mysql_store_result()
и mysql_use_result()
позволяют Вам получать информацию относительно полей, которые составляют
набор результатов (число полей, их имена, типы и т.п.). Вы можете обращаться
к информации поля последовательно внутри строки, вызывая
mysql_fetch_field()
неоднократно, или по номеру поля внутри
строки, вызывая mysql_fetch_field_direct()
напрямую. Текущая
(актуальная) позиция курсора поля может быть изменена вызовом
mysql_field_seek()
. Установка курсора поля воздействует на
последующие обращения к mysql_fetch_field()
. Вы можете также
получать информацию для полей в любой момент, вызывая
mysql_fetch_fields()
.mysql_errno()
и
mysql_error()
. Они возвращают код ошибки или сообщение об ошибке
для последней вызванной функции, позволяя Вам определить, когда ошибка
произошла, и что это было.6.3 Описание функций API
NULL
означает
NULL
в смысле языка программирования C, а не MySQL-значение
NULL
.NULL
, чтобы указать успех, или значение
NULL
, чтобы указать ошибку, а функции, возвращающие число,
возвращают целочисленный ноль, чтобы указать успех, или отличное от нуля
значение, чтобы указать ошибку. Обратите внимание, что "отличное от нуля"
означает только это. Если функциональное описание не говорит иного, не надо
проверять результат на соответствие каким-либо числам, кроме нуля.
if (result) /* правильно */
... error ...
if (result < 0) /* неправильно */
... error ...
if (result = -1) /* неправильно */
... error ...
mysql_errno()
. Представление
строки ошибки может быть получено, вызывая mysql_error()
.6.3.1
mysql_affected_rows()
tmy_ulonglong mysql_affected_rows(mysql:PMYSQL):TMY_ULONGLONG;
stdcall;
Описание
UPDATE
,
удаленных последним DELETE
или вставленных последней инструкцией
INSERT
. Может быть вызвана немедленно после
mysql_query()
для UPDATE
, DELETE
или
INSERT
. Для инструкции SELECT
mysql_affected_rows()
работает подобно
mysql_num_rows()
.Возвращаемые значения
SELECT
mysql_affected_rows()
был вызван до вызова
mysql_store_result()
.CLIENT_FOUND_ROWS
, при соединение с
mysqld
mysql_affected_rows()
возвратит число строк,
согласованных инструкцией WHERE
для UPDATE
.REPLACE
,
mysql_affected_rows()
вернет 2 потому, что в этом случае одна
строка была вставлена, а затем дубликат был удален.6.3.2
mysql_close()
mysql_close(sock:PMYSQL);stdcall;
Описание
mysql_close()
также освободит дескриптор подключения, указанный в mysql
, если
дескриптор был распределен автоматически mysql_init()
или
mysql_connect()
.Возвращаемые значения
6.3.3
mysql_connect()
mysql_connect(mysql: PMYSQL; const host,user,passwd:pchar):PMYSQL;
stdcall;
Описание
host
. mysql_connect()
должна завершиться успешно
прежде, чем Вы сможете выполнить любую из функций API, за исключением
mysql_get_client_info()
.mysql_real_connect()
с тем различием, что параметр подключения
может быть NULL
. В этом случае API распределяет память для
структуры подключения автоматически и освобождает ее, когда Вы вызываете
mysql_close()
. Недостаток этого подхода в том, что Вы не можете
получить сообщение об ошибке, если подключение терпит неудачу. Чтобы получать
информацию об ошибке из mysql_errno()
или
mysql_error()
, Вы должны обеспечить имеющий силу указатель
на структуру MYSQL
.Возвращаемые значения
mysql_real_connect()
.Ошибки
mysql_real_connect()
.6.3.4
mysql_change_user()
mysql_change_user(mysql: PMYSQL; const user,passwd,
db:pchar):TMY_BOOL;stdcall;
Описание
db
, стать заданной по умолчанию (текущей) базой данных на
подключении, определенном mysql
. В последующих запросах эта база
данных будет значением по умолчанию для ссылок на таблицы, которые не
включают явный спецификатор базы данных.mysql_change_user()
терпит неудачу, если указанный
пользователь не может быть использован, или если он не имеет разрешения
использовать эту базу данных. В этом случае пользователь и база данных не
будут изменены вообще.db
может быть установлен в NULL
, если
Вы не хотите иметь заданную по умолчанию базу данных.Возвращаемые значения
Ошибки
mysql_real_connect()
.
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
ER_UNKNOWN_COM_ERROR
ER_ACCESS_DENIED_ERROR
ER_BAD_DB_ERROR
ER_DBACCESS_DENIED_ERROR
ER_WRONG_DB_NAME
6.3.5
mysql_create_db()
mysql_create_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Описание
db
.Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.6
mysql_data_seek()
mysql_data_seek(res:PMYSQL_RES;offset:TMY_ULONGLONG); stdcall;
Описание
mysql_data_seek()
может использоваться только в конъюнкции с
mysql_store_result()
, но никак не с
mysql_use_result()
.mysql_num_rows(result)-1
.6.3.7
mysql_debug()
mysql_debug(const debug:pchar);stdcall;
Описание
DBUG_PUSH
с заданной строкой. Вызов
mysql_debug()
использует библиотеку отладки Fred Fish. Чтобы
использовать эту функцию, Вы должны компилировать библиотеку клиентов так,
чтобы поддерживать отладку.Пример
mysql_debug("d:t:O,/tmp/client.trace");
6.3.8
mysql_drop_db()
mysql_drop_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Описание
db
.Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.9
mysql_dump_debug_info()
mysql_dump_debug_info(mysql:PMYSQL):integer;stdcall;
Описание
Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.10
mysql_eof()
mysql_eof(res:PMYSQL_RES):TMY_BOOL;stdcall;
Описание
mysql_eof()
определяет, читалась или нет последняя
строка набора результатов.mysql_store_result()
, клиент получает весь набор в одной
операции. В этом случае возврат NULL
из
mysql_fetch_row()
всегда означает, что конец набора результатов
был достигнут и не нужно вызвать mysql_eof()
.mysql_use_result()
,
чтобы инициализировать поиск набора результата, строки набора получены с
сервера по одной, поскольку Вы вызываете mysql_fetch_row()
неоднократно. Потому что ошибка может происходить на подключении в течение
этого процесса, значение NULL
из функции
mysql_fetch_row()
не обязательно означает, что конец набора
результатов был достигнут. В этом случае, Вы можете использовать
mysql_eof()
, чтобы определить, что там случилось. Функция
mysql_eof()
возвращает значение, отличное от нуля, если конец
набора результатов был достигнут и ноль, если произошла ошибка.mysql_eof()
предшествует стандартной функции
MySQL mysql_errno()
и mysql_error()
. Так как те
функции ошибки обеспечивают ту же самую информацию, их использование
предпочтительнее mysql_eof()
. Фактически, они обеспечивают
большее количество информации потому, что mysql_eof()
возвращает
только булево значение, в то время как функции ошибки указывают причину.Возвращаемые значения
mysql_eof()
возвращает значение, отличное от нуля,
если конец набора результатов был достигнут и ноль, если произошла ошибка.
6.3.11
mysql_errno()
mysql_errno(mysql:PMYSQL):longword;stdcall;
Описание
mysql
,
mysql_errno()
возвращает код ошибки для вызванной функции
API, которая может сработать нормально или потерпеть неудачу. Значение
возврата 0 означает, что никакой ошибки не произошло. Числа сообщений об
ошибках клиента перечислены в файле заголовка MySQL errmsg.h.
Серверные ошибки перечислены в mysqld_error.h. В дистрибутиве
исходного кода MySQL Вы можете найти полный список сообщений об ошибках и их
кодов в файле Docs/mysqld_error.txt.Возвращаемые значения
6.3.12
mysql_error()
mysql_error(mysql:PMYSQL):pchar;stdcall;
Описание
mysql
,
mysql_error()
возвращает сообщение об ошибках для вызванной
функции API, которая может сработать нормально или потерпеть неудачу. Пустая
строка вернется, если никакой ошибки не произошло. Это означает, что
следующие тесты эквивалентны:
if (mysql_errno(&mysql))
{
// an error occurred
}
if (mysql_error(&mysql)[0] != '\0')
{
// an error occurred
}
Возвращаемые значения
6.3.13
mysql_escape_string()
mysql_real_escape_string()
за исключением того,
что требуется подключение как первый параметр.
mysql_real_escape_string()
обработает строку согласно текущему
(актуальному) набору символов, в то время как
mysql_escape_string()
игнорирует установку charset.6.3.14
mysql_fetch_field()
mysql_fetch_field(res:PMYSQL_RES):PMYSQL_FIELD;stdcall;
Описание
MYSQL_FIELD
. Вызовите эту функцию неоднократно, чтобы собрать
информацию относительно всех столбцов в наборе результатов.
mysql_fetch_field()
возвращает NULL
, когда все поля
уже обработаны или их не было вовсе.mysql_fetch_field()
будет сброшен так, чтобы возвратить
информацию относительно первого поля каждый раз, когда Вы выполняете новый
запрос SELECT
. На поле, возвращенное
mysql_fetch_field()
также воздействуют обращения к
mysql_field_seek()
.mysql_query()
чтобы выполнить
SELECT
на таблице, но не вызвали
mysql_store_result()
, MySQL возвращает заданную по умолчанию
длину blob (8K), если Вы вызываете mysql_fetch_field()
, чтобы
спросить о длине поля типа BLOB
. Размер в 8K выбран потому, что
MySQL не знает максимальную длину для BLOB
. Это должно быть
сделано с перестраиваемой конфигурацией когда-нибудь. Как только Вы получили
набор результатов, field.max_length
хранит длину самого
большого значения для этого столбца в специфическом запросе.Возвращаемые значения
MYSQL_FIELD
для текущего (актуального)
столбца. NULL
, если никакие столбцы не обработаны.6.3.15
mysql_fetch_fields()
mysql_fetch_fields(res:PMYSQL_RES):PMYSQL_FIELDS;stdcall;
Описание
MYSQL_FIELD
для набора
результатов. Каждая структура обеспечивает определение поля для одного
столбца набора результатов.Возвращаемые значения
MYSQL_FIELD
для всех
столбцов набора результатов.6.3.16
mysql_fetch_field_direct()
mysql_fetch_field_direct(res:PMYSQL_RES;
fieldnr:integer):PMYSQL_FIELD;stdcall;
Описание
fieldnr
для столбца внутри набора
результатов, возвращает определение поля столбца как структура
MYSQL_FIELD
. Вы можете использовать эту функцию, чтобы получить
описание для произвольного столбца. Значение fieldnr
должно быть
в диапазоне от 0 до mysql_num_fields(result)-1
.Возвращаемые значения
MYSQL_FIELD
для определенного столбца.6.3.17
mysql_fetch_lengths()
mysql_fetch_lengths(res:PMYSQL_RES):longword;stdcall;
Описание
strlen()
. Кроме того, если набор результатов содержит двоичные
данные, Вы должны использовать эту функцию, чтобы определить размер
данных потому, что функция strlen()
возвращает неправильные
результаты для любого поля, содержащего символы пробела.NULL
, равна нулю. Чтобы видеть, как отличить эти два случая,
обратитесь к описанию mysql_fetch_row()
.Возвращаемые значения
NULL
, если
что-то пошло не так.Ошибки
mysql_fetch_lengths()
имеет силу только для текущей строки
набора результатов. Этот вызов возвращает NULL
, если Вы
вызываете его перед mysql_fetch_row()
или после получения
всех строк в результате.6.3.18
mysql_fetch_row()
mysql_fetch_row(res:PMYSQL_RES):PMYSQL_ROW;stdcall;
Описание
mysql_store_result()
, mysql_fetch_row()
возвращает
NULL
, когда не имеется больше строк, чтобы получить. Когда
используется после mysql_use_result()
,
mysql_fetch_row()
вернет NULL
, когда не имеется
больше строк, чтобы получить, или произошла ошибка.mysql_num_fields(result)
. Если
row
хранит значение возврата от обращения к
mysql_fetch_row()
, указатели на значения меняются с
row[0]
на row[mysql_num_fields(result)-1]
. Значения
NULL
в строке обозначены указателями NULL
.mysql_fetch_lengths()
. Пустые поля и поля, содержащие
NULL
имеют длину 0. Вы можете отличать их, проверяя указатель
для значения поля. Если указатель равен NULL
, поле
NULL
, иначе поле пустое.Возвращаемые значения
MYSQL_ROW
для следующей строки. NULL
,
если не имеется больше строк, чтобы получить, или произошла ошибка.Ошибки
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.19
mysql_field_count()
mysql_field_count(mysql:PMYSQL):longword;stdcall;
mysql_num_fields(res:PMYSQL_RES):longword;
stdcall;
.Описание
mysql_store_result()
возвращает NULL
(и таким
образом Вы не имеете никакого указателя на набор результатов). В этом случае
Вы можете вызывать mysql_field_count()
, чтобы определить, должен
или нет mysql_store_result()
произвести не пустой результат. Это
позволяет программе пользователя выбрать соответствующее действие без того,
чтобы знать, был или нет запрос SELECT
(или
SELECT
-подобным). Пример, показанный ниже иллюстрирует, как это
может быть выполнено.Возвращаемые значения
6.3.20
mysql_field_seek()
mysql_field_seek(res:PMYSQL_RES; offset:TMYSQL_FIELD_OFFSET):
TMYSQL_FIELD_OFFSET; stdcall;
Описание
mysql_fetch_field()
получит определение поля столбца, связанного
именно с этим смещением.offset
.Возвращаемые значения
6.3.21
mysql_field_tell()
mysql_field_tell(res:PMYSQL_RES):longword;stdcall;
Описание
mysql_fetch_field()
. Это значение может использоваться как
параметр для mysql_field_seek()
.Возвращаемые значения
6.3.22
mysql_free_result()
mysql_free_result(res:PMYSQL_RES);stdcall;
Описание
mysql_store_result()
, mysql_use_result()
,
mysql_list_dbs()
и другими подобными функциями. Когда Вы
закончили работу с набором результатов, Вы должны освободить память, которую
он использует, вызывая mysql_free_result()
.6.3.23
mysql_get_client_info()
mysql_get_client_info:pchar;stdcall;
Описание
Возвращаемые значения
6.3.24
mysql_get_host_info()
mysql_get_host_info(mysql:PMYSQL):pchar;stdcall;
Описание
Возвращаемые значения
6.3.25
mysql_get_proto_info()
mysql_get_proto_info(mysql:PMYSQL):longword;stdcall;
Описание
Возвращаемые значения
6.3.26
mysql_get_server_info()
mysql_get_server_info(mysql:PMYSQL):pchar;stdcall;
Описание
Возвращаемые значения
6.3.27
mysql_info()
mysql_info(mysql:PMYSQL):pchar;stdcall;
Описание
mysql_info()
всегда возвращает
NULL
. Формат строки изменяется в зависимости от типа запроса,
как описано ниже. Числа только иллюстративны: строка будет содержать
значения, соответствующие запросу.
INSERT INTO ... SELECT ...
Records: 100 Duplicates: 0 Warnings: 0
INSERT INTO ... VALUES (...),(...),(...)...
Records: 3 Duplicates: 0 Warnings: 0
LOAD DATA INFILE ...
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
ALTER TABLE
Records: 3 Duplicates: 0 Warnings: 0
UPDATE
Rows matched: 40 Changed: 40 Warnings: 0
mysql_info()
возвращает значение
не-NULL
для инструкции INSERT ... VALUES
только,
если много списков значений было определено в инструкции.Возвращаемые значения
NULL
, если никакая информация
не доступна для запроса.6.3.28
mysql_init()
mysql_init(mysql: PMYSQL):PMYSQL;stdcall;
Описание
MYSQL
, подходящий для
mysql_real_connect()
. Если mysql
является
указателем NULL
, функция распределяет память, инициализирует и
возвращает новый объект. Иначе объект будет просто инициализирован, и адрес
объекта возвращен. Если mysql_init()
распределяет новый объект,
место будет освобождено, когда будет вызвана mysql_close()
.Возвращаемые значения
MYSQL*
. NULL
, если
недостаточно памяти, чтобы распределить и инициализировать новый объект.Ошибки
NULL
.6.3.29
mysql_insert_id()
mysql_insert_id(mysql:PMYSQL):TMY_ULONGLONG;stdcall;
Описание
AUTO_INCREMENT
. Используйте эту функцию после того,
как Вы выполнили запрос INSERT
для таблицы, которая содержит
поле AUTO_INCREMENT
.mysql_insert_id()
возвращает
0
, если предыдущий запрос не генерирует значение
AUTO_INCREMENT
. Если Вы должны сохранить значение для
последующего неспешного потребления убедитесь, что вызвали
mysql_insert_id()
немедленно после того запроса,
который генерирует значение.mysql_insert_id()
модифицируется после инструкций
INSERT
и UPDATE
, которые генерируют значение
AUTO_INCREMENT
, или установки значения столбца с помощью
LAST_INSERT_ID(expr)
.LAST_INSERT_ID()
всегда содержит самое последнее сгенерированное
значение AUTO_INCREMENT
, и оно не будет сброшено между запросами
потому, что значение этой функции поддерживается сервером.Возвращаемые значения
AUTO_INCREMENT
, которое модифицировалось
предыдущим запросом. 0, если не имелось никакого предыдущего запроса на
подключении, или если запрос не модифицировал AUTO_INCREMENT
.
6.3.30
mysql_kill()
mysql_kill(mysql:PMYSQL;pid:longword):integer;stdcall;
Описание
pid
.
Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.31
mysql_list_dbs()
mysql_list_dbs(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;
Описание
wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем базам данных. Вызов
mysql_list_dbs()
подобен выполнению запроса SHOW
databases [LIKE wild]
.mysql_free_result()
.Возвращаемые значения
MYSQL_RES
для успеха, NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.32
mysql_list_fields()
mysql_list_fields(mysql:PMYSQL;const table,wild:pchar):PMYSQL_RES;
stdcall;
Описание
wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем полям. Вызов
mysql_list_fields()
подобен выполнению запроса SHOW
COLUMNS FROM tbl_name [LIKE wild]
.SHOW
COLUMNS FROM tbl_name
вместо mysql_list_fields()
.mysql_free_result()
.Возвращаемые значения
MYSQL_RES
для успеха. NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.33
mysql_list_processes()
mysql_list_processes(mysql:PMYSQL):PMYSQL_RES;stdcall;
Описание
mysqladmin
processlist
или запросом SHOW PROCESSLIST
.mysql_free_result()
.Возвращаемые значения
MYSQL_RES
для успеха. NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.34
mysql_list_tables()
mysql_list_tables(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;
Описание
wild
. Здесь wild
может содержать
групповые символы % или _, или может быть
NULL
, чтобы соответствовать всем таблицам. Вызов
mysql_list_tables()
подобен выполнению запроса SHOW
tables [LIKE wild]
.mysql_free_result()
.Возвращаемые значения
MYSQL_RES
для успеха. NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.35
mysql_num_fields()
mysql_num_fields(res:PMYSQL_RES):longword;stdcall;
Описание
mysql_store_result()
или
mysql_use_result()
возвращает NULL
(и таким образом
Вы не имеете никакого указателя набора результата). В этом случае Вы можете
вызывать mysql_field_count()
чтобы определить, должен или нет
mysql_store_result()
произвести непустой результат. Это
позволяет программе пользователя выбрать соответствующее действие без того,
чтобы знать, был или нет запрос SELECT
(или
SELECT
-подобным). Пример, показанный ниже иллюстрирует, как это
может быть выполнено.Возвращаемые значения
6.3.36
mysql_num_rows()
mysql_num_rows(res:PMYSQL_RES):TMY_ULONGLONG;stdcall;
Описание
mysql_num_rows()
зависит от того, используете
ли Вы mysql_store_result()
или mysql_use_result()
,
чтобы получить набор результатов. Если Вы используете
mysql_store_result()
, mysql_num_rows()
может
быть вызван немедленно. Если Вы используете mysql_use_result()
,
mysql_num_rows()
не будет возвращать правильное значение, пока
все строки в наборе результатов не будут получены.Возвращаемые значения
6.3.37
mysql_options()
mysql_options(mysql:PMYSQL;option:TMYSQL_OPTION;
const arg:pchar):integer;stdcall;
Описание
mysql_options()
должна быть вызвана после
mysql_init()
, но перед mysql_connect()
или
mysql_real_connect()
.option
представляет собой опцию, которую Вы хотите
устанавливать, arg
задает значение для опции. Если опция целое
число, то arg
должен указывать на значение целого числа.Опция Тип аргумента
Действие MYSQL_OPT_CONNECT_TIMEOUT
longword
Время ожидания в секундах. MYSQL_OPT_COMPRESS
TMY_BOOL
Использовать сжатый протокол клиент-сервер. MYSQL_OPT_NAMED_PIPE
TMY_BOOL
Использовать именованные каналы, чтобы соединиться с сервером MySQL под NT.
MYSQL_INIT_COMMAND
PCHAR
Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически
выполнена при повторном соединении. MYSQL_READ_DEFAULT_FILE
PCHAR
Читать параметры из указанного файла опций вместо my.cnf.
MYSQL_READ_DEFAULT_GROUP
PCHAR
Читать параметры из именованной группы из файла опций
my.cnf или файла, определенного в
MYSQL_READ_DEFAULT_FILE
.client
всегда читается, если Вы
используете MYSQL_READ_DEFAULT_FILE
или
MYSQL_READ_DEFAULT_GROUP
.connect_timeout
Время ожидания в секундах.
В Linux это время ожидания также используется для ожидания первого ответа.
compress
Использовать сжатый протокол
клиент-сервер. database
Соединиться с этой базой данных, если
никакая база данных не была определена в команде подключения. debug
Опции для отладки. host
Имя сервера по умолчанию. init-command
Команда, чтобы выполнить при
соединении с сервером MySQL. Будет автоматически заново выполнена при
повторном соединении, если связь прервалась. interactive-timeout
Аналогично указанию опции
CLIENT_INTERACTIVE
в mysql_real_connect()
.password
Пароль по умолчанию. pipe
Использовать именованные каналы, чтобы
соединиться с сервером MySQL, работая под NT. port
Порт по умолчанию. return-found-rows
Сообщить
mysql_info()
о том, что нужно возвратить найденные строки вместо
модифицируемых строк при использовании UPDATE
.socket
Сокет по умолчанию. user
Пользователь по умолчанию. timeout
был заменен на
connect_timeout
, но timeout
будет все еще работать
некоторое время для совместимости.Возвращаемые значения
6.3.38
mysql_ping()
mysql_ping(mysql:PMYSQL):integer;stdcall;
Описание
Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_UNKNOWN_ERROR
6.3.39
mysql_query()
mysql_query(mysql:PMYSQL; const q:pchar):integer;stdcall;
Описание
\g
для завершения запроса.mysql_query()
не может использоваться для запросов, которые
содержат двоичные данные, взамен Вы должны использовать
mysql_real_query()
. Двоичные данные могут содержать в себе
символ \0, который mysql_query()
интерпретирует как
конец строки запроса. Если Вы хотите знать, возвратил ли запрос набор
результатов или нет, Вы можете использовать mysql_field_count()
,
чтобы проверить это.Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.40
mysql_real_connect()
mysql_real_connect(mysql: PMYSQL; const host,user,passwd,db:pchar;
port:longword; const unix_socket:pchar;
clientflag:longword):PMYSQL;stdcall;
Описание
mysql_real_connect()
пытается установить подключение с
сервером MySQL, запущенным на машине host
.
mysql_real_connect()
должен завершиться успешно прежде, чем Вы
сможете выполнить любую из других функций API, за исключением
mysql_get_client_info()
.TMYSQL
. Перед вызовом mysql_real_connect()
Вы
должны вызвать mysql_init()
, чтобы инициализировать структуру
TMYSQL
. Вы можете изменять много параметров подключения через
вызов mysql_options()
.
host
может быть имя или адрес IP. Если это
NULL
или строка localhost
, выполняется подключение
к локальной системе. Если OS поддерживает сокеты (Unix) или именованные
каналы (Windows), именно они используются вместо стека протоколов TCP/IP,
чтобы соединиться с сервером.
user
содержит ID пользователя MySQL. Если
user
равен NULL
, предполагается текущий
пользователь. Под Unix это текущее (актуальное) имя входа в систему. Под
Windows ODBC имя пользователя должно быть определено явно!
passwd
содержит пароль для user
. Если
passwd
равен NULL
, только записи в таблице
user
, которые имеют пустое поле пароля, будут проверены на
соответствие. Это позволяет администратору базы данных устанавливать систему
привилегий MySQL таким способом, которым пользователи получают различные
привилегии в зависимости от того, определили или нет они пароль. ОБРАТИТЕ
ВНИМАНИЕ: Не пытайтесь шифровать пароль перед вызовом
mysql_real_connect()
: шифрование пароля обработано автоматически.
db
задает имя базы данных. Если db
не
NULL
, подключение установит заданную по умолчанию базу данных.
port
не равен 0, значение будет использоваться как
номер порта для подключения по TCP/IP. Обратите внимание, что параметр
host
определяет тип подключения.
unix_socket
не равен NULL
, строка
определяет сокет или именованный канал, который должен использоваться.
Обратите внимание, что параметр host
определяет тип подключения.
client_flag
как правило равно 0, но может быть
установлено к комбинации из следующих флажков в специальных обстоятельствах:
Имя флажка Что он делает
CLIENT_COMPRESS
Использовать протокол сжатия.
CLIENT_FOUND_ROWS
Возвратить число найденных, а
не обработанных строк. CLIENT_IGNORE_SPACE
Позволить использовать
пробелы после имен функций. Делает все зарезервированные
слова именами функций. CLIENT_INTERACTIVE
Позволить
interactive_timeout
секунд (вместо wait_timeout
секунд) бездеятельности перед закрытием подключения.CLIENT_NO_SCHEMA
Не позволять синтаксис
db_name.tbl_name.col_name
. Это сделано для ODBC. Это заставляет
синтаксический анализатор генерировать ошибку, если Вы используете тот
синтаксис, который является полезным для заманивания в ловушку ошибок в
некоторых программах ODBC.CLIENT_ODBC
Работает клиент ODBC. CLIENT_SSL
Использовать шифрованный протокол SSL.
Возвращаемые значения
MYSQL*
, если подключение было успешно,
NULL
, если подключение было неудачно. Для успешного подключения,
значение возврата: такое же, как значение первого параметра, если Вы не
передаете NULL
для этого параметра.Ошибки
CR_CONN_HOST_ERROR
CR_CONNECTION_ERROR
CR_IPSOCK_ERROR
CR_OUT_OF_MEMORY
CR_SOCKET_CREATE_ERROR
CR_UNKNOWN_HOST
CR_VERSION_ERROR
--old-protocol
.
CR_NAMEDPIPEOPEN_ERROR
CR_NAMEDPIPEWAIT_ERROR
CR_NAMEDPIPESETSTATE_ERROR
CR_SERVER_LOST
connect_timeout
> 0 и требуется более, чем
connect_timeout
секунд, чтобы соединиться с сервером, или если
сервер свалился при выполнении init-command
, вернется это.mysql_options()
, библиотека клиентов MySQL будет
читать группы [client]
и your_prog_name
в файле
my.cnf
, что гарантирует, что Ваша программа будет работать, даже
если кто-то установил MySQL некоторым ненормативным способом.mysql_real_connect()
устанавливает флажок reconnect
(часть структуры TMYSQL) в
значение 1
. Этот флажок указывает, что когда запрос не может
выполниться из-за потерянного подключения, надо попробовать повторно
соединиться с сервером перед отказом.6.3.41
mysql_real_escape_string()
mysql_real_escape_string(mysql:PMYSQL; wto:pchar;
const wfrom:pchar; wfromlength:longword):longword;stdcall;
Описание
from
бужет закодирована до экранированной строки
SQL, принимая во внимание текущий (актуальный) набор символов подключения.
Результат будет помещен в to
и завершающий байт пустого
указателя допишется автоматически. Символы NUL
(ASCII 0),
\n, \r, \, ',
", а также Control-Z, будуь экранированы.from
должна быть length
байтов длины. Вы должны распределить буфер по крайней мере
length*2+1
байт. В худшем случае каждый символ должен быть
закодирован как использование двух байтов, и Вы нуждаетесь в участке памяти
для завершающего байта пустого указателя. Когда
mysql_escape_string()
завершится, в to
будет
строка с нулевым байтом в конце. Значение возврата: длина закодированной
строки, не включая символ завершения.Возвращаемые значения
to
, не включая
нулевой символ завершения.6.3.42
mysql_real_query()
mysql_real_query(mysql:PMYSQL; const q:pchar;
length:longword):integer;stdcall;
Описание
query
, который должен быть
строкой длиной в length
байт. Запрос должен состоять из
одиночной инструкции SQL. Вы не должны добавлять точку с запятой
(`;') или \g
для завершения запроса.mysql_real_query()
вместо
mysql_query()
для запросов, которые содержат двоичные данные,
потому, что двоичные данные могут сами содержать символ \0.
Кроме того, mysql_real_query()
быстрее, чем
mysql_query()
потому, что не вызывает strlen()
.mysql_field_count()
, чтобы проверить это.
Подробности в разделе "6.3.85
mysql_field_count()
".Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.43
mysql_reload()
mysql_reload(mysql:PMYSQL):integer;stdcall;
Описание
Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.44
mysql_row_seek()
mysql_row_seek(res:PMYSQL_RES;
offset:PMYSQL_ROW_OFFSET):PMYSQL_ROW_OFFSET;stdcall;
Описание
mysql_row_seek()
может использоваться
в конъюнкции только с mysql_store_result()
, но не с
mysql_use_result()
.mysql_row_tell()
для mysql_row_seek()
. Это значение
не просто номер строки, если Вы хотите перейти к строке внутри набора
результатов, используйте mysql_data_seek()
.Возвращаемые значения
mysql_row_seek()
.6.3.45
mysql_row_tell()
mysql_row_tell(res:PMYSQL_RES):PMYSQL_ROWS;stdcall;
Описание
mysql_fetch_row()
. Это значение может использоваться как
параметр для mysql_row_seek()
.mysql_row_tell()
только после
mysql_store_result()
, но не после
mysql_use_result()
.Возвращаемые значения
6.3.46
mysql_select_db()
mysql_select_db(mysql:PMYSQL; const db:pchar):integer;stdcall;
Описание
db
, стать заданной
по умолчанию базой данных на подключении, определенном в mysql
.
В последующих запросах эта база данных будет значением по умолчанию для
ссылок на таблицы, которые не включают явный спецификатор базы данных.mysql_select_db()
терпит неудачу, если связанный пользователь
не имеет прав доступа, чтобы использовать базу данных.Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.47
mysql_shutdown()
mysql_shutdown(mysql:PMYSQL):integer;stdcall;
Описание
Возвращаемые значения
Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.48
mysql_stat()
mysql_stat(mysql:PMYSQL):pchar;stdcall;
Описание
mysqladmin status
. Это включает
uptime в секундах, число работающих потоков, количество запросов,
перезагрузок и открытых таблиц.Возвращаемые значения
NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.49
mysql_store_result()
mysql_store_result(mysql:PMYSQL):PMYSQL_RES;stdcall;
Описание
mysql_store_result()
или
mysql_use_result()
для каждого запроса, который успешно получает
данные (SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
).mysql_store_result()
или
mysql_use_result()
для других запросов, но это не причинит
вреда, если Вы вызываете mysql_store_result()
во всех случаях.
Правда, и эффективности не прибавится... Вы могли обнаружить, что запрос не
имеет набора результатов, проверяя равенство нулю возврата
mysql_store_result()
. Если Вы хотите знать, возвратил ли запрос
набор результатов или нет, Вы можете использовать mysql_field_count()
, чтобы проверить это.mysql_store_result()
читает весь результат запроса,
распределяет структуру TMYSQL_RES
и помещает
результат в эту структуру.mysql_store_results()
вернет пустой указатель, если запрос не
возвращал набор результатов вообще (если запрос был, например, инструкцией
INSERT
).mysql_store_results()
также возвращает пустой указатель, если
чтение набора результатов потерпело неудачу. Вы можете проверить, получили
ли Вы ошибку, проверяя возвращает ли mysql_error()
пустой
указатель. Если mysql_errno()
<> 0, или если
mysql_field_count()
<> 0, значит, есть ошибочка.mysql_store_result()
и получили
результат, который не пустой указатель, Вы можете вызывать
mysql_num_rows()
, чтобы выяснить, сколько строк
находится в наборе результатов.mysql_fetch_row()
, чтобы выбрать строки из
набора результатов, или mysql_row_seek()
и
mysql_row_tell()
, чтобы получить или установить текущую позицию
строки внутри набора результатов.mysql_free_result()
как только Вы закончите
работу с данным набором результатов.Возвращаемые значения
MYSQL_RES
с результатами. NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.3.50
mysql_thread_id()
mysql_thread_id(mysql:PMYSQL):longword;stdcall;
Описание
mysql_kill()
, чтобы
уничтожить этот поток.mysql_ping()
, ID потока изменится. Это означает, что Вы не
должны получить ID потока и хранить его. Надо получать ID по мере надобности.
Возвращаемые значения
6.3.51
mysql_use_result()
mysql_use_result(mysql:PMYSQL):PMYSQL_RES;stdcall;
Описание
mysql_store_result()
или
mysql_use_result()
для каждого запроса, который успешно получает
данные (SELECT
, SHOW
, DESCRIBE
,
EXPLAIN
).mysql_use_result()
инициализирует поиск набора результата, но
фактически не читает набор результатов подобно
mysql_store_result()
. Вместо этого, каждая строка должна быть
получена индивидуально, делая обращения к mysql_fetch_row()
. Это
читает результат запроса непосредственно с сервера без того, чтобы сохранить
его во временной таблице или локальном буфере, что несколько быстрее и
использует намного меньше памяти, чем mysql_store_result()
.
Пользователь распределит память только для текущей (актуальной) строки и
буфера связей, который может сам вырасти до max_allowed_packet
.
mysql_use_result()
если Вы делаете много обработки для каждой
строки на стороне пользователя, или если вывод послан экрану, на котором
пользователь может напечатать ^S
(приостановить показ данных).
Это свяжет сервер и не даст другим потокам модифицировать любые таблицы, из
которых выбираются данные.mysql_use_result()
Вы должны выполнять
mysql_fetch_row()
до тех пор, пока значение не вернется значение
NULL
, иначе невыбранные строки будут возвращены как часть набора
результатов для Вашего следующего запроса. API выдает ошибку
"Commands out of sync; You can't run this command now
", если Вы
забываете про это!mysql_data_seek()
,
mysql_row_seek()
, mysql_row_tell()
,
mysql_num_rows()
или mysql_affected_rows()
с
результатом, возвращенным из mysql_use_result()
, и при этом Вы
не можете выдавать другие запросы, пока не закончится
mysql_use_result()
. Однако, после того, как Вы выбрали все
строки, mysql_num_rows()
точно возвратит число выбранных строк.
mysql_free_result()
как только Вы закончили
с этим набором результатов.Возвращаемые значения
TMYSQL_RES
. NULL
,
если произошла ошибка.Ошибки
CR_COMMANDS_OUT_OF_SYNC
CR_OUT_OF_MEMORY
CR_SERVER_GONE_ERROR
CR_SERVER_LOST
CR_UNKNOWN_ERROR
6.4 Общие вопросы и проблемы
при использовании API
6.4.1 Почему при успехе
mysql_query()
вызов mysql_store_result()
иногда возвращает NULL?
malloc()
(например, если набор результатов
был слишком большой).
INSERT
, UPDATE
или DELETE
).mysql_field_count()
. Если
mysql_field_count()
вернет ноль, результат пуст, и последний
запрос был инструкцией, которая не возвращает значения (например,
INSERT
или DELETE
). Если
mysql_field_count()
вернет не ноль, инструкция должна была
произвести не пустой результат.mysql_error()
или
mysql_errno()
.6.4.2 Какой результаты я могу
получить из запроса?
mysql_affected_rows()
возвращает число строк, на которые
воздействует последний запрос при выполнении INSERT
,
UPDATE
или DELETE
. Исключительная ситуация:
DELETE
используется без предложения WHERE
, таблица
будет пересоздана пустой, что намного быстрее! В этом случае
mysql_affected_rows()
возвращает ноль для числа записей.
mysql_num_rows()
возвращает число строк в наборе
результатов. При использовании mysql_store_result()
mysql_num_rows()
может быть вызван, как только отработает
mysql_store_result()
. При использовании
mysql_use_result()
mysql_num_rows()
может быть
вызван только после того, как Вы выбрали все строки с помощью
mysql_fetch_row()
.
mysql_insert_id()
возвращает ID, сгенерированный последним
запросом, который вставил строку в таблицу с индексом
AUTO_INCREMENT
. Подробности в разделе
"6.3.126 mysql_insert_id()
".
LOAD DATA INFILE ...
, INSERT INTO
... SELECT ...
, UPDATE
) возвращают дополнительную
информацию. Результат возвращен через mysql_info()
.
mysql_info()
вернет NULL
если не имеется
никакой дополнительной информации.6.4.3 Как я могу получить уникальный ID для
последней вставленной строки?
AUTO_INCREMENT
, Вы можете получать последнее значение
ID вызовом mysql_insert_id()
.LAST_INSERT_ID()
в строке запроса, которую Вы передаете
mysql_query()
.AUTO_INCREMENT
,
выполняя следующий код. Это также проверит, был ли запрос INSERT
с индексом AUTO_INCREMENT
:
if (mysql_error(pmysql)[0]=0) && (mysql_num_fields(result)=0) &&
(mysql_insert_id(pmysql) != 0) then begin
used_id := mysql_insert_id(pmysql);
end;
AUTO_INCREMENT
не со специальным
значением (то есть значением, которое не NULL
и не
0
).
INSERT INTO foo (auto,text)
VALUES(NULL,'text'); # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
VALUES(LAST_INSERT_ID(),'text'); # use ID in second table