Версия для печати

Архив документации на OpenNet.ru / Раздел "Базы данных, SQL" (Многостраничная версия)

MySQL: Руководство разработчика

Версия 1.0.

Автор: Алексей Паутов.

Источник: RussianLDP:MySQL


Приложение 1. Переменные окружения

Имеется список всех системных переменных, которые используются 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.

Приложение 2. Выяснение вопросов или сообщение об ошибках в пакете

Перед отправкой отчета об ошибке или вопроса сделайте следующее:

Если Вы не можете найти ответ в руководстве или архиве, проконсультируйтесь с Вашим локальным экспертом 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, подробности ниже).

Пожалуйста, включите следующую информацию в Ваш отчет:

Направьте отчет на адрес соответствующей рассылки. Может кто-то еще испытал (и возможно решил) такую проблему. Если Вы подписаны на поддержку, пишите на mysql-support@mysql.com.

Когда ответы посланы Вам индивидуально, а не списку рассылки, считается хорошим тоном суммировать ответы и послать резюме в список рассылки, чтобы все могли с ним ознакомиться и решить свои проблемы.

Руководящие принципы ответов на вопросы в списках рассылки

Если Вы полагаете, что Ваш ответ представляет широкий интерес, Вы можете отправить его в список рассылки вместо того, чтобы ответить лично индивидууму, который Вас спросил. Пожалуйста, удостоверьтесь, что Ваш ответ не дублирует другой.

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


Приложение 3. GNU GENERAL PUBLIC LICENSE

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.

Preamble

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.

2 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The ``Program'', below, refers to any such program or work, and a ``work based on the Program'' means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) Each licensee is addressed as ``you''. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
  2. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
  3. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
    1. You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
    2. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
    3. If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)
    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
  4. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
    1. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    2. Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
    3. Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
    The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
  5. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
  6. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.
  7. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
  8. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
  9. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
  10. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
  11. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

    9.4 NO WARRANTY

  12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  13. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

9.5 END OF TERMS AND CONDITIONS

3 How to Apply These Terms to Your New Programs

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.


Приложение 4. GNU LESSER GENERAL PUBLIC 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.]

1 Preamble

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.

2 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  1. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called ``this License''). Each licensee is addressed as ``you''. A ``library'' means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The ``Library'', below, refers to any such software library or work which has been distributed under these terms. A ``work based on the Library'' means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term ``modification''.) ``Source code'' for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
  2. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
  3. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
    1. The modified work must itself be a software library.
    2. You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
    3. You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
    4. If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
  4. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
  5. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
  6. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a ``work that uses the Library''. Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a ``work that uses the Library'' with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a ``work that uses the library''. The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a ``work that uses the Library'' uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
  7. As an exception to the Sections above, you may also combine or link a ``work that uses the Library'' with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
    1. Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable ``work that uses the Library'', as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
    2. Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
    3. Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
    4. If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
    5. Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
    For an executable, the required form of the ``work that uses the Library'' must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
  8. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
    1. Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
    2. Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
  9. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
  10. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
  11. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
  12. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
  13. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
  14. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and ``any later version'', you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
  15. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

    9.6 NO WARRANTY

  16. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  17. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

9.7 END OF TERMS AND CONDITIONS

3 How to Apply These Terms to Your New Libraries

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!


1 MySQL API

Эта глава описывает API, доступные для MySQL, где получить, как использовать их и так далее. C API наиболее подробно рассмотрен, поскольку был разработан авторами MySQL и послужил основой для большинства других API.

1.1 MySQL PHP API

PHP представляет собой серверный, встроенный в HTML, скриптовый язык, который может использоваться, чтобы создать динамическую веб-страницу. Это содержит поддержку обращений к нескольким базам данных, включая MySQL. PHP может быть выполнен как отдельная программа или компилироваться как модуль для использования с веб-сервером Apache.

Дистрибутивы и документация доступны на web-сайте PHP.

1.1.1 Основные проблемы с MySQL и PHP

1.2 MySQL C++ API

Два комплекта API доступны в каталоге MySQL Contrib.

1.2.1 Borland C++

Вы можете компилировать исходники MySQL для Windows с помощью Borland C++ 5.02. Исходники для Windows включают только проекты для Microsoft VC++, для Borland C++ Вы должны сделать файлы проекта самостоятельно.

Одна известная проблема с Borland C++ состоит в том, что этот компилятор использует иное выравнивание структуры, чем VC++. Это означает, что Вы столкнетесь с проблемами, если попробуете использовать заданную по умолчанию библиотеку libmysql.dll (которая компилировалась с VC++) с Borland C++. Вы можете сделать одно действие из следующего перечня решений, чтобы избежать этой проблемы.

1.3 MySQL Java Connectivity (JDBC)

Имеются два официально поддерживаемых драйвера 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-специфическим свойствам.

1.4 MySQL Python API

Каталог MySQL Contrib хранит интерфейс с языком Python, написанный Joseph Skinner.

Вы можете также использовать интерфейс Python для iODBC, чтобы обратиться к серверу MySQL (пакет mxODBC).

1.5 MySQL Tcl API

Есть пакет Tcl at binevolve. Кроме того, каталог Contrib включает интерфейс с Tcl, основанный на msqltcl 1.50.

1.6 MySQL Eiffel драйвер

Каталог MySQL Contrib включает драйвер для языка Eiffel, написанный Michael Ravits.


2 MySQL C API

Код 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".

2.1 Типы данных в C API

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. Используются в вызове 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_TINYTINYINT
FIELD_TYPE_SHORTSMALLINT
FIELD_TYPE_LONGINTEGER
FIELD_TYPE_INT24MEDIUMINT
FIELD_TYPE_LONGLONGBIGINT
FIELD_TYPE_DECIMALDECIMAL или NUMERIC
FIELD_TYPE_FLOATFLOAT
FIELD_TYPE_DOUBLEDOUBLE или REAL
FIELD_TYPE_TIMESTAMPTIMESTAMP
FIELD_TYPE_DATEDATE
FIELD_TYPE_TIMETIME
FIELD_TYPE_DATETIMEDATETIME
FIELD_TYPE_YEARYEAR
FIELD_TYPE_STRINGСтрока (CHAR или VARCHAR)
FIELD_TYPE_BLOBBLOB или TEXT (используйте max_length, чтобы определить максимальную длину поля)
FIELD_TYPE_SETSET
FIELD_TYPE_ENUMENUM
FIELD_TYPE_NULLNULL
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
Число допустимых десятичных чисел для числовых полей.

2.2 Обзор функций C API

Функции, доступные в 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(). Они возвращают код ошибки или сообщение об ошибке для последней вызванной функции, позволяя Вам определить, когда ошибка произошла, и что это было.

2.3 Описание функций C API

В описаниях ниже параметр или значение возврата NULL означает NULL в смысле языка программирования C, а не MySQL-значение NULL.

Функции, которые возвращают значение, возвращают указатель или целое число. Если не определено иное, функции, возвращающие указатель, возвращают значение не-NULL, чтобы указать успех, или значение NULL, чтобы указать ошибку, а функции, возвращающие число, возвращают целочисленный ноль, чтобы указать успех, или отличное от нуля значение, чтобы указать ошибку. Обратите внимание, что "отличное от нуля" означает только это. Если функциональное описание не говорит иного, не надо проверять результат на соответствие каким-либл числам, кроме нуля.

if (result)                   /* правильно */
    ... error ...

if (result < 0)           /* неправильно */
    ... error ...

if (result == -1)             /* неправильно */
    ... error ...

Когда функция возвращает ошибку, подраздел Ошибки описания функции вносит в список возможные типы ошибок. Вы можете выяснить, который из них произошел, вызывая mysql_errno(). Представление строки ошибки может быть получено, вызывая mysql_error().

2.3.1 mysql_affected_rows()

my_ulonglong mysql_affected_rows(MYSQL *mysql)

2.3.2 Описание

Возвращает число строк, измененных последним UPDATE, удаленных последним DELETE или вставленных последней инструкцией INSERT. Может быть вызвана немедленно после mysql_query() для UPDATE, DELETE или INSERT. Для инструкции SELECT mysql_affected_rows() работает подобно mysql_num_rows().

2.3.3 Возвращаемые значения

Целое число, большее, чем ноль, указывает количество обработанных строк. Ноль указывает, что никакие записи обработаны не были. -1 указывает, что запрос возвратил ошибку или то, что для запроса SELECT mysql_affected_rows() был вызван до вызова mysql_store_result().

2.3.4 Ошибки

Нет.

2.3.5 Пример

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 потому, что в этом случае одна строка была вставлена, а затем дубликат был удален.

2.3.6 mysql_close()

void mysql_close(MYSQL *mysql)

2.3.7 Описание

Закрывает предварительно открытое подключение. mysql_close() также освободит дескриптор подключения, указанный в mysql, если дескриптор был распределен автоматически mysql_init() или mysql_connect().

2.3.8 Возвращаемые значения

Нет.

2.3.9 Ошибки

Нет.

2.3.10 mysql_connect()

MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)

2.3.11 Описание

пытается устанавливать подключение с сервером MySQL на компьютере host. mysql_connect() должна завершиться успешно прежде, чем Вы сможете выполнить любую из функций API, за исключением mysql_get_client_info().

Значения параметров такие же, как для соответствующих параметров mysql_real_connect() с тем различием, что параметр подключения может быть NULL. В этом случае C API распределяет память для структуры подключения автоматически и освобождает ее, когда Вы вызываете mysql_close(). Недостаток этого подхода в том, что Вы не можете получить сообщение об ошибке, если подключение терпит неудачу. Чтобы получать информацию об ошибке из mysql_errno() или mysql_error(), Вы должны обеспечить имеющий силу указатель на структуру MYSQL.

2.3.12 Возвращаемые значения

Аналогично mysql_real_connect().

2.3.13 Ошибки

Аналогично mysql_real_connect().

2.3.14 mysql_change_user()

my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)

2.3.15 Описание

Меняет пользователя и заставляет базу данных, определенную как db, стать заданной по умолчанию (текущей) базой данных на подключении, определенном mysql. В последующих запросах эта база данных будет значением по умолчанию для ссылок на таблицы, которые не включают явный спецификатор базы данных.

Эта функция представлена в MySQL Version 3.23.3.

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

Параметр db может быть установлен в NULL, если Вы не хотите иметь заданную по умолчанию базу данных.

2.3.16 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если произошла ошибка.

2.3.17 Ошибки

Аналогично mysql_real_connect().

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.
ER_UNKNOWN_COM_ERROR
Сервер MySQL не выполняет эту команду (вероятно, старая версия).
ER_ACCESS_DENIED_ERROR
Пользователь или пароль ошибочен.
ER_BAD_DB_ERROR
База данных не существует.
ER_DBACCESS_DENIED_ERROR
Пользователь не имеет прав доступа к базе данных.
ER_WRONG_DB_NAME
Имя базы данных слишком длинное.

2.3.18 Пример

if (mysql_change_user(&mysql, "user", "password", "new_database"))
{
   fprintf(stderr, "Failed to change user.  Error: %s\n",
           mysql_error(&mysql));
}

2.3.19 mysql_character_set_name()

const char *mysql_character_set_name(MYSQL *mysql)

2.3.20 Описание

Возвращает заданный по умолчанию набор символов для текущего (актуального) подключения.

2.3.21 Возвращаемые значения

Заданный по умолчанию набор символов

2.3.22 Ошибки

Нет.

2.3.23 mysql_create_db()

int mysql_create_db(MYSQL *mysql, const char *db)

2.3.24 Описание

Создает базу данных с именем db.

2.3.25 Возвращаемые значения

Ноль, если база данных была создана успешно. Отличное от нуля, если в процессе произошла ошибка.

2.3.26 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.Произошла неизвестная ошибка.

2.3.27 Пример

if (mysql_create_db(&mysql, "my_database"))
{
   fprintf(stderr, "Failed to create new database. Error: %s\n",
           mysql_error(&mysql));
}

2.3.28 mysql_data_seek()

void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)

2.3.29 Описание

Переходит к произвольной строке в наборе результатов запроса. Это требует, чтобы структура набора результата содержала весь результат запроса, так что mysql_data_seek() может использоваться только в конъюнкции с mysql_store_result(), но никак не с mysql_use_result().

Смещение должно быть значением в диапазоне от 0 до mysql_num_rows(result)-1.

2.3.30 Возвращаемые значения

Нет.

2.3.31 Ошибки

Нет.

2.3.32 mysql_debug()

void mysql_debug(char *debug)

2.3.33 Описание

Делает DBUG_PUSH с заданной строкой. Вызов mysql_debug() использует библиотеку отладки Fred Fish. Чтобы использовать эту функцию, Вы должны компилировать библиотеку клиентов так, чтобы поддерживать отладку.

2.3.34 Возвращаемые значения

Нет.

2.3.35 Ошибки

Нет.

2.3.36 Пример

Обращение, показанное ниже, заставляет библиотеку клиентов генерировать файл трассировки /tmp/client.trace на машине пользователя:

mysql_debug("d:t:O,/tmp/client.trace");

2.3.37 mysql_drop_db()

int mysql_drop_db(MYSQL *mysql, const char *db)

2.3.38 Описание

Удвляет базу данных, упомянутую как параметр db.

2.3.39 Возвращаемые значения

Ноль, если база данных была удалена успешно. Отличное от нуля, если в процессе произошла ошибка.

2.3.40 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.41 Пример

if (mysql_drop_db(&mysql, "my_database"))
   fprintf(stderr, "Failed to drop the database: Error: %s\n",
           mysql_error(&mysql));

2.3.42 mysql_dump_debug_info()

int mysql_dump_debug_info(MYSQL *mysql)

2.3.43 Описание

Инструктирует сервер, чтобы писать некоторую информацию отладки в файл регистрации. Отдавший команду пользователь должен иметь привилегию process, чтобы работать.

2.3.44 Возвращаемые значения

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

2.3.45 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.46 mysql_eof()

my_bool mysql_eof(MYSQL_RES *result)

2.3.47 Описание

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() возвращает только булево значение, в то время как функции ошибки указывают причину.

2.3.48 Возвращаемые значения

Функция mysql_eof() возвращает значение, отличное от нуля, если конец набора результатов был достигнут и ноль, если произошла ошибка.

2.3.49 Ошибки

Нет.

2.3.50 Пример

Следующий пример показывает, как Вы могли бы использовать 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));
}

2.3.51 mysql_errno()

unsigned int mysql_errno(MYSQL *mysql)

2.3.52 Описание

Для подключения, определенного в mysql, mysql_errno() возвращает код ошибки для вызванной функции API, которая может сработать нормально или потерпеть неудачу. Значение возврата 0 означает, что никакой ошибки не произошло. Числа сообщений об ошибках клиента перечислены в файле заголовка MySQL errmsg.h. Серверные ошибки перечислены в mysqld_error.h. В дистрибутиве исходного кода MySQL Вы можете найти полный список сообщений об ошибках и их кодов в файле Docs/mysqld_error.txt.

2.3.53 Возвращаемые значения

Значение кода ошибки. 0, если никакая ошибка не произошла.

2.3.54 Ошибки

Нет.

2.3.55 mysql_error()

char *mysql_error(MYSQL *mysql)

2.3.56 Описание

Для подключения, определенного в mysql, mysql_error() возвращает сообщение об ошибках для вызванной функции API, которая может сработать нормально или потерпеть неудачу. Пустая строка ("") вернется, если никакой ошибки не произошло. Это означает, что следующие тесты эквивалентны:

if (mysql_errno(&mysql))
{
   // an error occurred
}
if (mysql_error(&mysql)[0] != '\0')
{
   // an error occurred
}

Язык сообщений об ошибках пользователя может быть изменен перекомпиляцией библиотеки клиента MySQL. В настоящее время Вы можете выбирать сообщения об ошибках на нескольких различных языках.

2.3.57 Возвращаемые значения

Символьная строка, которая описывает ошибку. Пустая строка, если никакой ошибки не произошло.

2.3.58 Ошибки

Нет.

2.3.59 mysql_escape_string()

Это идентично mysql_real_escape_string() за исключением того, что требуется подключение как первый параметр. mysql_real_escape_string() обработает строку согласно текущему (актуальному) набору символов, в то время как mysql_escape_string() игнорирует установку charset.

2.3.60 mysql_fetch_field()

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)

2.3.61 Описание

Возвращает определение одного столбца набора результатов как структуру 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 хранит длину самого большого значения для этого столбца в специфическом запросе.

2.3.62 Возвращаемые значения

Структура типа MYSQL_FIELD для текущего (актуального) столбца. NULL, если никакие столбцы не обработаны.

2.3.63 Ошибки

Нет.

2.3.64 Пример

MYSQL_FIELD *field;

while((field = mysql_fetch_field(result)))
{
  printf("field name %s\n", field->name);
}

2.3.65 mysql_fetch_fields()

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

2.3.66 Описание

Возвращает массив всех структур MYSQL_FIELD для набора результатов. Каждая структура обеспечивает определение поля для одного столбца набора результатов.

2.3.67 Возвращаемые значения

Массив структур MYSQL_FIELD для всех столбцов набора результатов.

2.3.68 Ошибки

Нет.

2.3.69 Пример

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);
}

2.3.70 mysql_fetch_field_direct()

MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)

2.3.71 Описание

Получает код поля fieldnr для столбца внутри набора результатов, возвращает определение поля столбца как структура MYSQL_FIELD. Вы можете использовать эту функцию, чтобы получить описание для произвольного столбца. Значение fieldnr должно быть в диапазоне от 0 до mysql_num_fields(result)-1.

2.3.72 Возвращаемые значения

Структура MYSQL_FIELD для определенного столбца.

2.3.73 Ошибки

Нет.

2.3.74 Пример

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);
}

2.3.75 mysql_fetch_lengths()

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)

2.3.76 Описание

Возвращает длины столбцов текущей (актуальной) строки внутри набора результатов. Если Вы планируете копировать значения поля, эта информация также полезна для оптимизации потому, что Вы можете избежать вызова strlen(). Кроме того, если набор результатов содержит двоичные данные, Вы должны использовать эту функцию, чтобы определить размер данных потому, что функция strlen() возвращает неправильные результаты для любого поля, содержащего символы пробела.

Длина для пустых столбцов и для столбцов, содержащих значения NULL, равна нулю. Чтобы видеть, как отличить эти два случая, обратитесь к описанию mysql_fetch_row().

2.3.77 Возвращаемые значения

Массив длинных целых чисел без знака, представляющих размер каждого столбца (не включая любые символы пробелов в хвосте). NULL, если что-то пошло не так.

2.3.78 Ошибки

mysql_fetch_lengths() имеет силу только для текущей строки набора результатов. Этот вызов возвращает NULL, если Вы вызываете его перед mysql_fetch_row() или после получения всех строк в результате.

2.3.79 Пример

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]);
   }
}

2.3.80 mysql_fetch_row()

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

2.3.81 Описание

Получает следующую строку набора результатов. Когда используется после 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, иначе поле пустое.

2.3.82 Возвращаемые значения

Структура MYSQL_ROW для следующей строки. NULL, если не имеется больше строк, чтобы получить, или произошла ошибка.

2.3.83 Ошибки

CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.84 Пример

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");
}

2.3.85 mysql_field_count()

unsigned int mysql_field_count(MYSQL *mysql)

Если Вы используете версию MySQL ранее, чем Version 3.22.24, Вы должны вместо этого использовать unsigned int mysql_num_fields(MYSQL *mysql).

2.3.86 Описание

Возвращает число столбцов для самого последнего запроса на подключении.

Нормальное использование этой функции: когда mysql_store_result() возвращает NULL (и таким образом Вы не имеете никакого указателя на набор результатов). В этом случае Вы можете вызывать mysql_field_count(), чтобы определить, должен или нет mysql_store_result() произвести не пустой результат. Это позволяет программе пользователя выбрать соответствующее действие без того, чтобы знать, был или нет запрос SELECT (или SELECT-подобным). Пример, показанный ниже иллюстрирует, как это может быть выполнено.

2.3.87 Возвращаемые значения

Целое число без знака, представляющее число полей в наборе результатов.

2.3.88 Ошибки

Нет.

2.3.89 Пример

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.

2.3.90 mysql_field_seek()

MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)

2.3.91 Описание

Устанавливает курсор поля к данному смещению. Следующее обращение к mysql_fetch_field() получит определение поля столбца, связанного именно с этим смещением.

Чтобы перейти к началу строки, передайте 0 как значение offset.

2.3.92 Возвращаемые значения

Предыдущее значение курсора поля.

2.3.93 Ошибки

Нет.

2.3.94 mysql_field_tell()

MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)

2.3.95 Описание

Возвращает позицию курсора поля, используемого для последнего mysql_fetch_field(). Это значение может использоваться как параметр для mysql_field_seek().

2.3.96 Возвращаемые значения

Текущее смещение курсора поля.

2.3.97 Ошибки

Нет.

2.3.98 mysql_free_result()

void mysql_free_result(MYSQL_RES *result)

2.3.99 Описание

Освобождает память, распределенную для набора результатов mysql_store_result(), mysql_use_result(), mysql_list_dbs() и другими подобными функциями. Когда Вы закончили работу с набором результатов, Вы должны освободить память, которую он использует, вызывая mysql_free_result().

2.3.100 Возвращаемые значения

Нет.

2.3.101 Ошибки

Нет.

2.3.102 mysql_get_client_info()

char *mysql_get_client_info(void)

2.3.103 Описание

Возвращает строку, которая представляет версию клиентской библиотеки.

2.3.104 Возвращаемые значения

Символьная строка, которая представляет версию клиентской библиотеки MySQL.

2.3.105 Ошибки

Нет.

2.3.106 mysql_get_host_info()

char *mysql_get_host_info(MYSQL *mysql)

2.3.107 Описание

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

2.3.108 Возвращаемые значения

Символьная строка, представляющая имя компьютера и тип подключения.

2.3.109 Ошибки

Нет.

2.3.110 mysql_get_proto_info()

unsigned int mysql_get_proto_info(MYSQL *mysql)

2.3.111 Описание

Возвращает код версии протокола, используемой текущим подключением.

2.3.112 Возвращаемые значения

Целое число без знака, представляющее версию протокола, используемую текущим (актуальным) подключением.

2.3.113 Ошибки

Нет.

2.3.114 mysql_get_server_info()

char *mysql_get_server_info(MYSQL *mysql)

2.3.115 Описание

Возвращает строку, которая представляет номер версии сервера.

2.3.116 Возвращаемые значения

Символьная строка, которая представляет номер версии станции.

2.3.117 Ошибки

Нет.

2.3.118 mysql_info()

char *mysql_info(MYSQL *mysql)

2.3.119 Описание

Возвращает строку, обеспечивающую информацию относительно недавно выполненного запроса, но только для инструкций, перечисленных ниже. Для других инструкций 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 только, если много списков значений было определено в инструкции.

2.3.120 Возвращаемые значения

Символьная строка, представляющая дополнительную информацию относительно последнего выполненного запроса. NULL, если никакая информация не доступна для запроса.

2.3.121 Ошибки

Нет.

2.3.122 mysql_init()

MYSQL *mysql_init(MYSQL *mysql)

2.3.123 Описание

Распределяет или инициализирует объект MYSQL, подходящий для mysql_real_connect(). Если mysql является указателем NULL, функция распределяет память, инициализирует и возвращает новый объект. Иначе объект будет просто инициализирован, и адрес объекта возвращен. Если mysql_init() распределяет новый объект, место будет освобождено, когда будет вызвана mysql_close().

2.3.124 Возвращаемые значения

Инициализированный дескриптор MYSQL*. NULL, если недостаточно памяти, чтобы распределить и инициализировать новый объект.

2.3.125 Ошибки

В случае недостаточной памяти вернется NULL.

2.3.126 mysql_insert_id()

my_ulonglong mysql_insert_id(MYSQL *mysql)

2.3.127 Описание

Возвращает 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, и оно не будет сброшено между запросами потому, что значение этой функции поддерживается сервером.

2.3.128 Возвращаемые значения

Значение поля AUTO_INCREMENT, которое модифицировалось предыдущим запросом. 0, если не имелось никакого предыдущего запроса на подключении, или если запрос не модифицировал AUTO_INCREMENT.

2.3.129 Ошибки

Нет.

2.3.130 mysql_kill()

int mysql_kill(MYSQL *mysql, unsigned long pid)

2.3.131 Описание

Просит, чтобы сервер уничтожил поток, определенный как pid.

2.3.132 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если произошла ошибка.

2.3.133 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.134 mysql_list_dbs()

MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)

2.3.135 Описание

Возвращает набор результатов, состоящий из имен баз данных на сервере, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем базам данных. Вызов mysql_list_dbs() подобен выполнению запроса SHOW databases [LIKE wild].

Вы должны освободить набор результатов с помощью mysql_free_result().

2.3.136 Возвращаемые значения

Набор результатов MYSQL_RES для успеха, NULL, если произошла ошибка.

2.3.137 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_OUT_OF_MEMORY
Не хватило памяти.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.138 mysql_list_fields()

MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)

2.3.139 Описание

Возвращает набор результатов, состоящий из имен полей в данной таблице, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем полям. Вызов mysql_list_fields() подобен выполнению запроса SHOW COLUMNS FROM tbl_name [LIKE wild].

Обратите внимание, что рекомендуется, чтобы Вы использовали SHOW COLUMNS FROM tbl_name вместо mysql_list_fields().

Вы должны освободить набор результатов с помощью mysql_free_result().

2.3.140 Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если произошла ошибка.

2.3.141 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.142 mysql_list_processes()

MYSQL_RES *mysql_list_processes(MYSQL *mysql)

2.3.143 Описание

Возвращает набор результатов, описывающий текущие потоки сервера. Это тот же самый вид информации, что и сообщаемый командой mysqladmin processlist или запросом SHOW PROCESSLIST.

Вы должны освободить набор результатов с помощью mysql_free_result().

2.3.144 Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если произошла ошибка.

2.3.145 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.146 mysql_list_tables()

MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)

2.3.147 Описание

Возвращает набор результатов, состоящий из имен таблиц в текущей базе данных, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или может быть NULL, чтобы соответствовать всем таблицам. Вызов mysql_list_tables() подобен выполнению запроса SHOW tables [LIKE wild].

Вы должны освободить набор результатов с помощью mysql_free_result().

2.3.148 Возвращаемые значения

Набор результатов MYSQL_RES для успеха. NULL, если произошла ошибка.

2.3.149 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.150 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).

2.3.151 Описание

Возвращает число столбцов в наборе результатов.

Обратите внимание, что Вы можете получать число столбцов из указателя набора результатов или от дескриптора подключения. Вы используете дескриптор подключения, если mysql_store_result() или mysql_use_result() возвращает NULL (и таким образом Вы не имеете никакого указателя набора результата). В этом случае Вы можете вызывать mysql_field_count() чтобы определить, должен или нет mysql_store_result() произвести непустой результат. Это позволяет программе пользователя выбрать соответствующее действие без того, чтобы знать, был или нет запрос SELECT (или SELECT-подобным). Пример, показанный ниже иллюстрирует, как это может быть выполнено.

2.3.152 Возвращаемые значения

Целое число без знака, представляющее число полей в наборе результатов.

2.3.153 Ошибки

Нет.

2.3.154 Пример

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.

2.3.155 mysql_num_rows()

my_ulonglong mysql_num_rows(MYSQL_RES *result)

2.3.156 Описание

Возвращает число строк в наборе результатов.

Использование mysql_num_rows() зависит от того, используете ли Вы mysql_store_result() или mysql_use_result(), чтобы получить набор результатов. Если Вы используете mysql_store_result(), mysql_num_rows() может быть вызван немедленно. Если Вы используете mysql_use_result(), mysql_num_rows() не будет возвращать правильное значение, пока все строки в наборе результатов не будут получены.

2.3.157 Возвращаемые значения

Число строк в наборе результатов.

2.3.158 Ошибки

Нет.

2.3.159 mysql_options()

int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)

2.3.160 Описание

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

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_COMMANDchar * Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически выполнена при повторном соединении.
MYSQL_READ_DEFAULT_FILEchar * Читать параметры из указанного файла опций вместо my.cnf.
MYSQL_READ_DEFAULT_GROUPchar * Читать параметры из именованной группы из файла опций 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 будет все еще работать некоторое время для совместимости.

2.3.161 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если Вы использовали неизвестную опцию.

2.3.162 Пример

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.

2.3.163 mysql_ping()

int mysql_ping(MYSQL *mysql)

2.3.164 Описание

Проверяет работает или нет подключение. В случае неработоспособности будет предпринято автоматическое переподключение.

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

2.3.165 Возвращаемые значения

Ноль, если подключение работает. Отличное от нуля, если произошла ошибка.

2.3.166 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.167 mysql_query()

int mysql_query(MYSQL *mysql, const char *query)

2.3.168 Описание

Выполняет запрос SQL, указанный строкой с нулевым символом в конце. Запрос должен состоять из одиночной инструкции SQL. Вы не должны добавлять точку с запятой (;) или \g для завершения запроса.

mysql_query() не может использоваться для запросов, которые содержат двоичные данные, взамен Вы должны использовать mysql_real_query(). Двоичные данные могут содержать в себе символ \0, который mysql_query() интерпретирует как конец строки запроса.

Если Вы хотите знать, возвратил ли запрос набор результатов или нет, Вы можете использовать mysql_field_count(), чтобы проверить это. Подробности в разделе "2.3.85 mysql_field_count()".

2.3.169 Возвращаемые значения

Ноль, если запрос был успешен. Отличное от нуля, если произошла ошибка.

2.3.170 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.171 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)

2.3.172 Описание

mysql_real_connect() пытается установить подключение с сервером MySQL, запущенным на машине host. mysql_real_connect() должен завершиться успешно прежде, чем Вы сможете выполнить любую из других функций API, за исключением mysql_get_client_info().

Параметры определены следующим образом:

2.3.173 Возвращаемые значения

Дескриптор MYSQL*, если подключение было успешно, NULL, если подключение было неудачно. Для успешного подключения, значение возврата: такое же, как значение первого параметра, если Вы не передаете NULL для этого параметра.

2.3.174 Ошибки

CR_CONN_HOST_ERROR
Не удалось связаться с сервером.
CR_CONNECTION_ERROR
Не удалось связаться с локальным сервером.
CR_IPSOCK_ERROR
Не удалось создать IP-сокет.
CR_OUT_OF_MEMORY
Не хватило памяти.
CR_SOCKET_CREATE_ERROR
Не удалось создать Unix-сокет.
CR_UNKNOWN_HOST
Не удалось найти IP-адрес для hostname.
CR_VERSION_ERROR
Несоответствие протоколов следовало из попытки соединиться с сервером с помощью клиентской библиотеки, которая использует иную версию протокола. Это может случиться, если Вы используете очень старую библиотеку, чтобы соединиться с новым сервером, который не был запущен с параметром --old-protocol.
CR_NAMEDPIPEOPEN_ERROR
Не удалось создать именованный канал в Windows.
CR_NAMEDPIPEWAIT_ERROR
Не удалось дождаться именованного канала в Windows.
CR_NAMEDPIPESETSTATE_ERROR
Не удалось получить дескриптор для именованного канала в Windows.
CR_SERVER_LOST
Если connect_timeout> 0 и требуется более, чем connect_timeout секунд, чтобы соединиться с сервером, или если сервер свалился при выполнении init-command, вернется это.

2.3.175 Пример

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. Этот флажок указывает, что когда запрос не может выполниться из-за потерянного подключения, надо попробовать повторно соединиться с сервером перед отказом.

2.3.176 mysql_real_escape_string()

unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)

2.3.177 Описание

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

Строка в from бужет закодирована до экранированной строки SQL, принимая во внимание текущий (актуальный) набор символов подключения. Результат будет помещен в to и завершающий байт пустого указателя допишется автоматически. Символы NUL (ASCII 0), \n, \r, \, ', ", а также Control-Z, будуь экранированы.

Строка, указанная в from должна быть length байтов длины. Вы должны распределить буфер по крайней мере length*2+1 байт. В худшем случае каждый символ должен быть закодирован как использование двух байтов, и Вы нуждаетесь в участке памяти для завершающего байта пустого указателя. Когда mysql_escape_string() завершится, в to будет строка с нулевым байтом в конце. Значение возврата: длина закодированной строки, не включая символ завершения.

2.3.178 Пример

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(), но возвращает указатель на завершающий символ первого параметра.

2.3.179 Возвращаемые значения

Длина значения, помещенного в to, не включая нулевой символ завершения.

2.3.180 Ошибки

Нет.

2.3.181 mysql_real_query()

int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)

2.3.182 Описание

Выполняет запрос 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()".

2.3.183 Возвращаемые значения

Ноль, если запрос был успешным. Отличное от нуля, если произошла ошибка.

2.3.184 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.185 mysql_reload()

int mysql_reload(MYSQL *mysql)

2.3.186 Описание

Просит, чтобы сервер MySQL перезагрузил таблицы предоставления привилегий. Пользователь должен иметь привилегию reload.

2.3.187 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если произошла ошибка.

2.3.188 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.189 mysql_row_seek()

MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)

2.3.190 Описание

Устанавливает курсор строки на произвольную строку в наборе результатов запросов. Это требует, чтобы структура набора результата содержала весь результат запроса, так что mysql_row_seek() может использоваться в конъюнкции только с mysql_store_result(), но не с mysql_use_result().

Смещение должно быть значением, возвращенным из mysql_row_tell() для mysql_row_seek(). Это значение не просто номер строки, если Вы хотите перейти к строке внутри набора результатов, используйте mysql_data_seek().

2.3.191 Возвращаемые значения

Предыдущее значение курсора строки. Это значение может быть передано последующему обращению к mysql_row_seek().

2.3.192 Ошибки

Нет.

2.3.193 mysql_row_tell()

MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)

2.3.194 Описание

Возвращает текущую (актуальную) позицию курсора строки для последнего вызова mysql_fetch_row(). Это значение может использоваться как параметр для mysql_row_seek().

Вы должны использовать mysql_row_tell() только после mysql_store_result(), но не после mysql_use_result().

2.3.195 Возвращаемые значения

Текущее (актуальное) смещение курсора строки.

2.3.196 Ошибки

Нет.

2.3.197 mysql_select_db()

int mysql_select_db(MYSQL *mysql, const char *db)

2.3.198 Описание

Заставляет базу данных, определенную через db, стать заданной по умолчанию базой данных на подключении, определенном в mysql. В последующих запросах эта база данных будет значением по умолчанию для ссылок на таблицы, которые не включают явный спецификатор базы данных.

mysql_select_db() терпит неудачу, если связанный пользователь не имеет прав доступа, чтобы использовать базу данных.

2.3.199 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если произошла ошибка.

2.3.200 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.201 mysql_shutdown()

int mysql_shutdown(MYSQL *mysql)

2.3.202 Описание

Выключает сервер. Связанный пользователь должен иметь привилегии закрытия системы (shutdown).

2.3.203 Возвращаемые значения

Ноль для успеха. Отличное от нуля, если произошла ошибка.

2.3.204 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.205 mysql_stat()

char *mysql_stat(MYSQL *mysql)

2.3.206 Описание

Возвращает символьную строку, содержащую информацию, подобную обеспечиваемой командой mysqladmin status. Это включает uptime в секундах, число работающих потоков, количество запросов, перезагрузок и открытых таблиц.

2.3.207 Возвращаемые значения

Символьная строка, описывающая состояние сервера. NULL, если произошла ошибка.

2.3.208 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.209 mysql_store_result()

MYSQL_RES *mysql_store_result(MYSQL *mysql)

2.3.210 Описание

Вы должны вызвать 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() как только Вы закончите работу с данным набором результатов.

2.3.211 Возвращаемые значения

Структура MYSQL_RES с результатами. NULL, если произошла ошибка.

2.3.212 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_OUT_OF_MEMORY
Не хватило памяти.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.3.213 mysql_thread_id()

unsigned long mysql_thread_id(MYSQL *mysql)

2.3.214 Описание

Возвращает ID потока текущего (актуального) подключения. Это значение может использоваться как параметр для mysql_kill(), чтобы уничтожить этот поток.

Если подключение потеряно, и Вы повторно соединяетесь через mysql_ping(), ID потока изменится. Это означает, что Вы не должны получить ID потока и хранить его. Надо получать ID по мере надобности.

2.3.215 Возвращаемые значения

ID потока текущего (актуального) подключения.

2.3.216 Ошибки

Нет.

2.3.217 mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)

2.3.218 Описание

Вы должны вызвать 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() как только Вы закончили с этим набором результатов.

2.3.219 Возвращаемые значения

Структура MYSQL_RES. NULL, если произошла ошибка.

2.3.220 Ошибки

CR_COMMANDS_OUT_OF_SYNC
Команды были выполнены в неподходящем порядке.
CR_OUT_OF_MEMORY
Не хватило памяти.
CR_SERVER_GONE_ERROR
Сервер MySQL занят.
CR_SERVER_LOST
Подключение было потеряно в течение запроса.
CR_UNKNOWN_ERROR
Произошла неизвестная ошибка.

2.4 Описание поточных функций C

Вы должны использовать следующие функции, когда Вы хотите создавать поточного клиента. Подробности в разделе "2.8 Как делать поточного клиента".

2.4.1 my_init()

2.4.2 Описание

Эта функция должна быть вызвана однажды в программе перед вызовом любой функции MySQL. Это инициализирует некоторые глобальные переменные. Если Вы используете поточно-безопасную библиотеку клиентов, это также вызовет для этого потока функцию mysql_thread_init().

Это автоматически вызвано функциями mysql_init(), mysql_server_init() и mysql_connect().

2.4.3 Возвращаемые значения

Нет.

2.4.4 mysql_thread_init()

2.4.5 Описание

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

Это автоматически вызвано my_init() и mysql_connect().

2.4.6Возвращаемые значения

Нет.

2.4.7 mysql_thread_end()

2.4.8 Описание

Эта функция должна быть вызвана перед вызовом pthread_exit(), чтобы освободить память, распределенную в mysql_thread_init().

Обратите внимание, что эта функция не вызывается автоматически библиотекой. Это должно быть вызвано явно, чтобы избежать утечки памяти.

2.4.9 Возвращаемые значения

Нет.

2.5 Описание C-функций встроенного сервера

Вы должны использовать следующие функции, если Вы хотите, чтобы в Вашей прикладной программе была функциональность встроенного сервера MySQL. Подробности в разделе "2.9 libmysqld, библиотека встроенного сервера MySQL ".

Если программа скомпонована с -lmysqlclient вместо -lmysqld, эти функции не делают ничего. Это делает возможным выбирать между использованием встроенного и автономного сервера без изменения какого-либо кода.

2.5.1 mysql_server_init()

void mysql_server_init(int argc, const char **argv, const char **groups)

2.5.2 Описание

Эта функция должна быть вызвана в программе перед вызовом любой другой функции MySQL. Она запускает сервер и инициализирует все подсистемы (mysys, InnoDB и т.д.), используемые сервером. Если эта функция не была вызвана, программа разрушится.

Параметры argc и argv аналогичны параметрам main(). Первый элемент argv игнорируется (он обычно содержит имя программы). Для удобства argc может быть 0, если не имеется никаких параметров командной строки сервера.

Завершаемый символом NULL список строк в groups задает то, какие группы в файле опций будут активны. Для удобства groups может быть NULL, тогда будет активна группа [server].

2.5.3 Пример

#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;
}

2.5.4 Возвращаемые значения

Нет.

2.5.5 mysql_server_end()

2.5.6 Описание

Эта функция должна быть вызвана в программе, в конце. Она завершает сервер.

2.5.7 Возвращаемые значения

Нет.

2.6 Общие вопросы и проблемы при использовании C API

2.6.1 Почему при успехе mysql_query() вызов mysql_store_result() иногда возвращает NULL?

Когда это случается, это означает, что одно из следующего произошло:

Вы можете всегда проверить, должна или нет инструкция произвести непустой результат, вызывая mysql_field_count(). Если mysql_field_count() вернет ноль, результат пуст, и последний запрос был инструкцией, которая не возвращает значения (например, INSERT или DELETE). Если mysql_field_count() вернет не ноль, инструкция должна была произвести не пустой результат.

Вы можете проверить наличие ошибки вызовом mysql_error() или mysql_errno().

2.6.2 Какой результат я могу получить из запроса?

В дополнение к набору результатов, возвращенному запросом, Вы можете также получать следующую информацию:

2.6.3 Как я могу получить уникальный ID для последней вставленной строки?

Если Вы вставляете запись в таблицу, содержащую столбец, который имеет атрибут 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

2.6.4 Проблемы компоновки с C API

При компоновке с 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 к концу строки для компоновки.

2.7 Построение клиентских программ

Если Вы компилируете MySQL клиентуру, которую вы написали самостоятельно или получили от третьего лица, программы должны быть скомпонованы, используя опцию -lmysqlclient -lz. Вы также должны определить опцию -L, чтобы сообщить компоновщику, где найти библиотеку. Например, если библиотека установлена в /usr/local/mysql/lib, используйте -L/usr/local/mysql/lib -lmysqlclient -lz на строке компоновки.

Для клиентуры, которая использует файлы заголовков MySQL, Вы должны определить опцию -I, когда Вы компилируете их (например, -I/usr/local/mysql/include), чтобы транслятор смог найти файлы.

2.8 Как делать поточные клиенты

Самая большая проблема состоит в том, что подпрограммы в 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, но не создал подключение к базе данных MySQL:

Когда Вы вызываете mysql_init() или mysql_connect(), MySQL создаст специфические переменные для потока, которые используются библиотекой отладки.

Если Вы имеете в потоке вызов функции MySQL прежде, чем поток вызвал mysql_init() или mysql_connect(), поток не будет иметь необходимых специфических переменных, и Вы, вероятно, свалите программу в дамп рано или поздно (скорее рано, чем поздно). Чтобы работать спокойно, надо предпринять следующее:

  1. Вызовите my_init() в начале Вашей программы, если она вызывает любую другую функцию MySQL, перед вызовом mysql_real_connect().
  2. Вызовите mysql_thread_init() в драйвере потока перед вызовом любой функции MySQL.
  3. В потоке вызовите mysql_thread_end() перед вызовом pthread_exit(). Это освободит память, используемую специфическими переменными MySQL.

Вы можете получать некоторые ошибки из-за неопределенных символов при компоновке Вашего клиента с mysqlclient_r. В большинстве случаев это потому, что Вы не включили библиотеки потоков в строку компоновки.

2.9 libmysqld, библиотека встроенного сервера MySQL

2.9.1 Обзор библиотеки встроенного сервера MySQL

Библиотека встроенного сервера MySQL делает возможным выполнить полнофункциональный сервер MySQL внутри прикладной программы. Основные выгоды: увеличивается быстродействие и упрощается управление.

2.9.2 Компиляция программ с libmysqld

В настоящее время, все библиотеки должны быть явно перечислены при компоновке с -lmysqld. В будущем mysql_config --libmysqld-libs назовет библиотеки, чтобы делать этот проще. Также, все библиотеки будут, вероятно, включены в libmysqld, чтобы упростить этот процесс еще сильнее.

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

2.9.3 Пример простого встроенного сервера

Эта программа должна работать без любых изменений на 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

2.9.4 Лицензирование встроенного сервера

Исходный текст MySQL охвачен GNU GPL. Один результат этого: любая программа, которая компонуется с libmysqld и с исходным текстом MySQL, должна быть выпущена как свободное программное обеспечение (согласно лицензии, совместимой с GPL).

Авторы поощряют каждого поддерживать свободное программное обеспечение, выпуская код под GPL или совместимой лицензией. Для тех, кто не способен делать это, есть другой вариант: они должны приобрести MySQL у MySQL AB согласно более свободной лицензии.


Глава 3. C++ API

3.1. Mysql++. Введение

3.1.1 Что такое Mysql++

Mysql++ представляет собой полноценный C++ API для Mysql (а в скором времени и для других баз данных на SQL также). Цель этого API: сделать работу с запросами столь же простой, как работа с другими STL Контейнерами

3.1.2 Получение Mysql++

Последняя версия Mysql++ лежит на web-сайте mysql++ по адресу http://www.mysql.com/download_mysql++.html

3.1.3 Список рассылки Mysql++

Инструкции по присоединению к списку рассылки (и архив списка рассылки) могут быть найдены на домашней страничке Mysql++ по адресу http://www.mysql.com/download_mysql++.html. Если Вы желаете только задать вопрос, можете писать на mysql-plusplus@lists.mysql.com.


3.2. Обзор

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.

3.3. Важные изменения

3.3.1 Текущие изменения

3.3.2 Что планируется сделать

3.4. Руководство по примерам

3.4.1 Введение

Это описание, как предполагается, дает Вам начало использования Mysql++ API. Пакет этот сложный, с большим количеством свойств, так что начните с чего-то простого.

3.4.2 Предположения

Этот учебник предполагает, что Вы знаете C++ довольно хорошо. Считается, что Вы знакомы с исключениями и Standard Template Library (STL).

3.4.3 Запуск примеров

Все коды примеров формируют полные программы. Однако, чтобы использовать их, Вы должны сначала откомпилировать их, для чего перейдите в каталог с примерами и наберите там make. Затем Вы должны установить базу данных запуском reset-db. Параметры здесь такие:

reset-db [host [user [password]]]
Если Вы не указываете host, по умолчанию принимается localhost. Если Вы не указываете имя пользователя, по умолчанию принимается Ваше актуальное имя пользователя. Если Вы не указываете пароль, по умолчанию принимается, что Вы не нуждаетесь в нем.

Когда Вы выполняете программу, Вы должны иметь права доступа с разрешением создавать базы данных. Как только база данных создана, Вы можете использовать другие права доступа для полного доступа к базе данных mysql_cpp_data.

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

3.4.4 Основы

3.4.4.1 Простой пример

Следующий пример показывает, как открыть подключение, выполнить простой запрос и отобразить результаты. Код может быть найден в файле 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;
}

3.4.4.2 Немного более сложный пример

Этот пример почти подобен предыдущему, однако он использует исключительные ситуации и автоматическое свойство преобразования 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;
  }
}

Все должно быть довольно очевидно. Приведу лишь несколько примечаний относительно исключительных ситуаций:

    Когда флажок use_exceptions установлен для родительского объекта, он также установлен для всех потомков, созданных после того, как флажок был установлен. Например, когда флажок use_exceptions установлен для объекта con, он также установлено и для объекта query. Пожалуйста, обратите внимание, что флажок use_exceptions не компонуется, а копируется. Это означает, что, когда Вы изменяете флажок use_exceptions, это воздействует только на новые объекты, но не на старые.
  1. ColData будет всегда создавать исключительную ситуацию, когда сталкивается с плохим преобразованием. Плохое преобразование определено как преобразование в котором: a) Не все символы из строки читаются, и b) Символы после числа не точки (.), нули (0) или пробелы. Таким образом, когда ``1.25'' преобразован в int, исключительная ситуация будет создана, а вот при обработке ``1.00'' в int все будет в порядке, поскольку символы нуль и точка.

3.4.4.3 Получение информации о полях

Следующий пример показывает, как получить некоторую базисную информацию относительно полей, включая имя поля и тип 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;
  }
}

3.4.5 Специализированные структуры SQL

3.4.5.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 очень мощная штука.

3.4.5.2 Добавление данных

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 после работы примера.

3.4.5.3 Изменение данных

Очень просто изменять данные с помощью 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 после работы этого примера.

3.4.5.4 Less-Than-Comparable

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;
  }
}

3.4.6 Сделаем еще лучше

При начале разработки MySQl++ 1.6 авторы представили три новых примера, чья цель состоит в том, чтобы показать некоторых из самых сильных свойств MySQL++, а также обеспечить решение некоторых из наиболее частых проблем. Эти примеры иллюстрируют превосходство C++ над другими существующими языками.

Поскольку эти примеры предполагаются к активному использованию (и применяются многими пользователями), константы, которые могут отличаться в разных ситуациях, были сгруппированы, чтобы упростить редактирование. Также, все эти примеры содержат полную ошибку, проверяющую код. Это один из тех редких случаев, в которых обработка исключительной ситуации, принятая в С++, полностью применена в MySQL++.

3.4.6.1 Загрузка двоичного файла в столбец типа BLOB

Эта функция появилась в 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.4.6.1 Отображение картинок в HTML из столбцов типа BLOB

Этот пример также очень короткий. Рассмотрим функцию, которую он выполняет. Хотя с версии 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. Гибкое использование потоков допускает легкое использование этого кода во многих прикладных программах.

3.4.6.2 Удаление или модификация из Select

Об этом свойстве просят многие пользователи, но пока оно не сделано на уровне ядра СУБД, эта программа может использоваться вместо него. Это маленькая программка, которая также показывает некоторые свойства 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. Эта проверка должна быть добавлна.

3.4.6.2 Двинемся дальше

Это только общий обзор того, что SSQLS может делать. Для получения большего количества информации обратитесь к главе 3.7.

3.4.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;
  }
}

3.3.5. Обзор классов

Этот раздел документирует все классы для внешнего использования. Если некий класс не зарегистрирован здесь, не используйте кго, поскольку он представляет собой метод или класс для внутреннего пользования.

3.3.5.1 struct BadConversion

Используется для создания исключительной ситуации, когда происходит плохое преобразование.

Тип

instantiable

Включаемый файл

coldata1.hh

Описание

Методы public

3.5.2 class BadNullConversion

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

Тип

instantiable

Включаемый файл

null1.hh

3.5.3 class Connection

Основной обработчик базы данных.

Тип

instantiable

Включаемый файл

connection1.hh

Описание

Методы public

Методы Friend

3.5.4 struct Date

Специальный тип для хранения дат в формате mysql.

Тип

instantiable

Суперклассы

public mysql_date, public MysqlDTbase Date

Включаемый файл

datetime1.hh

Детальное описание

Date представляет собой структуру данных для хранения типов дат mysql. Используется в приеме потоков и операциях вставки.

Методы public

3.5.5 struct DateTime

Комбинация из Date и Time для хранения mysql-типа DateTime.

Тип

instantiable

Суперклассы

public mysql_date, public mysql_time, public MysqlDTbase DateTime

Включаемый файл

datetime1.hh

Описание

Методы public

3.5.6 class FieldNames

Вектор имен полей.

Тип

instantiable

Суперклассы

public vector string

Включаемый файл

field_names1.hh

Описание

Методы public

3.5.7 class FieldTypes

Вектор типов полей.

Тип

instantiable

Суперклассы

public vector mysql_type_info

Включаемый файл

field_types1.hh

Описание

Методы public

3.5.8 class Fields

Вектор, подобный контейнеру с чистыми данными mysql о поле.

Тип

instantiable

Суперклассы

public const_subscript_container Fields, Field

Включаемый файл

fields1.hh

Описание

Методы public

3.5.9 template class MysqlCmp class BinaryPred, class CmpТип

Тип

instantiable

Суперклассы

public unary_function const MysqlRow&, bool

Включаемый файл

compare1.hh

Описание

Методы public

Методы Protected

3.5.10 template class MysqlCmpCStr class BinaryPred

Тип

instantiable

Суперклассы

public MysqlCmp BinaryPred, const char *

Включаемый файл

compare1.hh

Описание

Методы public

3.5.11 template struct MysqlDTbase class T

Тип

abstract

Включаемый файл

datetime1.hh

Методы public

3.5.12 template class MysqlListInsert class T, class value_type = typename T::value_type

Тип

instantiable

Включаемый файл

set1.hh

Методы public

3.5.13 template class MysqlSetInsert class T, class key_type = typename T::key_Тип

Тип

instantiable

Включаемый файл

set1.hh

Методы public

3.5.14 template class Null class Type, class Behavior = NullisNull

Контейнерный класс для хранения типов с поддержкой null.

Тип

instantiable

Включаемый файл

null1.hh

Методы public

3.5.15 struct NullisBlank

Тип нужный, чтобы использовать для параметра поведения для Null.

Тип

instantiable

Включаемый файл

null1.hh

Описание

Методы public

3.5.16 struct NullisNull

Тип нужный, чтобы использовать для параметра поведения для Null.

Тип

instantiable

Включаемый файл

null1.hh

Описание

Методы public

3.5.17 struct NullisZero

Тип нужный, чтобы использовать для параметра поведения для Null.

Тип

instantiable

Включаемый файл

null1.hh

Описание

Методы public

3.5.18 class Query

Класс для выполнения запросов.

Тип

instantiable

Суперклассы

public SQLQuery

Включаемый файл

query1.hh

Детальное описание

Этот класс подклассифицируется из SQLQuery. Этот класс в отличие от SQLQuery свободно присоединен к объекту Mysql так, чтобы он мог выполнять запросы.

Описание

Методы public

3.5.19 struct ResNSel

Эта структура хранит информацию относительно успеха запросов, которые не возвращают наборы результатов.

Тип

instantiable

Включаемый файл

result1.hh

Описание

Методы public

3.5.20 class ResUse

Тип

instantiable

Включаемый файл

result1.hh

Описание

Методы public

Методы protected

Методы friend

3.5.21 class Result

Этот класс обрабатывает набор результатов.

Тип

instantiable

Суперклассы

public ResUse, public const_subscript_container Result,Row,const Row

Включаемый файл

result1.hh

Подробное описание

Это также Random Access Container, который не LessThanComparable и не Assignable. Будучи контейнером произвольного доступа (Random Access Container), это может возвращать Random Access Iterator или обратный Random Access Iterator.

Методы public

Методы Friend

3.5.22 class Row

Этот класс обрабатывает фактические строки интеллектуальным способом.

Тип

instantiable

Суперклассы

public const_subscript_container Row,ColData,const ColData, public RowTemplate Row, ResUse

Включаемый файл

row1.hh

Методы public

3.5.23 template class RowTemplate class ThisType, class Res

Тип

abstract

Включаемый файл

row1.hh

Методы public

Методы protected

3.5.24 struct SQLParseElement

Тип

instantiable

Включаемый файл

sql_query1.hh

Описание

Методы public

3.5.25 class SQLQuery

Чистый класс запроса.

Тип

instantiable

Суперклассы

public strstream

Включаемый файл

sql_query1.hh

Подробное описание

Это чистый класс запроса. Он используется для того, чтобы формировать запросы, которые планируется послать объекту Connection. Класс Query может использоваться, если Вы желаете также выполнить запросы без того, чтобы посылать их объекту Connection.

Этот класс подклассифицируется из strstream. Это означает, что Вы можете писать в него подобно потоку, чтобы избежать необходимости создавать свой strstream или применять sprintf. Хотя Вы можете читать из запроса (потому, что это поток), это не рекомендуется. Я не могу гарантировать предсказуемость класса. Однако, можно использовать любой из методов потока, чтобы писать в него. Только удостоверьтесь, что буферные точки Вашего запроса записаны прежде, чем Вы попробуете использовать любой из специфических методов SQLQuery, кроме error() и success().

Методы public

Методы Protected

Методы Friend

3.5.26 struct SQLQueryNEParms

Исключительная ситуация, когда не задано достаточно параметров.

Тип

instantiable

Включаемый файл

sql_query1.hh

Подробное описание

Возникает, когда не задано достаточно параметров для шаблона запроса.

Методы public

3.5.27 class SQLQueryParms

Этот класс хранит значения параметров для заполнения шаблонов запроса.

Тип

instantiable

Суперклассы

public vector SQLString

Включаемый файл

sql_query1.hh

Подробное описание

Это подкласс вектора SQLStrings.

Методы public

Методы friend

3.5.28 class SQLString

Специальная строка, которая преобразуется из чего-либо.

Тип

instantiable

Суперклассы

public string

Включаемый файл

sql_string1.hh

Подробное описание

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

Методы public

3.5.29 template class Set class Container = set string

Специальный набор для хранения множеств в формате mysql.

Тип

instantiable

Суперклассы

public Container

Включаемый файл

set1.hh

Методы public

3.5.30 struct Time

Специальный тип для хранения времени в формате mysql.

Тип

instantiable

Суперклассы

public mysql_time, public MysqlDTbase Time

Включаемый файл

datetime1.hh

Подробное описание

Структура предназначена для хранения данных из типа Time. Она также используется при извлечении потока и в операторе insert.

Методы public

3.5.31 class const_string

Специальная строка, которая создана из существующей const char *.

Тип

instantiable

Включаемый файл

const_string1.hh

Подробное описание

Содержит маленькое подмножество стандартного класса string. Когда объект создан, будет создана только связь с const char *. Данные не будут скопированы. Таким образом, const char * должна существовать все время использования данного класса.

Методы public

3.5.32 template class const_subscript_container class OnType, class ValueType, class ReturnType = const ValueType&, class SizeType = unsigned int, class DiffType = int

Адаптер контейнера, чтобы сделать контейнер контейнером произвольного доступа (Random Access Container).

Тип

abstract

Включаемый файл

resiter1.hh

Подробное описание

Требования: контейнер имеет определенные функции-члены *operator[] (SizeType)* и *size()*.

Методы public

3.5.33 struct cstr_equal_to

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Методы public

3.5.34 struct cstr_greater

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Методы public

3.5.35 struct cstr_greater_equal

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Методы public

3.5.36 struct cstr_less

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Методы public

3.5.37 struct cstr_less_equal

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Методы public

3.5.38 struct cstr_not_equal_to

Тип

instantiable

Суперклассы

bin_char_pred

Включаемый файл

compare1.hh

Описание

Методы public

3.5.39 struct do_nothing_type1

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.40 struct do_nothing_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.41 template struct equal_list_b class Seq1, class Seq2, class Manip

Тип

instantiable

Включаемый файл

vallist1.hh

Методы public

3.5.42 template struct equal_list_ba class Seq1, class Seq2, class Manip

Тип

instantiable

Включаемый файл

vallist1.hh

Методы public

3.5.43 struct escape_type1

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.44 struct escape_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.45 struct ignore_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.46 template class mysql_ColData class Str

Основной класс для автопреобразований данных столбца. Не используйте непосредственно.

Тип

instantiable

Суперклассы

public Str

Включаемый файл

coldata1.hh

Подробное описание

Интеллектуальная строка. Это автоматически преобразуется в любой из базисных типов C. Когда используется с двоичными операторами, она автоматически преобразуется в тип, используемый с другой стороны оператора, если это базисный тип. Однако, будьте внимательным при использовании этого с двоичными операторами, так как MysqlStr("12.86")+2 вернет 14, поскольку 2 является целым числом. Если это мешает, определите макрос NO_BINARY_OPERS для отмены такого поведения. Этот класс также имеет некоторую базисную информацию относительно типа данных, сохраненных в нем. Не используйте этот класс непосредственно. Используйте вместо этого typedef ColData или MutableColData.

Методы public

3.5.47 class mysql_convert

Тип

instantiable

Включаемый файл

convert1.hh

3.5.48 struct mysql_date

Тип

instantiable

Суперклассы

virtual public mysql_dt_base

Включаемый файл

datetime1.hh

Методы public

Методы protected

3.5.49 struct mysql_dt_base

Тип

abstract

Включаемый файл

datetime1.hh

Методы public

3.5.50 class mysql_ti_sql_type_info

Тип

instantiable

Включаемый файл

type_info1.hh

Методы friend

3.5.51 class mysql_ti_sql_type_info_lookup

Тип

instantiable

Включаемый файл

type_info1.hh

Методы friend

3.5.52 struct mysql_time

Тип

instantiable

Суперклассы

virtual public mysql_dt_base

Включаемый файл

datetime1.hh

Методы public

Методы protected

3.5.53 class mysql_type_info

Класс, который хранит базисную информацию типа для ColData.

Тип

instantiable

Включаемый файл

type_info1.hh

Описание

Методы public

3.5.54 class null_type

Тип

instantiable

Включаемый файл

null1.hh

Методы public

3.5.55 struct quote_double_only_type1

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.56 struct quote_double_only_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.57 struct quote_only_type1

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.58 struct quote_only_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.59 struct quote_type1

Тип

instantiable

Включаемый файл

manip1.hh

Описание

Методы public

3.5.60 struct quote_type2

Тип

instantiable

Включаемый файл

manip1.hh

Методы public

3.5.61 template class simp_list_b class Iter

Тип

instantiable

Включаемый файл

vallist1.hh

Методы public

3.5.62 template class subscript_iterator class OnType, class ReturnType, class SizeType, class DiffТип

Тип

instantiable

Суперклассы

public random_access_iterator ReturnType, SizeType

Включаемый файл

resiter1.hh

Методы public

3.5.63 struct type_info_cmp

Тип

instantiable

Включаемый файл

type_info1.hh

Методы public

3.5.64 template struct value_list_b class Seq, class Manip

Тип

instantiable

Включаемый файл

vallist1.hh

Методы public

3.5.65 template struct value_list_ba class Seq, class Manip

Тип

instantiable

Включаемый файл

vallist1.hh

Методы public

3.5.66 Манипуляторы

Следующие манипуляторы изменяют только следующий элемент направо от них в цепочке <<. Они могут использоваться с любым ostream (который включает SQLQuery и Query, поскольку они также ostream) или с SQLQueryParms. Когда используются с SQLQueryParms, они отменят любой набор параметров настройки шаблона запросов для этого элемента.

quote
Цитирует и экранирует следующий элемент. Может использоваться с ostream или с SQLQueryParms.
quote_only
Цитирует, но не экранирует следующий элемент. Может использоваться с ostream или с SQLQueryParms.
quote_only_double
Цитирует, но не экранирует следующий элемент. Использует `` вместо '.
escape
Экранирует следующий элемент.
do_nothing
Не делает ничего. Используется как фиктивный манипулятор, когда надо применить некоторый манипулятор. Когда используется с SQLQueryParms, всегда удостоверится, что это не перекрывает параметры шаблона запросов.
ignore
Используется только с SQLQueryParms. Подобен do_nothing, но не будет отменять набор форматирований шаблона запросов.
Начиная с версии 1.6, автоматическое цитирование и экранирование были добавлены в манипуляторы. Этот механизм применяется только к mysql_ColData. Автоматическое цитирование или экранирование используется только с оператором <<, и во всех классах, полученных потоками, объектах, включая strstream, а также в объектах запросов. Исключение составляют потоки cout, cerr и clog. Это было разработано именно так преднамеренно, поскольку внешние (для этих потоков) переменные не требует цитирования или экранирования. Но это свойство удобно при создании объекта запроса или объекта класса strstream.

Это свойство можно выключить, установив в Вашем коде переменную dont_quote_auto в значение true.

3.6. Шаблоны запросов

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

3.6.1 Установка

Чтобы установить шаблон запроса, просто создайте обычным порядком нормальный запрос, например:

query << "select (%2:field1, %3:field2)
      from stock where %1: wheref = %q0:what"
А затем выполните метод Query::parse(). Например:
query.parse()

3.6.2 Формат шаблонов

Шаблон выглядит примерно так:

select (%2:field1, %3:field2) from stock where %1:wheref = %q0:what

Числа представляют номер элемента в структуре SQLQueryParms (рассмотрена чуть ниже).

Формат параметров подстановки:

%(modifier)##(:name)(:)

Здесь Modifier может быть любым из следующего перечня:

%
Вывести знак "%".
""
"" Не делает ничего.
q
Это цитирует и экранирует строку, применяя для этого mysql_escape_string, если это строка, char *, или другие специфические для Mysql типы, которые должны всегда цитироваться.
Q
Цитирует, но не экранирует строку, исходя из тех же правил. Это может сэкономить немного времени, если Вы знаете, что строки никогда не будут нуждаться в экранировке спецсимволов.
r
Обязательно цитирует и экранирует, даже если это число.
R
Обязательно цитирует, но не экранирует, даже если это число.
## Представляет число длиной в две цифры.

``:name'' представляет собой факультативное имя, которое помогает в заполнении SQLQueryParms. Имя может содержать любые алфавитно-цифровые символы или символ подчеркивания. Если Вы используете имя, и должны ввести двоеточие, введите их два последовательно. Первый символ закончит имя, так что второй не будет обработан.

3.6.3 Задание параметров

Параметры могут заданы когда запрос выполнен, или раньше срока, используя заданные по умолчанию параметры.

3.6.3.1 При выполнении запроса

Чтобы определять параметры, когда Вы хотите выполнять запрос, просто используйте 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
Станет очевидным быстрее.

3.6.3.2 Использование значений по умолчанию

Вы можете также устанавливать параметры по одному посредством общего члена данных 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()

3.6.3.3 Комбинирование

Вы можете также объединять использование установки параметров во время выполнения и использование объекта 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")).

3.6.3.4 Обработка ошибок

Если по некоторым причинам Вы не определяли все параметры при выполнении запроса, и неопределенные параметры не имеют значений по умолчанию, заданных через объект def, объект запроса породит объект исключения SQLQueryNEParms. Вы можете выяснить, что же случилось, проверяя значение SQLQueryNEParms::string. Например:

query.def["field1"] = "item";
query.def["field2"] = "price";
Result res = query.store(1.25);
породит исключение SQLQueryNEParms по причине того, что wheref не был опеределен нигде.

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

3.7. Специализированные структуры SQL

Специализированные структуры SQL (Specialized SQL Structures, SSQLS) позволяют Вам создавать свои структуры для хранения данных для запросов mysql с дополнительными функциональными возможностями. Эти структуры никоим образом не связаны с контейнерами и типами из Standard Template Library (STL). Это именно структуры (structs). Каждый элемент члена сохранен под уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-то еще из STL, чтобы работать с индивидуальными структурами. Однако Вы можете использовать эти структуры как value_type для контейнеров STL.

3.7.1 sql_create_basic

Следующая команда создаст базисный запрос 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 представляет собой имя переменной для первого элемента и т.д.

3.7.2 sql_create_basic со сравнением

Вы можете также сделать структуру сравнимой, заменяя первый 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 переменных являются теми же самыми, то две структуры одинаковы.

3.7.3 sql_create_basic с расширенным конструктором

Последний ноль в последнем примере предназначен для создания другого конструктора. Замените этот ноль на 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&);
}

3.7.4 Основной формат sql_create_basic

Основной формат для sql_create_basic следующий:

sql_create_basic_#(NAME, CMP, CNST, TYPE1, ITEM1, ..., TYPE#, ITEM#)

3.7.5 sql_create_basic_c_order

Вы можете также определять альтернативный порядок, когда 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-м и так далее.

3.7.6 Основной формат sql_create_basic_c_order

Таким образом, общий формат для sql_create_basic такой:

sql_create_basic_c_order_#(NAME, CMP, CNST, TYPE1, ITEM1,
                           ORDER1, ... TYPE#, ITEM#, ORDER#)

3.7.7 sql_create

В дополнение к базисным структурам Вы можете устанавливать расширенные структуры, которые также имеют методы определенные, чтобы помочь в создании запросов и во вставке данных в таблицах. Например:

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.97
bool 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);
Произведет тот же самый запрос, что и в вышеупомянутом примере.

3.7.8 sql_create_c_names

Вы можете также определять альтернативные имена поля так:

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'

3.7.9 Основной формат sql_create_c_names

Основной формат таков:

sql_create_c_names_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ...
                     TYPE#, ITEM#, NAME#) 
Здесь NAME1 представляет собой имя первого поля. Все остальное так же, как и в формате sql_create_basic_c_order.

3.7.10 sql_create_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.

3.7.11 sql_create_complete

Вы можете также определять заказной порядок и заказные имена поля вместе. Основная форма такая:

sql_create_complete_#(NAME, CMP, CNST, TYPE1, ITEM1, NAME1, ORDER1, ...
                      TYPE#, ITEM#, NAME#, ORDER#)
Здесь все так же, как и в основном формате sql_create_c_order и sql_create_c_names.

3.7.12 Изменение имени таблицы

Вы не можете определять различные имена таблицы в фактическом макрообращении. Имя таблицы используется в SQLQuery::insert, replace и update. Однако Вы можете изменять заданное по умолчанию имя таблицы, которое является тем же самым, что и имя структуры, заменяя ссылку NAME::table() на другую const char *:

stock::table() = "in_stock"
Это заменит имя таблицы на "in_stock" в примерах, используемых во всем этом руководстве.

3.7.13 Наблюдение фактического кода

Увидеть фактический код, который используют макро вставки sql++pretty, довольно просто. Например так:

sql++pretty < test.cc | less

3.7.14 Добавление функциональных возможностей

Самый лучший способ добавлять функциональные возможности: через наследование. Даже при том, что Вы могли бы вставлять выводимый код из pretty.pl и изменять его, это не рекомендуется делать потому, что это не будет отражать будущие расширения.

3.7.15 Дополнительные замечания

Макрокоманды определены для структур длиной до 25 элементов. Если Вы должны использовать больше, надо изменить основной скрипт perl (custom.pl). Этот скрипт на perl используется, чтобы генерировать файл заголовка. Он никоим образом не пробует анализировать код на C++.

Файл заголовка, который строит скрипт custom.pl занимает около мегабайта. Однако, пожалуйста обратите внимание, что заголовочный файл (custom-macros.hh) включает ТОЛЬКО макрокоманды. Так что компилятор должен делать очень малый объем работ при чтении файла.

Также, все включенное макрообращением выполнено таким способом, что Вы можете безопасно включать макрокоманду в файл заголовка и не должны волноваться относительно двойных обращений к функции или чего-то подобного.

3.8. Длинные имена

По умолчанию Mysql++ API использует как короткие имена без префиксов Mysql или mysql_, так и их длинные версии уже с префиксами Mysql или mysql_. Если это вызывает проблемы, определите макрос MYSQL_NO_SHORT_NAMES перед включением mysql++. После этого в принудительном порядке будут использоваться исключительно длинные имена. Их соответствие коротким такое:
Короткое имя Длинное имя
BadQueryMysqlBadQuery
ConnectionMysqlConnection
ResNSelResNSel
ResUseResUse MysqlResUse
ResultMysqlRes
FieldMysqlField
FieldsMysqlFields
ResIterMysqlResIter
ResultIterMysqlResIter
RowMysqlRow
MutableRowMysqlMutableRow
FieldNamesMysqlFieldNames
QueryMysqlQuery
BadConversionMysqlBadConversion
ColDataMysqlColData
MutableColData MysqlMutableColData
quotemysql_quote
quote_onlymysql_quote_only
quote_double_only mysql_quote_double_only
escapemysql_escape
do_nothingmysql_do_nothing
ignoremysql_ignore
DateMysqDate
TimeMysqlTime
DateTimeMysqlDateTime
SetMysqlSet
NullMysqlNull
null_typemysql_null_type
nullmysql_null
NullisNullMysqlNullisNull
NullisZeroMysqlNullisZero
NullisBlankMysqlNullisBlank


Глава 4. Язык LUA

Справочное руководство по языку программирования Lua 4.0

4.1 Введение

4.1.1 Что такое Lua?

Сайт языка 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 может быть расширена, чтобы справиться с широким диапазоном различных областей, таким образом создавая настроенные языки программирования, совместно использующие синтаксические рамки.

4.1.2 Доступность

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.

4.1.3 Связь с авторами

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.

4.2 Среда и составные части

Все инструкции в 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 автоматически обнаруживает тип файла и действует соответственно.

4.3 Типы и тэги

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).

4.4 Язык

Этот раздел описывает лексику, синтаксис и семантику Lua.

4.4.1 Лексические соглашения в языке

Идентификатором в 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

4.4.2 Приведение

Lua обеспечивает некоторые автоматические преобразования между значениями во время выполнения. Любая арифметическая операция, примененная к строке, пробует преобразовывать эту строку в соответствующее число, следуя обычным правилам. Наоборот, всякий раз, когда используется число, а ожидается строка, это число будет преобразовано в строку в приемлемом формате. Формат выбран так, чтобы преобразование из числа в строку было таким, чтобы обратное преобразование из строки в число было точным. Таким образом, преобразование не обязательно генерирует хороший текст для некоторых чисел. Для полного управления тем, как числа будут преобразованы в строки, используйте функцию format (подробности в разделе 4.6.2).

4.4.3 Корректировка

Функции в Lua могут возвращать много значений. Потому, что не имеется никаких объявлений типа когда функция вызвана, система не знает, сколько значений вернется, или сколько параметры требуется. Следовательно, иногда список значений должен быть откорректирован во время выполнения к данной длине. Если имеется большее количество значений, чем необходимы, то лишние значения отбрасываются. Если имеется меньшее количество значений, чем необходимы, то список расширен добавлением потребного количества nil. Эта корректировка происходит в многократных назначениях (подробности в разделе 4.4.4.2) и в обращениях к функции (подробности в разделе 4.4.5.8).

4.4.4 Инструкции

Lua поддерживает почти стандартный набор инструкций, подобных таким же наборам на Pascal или C. Стандартные команды включают присваивание, контроль выполнения и вызовы процедур. Нестандартные команды включают конструкторы таблицы и объявления локальных переменных.

4.4.4.1 Блоки

Блоком является список инструкций. Синтаксически блок равен составной части (chunk):
block ::= chunk

Блок может быть явно разграничен:

stat ::= do block end
Явные блоки полезны, чтобы управлять областью видимости (контекстом) локальных переменных. Явные блоки также иногда используются, чтобы добавить возврат или разрывать инструкцию в середине другого блока.

4.4.4.2 Присваивания

Lua поддерживает такую удобную вещь, как многократные присваивания. Следовательно, синтаксис определяет список переменных с левой стороны и список выражений с правой сторона. Элементы в обоих списках отделяются запятыми:
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 | functioncall
varorfunc должен иметь в качестве результата значение из таблицы, где поле, индексированное значением выражения 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 используется только для объяснительных целей).

4.4.4.3 Структуры управления

Структуры управления if, while и repeat имеют обычное значение и знакомый синтаксис:
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 ::= break
break заканчивает самый внутренний вложенный цикл (while, repeat или for).

По синтаксическим причинам инструкции return и break могут быть написаны только как последние инструкции блока. Если действительно необходимо вставить их в середину, надо применить явный внутренний блок, например, do return end потому, что теперь return в самом деле последняя инструкция во внутреннем блоке.

4.4.4.4 Инструкция For

Инструкция 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
Обратите внимание на следующее:

Таблица для инструкции 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
Обратите внимание на следующее:

4.4.4.5 Обращения к функции как инструкции

Из-за возможных побочных эффектов, обращения к функции могут быть выполнены как инструкции:
stat ::= functioncall
В этом случае все возвращенные значения утрачены. Обращения к функции объясняются в разделе 4.4.5.8.

4.4.4.6 Локальные объявления

Локальные переменные могут быть объявлены где-нибудь внутри блока. Объявление может включать начальное присваивание:
stat ::= local declist [init]
declist ::= name {`,' name}
init ::= `=' explist1
Если представлено начальное назначение, то оно имеет ту же самую семантику многократного назначения. Иначе все переменные инициализированы nil.

Сhunk также блок, так что локальные переменные могут быть объявлены снаружи любого явного блока.

Область действия (контекст) локальных переменных начинается после объявления и продолжается до конца блока. Таким образом, код local print=print создает локальную переменную, названную print, чье начальное значение будет взято из глобальной переменной с тем же самым именем.

4.4.5 Выражения

4.4.5.1 Базисные выражения

Базисные выражения в 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.5.2 Арифметические операторы

Lua поддерживает комплект обычных арифметических операторов: двоичный + (сложение), - (вычитание), * (умножение), / (деление), ^ (возведение в степень), а также унарный - (обращение знака числа). Если операнды числа или строки, которые могут быть преобразованы в числа, (согласно правилам, данным в разделе 4.4.2), то все операции за исключением возведения в степень имеют обычное значение. Иначе будет вызван соответствующий метод тэга. Возведение в степень всегда вызывает метод тэга. Стандартная математическая библиотека переопределяет этот метод для чисел, давая ожидаемое значение (подробности в разделе 4.6.3).

4.4.5.3 Реляционные операторы

Реляционные операторы в Lua:
==    ~=    <     >     <=    >=
Эти операторы возвращают nil как ложь, или любое другое значение (но не nil) в качестве истины.

Равенство (==) сначала сравнивает тэги операндов. Если они различны, то результатом будет nil. Иначе сравниваются их значения. Числа и строки сравниваются обычным способом. Таблицы, userdata, и функции сравниваются как ссылки, то есть две таблицы рассматриваются равными только, если они реально та же самая таблица. Оператор ~= прямо противоположен оператору равенства (==).

Правила преобразования из раздела 4.4.2 НЕ применяются к сравнениям равенства. Таким образом, "0"==0 вернет false, а t[0] и t["0"] обозначают различные записи в таблице.

Операторы порядка работают следующим образом. Если оба параметра числа, то они сравниваются также. Иначе, если оба параметра строки, то их значения сравниваются, используя лексикографический порядок. Во всех остальных ситуациях будет вызван метод lt тэга (подробности в разделе 4.4.8).

4.4.5.4 Логические операторы

Логические операторы в Lua:
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.

4.4.5.5 Объединения

Оператор объединения строк в Lua обозначен двумя точками (`..'). Если оба операнда строки или числа, они будут преобразованы в строки согласно правилам в разделе 4.2. Иначе будет вызван метод concat тэга.

4.4.5.6 Старшинство

Порядок старшинства в Lua следует из таблицы ниже. Операторы в ней перечислены в порядке от низкого к более высокому приоритету:
and   or
<     >     <=    >=    ~=    ==
..
+     -
*     /
not   - (unary)
^
Все двоичные операторы ассоциативны слева, кроме возведения в степень, который является ассоциативным справа. Прекомпилятор может перестраивать порядок оценки ассоциативных операторов (типа .. или +), пока эти оптимизация не изменяют нормальные результаты. Однако, эти оптимизация могут изменять некоторые результаты, если Вы определяете не ассоциативные методы тэгов для этих операторов.

4.4.5.7 Конструкторы таблиц

Конструкторы таблиц представляют собой выражения, которые создают таблицы: каждый раз конструктор оценен, и новая таблица создана. Конструкторы могут использоваться, чтобы создать пустые таблицы или создать таблицу и инициализировать некоторые из полей (необязательно все). Общий синтаксис для конструкторов:
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,}

4.4.5.8 Вызовы функций

Вызовы функций в Lua имеют синтаксис:
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()

4.4.5.9 Определение функций

Синтаксис для определения функций такой:

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.

4.4.6 Зона видимости и Upvalues

Функциональное тело может обратиться к собственным локальным переменным (которые включают и параметры), а также к глобальным переменным, пока они не затенены локальными переменными с тем же самым именем. Функция не может обращаться к локальной переменной из функции включения, так как такие переменные больше не могут существовать, когда функция вызвана. Однако, функция может обращаться к значению локальной переменной из функции включения, используя 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

4.4.7 Обработка ошибок

Поскольку 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).

4.4.8 Методы тэгов

Lua обеспечивает мощный механизм, чтобы расширить семантику, названный методами тэгов. Это определенная программистом функция, которая вызвана в специфических точках в течение выполнения программы Lua, позволяя программисту изменить стандартное поведение Lua в этих точках. Каждая из этих точек названа событием (event).

Метод тэга для некоего специфического события выбран согласно тэгу значения. Функция settagmethod изменяет метод тэга, связанный с данной парой (tag, event). Первый параметр представляет собой тэг, второй строку (имя события), а третий параметр (функция) задает новый метод или nil, чтобы восстановить заданное по умолчанию поведение для пары. Функция settagmethod возвращает предыдущий метод тэга для этой пары. Функция-компаньон gettagmethod получает тэг и имя события и возвращает текущий метод, связанный с парой.

Методы тэгов вызваны при соответствующих событиях, которые идентифицированы данными именами. Семантика методов лучше объяснена функцией Lua, описывающей поведение интерпретатора в каждом событии. Эта функция не только показывает, когда метод вызван, но также параметры, результаты и заданное по умолчанию поведение. Код, показанный здесь, только иллюстративен: реальное поведение сложно закодировано в интерпретаторе и намного более эффективно, чем это моделирование. Все функции, используемые в этих описаниях (rawget, tonumber, call и т.д.), описаны подробно в разделе 4.6.1.

``add'':
Вызван, когда операция + применяется к не числовым операндам.

Функция 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

``sub'':
Вызван, когда операция - применяется к не числовым операндам. Поведение подобно событию ``add''.

``mul'':
Вызван, когда операция * применяется к не числовым операндам. Поведение подобно событию ``add''.

``div'':
Вызван, когда операция / применяется к не числовым операндам. Поведение подобно событию ``add''.

``pow'':
Вызван, когда операция ^ (возведение в степень) применяется к числовым операндам.
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

``unm'':
Вызван, когда одноместная операция - применяется к не числовому операнду.
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

``lt'':
Вызван, когда операция порядка применяется к не числовому или не строчному операнду. Это соответствует оператору <.
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)
``concat'':
Вызван, когда конкатенация применяется к не строчным операндам.
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

``index'':
Вызван, когда Lua пробует найти значение индекса, не представленного в таблице.

``getglobal'':
Вызван всякий раз, когда Lua нуждается в значении глобальной переменной. Этот метод может быть установлен только для nil и для тэгов, порожденных вызовом 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 определена в базисной библиотеке.
``setglobal'':
Вызван всякий раз, когда Lua присваивает значение глобальной переменной. Этот метод не может быть установлен для чисел, строк, таблиц и userdata с заданным по умолчанию тэгом.
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 определена в базисной библиотеке.

``gettable'':
Вызван всякий раз, когда Lua обращается к индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом.
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

``settable'':
Вызван, когда Lua присваивает значение индексированной переменной. Этот метод не может быть установлен для таблиц с заданным по умолчанию тэгом.
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'':
Вызван, когда Lua пробует вызывать не функциональное значение.
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

``gc'':
Вызван, когда Lua начинает уборку мусора в userdata. Этот метод может быть установлен только из C, и не может быть установлен для userdata с заданным по умолчанию тэгом. Для каждого объекта userdata, который будет собран, Lua делает эквивалент следующей функции в цикле уборки мусора:
function gc_event (obj)
  local tm = gettagmethod(tag(obj), "gc")
  if tm then tm(obj)
  end
end
В цикле уборки мусора методы тэгов для userdata вызываются в порядке, обратном созданию тэгов, то есть первые методы, которые будут вызваны, связаны с последним тэгом, созданным в программе. Кроме того, в конце цикла Lua делает эквивалент обращения gc_event(nil).

4.5 API

Этот раздел описывает API для Lua, то есть набор функций C, доступных ведущей программе, чтобы связаться с Lua. Все функции API, связанные типы и константы объявлены в файле заголовка lua.h.

Даже когда используем термин "функция", любое средство в API можно обеспечить как макрокоманду. Все такие макрокоманды используют каждый из параметров точно однажды и не генерируют скрытые побочные эффекты.

4.5.1 Состояния

Библиотека 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 нуждаются в состоянии как в первом параметре.

4.5.2 Стек и индексы

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 не является приемлемым индексом.

4.5.3 Манипуляции со стеком

API предлагает следующие функции для базисного манипулирования стеком:
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

4.5.4 Запросы к стеку

Чтобы проверять тип элемента стека, следующие функции доступны:

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.

4.5.5 Помещение значений в стек

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, которая принимает явный размер данных.

4.5.6 Уборка мусора

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 сбрасывает порог).

4.5.7 Userdata и тэги

Поскольку 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.

4.5.8 Выполнение Lua-кода

Ведущая программа может выполнять Lua-chunk, записанные в файле или в строке, используя следующие функции:
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 в случае успеха, или один из следующих кодов ошибки, если они терпят неудачу: Эти константы определены в 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);
}

4.5.9 Управление глобальными переменными в Lua

Чтобы прочитать значение глобальной переменной 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);
Таблица, которую нужно использовать, извлекается из стека.

4.5.10 Управление таблицами в Lua

Lua-таблицы могут также управляться через API.

Чтобы читать значение в таблице, таблица должна находиться где-нибудь в стеке. Теперь вызовите

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);
создает новую, пустую, таблицу и помещает ее в стек.

4.5.11 Использование таблиц как массивов

API имеет функции, которые помогают использовать таблицы Lua как массивы, то есть таблицы, индексированные только числами:
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 в таблице.

4.5.12 Вызов функций Lua

Функции, определенные в 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

4.5.13 Определение функций C

Чтобы зарегистрировать функцию C в 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.

4.5.14 Ссылки к 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.

4.5.15 Системный реестр

При своем запуске Lua регистрируют таблицу в позиции LUA_REFREGISTRY. К этому можно обращаться через макрокоманду:

#define lua_getregistry(L) lua_getref(L, LUA_REFREGISTRY)
Эта таблица может использоваться C-библиотеками как общий механизм системного реестра. Любая C-библиотека может сохранять данные в этой таблице, пока она выбирает ключ регистрации, отличный от других библиотек.

4.6 Стандартные библиотеки

Стандартные библиотеки обеспечивают полезные функции, которые выполнены непосредственно через стандартный API. Следовательно, они не так уж и необходимы для самого языка, а обеспечиваются как отдельные C-модули. В настоящее время, Lua имеет следующие стандартные библиотеки:

Чтобы иметь доступ к этим библиотекам, ведущая C-программа должна вызвать функции lua_baselibopen, lua_strlibopen, lua_mathlibopen и lua_iolibopen, которые объявлены в файле заголовков lualib.h.

4.6.1 Базисные функции

Базисная библиотека обеспечивает некоторые основные функции для Lua. Следовательно, если Вы не включаете эту библиотеку в Вашей прикладной программе, Вы должны тщательно проверить, должны ли Вы обеспечить какую-то альтернативную реализацию для некоторых средств. Например, без функции _ERRORMESSAGE Lua не способен показать сообщения об ошибках.

_ALERT (message)

Печатает только строковый аргумент на stderr. Все сообщения об ошибках в Lua напечатаны через функцию, сохраненную в глобальной переменной _ALERT. Следовательно, программа может назначать другую функцию к этой переменной, и изменять путь, которым такие сообщения показываются (например, для систем без stderr).

assert (v [, message])

Выдает ошибку assertion failed!, когда параметр v равен nil. Эта функция эквивалентна следующей функции Lua:
function assert(v, m)
  if not v then m = m or ""
     error("assertion failed!  " .. m)
  end
end

call (func, arg [, mode [, errhandler]])

Вызывает функцию 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, никакие сообщения об ошибках не будут выданы в течение выполнения вызванной функции вообще.

collectgarbage ([limit])

Устанавливает порог для мусоросборщика в данное значение (в Kbytes). Если новый порог меньше, чем счетчик байтов, то Lua немедленно выполняет уборку мусора в памяти. Если limit отсутствует, значением по умолчанию является ноль (таким образом уборка мусора запустится сразу).

copytagmethods (tagto, tagfrom)

Копирует все методы тэга из одного тэга в другой, возвращает tagto.

dofile (filename)

Получает имя файла, открывает именованный файл и выполняет его содержимое как Lua-код или как прекомпилируемый код. Когда вызвано без параметров, dofile выполняет содержание стандартного ввода (stdin). Если имеется любая ошибка, dofile вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если блок кода не возвращает никаких значений. Это выдает ошибку, когда вызвано не со строчным параметром.

dostring (string [, chunkname])

Выполняет данную строку как код на Lua. Если имеется любая ошибка, то dostring вернет nil. Иначе это возвращает значения, возвращенные кодом, или значение не-nil, если код не возвращает никакие значения. Факультативный параметр chunkname имя кода, используемого для информации об ошибках и отладочных сообщений.

error (message)

Вызывает драйвер ошибки и затем завершает последнюю защищенную вызванную функцию (в C: lua_dofile, lua_dostring, lua_dobuffer или lua_callfunction, в Lua: dofile, dostring или call в защищенном режим). Если message равно nil, то драйвер ошибки не будет вызван. Функция error никогда ничего не возвращает.

foreach (table, func)

Выполняется данную 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 в ходе работ.

foreachi (table, func)

Выполняет данную 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

getglobal (name)

Получает значение глобальной переменной или вызывает метод тэга для события getglobal. Полная семантика объясняется в разделе 4.4.8 . Строка name задает имя переменной.

getn (table)

Возвращает размер таблицы, представленной как список. Если таблица имеет 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

gettagmethod (tag, event)

Возвращает текущий метод тэга для данной пары (tag, event). Эта функция не может использоваться, чтобы получить метод тэга для события gc. Такие методы тэга могут управляться только C-кодом.

globals ([table])

Возвращает текущую таблицу глобальных переменных. Если параметр table задан, то это также устанавливает его как новую таблицу глобальных переменных.

newtag ()

Возвращает новый тэг.

next (table, [index])

Позволяет программе пересекать все поля таблицы. Первый параметр: таблица, а второй параметр задает индекс в этой таблице. next вернет следующий индекс таблицы и значение, связанное с индексом. Когда вторым параметром является nil, next вернет первый индекс таблицы и связанное значение. При вызове с последним индексом или с nil в пустой таблице, next вернет nil. Если второй параметр отсутствует, то это интерпретируется как указание nil.

Lua не имеет никакого объявления полей: семантически не имеется никакого различия между полем, не представленным в таблице, или полем со значением nil. Следовательно, next рассматривает только поля со значениями не-nil. Порядок, в котором индексы перечислены, не определен даже для числовых индексов. Чтобы обработать таблицу в числовом порядке, надо использовать функцию foreachi.

Поведение next неопределено, если Вы изменяете таблицу в ходе работ.

print (e1, e2, ...)

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

rawget (table, index)

Получает реальное значение table[index] без того, чтобы вызвать любой метод тэга. Таблица должна быть задана как table, а index представляет собой любое значение, отличное от nil.

rawset (table, index, value)

Устанавливает реальное значение table[index] в value без того, чтобы вызвать любой метод тэга. Параметр table должен быть таблицей, index представляет собой любое значение, отличное от nil, а value задает любое значение Lua.

setglobal (name, value)

Устанавливает именованную глобальную переменную к данному значению, или вызывает метод тэга для события setglobal. Полная семантика объясняется в разделе 4.8.

settag (t, tag)

Устанавливает тэг данной таблицы. Тэг (tag) должен быть значением, созданным через newtag. settag вернет значение первого параметра (таблицу). Для безопасности ведущих программ невозможно изменить тэг userdata прямо из Lua.

settagmethod (tag, event, newmethod)

Устанавливает новый метод тэга к данной паре (tag, event) и возвращает старый метод. Если newmethod равно nil, то settagmethod восстанавливает заданное по умолчанию поведение для данного события. Эта функция не может использоваться, чтобы установить метод для события gc. Такие методы могут управляться только C-кодом.

sort(table [, comp])

Сортирует элементы таблицы в данном порядке, данные берутся из table[1] и помещаются в table[n], где n представляет собой результат getn(table). Если comp задан, то это должно быть функцией, которая получает два элемента таблицы и возвращает истину (то есть значение, отличное от nil), когда первый меньше, чем второй (так, чтобы not comp(a[i+1], a[i]) был истиной после сортировки). Если comp не задано, то вместо этого используется стандартный оператор < языка Lua.

Алгоритм сортировки неустойчив (то есть элементы, рассматриваемые как равные, могут изменить свои относительные позиции после сортировки).

tag (v)

Позволяет программам Lua проверять тэг значения. Это получает один параметр и возвращает тэг (число).

tonumber (e [, base])

Пробует преобразовывать параметр в число. Если параметр уже число или строка, обратимая в число, то tonumber вернет это число, иначе это всегда возвращает nil.

Факультативный параметр определяет ядро, чтобы интерпретировать цифру. Ядром может быть любое целое число между 2 и 36 включительно. В базах более, чем 10, символ A (заглавные или строчные буквы) представляет 10, B соответствует 11 и так далее до символа Z, соответствующему 35. В ядре 10 (значение по умолчанию) число может иметь десятичную часть, также как и факультативную часть экспоненты. В других базах только целые числа без знака.

tostring (e)

Получает параметр любого типа и преобразовывает его в строку в приемлемом формате. Для полного управления тем, как числа будут преобразованы, используйте функцию format.

tinsert (table [, pos] , value)

Вставляет значение элемента 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

tremove (table [, pos])

Удаляет из таблицы 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

type (v)

Позволяет программам Lua проверять тип значения. Это получает один параметр, а возвращает тип, кодированный как строка. Возможные результаты этой функции: "nil" (строка, а не значение nil!), "number", "string", "table", "function" и "userdata".

4.6.2 Строковые манипуляции в Lua

Эта библиотека обеспечивает универсальные функции для манипулирования строками, типа нахождения и извлечения соответствия образца и подстрок. При индексации строки в Lua, первый символ находится в позиции 1 (не в 0, как в C!). Также, индексам позволено быть отрицательными, что понимается как индексация в обратном направлении, с конца строка к началу. Таким образом, последний символ находится в позиции -1 и так далее.

strbyte (s [, i])

Возвращает внутренний числовой код i-го символа строки s. Если i отсутствует, то принято 1. i может быть отрицателен.

Числовые коды не обязательно переносимы между платформами.

strchar (i1, i2, ...)

Получает 0 или большее количество целых чисел. Возвращает строку с длиной, равной числу параметров, в которой каждый символ имеет внутренний числовой код, заданный соответствующим параметром.

Числовые коды не обязательно переносимы между платформами.

strfind (s, pattern [, init [, plain]])

Ищет первое соответствие образцу pattern в s. Если это найдено, strfind вернет индексы s, где эти вхождения начинаются и заканчивается, иначе это возвращает nil. Если образец определяет набор данных (подробности в описании gsub ниже), зафиксированные строки возвращены как дополнительные результаты. Факультативный числовой параметр init определяет, где запустить поиск: значение по умолчанию 1, и оно может быть отрицательным. Четвертый факультативный аргумент plain выключает средства поиска образца, так что функция просто ищет подстроку без символов в pattern, обрабатываемых особым образом. Обратите внимание, что если задана опция plain, должна быть задана и init.

strlen (s)

Получает строку и возвращает ее длину. Пустая строка ("") имеет длину 0. Вложенные ноли в строке считаются, так что строка "a\000b\000c" имеет длину 5 символов.

strlower (s)

Получает строку и возвращает ее копию со всеми символами верхнего регистра, измененными на строчные буквы. Все другие символы оставлены прежними. Определение того, какие буквы прописные, зависит от настроек региона.

strrep (s, n)

Возвращает строку, которая является суммой n копий строки s.

strsub (s, i [, j])

Возвращает другую строку, которая является подстрокой s, начинающегося в i и продолжающейся до j. i и j могут быть отрицательными, Если j отсутствует, то оно считается равным -1 (длине строки). В частности, обращение strsub(s,1,j) возвращает префикс s длиной j, а вызов strsub(s, -i) вернет суффикс s длиной i.

strupper (s)

Получает строку и возвращает копию со всеми символами строчных букв, измененными на верхний регистр. Все другие символы оставлены как есть. Что такое строчные буквы, читается из настроек региона.

format (formatstring, e1, e2, ...)

Возвращает форматированную версию переменного числа параметров после применения описания, заданного в первом параметре (который должен быть строкой). Строка формата следует тем же самым правилам, что и семейство стандартных функций 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 обрабатывает значения строк с вложенными нолями.

gsub (s, pat, repl [, n])

Возвращает копию 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
Здесь x любые волшебные символы: ^$()%.[]*+-?. Представляет непосредственно символ x.
. (точка)
Представляет все символы.
%a
Представляет все буквы.
%c
Представляет все спецсимволы.
%d
Представляет все цифры.
%l
Представляет все буквы в нижнем регистре.
%p
Представляет все символы пунктуации.
%s
Представляет все пробелы.
%u
Представляет все буквы в верхнем регистре.
%w
Представляет все алфавитно-цифровые символы.
%x
Представляет все шестнадцатеричные цифры.
%z
Представляет символ с представлением 0.
%x
Здесь x задает любой не алфавитно-цифровой символ. Представляет символ x. Это стандартный способ экранировки управляющих спецсимволов. Лучше следить за тем, чтобы любому символу пунктуации (даже не управляющему!) предшествовал %, когда символ применен в образце.
[char-set]
Представляет класс, который является объединением всех символов в char-set. Диапазон символов может быть определен, отделяя конечные символы диапазона тире (-). Все классы %x, описанные выше, могут также использоваться как компоненты в char-set. Все другие символы в char-set представляются как есть. Например, [%w_] (или [_%w]) представляет все алфавитно-цифровые символы плюс символ подчеркивания, [0-7] представляет восьмеричные цифры, а [0-7%l%-] представляет восьмеричные цифры плюс символы строчных букв плюс символ тире. Взаимодействие между диапазонами и классами не определено. Следовательно, образцы, подобные [%a-z] или [a-%%] не имеют никакого значения.
[^char-set]
Представляет дополнение char-set, где char-set интерпретируется как выше.

Для всех классов, представляемых одиночными символами (%a, %c, ...), соответствующая прописная буква представляет дополнение класса. Например, %S представляет все не пробелы.

Определения символа, пробела и т.д. зависят от текущего региона. В частности, класс [a-z] не может быть эквивалентен %l. Вторая форма должна быть предпочтительней для переносимости.

Элемент образца:

Элементом образца может быть:

Шаблоны:

Шаблон представляет собой последовательность элементов образца. Циркумфлекс (^) в начале образца закрепляет соответствие в начале подчиненной строки. $ в конце образца закрепляет соответствие в конце подчиненной строки. В других позициях ^ и $ не имеют никакого специального значения и представляются как есть.

Сборы данных:

Образец может содержать подобразцы, включенные в круглые скобки, они описывают сборы данных. Когда соответствие выполнено, подстроки подчиненной строки, которые соответствуют сборам данных, сохранены для будущего использования. Сборы данных пронумерованы согласно их левым круглым скобкам. Например, в образце "(a*(.)%w(%s*))", часть соответствия строки "a*(.)%w(%s*)" сохранена как первый сбор данных (а, следовательно, имеет номер 1), символьное соответствие . зафиксировано с номером 2, а часть, соответствующая %s*, конечно, имеет номер 3.

Образец не может содержать вложенные ноли. Используйте вместо этого %z.

4.6.3 Математические функции

Эта библиотека предоставляет интерфейс к некоторым функциям стандартной математической библиотеки 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]. Границы всегда входят в диапазон.

4.6.4 Средства ввода-вывода

Все операции ввода-вывода в Lua реализованы через два дескриптора файла, по одному на ввод и вывод. Эти дескрипторы сохранены в двух глобальных переменных Lua, названных _INPUT и _OUTPUT. Глобальные переменные _STDIN, _STDOUT и _STDERR инициализированы с описателями файлов для stdin, stdout и stderr. Первоначально Initially, _INPUT=_STDIN и _OUTPUT=_STDOUT.

Дескриптор файла представляет собой объект userdata, содержащий поток файла (FILE*) с отличительным тэгом, созданным библиотекой ввода-вывода (I/O).

Если иное не установлено, все функции I/O возвращают nil на сбое и некоторое значение, отличное от nil, при успехе.

openfile (filename, mode)

Эта функция открывает файл в режиме, определенном в строке mode. Это возвращает новый дескриптор файла или, в случае ошибок, nil плюс строку, описывающую ошибку. Эта функция не изменяет _INPUT или _OUTPUT.

Строка mode может быть любой из следующего списка:

r
Режим чтения.
w
Режим записи.
a
Режим добавления к концу.
r+
Режим обновления, все ранее записанные данные сохраняются.
w+
Режим обновления, все ранее записанные данные уничтожаются.
a+
Режим модификации, предыдущие данные сохраняются, запись позволяется только в конце файла.
Строка mode может также иметь в конце b, что необходимо в некоторых системах, чтобы открыть файл в двоичном режиме. Эта строка аналогична той, что используется в стандартной функции C fopen.

closefile (handle)

Эта функция закрывает файл. Это не изменяет _INPUT или _OUTPUT.

readfrom (filename)

Эта функция может быть вызвана двумя путями. Когда она вызвана с именем файла, открывает именованный файл, устанавливает дескриптор как значение _INPUT и возвращает это значение. Это не закрывает текущий файл input. При вызове без параметров, она закрывает файл _INPUT и восстанавливает stdin как значение _INPUT. Если эта функция где-то не сработала, она возвращает nil плюс строку описания.

Если filename начинается с символа трубопровода |, открывается поточный ввод через функцию popen. Не все системы его выполняют. Кроме того, число файлов, которые могут быть открыты в то же самое время, обычно ограничивается и зависит от системы.

writeto (filename)

Эта функция может быть вызвана двумя путями. Когда она вызвана с именем файла, открывает именованный файл, устанавливает дескриптор как значение _OUTPUT и возвращает это значение. Это не закрывает текущий выходной файл. Обратите внимание, что если файл уже существует, то он будет полностью уничтожен этой операцией. Когда функция вызвана без параметров, она закрывает файл _OUTPUT и восстанавливает stdout как значение _OUTPUT. В случае ошибки функция возвращает nil плюс строку, описывающую ошибку.

Если filename начинается с символа трубопровода |, открывается поточный ввод через функцию popen. Не все системы его выполняют. Кроме того, число файлов, которые могут быть открыты в то же самое время, обычно ограничивается и зависит от системы.

appendto (filename)

Открывает файл, именованный filename и устанавливает это как значение _OUTPUT. В отличие от операции writeto, эта функция не стирает предыдущее содержание файла, вместо этого все, что пишется в файл, будет конкатенировано к концу. Если эта функция получила сбой, она вернет nil плюс строку, описывающую ошибку.

remove (filename)

Удаляет файл с данным именем. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

rename (name1, name2)

Переименовывает файл name1 в name2. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

flush ([filehandle])

Сохраняет любые записанные данные в заданный файл. Если filehandle не определен, то flush сбросит на диск все открытые файлы. Если эта функция получила сбой, она вернет nil плюс строку с описанием ошибки.

seek (filehandle [, whence] [, offset])

Получает позицию файла, измеряемую в байтах от начала файла, и меняет ее на позицию, данную смещением offset плюс ядром, определенным как строка whence следующим образом:

set
Позиция 0 (начало файла).
cur
Текущая позиция.
end
Конец файла.
В случае успеха функция seek возвращает конечную позицию файла, измеряемую в байтах от начала файла. Если эта функция получила сбой, она вернет nil плюс строку, описывающую эту ошибку.

Значение по умолчанию для whence равно cur, а для offset это 0. Следовательно, вызов seek(file) возвращает текущую позицию файла без того, чтобы изменить это. Вызов seek(file, "set") устанавливает позицию на начало файла (и возвращает 0), а seek(file, "end") устанавливает позицию в конец файла и возвращает его размер.

tmpname ()

Возвращает строку с именем файла, которое может безопасно использоваться для временного файла. Файл должен быть явно открыт перед использованием и удален, когда больше не нужен.

read ([filehandle,] format1, ...)

Читает файл _INPUT или filehandle, если этот параметр задан, согласно данным форматам, которые определяют, что читать. Для каждого формата, функция возвращает строку или число с прочитанными данными или nil, если не может читать данные с определенным форматом. Когда вызвана без форматов, эта функция использует заданный по умолчанию формат, который читает следующую строку.

Доступные форматы такие:

*n
Читает число. Это единственный формат, который возвращает число вместо строки.
*l
Читает следующую строку (обходя концы строк) или nil в конце файла. Это и есть заданный по умолчанию формат.
*a
Читает целый файл, начинающийся в текущей позиции. На конце файла, возвращает пустую строку.
*w
Читает следующее слово (максимальная последовательность символов без пробелов. Пробелы обходит в случае необходимости. Замечу, что под пробелом здесь понимается не только собственно пробел, но и спецсимволы. В конце файла функция вернет nil.
Число
Читает строку до указанного числа символов в длину или nil на конце файла.

write ([filehandle, ] value1, ...)

Пишет значение каждого из параметров в файл _OUTPUT или в filehandle, если этот параметр задан. Параметры должны быть строками или числами. Чтобы писать другие значения, используйте tostring или format перед write. Если эта функция нарвалась на ошибку, она вернет nil и строку с описанием данной ошибки.

4.6.5 Средства системы

clock ()

Возвращает приближение количество времени CPU, используемое программой (в секундах).

date ([format])

Возвращает строку, содержащую дату и время, форматируемую согласно данному формату format. Формат задается по тем же самым правилам, что и в функции ANSI C strftime. Когда вызвана без параметров, возвращает приемлемое представление даты и времени, которое зависит от ведущей системы и от текущего региона.

execute (command)

Эта функция эквивалентна функции C system. Это передает команду command, которая будет выполнена оболочкой операционной системы. Возвращает код состояния, который является зависимым от системы.

exit ([code])

Вызывает C-функцию exit с факультативным кодом завершения программы code. Значение по умолчанию для code: код успешного завершения.

getenv (varname)

Возвращает значение системной переменной процесса varname или nil, если эта переменная не определена.

setlocale (locale [, category])

Эта функция предоставляет интерфейс к функции ANSI C setlocale. locale представляет собой строку, определяющую регион, category факультативная строка, описывающая которую категорию изменить: "all", "collate", "ctype", "monetary", "numeric" или "time", заданная по умолчанию категория: "all". Функция возвращает имя нового региона или nil, если этот запрос не может быть выполнен.

4.7 Интерфейс отладки

Lua не имеет никаких встроенных средств отладки. Вместо этого, это предлагает специальный интерфейс, посредством функций и обработчиков прерываний, который позволяет создание различных видов отладчиков, профилировщиков и других инструментальных средств, которые нуждаются во внутренней информации из интерпретатора. Этот интерфейс объявлен в файле заголовков luadebug.h.

4.7.1 Информация стека и функций

Основная функция, чтобы получить информацию относительно стека интерпретатора:

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 начинается с @, а дальше имя файла.
short_src
Пригодная к печати версия source, чтобы использоваться в сообщениях об ошибке.
linedefined
Код строки, где было начато определение функции.
what
Строка "Lua", если это функция Lua, "C", если это функция C или "main", если это основная часть chunk.
currentline
Текущая строка, где данная функция выполняется. Когда никакая информация о строке недоступна, currentline установлен в -1.
name
Приемлемое имя для данной функции. Так как функции в Lua значения первого класса, они не имеют фиксированных имен. Именем функции может быть значение многих глобальных переменных, в то время как другие функции могут быть сохранены только в поле таблицы. Функция lua_getinfo проверяет, является ли данная функция методом тэга или значением глобальной переменной. Если данная функция представляет собой метод тэга, name указывает на имя события. Если данная функция является значением глобальной переменной, то name указывает на имя переменной. Если данная функция не является ни методом тэга, ни глобальной переменной, то name установлен в NULL.
namewhat
Объясняет предыдущее поле. Если функция глобальная переменная, namewhat равен "global". Если функция метод тэга, namewhat равен "tag-method", иначе namewhat равен "" (пустой строке).
nups
Число upvalues в функции.

4.7.2 Управление локальными переменными

Для манипулирования локальными переменными 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;
}

4.7.3 Обработчики прерываний

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, это выполнение идет без обращений к обработчикам прерываний.

4.7.4 Рефлексивный интерфейс отладки

Библиотека ldblib обеспечивает функциональные возможности интерфейса отладки программам Lua. Если Вы хотите использовать эту библиотеку, Ваша ведущая прикладная программа должна открыть ее вызовом lua_dblibopen.

Вы должны проявить большую осторожность при использовании этой библиотеки. Функции, обеспеченные здесь, должны использоваться исключительно для отладки и подобных задач (например, профилирования). Пожалуйста, сопротивляйтесь искушению использовать их как обычный инструмент программирования. Они медленны и нарушают некоторые аспекты языка (например, секретность локальных переменных). Как общее правило, если Ваша программа не нуждается в этой библиотеке, не открывайте ее вообще.

getinfo (function, [what])

Эта функция возвращает таблицу с информацией относительно функции. Вы можете давать функцию непосредственно, или Вы можете давать число как значение function, что означает функциональное управление в уровне стека function. Уровень 0 считается текущей функцией (непосредственно getinfo), уровень 1: функция, которая вызвала getinfo и так далее. Если function представляет собой число большее, чем число активных функций, то getinfo сразу вернет nil.

Возвращенная таблица содержит все поля, возвращенные lua_getinfo со строкой what описывающий, что нужно получить. Значение по умолчанию для what: нужно получить всю доступную информацию.

Например, выражение getinfo(1,"n").name вернет имя текущей функции, если приемлемое имя может быть найдено, и getinfo(print) возвращает таблицу со всей доступной информацией относительно функции print.

getlocal (level, local)

Эта функция возвращает имя и значение локальной переменной с индексом, local на уровне level стека. Первый параметр или локальная переменная имеет индекс 1 и так далее до последней активной локальной переменной. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с level вне диапазона. Вы можете вызывать getinfo, чтобы проверить, имеет ли этот уровень силу.

setlocal (level, local, value)

Эта функция назначает значение value локальной переменной с индексом local функции на уровне level стека. Функция вернет nil, если не имеется никакой локальной переменной с данным индексом, и поднимает ошибку когда вызвана с уровнем level вне диапазона.

setcallhook (hook)

Устанавливает функциональный обработчик прерываний hook как обработчик прерываний call. Этот обработчик прерываний будет вызван каждый раз при начале и завершении интерпретации функции. Единственный параметр на обработчик прерываний call: имя события ("call" или "return"). Вы можете вызывать getinfo с уровнем 2, чтобы получить большее количество информации относительно функции (уровень 0 соответствует функции getinfo, а уровень 1 задает функцию обработчика прерываний. Когда вызвана без параметров, эта функция выключает обработчики прерываний call. setcallhook вернет старый обработчик прерываний.

setlinehook (hook)

Устанавливает функциональный обработчик прерываний hook как обработчик прерываний line. Этот обработчик прерываний будет вызван каждый раз, когда интерпретатор изменяет обрабатываемую строку кода. Единственный параметр на обработчике прерываний line: код строки, которую интерпретатор собирается выполнять. Когда вызвана без параметров, эта функция выключает обработчики прерываний line. Вызов setlinehook возвращает старый обработчик прерываний.

4.8 Lua в автономном режиме

Хотя Lua был разработан как язык расширений, чтобы быть вложенным в ведущую программу на C, это часто используется как автономный язык. Интерпретатор для Lua, как автономного языка, называется просто lua. Эта программа может быть вызвана с любой последовательностью следующих параметров:

-sNUM
Устанавливает размер стека в NUM (если используется, должно быть первой опцией).
-
Выполняет stdin как файл.
-c
Вызывает lua_close после обработки всех параметров.
-e \rmstat
Выполняет строку stat.
-f filename
Выполняет файл filename с параметрами для таблицы arg.
-i
Вводит интерактивный режим с подсказкой.
-q
Вводит интерактивный режим без подсказки.
-v
Информация о версии пакета.
var=value
Устанавливает глобальную переменную var в строку "value".
filename
Выполняет файл 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, чтобы получить другие параметры.

4.10 Благодарности

Авторы пакета хотели бы поблагодарить CENPES/PETROBRAS, который, совместно с TeCGraf, использовал ранние версии этой системы и дал ценные комментарии. Авторы также хотели бы отблагодарить Carlos Henrique Levy за найденное имя для проекта. Lua на португальском означает луну.

4.11 Несовместимость с предыдущими версиями

Lua 4.0 представляет собой значительное изменение языка. Была проделана большая работа, чтобы избежать несовместимости с предыдущими общими версиями Lua, но некоторые различия нужно представлять. Есть список несовместимостей.

Несовместимости с version 3.2

Изменения в языке

Изменения в библиотеках

Изменения в API

4.12 Полный синтаксис Lua

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

4.13 lua: интерпретатор языка Lua

Синтаксис

lua [arguments]

Описание

lua представляет собой автономный интерпретатор языка Lua. Он загружает и выполняет программы на Lua, как в текстовой исходной форме, так и в виде прекомпилированных модулей, созданных компилятором luac. lua может использоваться как пакетный интерпретатор, а также в интерактивном режиме.

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 вывести информацию о версии.

Также можно посмотреть

luac(1)
http://www.tecgraf.puc-rio.br/lua.

Диагностика

Сообщения пакета об ошибках должны быть самодостаточными.

luac: компилятор Lua

Синтаксис вызова

luac [options] [filenames]

Описание

luac представляет собой компилятор Lua. Он транслирует программы, написанные на языке программирования Lua в двоичные файлы, которые могут быть загружены и выполнен с помощью lua_dofile в C или dofile в Lua.

Основные преимущества прекомпилированных программ: они быстрее при загрузке, исходный текст защищен от изменений пользователя и недоступно обнаружение ошибок синтаксиса.

Прекомпиляция не подразумевает более быстрое выполнение потому, что в 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).

4.14 Установка языка LUA

Построение Lua на системах Unix очень просто:

Ниже приведены инструкции для пользователей систем Windows и Macintosh.

4.14.1 Что Вы получаете

Если make выполнилась без проблем, Вы получите:

Это единственные каталоги, в которых Вы нуждаетесь для разработки.

Man-страницы для lua и luac в nroff и html, а также справочное описание в html помещаются в ./doc, некоторый типовой код в ./test, а некоторые полезные дополнения в ./etc. Вы не нуждаетесь в этих каталогах для разработки.

Изучите также README-файлы в различных подкаталогах. Удобная отправная точка: ./doc/readme.html.

4.14.2 Проблемы и некоторые решения

Если вызов make ничего хорошего не сделал, пожалуйста, сообщите на lua@tecgraf.puc-rio.br. Если Вы делаете изменения для config или в файлах Makefile, пожалуйста, пошлите их туда же.

4.14.3 Разделяемые библиотеки

Если Вы управляете Linux, сделайте make so после успешного выполнения make. Это создаст общедоступные библиотеки в ./lib. Вероятно, лучше формировать общедоступные библиотеки прежде, чем выполнять make install.

Если Вы хотите переделать интерпретатор и транслятор так, чтобы использовать общедоступные библиотеки, то выполните также make sobin.

Вы, возможно, должны включить lib в системную переменную LD_LIBRAY_PATH, чтобы компоновать программы, которые используют общедоступные библиотеки, если Вы не помещаете их в официальные места с помощью make install.

Формирование общедоступных библиотек в других системах подобно этому, но детали отличаются. Вы будете должны поправить несколько деталей в Makefile на верхнем уровне дерева кода.

4.14.4 Установка на Windows или Macintosh

Команды для формирования 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 как разделяемую библиотеку, Вы должны знать, как создавать и использовать библиотеки с Вашим компилятором и в Вашей операционной системе.

4.14.5 INSTALL для mysql 3.23.32