1 MySQL API

365
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 Error: "Maximum Execution Time Exceeded". Это ограничение PHP. Найдите файл настроек php3.ini и установите максимальное время выполнения как необходимо. Также неплохо увеличить выделяемую каждому скрипту память с 8 MB до 16 MB. Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in ..". Это означает, что Ваша версия PHP не имеет поддержки MySQL. Вы можете или скомпилировать динамический модуль MySQL и загруить его в PHP, или перетранслировать PHP со встроенной поддержкой MySQL. Это описано подробно в PHP руководстве. Error: "undefined reference to `uncompress'". Это означает, что библиотека клиентов компилируется с поддержкой для сжатого протокола клиент/сервер. Чтобы исправить ситуацию, добавьте -lz в конце строки для компоновки с -lmysqlclient. 1.2 MySQL C++ API

Transcript of 1 MySQL API

Page 1: 1 MySQL API

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

Error: "Maximum Execution Time Exceeded". Это ограничение PHP. Найдите файл настроек php3.ini и установите максимальное время выполнения как необходимо. Также неплохо увеличить выделяемую каждому скрипту память с 8 MB до 16 MB.

Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in ..". Это означает, что Ваша версия PHP не имеет поддержки MySQL. Вы можете или скомпилировать динамический модуль MySQL и загруить его в PHP, или перетранслировать PHP со встроенной поддержкой MySQL. Это описано подробно в PHP руководстве.

Error: "undefined reference to `uncompress'". Это означает, что библиотека клиентов компилируется с поддержкой для сжатого протокола клиент/сервер. Чтобы исправить ситуацию, добавьте -lz в конце строки для компоновки с -lmysqlclient.

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++. Вы

Page 2: 1 MySQL API

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

Вы можете использовать статические MySQL библиотеки для Borland C++, их можно скачать с http :// www . mysql . com / downloads / os - win 32. html .

Только вызовите mysql_init() с NULL в качестве параметра, не размещая предварительно структуру MYSQL.

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.

Page 3: 1 MySQL API

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

Page 4: 1 MySQL API

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

FIELD_TYPE_SHORT SMALLINT

FIELD_TYPE_LONG INTEGER

FIELD_TYPE_INT24 MEDIUMINT

FIELD_TYPE_LONGLONG BIGINT

FIELD_TYPE_DECIMAL DECIMAL или NUMERICFIELD_TYPE_FLOAT FLOAT

FIELD_TYPE_DOUBLE DOUBLE или REAL

Page 5: 1 MySQL API

FIELD_TYPE_TIMESTAMP TIMESTAMP

FIELD_TYPE_DATE DATE

FIELD_TYPE_TIME TIME

FIELD_TYPE_DATETIME DATETIME

FIELD_TYPE_YEAR YEAR

FIELD_TYPE_STRING Строка (CHAR или VARCHAR)

FIELD_TYPE_BLOB BLOB или TEXT (используйте max_length, чтобы определить максимальную длину поля)

FIELD_TYPE_SET SET

FIELD_TYPE_ENUM ENUM

FIELD_TYPE_NULL NULL

FIELD_TYPE_CHAR Не рекомендуется: используйте FIELD_TYPE_TINY

Вы можете использовать макрос IS_NUM(), чтобы проверить имеет или нет поле числовой тип. Передайте значение type в IS_NUM(). Вернется TRUE, если поле числовое: if (IS_NUM(field->type)) printf("Field is numeric\n");

unsigned int length Ширина поля, как она определена в описании таблицы.

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

unsigned int flags Различные биты задают флажки для поля. Значение flags может иметь ноль или большее количество из следующего набора битов:

Значение Flag Что это значит

NOT_NULL_FLAG Поле не может быть NULL

PRI_KEY_FLAG Поле часть первичного ключа

UNIQUE_KEY_FLAG Поле часть уникального ключа

MULTIPLE_KEY_FLAG Поле часть неуникального ключа

UNSIGNED_FLAG Поле имеет атрибут UNSIGNED

ZEROFILL_FLAG Поле имеет атрибут ZEROFILL

BINARY_FLAG Поле имеет атрибут BINARY

AUTO_INCREMENT_FLAG Поле имеет атрибут AUTO_INCREMENT

ENUM_FLAG Поле имеет тип ENUM

BLOB_FLAG Поле имеет тип BLOB или TEXT

TIMESTAMP_FLAG Поле имеет тип TIMESTAMP

Page 6: 1 MySQL API

Использование 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 NULLIS_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() Возвращает текстовое сообщение об ошибке для

Page 7: 1 MySQL API

вызванной недавно функции 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() Возвращает список текущих потоков сервера.

Page 8: 1 MySQL API

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() ожидает

Page 9: 1 MySQL API

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

Page 10: 1 MySQL API

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

Page 11: 1 MySQL API

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

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

Page 12: 1 MySQL API

Если определен флажок 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 Возвращаемые значения

Page 13: 1 MySQL API

Аналогично 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

Page 14: 1 MySQL API

База данных не существует. 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 Команды были выполнены в неподходящем порядке.

Page 15: 1 MySQL API

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 Возвращаемые значения

Page 16: 1 MySQL API

Нет.

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)

Page 17: 1 MySQL API

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(). Так как те функции ошибки обеспечивают ту же

Page 18: 1 MySQL API

самую информацию, их использование предпочтительнее 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 Описание

Page 19: 1 MySQL API

Для подключения, определенного в 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 Ошибки

Нет.

Page 20: 1 MySQL API

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

Page 21: 1 MySQL API

{ 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 Возвращаемые значения

Page 22: 1 MySQL API

Структура 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() или после получения всех строк в результате.

Page 23: 1 MySQL API

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

Page 24: 1 MySQL API

Произошла неизвестная ошибка.

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 Пример

Page 25: 1 MySQL API

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 Ошибки

Page 26: 1 MySQL API

Нет.

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 Описание

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

Page 27: 1 MySQL API

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 Описание

Page 28: 1 MySQL API

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

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

Page 29: 1 MySQL API

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 Возвращаемые значения

Page 30: 1 MySQL API

Значение поля 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, если произошла ошибка.

Page 31: 1 MySQL API

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)

Page 32: 1 MySQL API

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

Page 33: 1 MySQL API

Подключение было потеряно в течение запроса. 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}

Page 34: 1 MySQL API

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

Page 35: 1 MySQL API

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_COMMAND char *

Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически выполнена при повторном соединении.

MYSQL_READ_DEFAULT_FILE char * Читать параметры из указанного файла опций вместо my.cnf.

MYSQL_READ_DEFAULT_GROUP char *

Читать параметры из именованной группы из файла опций my.cnf или файла, определенного в MYSQL_READ_DEFAULT_FILE.

Обратите внимание, что группа client всегда читается, если Вы используете MYSQL_READ_DEFAULT_FILE или MYSQL_READ_DEFAULT_GROUP.

Определенная группа в файле опций может содержать следующие параметры:

connect_timeout Время ожидания в секундах. В Linux это время ожидания также

Page 36: 1 MySQL API

используется для ожидания первого ответа.

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

Page 37: 1 MySQL API

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

Page 38: 1 MySQL API

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

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

Первый параметр должен быть адресом существующей структуры типа MYSQL. Перед вызовом mysql_real_connect() Вы должны вызвать mysql_init(), чтобы инициализировать структуру MYSQL. Вы можете изменять много параметров подключения через вызов mysql_options(). Подробности в разделе "2.3.159 mysql_options()".

Значением host может быть имя или адрес IP. Если это NULL или строка localhost, выполняется подключение к локальной системе. Если OS поддерживает сокеты (Unix) или именованные каналы (Windows), именно они используются вместо стека протоколов TCP/IP, чтобы соединиться с сервером.

Аргумент user содержит ID пользователя MySQL. Если user равен NULL, предполагается текущий пользователь. Под Unix это текущее (актуальное) имя входа в систему. Под Windows ODBC имя пользователя должно быть определено явно.

Параметр passwd содержит пароль для user. Если passwd равен NULL, только записи в таблице user, которые имеют пустое поле пароля, будут проверены на соответствие. Это позволяет администратору базы данных устанавливать

Page 39: 1 MySQL API

систему привилегий MySQL таким способом, которым пользователи получают различные привилегии в зависимости от того, определили или нет они пароль. ОБРАТИТЕ ВНИМАНИЕ: Не пытайтесь шифровать пароль перед вызовом mysql_real_connect(): шифрование пароля обработано автоматически.

db задает имя базы данных. Если db не NULL, подключение установит заданную по умолчанию базу данных.

Если port не равен 0, значение будет использоваться как номер порта для подключения по TCP/IP. Обратите внимание, что параметр host определяет тип подключения.

Если unix_socket не равен NULL, строка определяет сокет или именованный канал, который должен использоваться. Обратите внимание, что параметр host определяет тип подключения.

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

Имя флажка Что он делает

CLIENT_COMPRESS Использовать протокол сжатия.

CLIENT_FOUND_ROWS Возвратить число найденных, а не обработанных строк.

CLIENT_IGNORE_SPACEПозволить использовать пробелы после имен функций. Делает все зарезервированные слова именами функций.

CLIENT_INTERACTIVEПозволить interactive_timeout секунд (вместо wait_timeout секунд) бездеятельности перед закрытием подключения.

CLIENT_NO_SCHEMA

Не позволять синтаксис db_name.tbl_name.col_name. Это сделано для ODBC. Это заставляет синтаксический анализатор генерировать ошибку, если Вы используете тот синтаксис, который является полезным для заманивания в ловушку ошибок в некоторых программах ODBC.

CLIENT_ODBC Работает клиент ODBC.

CLIENT_SSL Использовать шифрованный протокол SSL.

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

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

2.3.174 Ошибки

CR_CONN_HOST_ERROR

Page 40: 1 MySQL API

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

Page 41: 1 MySQL API

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, не включая нулевой символ завершения.

Page 42: 1 MySQL API

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.

Page 43: 1 MySQL API

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 Описание

Page 44: 1 MySQL API

Возвращает текущую (актуальную) позицию курсора строки для последнего вызова 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)

Page 45: 1 MySQL API

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)

Page 46: 1 MySQL API

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 Ошибки

Page 47: 1 MySQL API

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(). Пользователь распределит память только для текущей

Page 48: 1 MySQL API

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

Page 49: 1 MySQL API

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

Page 50: 1 MySQL API

Если программа скомпонована с -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()

Page 51: 1 MySQL API

2.5.6 Описание

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

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

Нет.

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

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

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

Имелся сбой malloc() (например, если набор результатов был слишком большой).

Данные не могли прочитаться (произошла ошибка на подключении). Запрос не возвратил никакие данные (например, это был INSERT, UPDATE или

DELETE).

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

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

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

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

mysql_affected_rows() возвращает число строк, на которые воздействует последний запрос при выполнении INSERT, UPDATE или DELETE. Исключительная ситуация: DELETE используется без предложения WHERE, таблица будет пересоздана пустой, что намного быстрее! В этом случае mysql_affected_rows() возвращает ноль для числа записей.

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

Page 52: 1 MySQL API

mysql_insert_id() возвращает ID, сгенерированный последним запросом, который вставил строку в таблицу с индексом AUTO_INCREMENT. Подробности в разделе "2.3.126 mysql_insert_id()".

Некоторые запросы (LOAD DATA INFILE ..., INSERT INTO ... SELECT ..., UPDATE) возвращают дополнительную информацию. Результат возвращен через mysql_info(). mysql_info() вернет NULL если не имеется никакой дополнительной информации.

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 NULLINSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table

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

При компоновке с C API следующие ошибки могут происходить на некоторых системах:

Page 53: 1 MySQL API

gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnslUndefined first referenced symbol in filefloor /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.

Page 54: 1 MySQL API

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

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

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

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

Если Вы программируете с потоками в стиле POSIX, Вы можете использовать pthread_mutex_lock() и pthread_mutex_unlock(), чтобы устанавливать и снимать блокировку mutex.

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

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

Page 55: 1 MySQL API

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

Page 56: 1 MySQL API

Чтобы испытать пример, создайте каталог 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, ...)

Page 57: 1 MySQL API

{ 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++ = '+';

Page 58: 1 MySQL API

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

Page 59: 1 MySQL API

Файл GNUmakefile:

# Set this to your mysql source directorym := ../mysql-4.0CC := ccCPPFLAGS := -I$m/include -D_THREAD_SAFE -D_REENTRANTCFLAGS := -g -W -WallLDFLAGS := -staticLDLIBS = $(embed_libs) -lz -lm -lcrypt

ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))# FreeBSDLDFLAGS += -pthreadelse# Assume LinuxLDLIBS += -lpthreadendif

# Standard librariesembed_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 librariesifneq (,$(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 \

Page 60: 1 MySQL API

$m/innobase/mem/libmem.a \ $m/innobase/sync/libsync.a \ $m/innobase/ut/libut.a \ $m/innobase/os/libos.a \ $m/innobase/ut/libut.aendif

ifneq (,$(shell test -r $m/bdb/build_unix/libdb.a && echo "yes"))embed_libs += $m/bdb/build_unix/libdb.aendif

# Support librariesembed_libs += \ $m/mysys/libmysys.a \ $m/strings/libmystrings.a \ $m/dbug/libdbug.a \ $m/regex/libregex.a

# Optionally built support librariesifneq (,$(shell test -r $m/readline/libreadline.a && echo "yes"))embed_libs += $m/readline/libreadline.aendif

# This works for simple one-file test programssources := $(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 согласно более свободной лицензии.

2.10 Справочное описание MyC

2.10.1 Введение

MyC представляет собой набор простых подпрограмм C, предназначенных, чтобы сделать создание прикладных программ для использования с базой данных MySQL проще, особенно для тех, кто знаком с Microsoft DAO engine model (используемой в пакетах Microsoft Access и Microsoft Visual Basic).

Page 61: 1 MySQL API

MyC использует подобную модель, чтобы обратиться к данным внутри базы данных: OpenDatabase, чтобы открыть базу данных, OpenRecordset, чтобы открыть набор результатов, Move, чтобы двигаться внутри набора результатов, AddNew/Edit и Update/Delete, чтобы добавлять, редактировать или удалять данные внутри базы данных.

2.10.1.1 Текущая версия

Текущей версией MyC является 0.0.1 ALPHA.

2.10.1.2 Ограничения

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

Если набор результатов не имеет уникального ключа, связанного с каждой записью, то Delete() удалит только первое соответствие названной записи. Это отличие от модели DAO, в которой удаляется только в настоящий момент указанная запись, неважно первая она или нет.

Сейчас MyC работает только под Linux, но планируется перенос на другие версии UNIX. Попыток переноса на платформу Windows не было.

Никаких тестов на утечки памяти пока не проводилось для MyC.

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

2.10.1.3 Разработчик пакета

Автор этого пакета: Ed Carp. Связаться с ним можно по [email protected]. Есть и веб-страница www.pobox.com/~erc. Он технический администратор и коммерческий программный разработчик, с обширным опытом в управлении проектами от начала до конца, а также в разработке программ на C и VB.

2.10.2 Разработка приложений

2.10.2.1 Файлы заголовков

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

Page 62: 1 MySQL API

Этот файл должен быть включен первым, также нужно включить stdio.h и stdlib.h. Если директива #define MYC_DEBUG помещена перед включением database.h, то обширный код отладки будет записан в поток stderr.

2.10.2.2 Компиляция

Программы MyC компилируются аналогично любым другим программам, использующим MySQL C API.

2.10.2.3 Инициализация

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

Вызов OpenRecordset() со строкой представляющей собой корректный запрос SQL, открывает набор результатов, который содержит результаты запроса. OpenRecordset() возвращает EOF при ошибке и NULL при успехе. Число записей в наборе результатов может быть получено вызовом RecordCount(), который возвращает число записей в наборе результатов как целое число без знака.

2.10.2.4 Перемещение внутри набора результатов

Набор результатов может быть пройден и изучен с помощью вызовов MoveNext, MovePrev, MoveFirst и MoveLast, которые перемещают в следующий, предыдущий, первый и в последний результат в наборе результатов соответственно. Если набор результатов некорректен, эти подпрограммы возвращают значение EOF, иначе они возвращают NULL.

2.10.2.5 Доступ к данным

К данным в текущей строке в наборе результатов можно обращаться, вызывая GetField или GetFieldN. GetField вызывается с именем поля как параметр и возвращает символьный указатель на данные или символьный указатель на EOF в случае сбоя. GetFieldN работает подобным способом, за исключением того, что GetFieldN вызывается с номером желательного поля (отсчет начинается с 0).

2.10.2.6 Запись данных

Данные могут быть записаны в таблицу одним из двух путей: вызовом OpenRecordset() с запросом INSERT INTO или UPDATE (или любой другой имеющей силу в этом отношении инструкцией SQL), или использованием встроенных функций AddNew или Edit.

AddNew() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к Update() генерирует инструкцию SQL INSERT INTO.

Page 63: 1 MySQL API

Точно так же Edit() вызывается без параметров и устанавливает внутренние флажки так, что последующее обращение к функции Update() сгенерирует инструкцию SQL UPDATE.

Чтобы устанавливать индивидуальные поля используются SetField, SetFieldN или SetFieldB. SetField вызывается с двумя параметрами: именем поля, которое будет установлено, и значением для него. Точно так же вызывается и SetFieldN, но первый параметр задает номер поля, а не его имя. SetFieldB используется с двоичными данными, и преобразует двоичные данные и NULL в форму, которая может быть сохранена. Обратите внимание, что SetFieldB перезаписывает указанные строки. Никакого средства пока не сделано для преобразования чистых двоичных данных, хотя можно вызывать mysql_escape_string() и передавать возвращенный указатель функциям SetField или SetFieldN.

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

В конце концов поля установлены, Update() вызван с именем таблицы, которую нужно модифицировать. Update() вернет EOF при ошибке или NULL при успехе.

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

2.10.2.7 Удаление данных

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

2.10.2.8 Получение информации

В настоящее время поддерживаются следующие информационные подпрограммы, RecordCount(), FieldCount(), AbsolutePosition() и RecordsetEOF(). RecordCount возвращает целое число без знака, указывающее текущее число записей в наборе результатов. FieldCount возвращает число полей в строке набора результатов. FieldValue вызывается с номером поля и возвращает его значение, в то время как FieldName тоже вызывается с номером поля, но возвращает уже его имя. AbsolutePosition возвращает номер строки текущей строки в наборе результатов. RecordsetEOF возвращает TRUE, если не имеется никаких имеющих силу записей в наборе результатов, или если текущая строка в конце или начале набора результатов, и никаких имеющих силу записей не осталось, чтобы прочитать их из набора записей. MoveLast и MoveFirst устанавливают RecordsetEOF в TRUE.

2.10.2.9 Все и сразу

Page 64: 1 MySQL API

Прикладные программы очень просто писать с MyC. В следующих примерах существует таблица test в базе данных mysql, а в ней есть 5 записей заданных следующим образом:

+--------+-----+| name | num |+--------+-----+| item 0 | 0 || item 1 | 1 || item 2 | 2 || item 3 | 3 || item 4 | 4 |+--------+-----+

Предположим, например, что прикладная программа должна сделать запрос к базе данных и записать все данные в поток stdout:

#include "database.h"main (){ int i;

OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("select * from test"); while(RecordsetEOF () != EOF) { for (i = 0; i < FieldCount(); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0);}

Немного более сложный пример иллюстрирует добавление, изменение и удаление данных. Этот пример будет формировать таблицу test, вносить в список все данные в таблице, затем просматривать таблицу, заменяя item 3 на item 5 и попутно удаляя item 4:

#include "database.h"main (){ int i; char buf[10], buf2[5];

OpenDatabase("mysql", NULL, NULL, NULL); OpenRecordset("delete from test"); CloseRecordset(); OpenRecordset("select * from test"); for (i = 0; i < 5; i++) { AddNew(); sprintf(buf, "item %d", i);

Page 65: 1 MySQL API

sprintf(buf2, "%d", i); SetField("name", buf); SetField("num", buf2); Update("test"); } Refresh(); MoveFirst(); while (RecordsetEOF () != EOF) { for (i = 0; i < FieldCount (); i++) printf("%s\t", GetFieldN(i)); puts(""); MoveNext(); } MoveFirst (); while (RecordsetEOF () != EOF) { printf ("Looking at '%s'\n", GetField ("name")); if (strcmp(GetField("name"), "item 3") == 0) { puts("Changing data"); Edit(); SetField("name", "item 5"); Update("test"); } if (strcmp(GetField("name"), "item 4") == 0) { puts("Deleting data"); Delete("test"); } MoveNext(); } CloseRecordset(); CloseDatabase(); exit(0);}

Глава 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++

Page 66: 1 MySQL API

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

3.2. Обзор

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

Подобно работе с большинством других SQL API, процесс выполнения запросов тот же самый: 1) Вы открываете подключение, 2) Вы формируете и выполняете запросы, 3) Вы выполняете итерации через набор результатов. Однако имеется много дополнительных функциональных возможностей.

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

Это тот класс, который обрабатывает подключение к серверу Mysql. Вы всегда нуждаетесь по крайней мере в одном из этих объектов, чтобы делать что-нибудь с сервером. Этот класс может создать отдельный объект запросов или непосредственно выполнять запросы. Отдельный объект запроса является рекомендуемым путем, поскольку это дает Вам гораздо больше мощности.

Объект запроса

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

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

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

Объект Query возвращает объект с информацией относительно успеха запроса для запросов не-select (запросы, которые не возвращают набор результатов).

Наборы результатов

Page 67: 1 MySQL API

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

Динамический набор результатов

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

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

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

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

Полностью изменяемый набор результатов подобен постоянному за исключением того, что данные полностью изменчивы в том смысле, что Вы можете изменять данные в фактическом наборе результатов. Однако, в отличие от первого, этот набор результатов не связан с набором результатов из C API. Взамен это создается копия данных, возвращенных C API в двухмерном векторе. Из-за этого детализированная информация относительно каждого из столбцов в настоящее время не доступна, только имена столбца и тип в C++, который наиболее близко соответствует оригинальному типу из SQL. Кроме того, поскольку это делает копию данных, возвращенных из C API, быстродействие будет чуть пониже.

Строки во всех динамических наборах результатов очень близки к контейнеру произвольного доступа из Standard Template Library (STL). Это означает, что они имеют iterator, который может использоваться для STL-алгоритмов. Имеется несколько специализированных сервисных функций, чтобы помочь в использовании наборов результатов в STL-алгоритмах.

Page 68: 1 MySQL API

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

Page 69: 1 MySQL API

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

Специализированные структуры являются термином C++ structs. Каждый элемент члена сохранен с уникальным именем внутри структуры. Вы никоим образом не можете использовать STL-алгоритмы или что-нибудь еще из STL, чтобы работать с индивидуальными элементами структур. Однако, поскольку эти структуры все равно затем будут сохранены в STL-контейнерах, Вы можете использовать STL-алгоритмы на контейнерах этих структур. Контейнеры представляют строки, а индивидуальные элементы структуры представляют столбцы. Например, Вы можете обращаться к элементу, именованному "price" в третьей строке как к result[3].price. В динамическом наборе результатов то же самое достигается записью result[3]["price"].

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

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

Динамические полностью изменчивые наборы

Этот набор результатов будет выполнен, когда курсоры на стороне сервера будут поддерживаться в MySQL. Но, основываясь на приобретенном знании и опыте при проектирования MySQL++ и MySQLGUI, была сделана предварительная версия. Этот набор результатов полностью динамический в том смысле, что весь набор результатов сохранен в динамическом контейнере C++. Этот контейнер будет только кэшировать набор результатов, и он будет иметь заданный по умолчанию размер. Этот динамический контейнер будет окном в M строк из всего набора результатов в N строк, где N ограничено сервером MySQL. Этот набор результатов будет также полностью динамическим в том смысле, что имена столбцов и тип информации столбцов не должны быть определены во время компиляции. Но все существующие функциональные возможности статических и динамических наборов будут также доступны и в этом наборе. Этот набор будет также иметь методы для модифицирования, удаления и вставки строк, а также ряд специализированных макрокоманд для конструирования классов.

Дополнение

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

Page 70: 1 MySQL API

с методом size() и определенным оператором subscript ([]), а также универсальный класс запроса SQL, который может использоваться любым SQL C или C++ API.

Начиная с версии 1.7, имеется новое дополнение к библиотекам. Добавилось несколько очень полезных функций для строк STL, которые могут применяться в любом приложении на C++, неважно, скомпоновано оно с MySQL++ или нет. Эти функции содержатся в исходных файлах string_util.hh и string_util.cc.

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

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

Синтаксис списка равенства для SSQLS сменился с equal_list (cchar *, Manip, cchar *) на equal_list (cchar *, cchar *, Manip).

Начиная с версии 1.3 mysql++, больше не может компилироваться транслятором GNU версии ниже, чем 2.95. Начиная с версии 1.3, mysql++ был изменен, чтобы учесть и обработать изменения в различных аспектах C++ в версии 2.95. Собственно из-за этого-то пакет и перестал компилироваться версиями GNU 2.7.xx, 2.8.xx и более ранними. Также не поддерживается egcs 1.x.x. Хотя с некоторыми изменениями в коде mysql++ может быть откомпилирован и этими трансляторами выполнение таких программ кончится провалом.

Из-за проблем совместимости нельзя использовать g++ 2.95.3 и g++ 2.96. Имеются отдельные версии для компиляторов Borland C++, VC++ и Compaq

на Tru64. Было также отмечено, что на некоторых инсталляциях SPARC Solaris

исключительные ситуации C++ не работают с gcc 2.95.2. Этот случай был проверен и установлено, что mysql++ формируется безукоризненно на Solaris с помощью gcc version 2.95 19990728 (release).

Конструкторы ``connection'' для Connection и Connection::connect (формально известны как Mysql) переделаны так, чтобы имя базы данных было первым параметром. То же самое имеет силу для метода connect.

Все новые свойства клиентов, реализованные в 3.22.xx как различные параметры на connect, поддерживаются новым конструктором и методом real_connect.

Также поддерживаются новые параметры конфигурации в 3.23.xx. Mysql++ теперь может компилироваться на Win32 с использованием Cygwin

транслятора от Cygnus Inc. Autoconf и Automake полностью выполнены. Specialized SQL Structures (формально известны как Custom Mysql

Structures) изменены с mysql_ на sql_. Изменены все функции, которые возвращают ноль (false) при успехе и

отличное от ноля значение (true) в противном случае, на bool. Это означает, что они теперь возвращают true при успехе и false в противном случае. Это означает, что Вы теперь должны отрицать Ваши выражения, которые проверяют вывод этих функций.

Page 71: 1 MySQL API

Почти все методы, которые возвращали MysqlString, теперь возвращают нормальные строки. Поскольку объекты MysqlString преобразуются в строки, нет проблем с MysqlString s = mysql.host_info.

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

Добавлены все необходимые методы, имеющие отношение к административным функциям.

Mysql++ теперь цитирует и экранирует объекты автоматически, если данные столбца используются с оператором <<.

Mysql++ теперь имеет намного более безопасное выполнение INSERT, UPDATE и DELETE с новым методом exec().

Mysql++ теперь имеет лучшую конфигурацию. Имеется новый метод выборки строк. Mysql++ может работать и с двоичными данными. Сделана стандартная обработка исключений для C++ с методом what(). Вся обработка преобразований 64 int в строки теперь переместились в

libmysqlclient. Программы, написанные с применением MySQL++, теперь будут

автоматически читать все релевантные файлы конфигурации MySQL.

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

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

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

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

3.4.1 Введение

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

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

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

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

Page 72: 1 MySQL API

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

Page 73: 1 MySQL API

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"

Page 74: 1 MySQL API

<<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 Получение информации о полях

Page 75: 1 MySQL API

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

Page 76: 1 MySQL API

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

Page 77: 1 MySQL API

}}

Как Вы можете видеть, 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; }}

Page 78: 1 MySQL API

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

Page 79: 1 MySQL API

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

Page 80: 1 MySQL API

}

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

Page 81: 1 MySQL API

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[]){

Page 82: 1 MySQL API

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 {

Page 83: 1 MySQL API

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.

Page 84: 1 MySQL API

#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. Обзор классов

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

Page 85: 1 MySQL API

3.3.5.1 struct BadConversion

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

Тип

instantiable

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

coldata1.hh

Описание

Методы public

BadConversion (const char* tn, const char* d, size_t r, size_t a) size_t actual_size const string data size_t retrieved const char* type_name

3.5.2 class BadNullConversion

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

Тип

instantiable

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

null1.hh

3.5.3 class Connection

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

Тип

instantiable

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

connection1.hh

Page 86: 1 MySQL API

Описание

Методы public

Connection () Connection (bool te) Connection (const char *db, const char *host = "", const char *user = "", const

char *passwd = "", bool te = true) Connection (const char *db, const char *host, const char *user, const char

*passwd, uint port, my_bool compress = 1, unsigned int connect_timeout = 5, bool te=true, cchar *socket_name = "")

int affected_rows () operator bool ()

возвращает success() string clinet_info () void close () bool connect (cchar *db = "", cchar *host = "", cchar *user = "", cchar *passwd =

"") bool connected () const

возвращает true, если соединение успешно установлено bool create_db (string db) bool drop_db (string db) int errnum () string error ()

послкднее сообщение об ошибке bool exec (const string &str) ResNSel execute (const string &str) ResNSel execute (const string &str, bool te) st_mysql_options get_options (void) const string host_info () string info () string infoo (void) int insert_id () int kill (unsigned long pid) bool lock () int ping (void) int proto_info () void purge (void) inline Query query () int read_options (enum mysql_option option, const char *arg) bool real_connect (cchar *db = "", cchar *host = "", cchar *user = "", cchar

*passwd = "", uint port = 0, my_bool compress = 0, unsigned int connect_timeout = 60, cchar *socket_name= "")

int refresh (unsigned int refresh_options) bool reload () bool select_db (const char *db) bool select_db (string db)

Page 87: 1 MySQL API

string server_info () bool shutdown () string stat () Result store (const string &str) Result store (const string &str, bool te) template class T void storein (deque T &con, const string &s) template class T void storein (list T &con, const string &s) template class T void storein (multiset T &con, const string &s) template class T void storein (set T &con, const string &s) template class T void storein (slist T &con, const string &s) template class T void storein (vector T &con, const string &s) template class Sequence void storein_sequence (Sequence &, const string &) template class Set void storein_set (Set &, const string &)

Сохраняет результаты в TYPE. TYPE может быть любым типом контейнера STL.

bool success ()возвращает true, если последний запрос был удачным

void unlock () ResUse use (const string &str) ResUse use (const string &str, bool te) ~ Connection ()

Методы Friend

friend Query friend ResNSel friend ResUse

3.5.4 struct Date

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

Тип

instantiable

Суперклассы

public mysql_date, public MysqlDTbase Date

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

datetime1.hh

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

Page 88: 1 MySQL API

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

Методы public

Date () Date (cchar* str) Date (const string &str) Date (const string &str) short int compare (const Date& other) const

3.5.5 struct DateTime

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

Тип

instantiable

Суперклассы

public mysql_date, public mysql_time, public MysqlDTbase DateTime

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

datetime1.hh

Описание

Методы public

DateTime () DateTime (cchar* str) DateTime (const string &str) DateTime (const string &str) short int compare (const DateTime& other) const cchar* convert (cchar*) ostream& out_stream (ostream&) const

3.5.6 class FieldNames

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

Тип

instantiable

Page 89: 1 MySQL API

Суперклассы

public vector string

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

field_names1.hh

Описание

Методы public

FieldNames () FieldNames (const ResUse *res) FieldNames (int i) FieldNames& operator = (const ResUse *res)

Создает новый список из данных в res. FieldNames& operator = (int i)

Создает новый список с i именами полей. string& operator (int i)

Возвращает имя поля для указанного индекса в списке. const string& operator (int i) const

Возвращает имя поля для указанного индекса в списке. uint operator (string i) const

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

3.5.7 class FieldTypes

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

Тип

instantiable

Суперклассы

public vector mysql_type_info

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

field_types1.hh

Описание

Методы public

FieldTypes ()

Page 90: 1 MySQL API

FieldTypes (const ResUse *res) FieldTypes (int i) FieldTypes& operator = (const ResUse *res)

Создает новый список, основанный на информации в res FieldTypes& operator = (int i)

Создает новый список с i полями. mysql_type_info& operator (int i)

Возвращает тип поля для поля со смещением i. const mysql_type_info& operator (int i) const

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

3.5.8 class Fields

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

Тип

instantiable

Суперклассы

public const_subscript_container Fields, Field

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

fields1.hh

Описание

Методы public

Fields () Fields (ResUse *r) const Field& operator (int i) const const Field& operator (size_type i) const size_type size () const

Число полей. Возвращает поле со смещением i.

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

Тип

instantiable

Суперклассы

public unary_function const MysqlRow&, bool

Page 91: 1 MySQL API

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

compare1.hh

Описание

Методы public

MysqlCmp (uint i, const BinaryPred &f, const CmpType &c) bool operator () (const MysqlRow& cmp1) const

Методы Protected

CmpType cmp2 BinaryPred func unsigned int index

3.5.10 template class MysqlCmpCStr class BinaryPred

Тип

instantiable

Суперклассы

public MysqlCmp BinaryPred, const char *

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

compare1.hh

Описание

Методы public

MysqlCmpCStr (uint i, const BinaryPred &f, const char* c) bool operator () (const MysqlRow& cmp1) const

3.5.11 template struct MysqlDTbase class T

Тип

abstract

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

datetime1.hh

Page 92: 1 MySQL API

Методы public

virtual short int compare (const T &other) const bool operator != (const T &other) const bool operator (const T &other) const bool operator = (const T &other) const bool operator == (const T &other) const bool operator (const T &other) const bool operator = (const T &other) const

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

Тип

instantiable

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

set1.hh

Методы public

MysqlListInsert (T *o) void operator () (const value_type &data)

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

Тип

instantiable

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

set1.hh

Методы public

MysqlSetInsert (T *o) void operator () (const key_type &data)

3.5.14 template class Null class Type, class Behavior = NullisNull

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

Тип

Page 93: 1 MySQL API

instantiable

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

null1.hh

Методы public

Null () Null (Type x) Null (const null_type &n)

Дает Null значение null. Type data bool is_null Null& operator = (const null_type &n) Null& operator = (const null_type &n) typedef Type value_type

3.5.15 struct NullisBlank

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

Тип

instantiable

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

null1.hh

Описание

Методы public

static const char * null_is () static ostream& null_ostr (ostream &o)

3.5.16 struct NullisNull

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

Тип

instantiable

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

Page 94: 1 MySQL API

null1.hh

Описание

Методы public

static null_type null_is () static ostream& null_ostr (ostream& o)

3.5.17 struct NullisZero

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

Тип

instantiable

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

null1.hh

Описание

Методы public

static int null_is () static ostream& null_ostr (ostream &o)

3.5.18 class Query

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

Тип

instantiable

Суперклассы

public SQLQuery

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

query1.hh

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

Page 95: 1 MySQL API

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

Описание

Методы public

Query (Connection *m, bool te = false) Создает новый объект запроса, связанный с подключением.

Query (const Query &q) string error ()

Сообщение об ошибке, если запрос не был успешным. bool exec (const string &str)

Выполняет запрос в буфере строк и возвращает структуру, которая содержит информацию о том, насколько успешным был запрос. Используйте это для запросов, которые не возвращают набор результатов, например, INSERT или UPDATE. Параметром может что-либо в имеющем силу SQLQuery.

template class T Query& insert (const T &v) Query& operator = (const Query &q) string preview () string preview (parms &p) template class T Query& replace (const T &v) bool success ()

Отображает строку, которая в настоящее время лежит в буфере. Аналогично string().

3.5.19 struct ResNSel

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

Тип

instantiable

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

result1.hh

Описание

Методы public

ResNSel () ResNSel (Connection *q)

Page 96: 1 MySQL API

operator bool ()Если запрос был успешным.

string infoДополнительная информация о запросе.

int insert_id int rows

Число обработанных строк. bool success

3.5.20 class ResUse

Тип

instantiable

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

result1.hh

Описание

Методы public

ResUse () ResUse (MYSQL_RES *result, Connection *m = NULL, bool te = false) ResUse (const ResUse &other) operator bool () const unsigned int columns () const bool eof () const

Функция c api. Field& fetch_field () const

Функция c api field. long unsigned int * fetch_lengths () const

Функция c api. Row fetch_row ()

Функция c api. inline string& field_name (int)

Возвращает поле со смещением i. inline const string& field_name (int) const

Возвращает поле-константу со смещением i. inline FieldNames& field_names ()

Возвращает ссылку на основнорй класс FieldNames. inline const FieldNames& field_names () const

Возвращает ссылку на основнорй класс FieldNames. inline int field_num (const string&) const

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

Page 97: 1 MySQL API

void field_seek (int field) Функция c api field.

inline mysql_type_info& field_type (int i) Возвращает ссылку на тип поля mysql для поля со смещением i.

inline const mysql_type_info& field_type (int) const Возвращает ссылку-константу на тип поля mysql для поля со смещением i.

inline FieldTypes& field_types () Возвращает ссылку на основной FieldTypes.

inline const FieldTypes& field_types () const Возвращает ссылку-константу на основной FieldTypes.

const Fields& fields () const Возвращает ссылку на структуру Fields.

const Field& fields (unsigned int i) const Возвращает ссылку на информацию mysql о поле для поля со смещением i.

MYSQL_RES * mysql_result (void) inline FieldNames& names ()

Возвращает ссылку на основной класс FieldNames. inline const FieldNames& names () const

Возвращает ссылку-константу на основной класс FieldNames. inline int names (const string& s) const

Возвращает смещение для объекта, который равняется str. inline string& names (int i)

Возвращает поле со смещением i. inline const string& names (int i) const

Возвращает поле со смещением i. int num_fields () const

Функция c api field. bool operator != (const ResUse &other) const inline ResUse& operator = (const ResUse &other) bool operator == (const ResUse &other) const void parent_leaving () void purge (void) inline void reset_field_names ()

Сбрасывает имена полей к первоначальным значениям. inline void reset_field_types ()

Сбрасывает field_types к первоначальным значениям. inline void reset_names ()

Сбрасывает имена полей к первоначальным значениям. inline void reset_types ()

Сбрасывает имена полей к первоначальным значениям. string& table ()

Имя таблицы. const string& table () const

Имя таблицы. inline FieldTypes& types ()

Возвращает ссылку на основной FieldTypes.

Page 98: 1 MySQL API

inline const FieldTypes& types () const Возвращает ссылку-константу на основной FieldTypes.

inline mysql_type_info& types (int i) Возвращает ссылку на тип поля mysql для поля со смещением i.

inline const mysql_type_info& types (int i) const Возвращает ссылку-константу на тип поля mysql для поля со смещением i.

~ ResUse ()

Методы protected

Fields _fields mutable FieldNames * _names string _table mutable FieldTypes * _types void copy (const ResUse& other) Connection * mysql mutable MYSQL_RES * mysql_res bool throw_exceptions, initialized

Методы friend

friend Connection

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

Page 99: 1 MySQL API

Result () Result (MYSQL_RES *result, bool te = false) Result (const Result &other) void data_seek (uint offset) const

Функция c api const Row fetch_row () const

Функция c api int num_rows () const

Функция c api const Row operator (size_type i) const

Возвращает строку со смещением i. size_type rows () const

Возвращает число строк. size_type size () const

Возвращает число строк. virtual ~ Result ()

Методы Friend

friend Connection

3.5.22 class Row

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

Тип

instantiable

Суперклассы

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

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

row1.hh

Методы public

Row () Row (MYSQL_ROW d, const ResUse *r, unsigned int *jj, bool te = false) operator bool () const

Возвращает true, если имеются какие-либо данные в строке. inline const ColData operator (const string &i) const

Возвращает значение поля с именем поля i. Этот метод не столь эффективен как использование индексного кода.

Page 100: 1 MySQL API

inline const ColData operator (const string &i) const Возвращает значение поля с именем поля i. Этот метод не столь эффективен как использование индексного кода.

const ColData operator (int i) const inline const ColData operator (size_type i) const

Возвращает значение поля с индексом поля i. const ResUse& parent () const const char * raw_data (int i) const Row& self () const Row& self () const inline size_type size () const

Возвращает число столбцов. ~ Row ()

3.5.23 template class RowTemplate class ThisType, class Res

Тип

abstract

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

row1.hh

Методы public

equal_list_ba FieldNames,ThisType,quote_type0 equal_list (const char *d = ",", const char *e = " = ") const

template class Manip equal_list_ba FieldNames,ThisType,Manip equal_list (const char *d, const char *e, Manip m) const

value_list_b FieldNames,quote_type0 field_list (bool t0, bool t1=false, bool t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc=false) const

value_list_b FieldNames,quote_type0 field_list (const vector bool &vb) const value_list_b FieldNames,quote_type0 field_list (const vector bool &vb) const template class Manip value_list_ba FieldNames,Manip field_list (const char *d,

Manip m) const template class Manip value_list_b FieldNames,Manip field_list (const char *d,

Manip m, bool t0, bool t1=false, bool t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc=false) const

template class Manip value_list_b FieldNames,Manip field_list (const char *d, Manip m, const vector bool &vb) const

template class Manip value_list_b FieldNames,Manip field_list (const char *d, Manip m, string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

Page 101: 1 MySQL API

value_list_b FieldNames,quote_type0 field_list (const char *d, bool t0, bool t1=false, bool t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc

value_list_b FieldNames,quote_type0 field_list (const char *d, const vector bool &vb) const

value_list_b FieldNames,quote_type0 field_list (const char *d, string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

value_list_b FieldNames,quote_type0 field_list (string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

virtual const Res & parent () const value_list_b ThisType,quote_type0 value_list (bool t0, bool t1=false, bool

t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc=false) const

value_list_b ThisType,quote_type0 value_list (const vector bool &vb) const value_list_b ThisType,quote_type0 value_list (const vector bool &vb) const template class Manip value_list_ba ThisType,Manip value_list (const char *d,

Manip m) const template class Manip value_list_b ThisType,Manip value_list (const char *d,

Manip m, bool t0, bool t1=false, bool t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc=false) const

template class Manip value_list_b ThisType,Manip value_list (const char *d, Manip m, const vector bool &vb) const

template class Manip value_list_b ThisType,Manip value_list (const char *d, Manip m, string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

value_list_b ThisType,quote_type0 value_list (const char *d, bool t0, bool t1=false, bool t2=false, bool t3=false, bool t4=false, bool t5=false, bool t6=false, bool t7=false, bool t8=false, bool t9=false, bool ta=false, bool tb=false, bool tc=false) const

value_list_b ThisType,quote_type0 value_list (const char *d, const vector bool &vb) const

value_list_b ThisType,quote_type0 value_list (const char *d, string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

value_list_b ThisType,quote_type0 value_list (string s0, string s1="", string s2="", string s3="", string s4="", string s5="", string s6="", string s7="", string s8="", string s9="", string sa="", string sb="", string sc="") const

virtual ~ RowTemplate ()

Методы protected

protected pure virtual ThisType& self ()

Page 102: 1 MySQL API

protected pure virtual const ThisType& self () const

3.5.24 struct SQLParseElement

Тип

instantiable

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

sql_query1.hh

Описание

Методы public

SQLParseElement (string b, char o, char n) string before char num char option

3.5.25 class SQLQuery

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

Тип

instantiable

Суперклассы

public strstream

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

sql_query1.hh

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

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

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

Page 103: 1 MySQL API

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

Методы public

SQLQuery () SQLQuery (const SQLQuery &q) operator bool () SQLQueryParms def

Заданный по умолчанию шаблон набора параметров. string error () const template class T SQLQuery& insert (const T &v) mysql_query_define_const1 (string,str) bool operator ! ()

Возвращает полную строку запроса, заменяя ее заданными по умолчанию параметрами шаблона в случае необходимости. Подобно str(query_reset), но устанавливает параметры запроса от 0 до 11. Здесь query_reset может быть DONT_RESET или RESET_QUERY. Если это установлено в RESET_QUERY, то reset() будет вызван после того, как запрос возвращен. Если не имеется достаточно параметров, то это возвратит пустую строку, а success() будет равно false. Если любой из требуемых параметров равен null, этот метод произведет ошибку и возвратит пустую строку.

SQLQuery& operator = (const SQLQuery &q) void parse () template class T SQLQuery& replace (const T &v) bool success () const

Методы Protected

bool Success char* errmsg typedef SQLQueryParms parms vector SQLParseElement parsed vector string parsed_names map string,int parsed_nums void proc (parms &p) typedef const SQLString& ss

Методы Friend

friend SQLQueryParms

3.5.26 struct SQLQueryNEParms

Page 104: 1 MySQL API

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

Тип

instantiable

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

sql_query1.hh

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

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

Методы public

SQLQueryNEParms (const char *c) const char* error

3.5.27 class SQLQueryParms

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

Тип

instantiable

Суперклассы

public vector SQLString

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

sql_query1.hh

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

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

Методы public

SQLQueryParms () SQLQueryParms (SQLQuery *p) bool bound () void clear ()

Очищает весь список.

Page 105: 1 MySQL API

SQLQueryParms operator + (const SQLQueryParms &other) const Устанавливает элементы списка: 0 в a, 1 в b и т.д. Может определять до дюжины элементов.

SQLQueryParms & operator += (const SQLString &str) Добавляет элемент в список.

SQLQueryParms & operator (const SQLString &str) Добавляет элемент в список.

SQLString & operator (const char *str) Обращается к значению элемента с ключом str.

const SQLString & operator (const char *str) const Обращается к значению элемента с ключом str.

SQLString & operator (size_type n) Обращается к элементу с кодом n.

const SQLString & operator (size_type n) const Обращается к элементу с кодом n.

void set (ss a) void set (ss a, ss b) void set (ss a, ss b, ss c) void set (ss a, ss b, ss c, ss d) void set (ss a, ss b, ss c, ss d, ss e) void set (ss a, ss b, ss c, ss d, ss e, ss f) void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g) void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h) void set (ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i) void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j) void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k) void set (ss a,ss b,ss c,ss d,ss e,ss f,ss g,ss h,ss i,ss j,ss k, ss l)

Методы friend

friend Query

3.5.28 class SQLString

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

Тип

instantiable

Суперклассы

public string

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

sql_string1.hh

Page 106: 1 MySQL API

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

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

Методы public

SQLString () SQLString (char i) SQLString (const char *str) SQLString (const char *str) SQLString (double i) SQLString (float i) SQLString (int i) SQLString (short int i) SQLString (unsigned int i) SQLString (unsigned int i) SQLString (unsigned int i) bool dont_escape bool is_string SQLString& operator = (const string& str) SQLString& operator = (const string& str) bool processed

3.5.29 template class Set class Container = set string

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

Тип

instantiable

Суперклассы

public Container

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

set1.hh

Методы public

Set (const ColData &str) Set (const ColData &str) Set (const ColData &str) ostream& out_stream (ostream &s) const operator string ()

Page 107: 1 MySQL API

3.5.30 struct Time

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

Тип

instantiable

Суперклассы

public mysql_time, public MysqlDTbase Time

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

datetime1.hh

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

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

Методы public

Time () Time (cchar* str) Time (const string &str) Time (const string &str) short int compare (const Time& other) const

3.5.31 class const_string

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

Тип

instantiable

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

const_string1.hh

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

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

Page 108: 1 MySQL API

Методы public

const_iterator begin () const const char* c_str () const typedef const char* const_iterator typedef const char* const_pointer typedef const char& const_reference const_string () const_string (const char *str) const char* data () const typedef int difference_type const_iterator end () const typedef const_iterator iterator

Также как const_iterator потому, что данные не могут быть изменены. size_type length () const size_type max_size () const const_reference operator (size_type pos) const typedef const_pointer pointer typedef const_reference reference typedef unsigned int size_type typedef const char value_type

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

iterator begin () const typedef iterator const_iterator typedef value_type* const_pointer

Page 109: 1 MySQL API

typedef value_type& const_reference typedef const ::reverse_iterator const_iterator const_reverse_iterator typedef DiffType difference_type bool empty () const iterator end () const typedef subscript_iterator const this_type, ReturnType, SizeType, DiffType

iterator size_type max_size () const virtual ReturnType operator (SizeType i) const typedef value_type* pointer reverse_iterator rbegin () const typedef value_type& reference reverse_iterator rend () const typedef const ::reverse_iterator iterator reverse_iterator virtual size_type size () const typedef SizeType size_type typedef const_subscript_container OnType,ValueType,ReturnType,SizeType,

DiffType this_type typedef ValueType value_type

3.5.33 struct cstr_equal_to

Тип

instantiable

Суперклассы

bin_char_pred

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

compare1.hh

Методы public

bool operator () (const char *x, const char *y) const

3.5.34 struct cstr_greater

Тип

instantiable

Суперклассы

bin_char_pred

Page 110: 1 MySQL API

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

compare1.hh

Методы public

bool operator () (const char *x, const char *y) const

3.5.35 struct cstr_greater_equal

Тип

instantiable

Суперклассы

bin_char_pred

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

compare1.hh

Методы public

bool operator () (const char *x, const char *y) const

3.5.36 struct cstr_less

Тип

instantiable

Суперклассы

bin_char_pred

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

compare1.hh

Методы public

bool operator () (const char *x, const char *y) const

3.5.37 struct cstr_less_equal

Тип

Page 111: 1 MySQL API

instantiable

Суперклассы

bin_char_pred

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

compare1.hh

Методы public

bool operator () (const char *x, const char *y) const

3.5.38 struct cstr_not_equal_to

Тип

instantiable

Суперклассы

bin_char_pred

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

compare1.hh

Описание

Методы public

bool operator () (const char *x, const char *y) const

3.5.39 struct do_nothing_type1

Тип

instantiable

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

manip1.hh

Методы public

do_nothing_type1 (ostream *o)

Page 112: 1 MySQL API

ostream * ostr

3.5.40 struct do_nothing_type2

Тип

instantiable

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

manip1.hh

Методы public

do_nothing_type2 (SQLQueryParms *p) SQLQueryParms * qparms

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

Тип

instantiable

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

vallist1.hh

Методы public

const char * delem equal_list_b (const Seq1 &s1, const Seq2 &s2, const vector bool &f, const char

*d, const char *e, Manip m) const char * equl const vector bool fields const Seq1 * list1 const Seq2 * list2 Manip manip

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

Тип

instantiable

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

vallist1.hh

Page 113: 1 MySQL API

Методы public

const char * delem equal_list_ba (const Seq1 &s1, const Seq2 &s2, const char *d, const char *e,

Manip m) const char * equl const Seq1 * list1 const Seq2 * list2 Manip manip

3.5.43 struct escape_type1

Тип

instantiable

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

manip1.hh

Методы public

escape_type1 (ostream *o) ostream * ostr

3.5.44 struct escape_type2

Тип

instantiable

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

manip1.hh

Методы public

escape_type2 (SQLQueryParms *p) SQLQueryParms * qparms

3.5.45 struct ignore_type2

Тип

instantiable

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

Page 114: 1 MySQL API

manip1.hh

Методы public

ignore_type2 (SQLQueryParms *p) SQLQueryParms * qparms

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

template class T, class B operator Null T, B () const operator cchar* () const operator unsigned char () const operator unsigned char () const template class Type Type conv (Type dummy) const

Преобразует данные столбца в TYPE. Если все символы не читаются в течение преобразования в TYPE, породит исключение BadConversion. TYPE определен для всего, созданного в типах. Обратите внимание: это не фактический шаблон.

Page 115: 1 MySQL API

operator double () const bool escape_q () const

Возвращает true или false в зависимости от того, экранированы ли данные. inline const string& get_string (void) const operator unsigned long int () const operator unsigned long int () const operator unsigned long int () const operator unsigned long int () const operator unsigned long int () const operator unsigned long int () const inline const bool is_null (void) const void it_is_null (void) mysql_ColData () bool quote_q () const

Возвращает true или false в зависимости от того, цитированы ли данные. mysql_type_info type ()

Возвращает текущий тип mysql для актуального элемента. operator ulonglong () const

3.5.47 class mysql_convert

Тип

instantiable

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

convert1.hh

3.5.48 struct mysql_date

Тип

instantiable

Суперклассы

virtual public mysql_dt_base

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

datetime1.hh

Методы public

cchar* convert (cchar*) tiny_int day

Page 116: 1 MySQL API

tiny_int month ostream& out_stream (ostream&) const short int year

Методы protected

short int compare (const mysql_date *other) const

3.5.49 struct mysql_dt_base

Тип

abstract

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

datetime1.hh

Методы public

virtual ostream& out_stream (ostream&) const operator string ()

3.5.50 class mysql_ti_sql_type_info

Тип

instantiable

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

type_info1.hh

Методы friend

friend mysql_ti_sql_type_info_lookup friend mysql_type_info

3.5.51 class mysql_ti_sql_type_info_lookup

Тип

instantiable

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

type_info1.hh

Page 117: 1 MySQL API

Методы friend

friend mysql_type_info

3.5.52 struct mysql_time

Тип

instantiable

Суперклассы

virtual public mysql_dt_base

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

datetime1.hh

Методы public

cchar* convert (cchar*) tiny_int hour tiny_int minute ostream& out_stream (ostream&) const tiny_int second

Методы protected

short int compare (const mysql_time *other) const

3.5.53 class mysql_type_info

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

Тип

instantiable

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

type_info1.hh

Описание

Методы public

unsigned int _length

Page 118: 1 MySQL API

unsigned int _max_length inline const mysql_type_info base_type () const

Возвращает type_info для внутреннего типа C++ внутри типа Null. Если тип не Null, работает аналогично c_type().

bool before (mysql_type_info &b) Обеспечивает упорядочение данных. Вы можете также использовать id() для той же самой цели.

inline const type_info& c_type () const bool escape_q () const

Возвращает true, если тип sql представляет собой тип, который должен быть экранирован.

int id () constВозвращает id для sql_type. Обратите внимание: не используйте этот идентификатор непосредственно, поскольку он может изменяться между версиями.

inline const unsigned int length () const inline const unsigned int max_length () const

Возвращает type_info для типа C++, связанного с типом sql. mysql_type_info () mysql_type_info (const type_info &t) mysql_type_info (const type_info &t) inline mysql_type_info (const MYSQL_FIELD &f) inline mysql_type_info (enum_field_types t, bool _unsigned, bool _null) mysql_type_info (unsigned char n) inline const char* name () const

Возвращает значение, определяющее имя типа c++. Возвращает имя, которое было бы возвращено typeid().name() для типа C++, связанного с типом sql.

mysql_type_info& operator = (const type_info &t) mysql_type_info& operator = (const type_info &t) mysql_type_info& operator = (unsigned char n) bool quote_q () const

Вернет true, если этот тип sql должен быть цитирован. inline const char* sql_name () const

Возвращает имя для типа sql. static const unsigned char string_type

3.5.54 class null_type

Тип

instantiable

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

null1.hh

Page 119: 1 MySQL API

Методы public

template class Type operator Type ()

3.5.55 struct quote_double_only_type1

Тип

instantiable

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

manip1.hh

Методы public

ostream * ostr quote_double_only_type1 (ostream *o)

3.5.56 struct quote_double_only_type2

Тип

instantiable

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

manip1.hh

Методы public

SQLQueryParms * qparms quote_double_only_type2 (SQLQueryParms *p)

3.5.57 struct quote_only_type1

Тип

instantiable

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

manip1.hh

Методы public

ostream * ostr

Page 120: 1 MySQL API

quote_only_type1 (ostream *o)

3.5.58 struct quote_only_type2

Тип

instantiable

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

manip1.hh

Методы public

SQLQueryParms * qparms quote_only_type2 (SQLQueryParms *p)

3.5.59 struct quote_type1

Тип

instantiable

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

manip1.hh

Описание

Методы public

ostream * ostr quote_type1 (ostream *o)

3.5.60 struct quote_type2

Тип

instantiable

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

manip1.hh

Методы public

SQLQueryParms * qparms

Page 121: 1 MySQL API

quote_type2 (SQLQueryParms *p)

3.5.61 template class simp_list_b class Iter

Тип

instantiable

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

vallist1.hh

Методы public

Iter _begin Iter _end Iter begin () const typedef Iter const_iterator Iter end () const simp_list_b (Iter b, Iter e)

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

bool operator != (const subscript_iterator &j) const ReturnType operator * () const subscript_iterator operator + (SizeType n) const subscript_iterator& operator ++ () subscript_iterator operator ++ (int) subscript_iterator& operator += (SizeType n) subscript_iterator operator - (SizeType n) const DiffType operator - (const subscript_iterator &j) const subscript_iterator& operator - ()

Page 122: 1 MySQL API

subscript_iterator operator - (int) subscript_iterator& operator -= (SizeType n) ReturnType operator - () const bool operator (const subscript_iterator &j) const bool operator = (const subscript_iterator &j) const bool operator == (const subscript_iterator &j) const bool operator (const subscript_iterator &j) const bool operator = (const subscript_iterator &j) const ReturnType operator (SizeType n) const subscript_iterator () subscript_iterator (OnType *what, SizeType pos)

3.5.63 struct type_info_cmp

Тип

instantiable

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

type_info1.hh

Методы public

bool operator() (const type_info *lhs, const type_info *rhs) const

3.5.64 template struct value_list_b class Seq, class Manip

Тип

instantiable

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

vallist1.hh

Методы public

const char * delem const vector bool fields const Seq * list Manip manip value_list_b (const Seq &s, const vector bool &f, const char *d, Manip m)

3.5.65 template struct value_list_ba class Seq, class Manip

Тип

Page 123: 1 MySQL API

instantiable

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

vallist1.hh

Методы public

const char * delem const Seq * list Manip manip value_list_ba (const Seq &s, const char* d, Manip m)

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.

Page 124: 1 MySQL API

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

Page 125: 1 MySQL API

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

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

Page 126: 1 MySQL API

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.

Page 127: 1 MySQL API

Следует, однако, помнить, что 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)

Это установит следующую структуру:

Page 128: 1 MySQL API

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

Page 129: 1 MySQL API

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 переменных. Например:

Page 130: 1 MySQL API

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

# задает числом переменных в векторе. NAME определяет имя структуры, которую Вы желаете создать CMP указывает, что если он не равен 0, и первые cmp переменных совпадут,

то структуры одинаковы. CNST указывает, что если он не равен 0, создается конструктор, который

заполнит первые n переменных. TYPE1 определяет имя типа для первого элемента, ITEM1 указывает

переменную для первого элемента и т.д.

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 такой:

Page 131: 1 MySQL API

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

# задает числом переменных в векторе. NAME определяет имя структуры, которую Вы желаете создать CMP указывает, что если он не равен 0, и первые cmp переменных совпадут,

то структуры одинаковы. CNST указывает, что если он не равен 0, создается конструктор, который

заполнит первые n переменных. TYPE1 задает имя типа для первого элемента, ITEM1 имя переменной для

него, ORDER1 указывает порядок для первого элемента и т.д.

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

Page 132: 1 MySQL API

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,

Page 133: 1 MySQL API

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;

выведет показанное в предыдущем примере.

Page 134: 1 MySQL API

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

Page 135: 1 MySQL API

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"

Page 136: 1 MySQL API

Это заменит имя таблицы на "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++. После этого в принудительном порядке будут использоваться исключительно длинные имена. Их соответствие коротким такое:

Короткое имя Длинное имяBadQuery MysqlBadQueryConnection MysqlConnectionResNSel ResNSel

Page 137: 1 MySQL API

ResUse ResUse MysqlResUseResult MysqlResField MysqlFieldFields MysqlFieldsResIter MysqlResIterResultIter MysqlResIterRow MysqlRowMutableRow MysqlMutableRowFieldNames MysqlFieldNamesQuery MysqlQueryBadConversion MysqlBadConversion ColData MysqlColDataMutableColData MysqlMutableColDataquote mysql_quotequote_only mysql_quote_onlyquote_double_only mysql_quote_double_onlyescape mysql_escapedo_nothing mysql_do_nothingignore mysql_ignoreDate MysqDateTime MysqlTimeDateTime MysqlDateTimeSet MysqlSetNull MysqlNullnull_type mysql_null_typenull mysql_nullNullisNull MysqlNullisNullNullisZero MysqlNullisZeroNullisBlank MysqlNullisBlank

3.9 Библиотека-оболочка mysql для C++

Автор: Roland Haenel ([email protected]). Эта программа является public domain. Распространять и использовать ее можно совершенно свободно.

Это маленькая оболочка для C++, которая написана вокруг базисной клиентской библиотеки mysql. Целью было создание единого универсального интерфейса для следующих баз данных:

mysql (разработан Michael Widenius). msql (разработан David Hughes).

Page 138: 1 MySQL API

postgres95 (разработан Postgres Group).

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

Программа примера может быть найдена в example.cc. Некоторые слова относительно классов библиотеки:

Класс Database обеспечивает интерфейс связи с базой данных mysqld. Следующие методы выполнены:

int Database::init()Фактически это не делает ничего в настоящее время, но вызовите его перед выполнением чего-нибудь еще. Это может быть важно для будущих выпусков.

int Database::status();Может быть вызван в любое время. Возвращает состояние подключения: DB_CONNECTION_NONE, DB_CONNECTION_OK или DB_CONNECTION_BAD.

char Database::*errorMessage();Если произошла ошибка, возвращает текст, описывающий ошибку

int Database::connect(char *host, char *port, char *db);Соединяется с базой данных db на машине host. Обратите внимание, что параметр port в настоящее время еще не задействован.

void Database::disconnect();Закрывает текущее подключение.

int Database::reset();Пока не реализовано.

DBResult *Database::exec(char *sqlFormat, ...);void Database::exec(DBResult *res, char *sqlFormat, ...);Выполнить произвольную команду SQL. Первая форма возвращает экземпляр класса DBResult (даже если имелся сбой). Последняя форма повторно использует уже созданный экземпляр класса DBResult.

int DBResult::status();Возвращает состояние транзакции, связанное с экземпляром класса. Значения могут быть следующими:

#define DB_COMMAND_OK 0 // OK: команда выполнена #define DB_EMPTY_QUERY 1 // Запрос не вернул данных #define DB_TUPLES_OK 2 // Запрос вернул данные #define DB_ERROR 5 // Ошибка в команде #define DB_BAD_RESPONSE 6 // Неправильный ответ сервера #define DB_UNEXPECTED 7 // Непонятная ошибка

int DBResult::nrTuples();Возвращает число выбранных записей (если status() == DB_TUPLES_OK).

int DBResult::nrFields();Возвращает число полей в записи (если status() == DB_TUPLES_OK).

Page 139: 1 MySQL API

char *DBResult::fieldName(int n);Возвращает имя поля n.

int DBResult::fieldSize(int n);Возвращает размер в байтах поля с номером n.

int DBResult::fieldSize(char *name);Возвращает размер в байтах поля с именем name.

void DBResult::seekTuple(int tuple);Устанавливает внутренний курсор на запись tuple. Она будет возвращена следующим вызовом getTuple().

char **DBResult::getTuple();Возвращает одну запись. Вызов getTuple()[0] вернет значение первого поля и т.д.

char **DBResult::getTuple(int tuple);Прямой доступ к записи. Для последовательного доступа, пожалуйста, не используйте этот метод. Применяйте вместо него сочетание seekTuple()/getTuple().

3.10 MyDAO: библиотека-оболочка для C++

Версия v0.1 (19-Feb-2000). Автор: Satish ([email protected]). Лицензия: Feel free to use/copy/modify/add bugs/find bugs, but keep the author informed.

Введение

Это C++ библиотека для сервера MySQL. Разработчик данного пакета искал библиотеку C++, которая может создавать и работать с Data Access Objects. Он натолкнулся на программное обеспечение, написанное Roland Hanel (MySQL C++) и Ed Carp (MyC). Но MyC написан на чистом C и не может создавать объект в истинном смысле. Также это не может создавать и работать с несколькими наборами результатов. На основе этих пакетов была написан пакет MyDAO ver 0.1.

Руководство программиста

dbconnect class: Один объект подключения должен быть создан. Это ответственно за соединение с сервером MySQL и открытие базы данных. Свойства:

bool Connected;Connected равно true, если подключение к серверу MySQL работает.

MYSQL *DBase;DBase является указателем на структуру MYSQL. Это требуется, чтобы открыть набор результатов.

Методы:

void dbconnect::Connect(char *host, char *port, char *uname, char*pwd);Пытается соединиться с сервером MySQL, используя указанные параметры

Page 140: 1 MySQL API

хоста, порта, имени пользователя и пароля. Если подключение успешно установлено, свойство Connected будет true.

void dbconnect::Disconnect();Разъединяет текущее подключение с сервером MySQL.

bool dbconnect::OpenDB(char *db);Открывает базу данных db. Если все в порядке, вернет true.

Пример:

dbconnect MyConnect;char host[]="localhost";char port[]="3306";char name[]="satish";char pwd[]="";char db[]="orders";

MyConnect.Connect(host, port, name, pwd);if (MyConnect.Connected) cout << "Connected" << endl;else{ cout << "Connection failed" << endl; return;}if (!MyConnect.OpenDB(db)) { cout << "Can not open selected database" << endl; return;}else{ cout << "Opened datbase: " << db << endl; // open recorset(s)... // Manipulate data...}MyConnect.Disconnect();

recordset class: Любое количество наборов результатов может быть создано из этого класса. Он имеет много свойств для простого манипулирования данными.

Свойства:

char RecSource[MAX_RECSRC_LEN];Источник записей, из которых данные должны обрабатываться. Это должна быть SQL-инструкция SELECT, возвращающая записи.

unsigned long int RecordCount;Число строк в открытом наборе результатов.

unsigned long int AffectedRows;Может использоваться только с Update, AddNew или Delete. Число строк фактически обработанных сервером.

bool EOR;Конец набора результатов. True, если Вы двигаетесь в последнюю строку.

Page 141: 1 MySQL API

bool BOR;Начало набора результатов. True, если Вы двигаетесь первую строку. Замечание: EOR и BOR вместе будут равны true, если RecordCount=0.

Методы:

void recordset::OpenRecordset(MYSQL *Structmysql, char *sql);Открывает набор результатов основанный на SQL-инструкции select.

void recordset::CloseRecordset();Закрывает набор результатов. Он должен быть закрыт, чтобы освободить память, используемую им.

void recordset::MoveNext();Перемещается в следующую строку набора результатов. Если уже достигнута последняя строка, в ней и останется.

void recordset::MovePrevious();Перемещается в предыдущую строку набора результатов. Если уже достигнута первая строка, в ней и останется.

void recordset::MoveFirst();Перемещается в первую строку набора результатов.

void recordset::MoveLast();Перемещается в последнюю строку набора результатов.

char* recordset::GetField(char *FName);Возвращает содержание поля FName.

void recordset::SetField(char *FName, char *Value);Устанавливает содержание поля FName в значение Value. Изменения будут отброшены, если после установки значения не используется метод Update/AddNew.

void recordset::Edit();Должен использоваться перед методами SetField и Update, иначе все изменения будет отброшены.

void recordset::AddNew();Используется, чтобы добавить новую строку в набор результатов. Для работы этого метода набор результатов должен быть основан на таблице. Метод Update должен использоваться после установки всех значений поля. Определение WHERE не должно использоваться в методе Update, если оно уже используется с методом AddNew. Свойство AffectedRows выдаст число добавленных строк.

void rercordset::Update(char *Where);Используется, чтобы редактировать или добавить строку вместе с методами Edit/AddNew. Определение WHERE не должно использоваться с AddNew.

void recordset::Delete(char *Where);Применяется, чтобы удалить строки из набора результатов.

void recordset::Refresh();Изменения, сделанные методом Update, невидимы, если метод Refresh не используется. Обновите набор результатов немедленно после Update.

Page 142: 1 MySQL API

char* recordset::GetFieldN(int FNum);Аналогично GetField, но вместо имени поля используется его код (номер).

void recordset::SetFieldN(int FNum, char *Value)Аналогично SetField, но вместо имени поля используется его код (номер).

Пример 1:

// Продолжение примера из dbconnect.// Откроем таблицу заказчиков (customers) и распечатаем// все записи из нее.recordset MySet;char sql[]="SELECT * FROM customers";

MySet.OpenRecordset(MyConnect.DBase, sql);if (MySet.EOR && MySet.BOR){ cout << "No records found" << endl; return;}else{ // Show number of records cout << "No. of records: " << MySet.RecordCount << endl; // Show all records while (!MySet.EOR) { cout << MySet.GetField("or_id") << "\t"; cout << MySet.GetField("customers") << "\t"; cout << MySet.GetField("city") << endl; MySet.MoveNext(); }}

Пример 2:

// Добавление новой строки в таблицу заказчиков.MySet.AddNew();MySet.SetField("cs_id", "7");MySet.SetField("name", "Satish");MySet.SetField("city", "Pune");MySet.Update(""); // where не используется!MySet.Refresh(); // Сделаем изменения видимыми.

Пример 3:

// Изменение имени заказчика.MySet.Edit();MySet.SetField("cs_id", "7");MySet.SetField("name", "Suresh");MySet.SetField("city", "Pune");MySet.Update("or_id=7"); // where здесь необходимо использовать.MySet.Refresh(); // Сделаем изменения видимыми.

Пример 4:

Page 143: 1 MySQL API

// Удаление записи.MySet.Delete("name='Suresh'");MySet.Refresh(); // Сделаем изменения видимыми.

Пример 5:

// Закроем набор результатов после употребления. Это ОБЯЗАТЕЛЬНО!MySet.CloseRecordset();

Что еще надо сделать:

Лучший контроль ошибок Методы поиска информации (FindFirst, FindNext, FindPrevious, FindLast) Сделать графическое представление набора результатов

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

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

4.1 Введение

4.1.1 Что такое Lua?

Сайт языка Lua: http :// www . lua . org / .

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 . lua . org / uses . html .

Lua объединяет простой процедурный синтаксис (подобный Паскалю) с мощными конструкциями описания данных, основанными на ассоциативных массивах и расширяемой семантике. Lua имеет динамические типы, интерпретируется из байт-кода и имеет автоматическое управление памятью.

Page 144: 1 MySQL API

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

Цели реализации: простота, эффективность, мобильность и низкая объемлющая стоимость. Результат: быстрое ядро языка с маленькими требованиями, что делает его идеальным также и во встроенных системах.

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

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

Lua свободно доступен для академических и коммерческих целей и может быть скачан с различных сайтов в сети:

Базовый сайт: http :// www . lua . org /

Зеркала: Brazil: http :// www . lua . org / ftp / Germany: http://ftp.gwdg.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

Россия: http :// ftp . chg . ru / pub / lang / lua /

Lua распространяется свободно. Реализация, описанная в этом руководстве, доступна по адресам: http :// www . lua . org / home . html

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

Lua был разработан и выполнен Waldemar Celes, Roberto Ierusalimschy и Luiz Henrique de Figueiredo. С ними можно входить в контакт по e-mail [email protected].

Page 145: 1 MySQL API

Шлите Ваши комментарии, вопросы и отчеты об ошибках на lua @ tecgraf . puc - rio . br . Для сообщений об ошибках попробуйте также список рассылки lua - l @ tecgraf . puc - rio . br . Для получения большего количества информации относительно этого списка, включая инструкции о том, как на него подписаться, обратитесь на http :// www . lua . org / mirrors . 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.

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

Page 146: 1 MySQL API

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

Page 147: 1 MySQL API

метод 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 returnend for function if in thenlocal nil not or repeat until while

Lua представляет собой язык, чувствительный к регистру символов: and является зарезервированным словом, но And и AND (если региональный язык разрешает) не

Page 148: 1 MySQL API

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

Page 149: 1 MySQL API

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

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

Page 150: 1 MySQL API

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

Lua поддерживает такую удобную вещь, как многократные присваивания. Следовательно, синтаксис определяет список переменных с левой стороны и список выражений с правой сторона. Элементы в обоих списках отделяются запятыми: stat ::= varlist1 `=' explist1varlist1 ::= var {`,' var}

Эта инструкция сначала оценивает все значения справа и возможные индексы слева, а затем делает примваивание. Так, код: i = 3i, 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 эквивалентно

Page 151: 1 MySQL API

settable_event(t,i,val). В разделе 4.4.8 есть полное описание этих функций (setglobal находится в базисной библиотеке, settable_event используется только для объяснительных целей).

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

Структуры управления if, while и repeat имеют обычное значение и знакомый синтаксис: stat ::= while exp1 do block endstat ::= repeat block until exp1stat ::= 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

является заменителем кода:

Page 152: 1 MySQL API

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 endend

Обратите внимание на следующее: sep=0pt _limit и _step являются невидимыми переменными. Имена здесь даны

только для объяснительных целей. Поведение неопределено, если Вы меняете значение var внутри блока. Если третье выражение (step) отсутствует, то используется step 1. Значения limit и step оценены только однажды, перед стартом цикла. Переменная var локальна для инструкции: Вы не можете использовать ее

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

значении индекса, присвойте его другой переменной перед выходом.

Таблица для инструкции for пересекает все пары (index,value) данной таблицы. Это имеет следующий синтаксис:

stat ::= for name `,' name in exp1 do block end

Инструкция for, подобная: for index, value in exp do block end

равносильна такому коду: do local _t = exp local index, value = next(t, nil) while index do block index, value = next(t, index) endend

Обратите внимание на следующее: sep=0pt _t является невидимомй переменномй. Имя здесь дано только для

объяснительных целей. Поведение неопределено, если Вы меняете значение index внутри блока. Поведение неопределено, если Вы меняете таблицу _t при работе цикла. Переменнае index и var локальны для инструкции: Вы не можете

использовать их значения после окончания работы for. Вы можете использовать break, чтобы выйти из for. Если Вы нуждаетесь в

значениях index или value, присвойте их другим переменным перед выходом.

Page 153: 1 MySQL API

Порядок, в котором элементы таблицы будут пересечены, неопределен, даже для числовых индексов. Если Вы хотите пересекать индексы в числовом порядке, используйте числовой вариант for.

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 ::= nilexp ::= numberexp ::= literalexp ::= varexp ::= upvalueexp ::= functionexp ::= functioncallexp ::= tableconstructor

Page 154: 1 MySQL API

Доступ к глобальной переменной 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 Логические операторы

Page 155: 1 MySQL API

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

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

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

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

Page 156: 1 MySQL API

порядок оценки ассоциативных операторов (типа .. или +), пока эти оптимизация не изменяют нормальные результаты. Однако, эти оптимизация могут изменять некоторые результаты, если Вы определяете не ассоциативные методы тэгов для этих операторов.

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

Конструкторы таблиц представляют собой выражения, которые создают таблицы: каждый раз конструктор оценен, и новая таблица создана. Конструкторы могут использоваться, чтобы создать пустые таблицы или создать таблицу и инициализировать некоторые из полей (необязательно все). Общий синтаксис для конструкторов: tableconstructor ::= `{' fieldlist `}'fieldlist ::= lfieldlist|ffieldlist|lfieldlist `;' ffieldlist|ffieldlist `;' lfieldlistlfieldlist ::= [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 = tempend

Форма 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

Page 157: 1 MySQL API

temp[0] = b+c a = tempend

Выражения, подобные {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 ::= tableconstructorargs ::= literalexplist1 ::= {exp1 `,'} exp

Все выражения параметра оценены перед обращением. Обращение в форме f{...} синтаксически аналогично f({...}), то есть список параметров представляет собой одиночную новую таблицу. Обращение в форме f'...' (f"..." или f[[...]]) синтаксически аналогично f('...'), то есть список параметров представляет собой одиночную строку литералов.

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

Page 158: 1 MySQL API

которое нуждается в одиночном значении (синтаксически обозначенном нетерминальным 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 endstat ::= function funcname `(' [parlist1] `)' block endfuncname ::= name | name `.' name | name `:' name

Инструкция function f () ... end

является только синтаксическим аналогом для f = function () ... end

а инструкция function v.f () ... end

является синтаксическим аналогом для v.f = function () ... end

Функциональное определение представляет собой выполнимое выражение, чье значение имеет тип function. Когда Lua прекомпилирует chunk, все функциональные тела также прекомпилируются. Затем, всякий раз, когда Lua выполняет функциональное определение верхние переменные (upvalues) фиксируются, и функция выполняется. Этот функциональный образец (или замкнутое выражение) представляет собой конечное значение выражения. Различные образцы той же самой функции могут иметь различные верхние переменные.

Page 159: 1 MySQL API

Параметры действуют как локальные переменные, инициализированные со значениями параметра:

parlist1 ::= `...'parlist1 ::= name {`,' name} [`,' `...']

Когда функция вызвана, список параметров будет откорректирован к длине списка параметров, если функция не vararg-функция, которая обозначена тремя точками (`...') в конце списка параметра. Функция vararg не корректирует список параметров, вместо этого она собирает все лишние параметры в неявный параметр, названный arg. Значением arg является таблицы из n полей, чьим значением является число параметров дополнительного пространства и сами эти параметры, перечисленные в полях 1, 2, ..., n.

Как пример, рассмотрите следующие определения:

function f(a, b) endfunction g(a, b, ...) endfunction r() return 1,2,3 end

Имеем следующее отображение параметров: ВЫЗОВ ПАРАМЕТРЫ

f(3) a=3, b=nilf(3, 4) a=3, b=4f(3, 4, 5) a=3, b=4f(r(), 10) a=1, b=10f(r()) a=1, b=2g(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

является только синтаксическим аналогом для

Page 160: 1 MySQL API

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 dfunction 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 -- gend -- f

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

Page 161: 1 MySQL API

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

Page 162: 1 MySQL API

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

``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")

Page 163: 1 MySQL API

else -- no tag method available: default behavior error("unexpected type at arithmetic operation") endend

``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 endend

``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 endend

Другие операторы порядка используют этот метод согласно обычным эквивалентностям: a>b <=> b<aa<=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")

Page 164: 1 MySQL API

else error("unexpected type for concatenation") end endend

``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) endend

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

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

``settable'':

Page 165: 1 MySQL API

Вызван, когда 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) endend

``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 endend

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

В цикле уборки мусора методы тэгов для userdata вызываются в порядке, обратном созданию тэгов, то есть первые методы, которые будут вызваны, связаны с последним тэгом, созданным в программе. Кроме того, в конце цикла Lua делает эквивалент обращения gc_event(nil).

4.5 API

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

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

Page 166: 1 MySQL 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 представляет первый элемент (то есть, первый элемент, помещенный в

Page 167: 1 MySQL API

стек), а индекс 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:

Page 168: 1 MySQL 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 30lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30lua_remove(L, -3) --> 10 20 30 40 30 30lua_remove(L, 6) --> 10 20 30 40 30lua_insert(L, 1) --> 30 10 20 30 40lua_insert(L, -1) --> 30 10 20 30 40 (никакого эффекта нет)lua_settop(L, -3) --> 30 10 20lua_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 для не имеющего силу индекса.

Page 169: 1 MySQL API

Функция 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.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 рассмотрен более подробно в отдельном разделе 4.5.13.

Page 170: 1 MySQL API

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

Page 171: 1 MySQL API

Если Вы хотите изменять поведение коллектора мусора адаптивно, Вы можете использовать метод тэга мусоросборщика для 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_ERRRUN: ошибка при управлении chunk. LUA_ERRSYNTAX: ошибка синтаксиса в течение прекомпиляции. LUA_ERRMEM: ошибка распределения памяти. Для таких ошибок, Lua не

вызывает _ERRORMESSAGE (подробности в разделе 4.4.7). LUA_ERRERR: ошибка при управлении _ERRORMESSAGE. Для таких ошибок Lua

не вызывает _ERRORMESSAGE снова, чтобы избежать циклов. LUA_ERRFILE: ошибка открытия файла (только для lua_dofile). В этом

случае Вы можете проверять errno, вызывая strerror или perror, чтобы сообщить пользователю, что пошло неправильно.

Page 172: 1 MySQL API

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

Page 173: 1 MySQL API

любой метод тэга, используют 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);

В заключение, еще одна функция

Page 174: 1 MySQL API

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

Page 175: 1 MySQL API

Следующий пример показывает, как ведущая программа может делать эквивалент коду на Lua:

a,b = f("how", t.x, 4)

Here it is in C: /* глобальная `t' (потом пригодится) */lua_getglobal(L, "t");/* функция, которая будет вызвана */lua_getglobal(L, "f");/* 1-ый параметр */lua_pushstring(L, "how");/* помещает в стек строку `x' */lua_pushstring(L, "x");/* помещает в стек результат t.x (2-ой аргумент) */lua_gettable(L, -4);/* 3-ий параметр */lua_pushnumber(L, 4);/* вызывает функцию с 3 параметрами и 2 результатами */lua_call(L, 3, 2);/* устанавливает глобальную переменную `b' */lua_setglobal(L, "b");/* устанавливает глобальную переменную `a' */lua_setglobal(L, "a");/* удаляет из стека `t' */lua_pop(L, 1);

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

Некоторые специальные функции 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);

Page 176: 1 MySQL API

Также возможно копировать все методы из одного тэга в другой:

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

Page 177: 1 MySQL API

функция 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-объектам

Page 178: 1 MySQL API

Если 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 имеет следующие стандартные библиотеки:

Базисная библиотека. Работа со строками. Различная математика (sin, log и т,п,). Ввод и вывод (плюс некоторые средства системы).

Page 179: 1 MySQL API

Чтобы иметь доступ к этим библиотекам, ведущая 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) endend

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

Вызывает функцию func с параметрами, заданными таблицей arg. Обращение эквивалентно func(arg[1], arg[2], ..., arg[n])

где n представляет собой результат getn(arg). Все результаты из func просто возвращены call.

По умолчанию, если ошибка происходит в течение обращения к func, она объясняется подробно. Если строка mode включает "x", то обращение защищено. В этом режиме обращение к функции не call не объясняет ошибку подробно, независимо от того, что случается в течение обращения. Вместо этого, это возвращает nil, чтобы сообщить об ошибке (помимо вызова приспособленного драйвера ошибки).

Page 180: 1 MySQL API

Если 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 так:

Page 181: 1 MySQL API

function foreach (t, f) for i, v in t do local res = f(i, v) if res then return res end endend

Поведение 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 maxend

gettagmethod (tag, event)

Page 182: 1 MySQL API

Возвращает текущий метод тэга для данной пары (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)

Page 183: 1 MySQL API

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

setglobal (name, value)

Устанавливает именованную глобальную переменную к данному значению, или вызывает метод тэга для события setglobal. Полная семантика объясняется в разделе 4.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.

Page 184: 1 MySQL API

Факультативный параметр определяет ядро, чтобы интерпретировать цифру. Ядром может быть любое целое число между 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] = valueend

tremove (table [, pos])

Удаляет из таблицы table элемент в позиции pos, сдвигая в случае необходимости другие элементы, чтобы закрыть образовавшуюся дырку. Возвращает значение удаленного элемента. Значение по умолчанию для pos равно n, где n является результатом getn(table), чтобы обращение tremove(t) удалило последний элемент из таблицы t. Эта функция также устанавливает поле n таблицы в значение n-1.

Эта функция эквивалентна следующей функции Lua, за исключением того, что доступ к таблице прямой (без использования методов тэгов):

Page 185: 1 MySQL API

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 valueend

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, где эти вхождения начинаются и заканчивается, иначе это возвращает

Page 186: 1 MySQL API

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

Page 187: 1 MySQL API

обратно 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 будет обработано.

Имеются некоторые примеры:

Page 188: 1 MySQL API

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

Page 189: 1 MySQL API

Лучше следить за тем, чтобы любому символу пунктуации (даже не управляющему!) предшествовал %, когда символ применен в образце.

[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. Вторая форма должна быть предпочтительней для переносимости.

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

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

символу в классе. Одиночный символьный класс, сопровождаемый *, что соответствует 0 или

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

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

Одиночный символьный класс, сопровождаемый -, что также соответствует 0 или большему количеству повторений символов в классе. В отличие от *, элементы повторения будут всегда соответствовать самой короткой возможной последовательности.

Одиночный символьный класс, сопровождаемый ?, что соответствует 0 или 1 местонахождению символа в классе.

Page 190: 1 MySQL API

%n, для n от 1 до 9. Такой элемент соответствует подстроке, равной n-й зафиксированной строке.

%bxy, здесь x и y два различных символа. Такой элемент соответствует строкам, которые начинаются с x, заканчиваются на y, и в них сбалансированы x и y. Это означает, что, если читать строку слева направо, подсчитывая +1 для x и -1 для y, то последний y является первым y, для которого счетчик равен 0. Например, элемент %b() соответствует выражениям со сбалансированными круглыми скобками.

Шаблоны:

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

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

Образец может содержать подобразцы, включенные в круглые скобки, они описывают сборы данных. Когда соответствие выполнено, подстроки подчиненной строки, которые соответствуют сборам данных, сохранены для будущего использования. Сборы данных пронумерованы согласно их левым круглым скобкам. Например, в образце "(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 log10max min mod rad sin sqrt tan frexp ldexp random randomseed

Плюс глобальная переменная PI. Большинство из них представляют собой только интерфейсы к функциям в C-библиотеке, за исключением того, что для тригонометрических функций все углы выражены в градусах, а не в радианах. Функции deg и rad могут использоваться для того, чтобы преобразовывать данные между радианами и градусами.

Page 191: 1 MySQL API

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

Page 192: 1 MySQL API

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

Строка 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 плюс строку, описывающую ошибку.

Page 193: 1 MySQL API

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

Page 194: 1 MySQL API

Читает файл _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. Когда вызвана без параметров, возвращает приемлемое

Page 195: 1 MySQL API

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

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.

Page 196: 1 MySQL API

Обычно 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, чтобы использоваться в сообщениях об ошибке.

Page 197: 1 MySQL API

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

Page 198: 1 MySQL API

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

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

Page 199: 1 MySQL API

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, если не имеется никакой

Page 200: 1 MySQL API

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

Page 201: 1 MySQL API

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, чтобы получить другие параметры.

Page 202: 1 MySQL API

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

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

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

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

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

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

Все прагмы ($debug, $if, ...) удалены. for, break и in теперь зарезервированные слова. Методы тэгов уборки мусора для таблиц теперь устаревшие. Имеется теперь только один метод тэга для операторов порядка. Во вложенных обращениях к функции, подобно f(g(x)), все возвращаемые

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

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

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

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

При пересечении таблицы с next или foreach таблица не может изменяться. Общие образцы чтения теперь устаревшие. Функции rawgettable и rawsettable теперь переименованы

соответственно в rawget и rawset. Функции foreachvar, nextvar, rawsetglobal и rawgetglobal устаревшие.

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

setglobal и sort больше не возвращают значение. Вызов type больше не возвращает второе значение.

Опция p в функции call устарела.

Изменения в API

Page 203: 1 MySQL API

API был полностью переделан. Это теперь полностью повторно используемо и намного более ясно.

Отладочный API был полностью переделан.

4.12 Полный синтаксис Lua

chunk ::= {stat [`;']}block ::= chunkstat ::= 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 | functioncalldeclist ::= `name' {`,' `name'}init ::= `=' explist1explist1 ::= {exp1 `,'} expexp1 ::= expexp ::= nil | `number' | `literal' | var | function | upvalue | functioncall | tableconstructor | `(' exp `)' | exp binop exp | unop expfunctioncall ::= varorfunc args | varorfunc `:' `name' argsargs ::= `(' [explist1] `)' | tableconstructor | `literal'function ::= function `(' [parlist1] `)' block endparlist1 ::= `...' | `name' {`,' `name'} [`,' `...']

Page 204: 1 MySQL API

upvalue ::= `%' `name'tableconstructor ::= `{' fieldlist `}'fieldlist ::= lfieldlist | ffieldlist | lfieldlist `;' ffieldlist | ffieldlist `;' lfieldlistlfieldlist ::= [lfieldlist1]ffieldlist ::= [ffieldlist1]lfieldlist1 ::= exp {`,' exp} [`,']ffieldlist1 ::= ffield {`,' ffield} [`,']ffield ::= `[' exp `]' `=' exp | `name' `=' expbinop ::= `+' | `-' | `*' | `/' | `\^{ ' | `..'

| `<' | `<=' | `>' | `>=' | `==' | `\ { '=}

| and | or}unop ::= `-' | not

4.13 lua: интерпретатор языка Lua

Синтаксис

lua [arguments]

Описание

lua представляет собой автономный интерпретатор языка Lua. Он загружает и выполняет программы на Lua, как в текстовой исходной форме, так и в виде прекомпилированных модулей, созданных компилятором luac. lua может использоваться как пакетный интерпретатор, а также в интерактивном режиме.

arguments могут быть параметрами, назначениями или именами файлов. Они будут обработаны слева направо.

Параметры начинаются с тире (-) и описаны ниже.

Назначение представляет собой параметр формы a=b, который назначает b глобальной переменной a. Обратите внимание, что никакие кавычки не нужны вокруг строки, если она не содержит пробелы или другие символы, специальные для оболочки. Вообще, Вы должны быть внимательны при использовании кавычек и пробелов в командной строке потому, что они обычно обрабатываются оболочкой непосредственно.

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

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

Page 205: 1 MySQL API

Опции

Тире (-) загрузить стандартный ввод как файл, то есть не в интерактивном режиме, даже когда стандартный ввод является терминалом.

-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 . lua . org / .

Диагностика

Сообщения пакета об ошибках должны быть самодостаточными.

luac: компилятор Lua

Синтаксис вызова

luac [options] [filenames]

Page 206: 1 MySQL API

Описание

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

Page 207: 1 MySQL API

-p загружают файлы, но не генерируют никакой выходной файл. Использован главным образом для проверки синтаксиса или тестирования прекомпиляции: разрушенные файлы, вероятно, сгенерируют ошибки, когда будут загружены. Для полного теста целостности используйте опцию -t.

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

-t выполняет полный тест целостности прекомпилированного кода. Код, который признает нормальным этот тест, полностью безопасен в том смысле, что это не будет разрывать интерпретатор. Однако, не имеется никакой гарантии, что такой код делает что-нибудь полезное. Если никакие файлы не заданы, то luac загружает luac.out и проверяет его содержимое.

-v выводит сведения о версии.

Файлы

luac.out представляет собой заданный по умолчанию выходной файл

Также можно посмотреть

lua(1) http :// www . lua . org / .

Диагностика

Сообщения пакета об ошибках должны быть самодостаточными.

Авторы пакета

R. Ierusalimschy,L. H. de Figueiredo иW. Celes ([email protected]).

4.14 Установка языка LUA

Построение Lua на системах Unix очень просто:

Отредактируйте файл config, чтобы соответствовать Вашей системе, если в этом есть необходимость.

Выполните команду make. Если Вы хотите устанавливать Lua в "официальное" место в Вашей системе,

то затем сделайте make install. Официальное место и способ устанавливать

Page 208: 1 MySQL API

файлы определены в config. Вам, вероятно, придется регистрироваться как root, чтобы сделать это.

Ниже приведены инструкции для пользователей систем Windows и Macintosh.

4.14.1 Что Вы получаете

Если make выполнилась без проблем, Вы получите:

Интерпретатор ./bin/lua, а также прекомпилятор ./bin/luac. Набор библиотек в ./lib. Включаемые файлы в ./include.

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

Man-страницы для lua и luac в nroff и html, а также справочное описание в html помещаются в ./doc, некоторый типовой код в ./test, а некоторые полезные дополнения в ./etc. Вы не нуждаетесь в этих каталогах для разработки.

Изучите также README-файлы в различных подкаталогах. Удобная отправная точка: ./doc/readme.shtml.

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

Page 209: 1 MySQL API

Команды для формирования 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.cstandard lib: lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c lstrlib.cinterpreter: core lib, standard lib, lua.ccompiler: core lib, dump.c luac.c opt.c print.c stubs.c

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

4.14.5 INSTALL для mysql 3.23.32

Скачайте LUA 4.0 patched для использования с mysql (оригинальный пакет не годится).

Установите и откомпилируйте LUA 4.0, но не в том же самом каталоге, где и mysql. Я использую /usr/src/lua для LUA и /usr/src/mysql для MySQL.

В дереве исходного кода mysql сделайте: cd sql tar zxf /download/mylua.tar.gz cd .. ./configure --enable-assembler \ --prefix=/usr/local/mysql \ --enable-assembler \ --with-mysqld-ldflags="-L/usr/src/lua/lib \ -llua -llualib"

Опробуйте скрипт примера: mysql mysql mysql< SELECT user,host FROM user PROCEDURE("/usr/src/mysql/sql/count.lua")

5. MySQLdb: Python-интерфейс для MySQL

MySQLdb представляет собой поточно-совместимый интерфейс с популярной СУБД MySQL, который обеспечивает Python API для баз данных. Здесь рассматривается его версия 0.9.1 (автор Andy Dustman, [email protected]). Пакет распространяется по лицензии GPL и доступен для закачки с http :// sourceforge . net / projects / mysql - python . Цели проекта:

Page 210: 1 MySQL API

Совместимость с Python API для баз данных (версия 2.0). Поточно-безопасная работа. Потоки теперь не будет блокировать друг друга. Совместимость с MySQL-3.23 и выше.

Требования:

Python 1.5.2 или выше:

http://www.python.org Версии ниже, чем 1.5.2, НЕ РАБОТАЮТ. Все версии, начиная с 1.5.2, работать должны. 1.6.x не тестировались. 2.0.1,

2.1.1 и 2.2a3 были протестированы успешно. Если Вы имеете Red Hat Linux или подобную систему установки пакетов,

надлежит установить бибилотеки и заголовки разработчика для Python (python-devel). Для версий Python-2.x это python2-devel.

Distutils 1.0.2 или выше:

Поставляется с Python 1.6 и выше. 1.0.2 включена в Python version 2.1 и выше. http :// www . python . org / sigs / distutils - sig / download . html

MySQL 3.22.19 или выше.

http://www.mysql.com/downloads Версии ниже, чем 3.22 точно НЕ РАБОТАЮТ. Версии ниже, чем 3.22.19 могут не работать. MySQL-4.0 поддерживается. MySQL-3.23 поддерживается. Если Вы имеете Red Hat Linux или подобную систему установки пакетов,

надлежит установить бибилотеки и заголовки разработчика для MySQL. Если Вы используете пакеты с mysql.com, Вам нужен пакет MySQL-devel. Если Вы используете пакеты Red Hat, Вам нужен mysql-devel. Я предпочитаю пакеты с сайта www.mysql.com.

5.1. Введение

Первое, что Вы будете делать, редактирование скрипта setup.py. Имеются некоторые переменные, которые сообщают где искать MySQL include-файлы и библиотеки. Значения корректны для стандартной установки MySQL в Red Hat Linux (6.2) RPM. Если Вы имеете другую платформу, Вы должны будете вычислить нужные значения самостоятельно. Вам почти никогда не придется изменять это. Если Вы имеете старую версию distutils (до 1.0.2), обновитесь или удалите параметры, относительно которых система возражает.

Page 211: 1 MySQL API

Обратите внимание, что недавние двоичные дистрибутивы с www.mysql.com включают два набора библиотек пользователей: mysqlclient и mysqlclient_r. Последний хранит поточно-безопасные библиотеки, так что используйте именно его, если потоки Вам нужны.

Если Вы имеете динамические библиотеки пользователей (в Linux .so-файлы), они будут использоваться по умолчанию. Если они не в Вашем стандартном пути загрузчика, Вы должны будете установить или откорректировать системную переменную LD_LIBRARY_PATH (в Linux) или ту, которую Ваша платформа требует. Иначе Вы можете скорректировать setup.py, чтобы компоновать со статической библиотекой. Если Вы используете стандартный пакет RPM, с этим не должно быть особых проблем.

ПРЕДУПРЕЖДЕНИЕ: Если Вы используете двоичный пакет Zope, Вы нуждаетесь в выполнении скрипта setup.py программой python из Zope. Иначе Zope (ZMySQLDA) не может найти _mysql.

Если Вы предпочитаете RPM, Вы можете использовать команду bdist_rpm с setup.py. Это только формирует RPM, но не устанавливает его.

Этот модуль должен быть совместим с более старым интерфейсом, написанным Joe Skinner. Однако, старая версия:

Не поточно-совместимая (операции базы данных могли бы блокировать все другие потоки)

Написан для MySQL 3.21 (не компилируется для более новых версий без заплаток)

Не очень активно поддерживается

MySQLdb полностью новый модуль, распространяемый бесплатно согласно GNU Public License. Никакой код из той версии не используется в MySQLdb.

5.1.1 Платформы

Linux/UNIX

Этот модуль разработан на RedHat Linux (в настоящее время 7.1) для Intel. Это должно формироваться без больших трудностей на большинстве платформ, используя скрипт setup.py. Возможно этот модуль работает и под MacOS X. Вы нуждаетесь в пакете Distutils, который поставляется с Python 2.0. Если Вы не имеете его (то есть Вы имеете Python 1.5.2), Вы можете скачать пакет с сайта http :// www . python . org / .

Windows (3.11, 95, 98, NT, 2000, CE)

Page 212: 1 MySQL API

Windows не поддерживаемая платформа. Однако, скрипт setup.py по сообщениям работает нормально.

5.1.2 Python

MySQLdb требует Python 1.5.2 или новее. Более ранние версии не будут работать потому, что MySQL нужна поддержка для C long long. Если Вы имеете более раннюю версию Python, обновитесь хотя бы до 1.5.2. Текущая разработка выполнена в Python 2.1, но старый Python 1.5.2 все еще будет поддержан в обозримом будущем.

5.1.3 MySQL

MySQL-3.22

Гарантируется работа версии 3.22.32 и выше. Некоторые старые версии могут работать, если Вы имеете старшую версию, Вы должны серьезно подумать об апгрейде в целях исправления ошибок и дыр в защите.

MySQL-3.22 имеет проблему при попытке вставить значения TIME с дробными секундами. Значения, подобные 12:56:13.00, возвращены как 344:13:00, очевидно интерпретируя первоначальный ввод как 12 дней, 56 часов, 13 минут и 0 секунд (12 дней и 56 часов=344 часа). Чтобы избежать этой проблемы, используйте тип DateTimeDelta.

MySQL-3.23

MySQLdb поддерживает транзакции, если их поддерживает сервер. Но не гарантирует, что транзакции будут работать. Для этого Вы должны использовать транзакционно-безопасную таблицу (TST). Текущие TST: BDB и InnoDB. Таблицы GEMINI намечены для MySQL-4.0. Обратите внимание, что MySQL функционирует в режиме AUTOCOMMIT по умолчанию, и MySQLdb считает, что AUTOCOMMIT включен. Чтобы изменить это, используйте инструкции SQL SET AUTOCOMMIT=0.

5.1.4 DateTime

Если Вы имеете установленный пакет mx . DateTime , MySQLdb использует его для связанных с датой объектов. Иначе они будут возвращены как строки. Вы можете также изменять словарь преобразования типов, чтобы возвратить их как другие объектные классы.

5.1.5 MySQLmodule

MySQLmodule, старый интерфейс MySQL, разработанный Joe Skinner, является также интерфейсом C/Python. MySQL, C-часть, имеет интерфейс, подобный perl DBI. Кроме того, имеется часть Python, Mysqldb, которая обеспечивает интерфейс DB

Page 213: 1 MySQL API

API v1.0, написанный James Henstridge. MySQLdb-0.2.2 и выше включает CompatMysqldb, который является адаптацией Mysqldb к _mysql. Это должно рассмотреться экспериментальным решением.

Напротив, C-часть MySQLdb, _mysql, разработана в соответствии с MySQL C API объектно-ориентированным способом. MySQLdb обеспечивает интерфейс DB API v2.0, который имеет некоторые отличия от v1.0, в частности такие изменения:

Действие Mysqldb MySQLdb

Соединениеdb=Mysqldb.Mysqldb("db@host user pass")

db=MySQLdb.connect(db='db', host='host', user='user', passwd='pass')

Неявный курсор

db.execute(SQL)Неявные курсоры удалены из DB API v2.0. Всегда используйте c=db.cursor()

Строка выборок как словарь

c.fetchDict(), ключи: "table.column"

Не стандарт: альтернативный класс DictCursor предоставляет интерфейс словаря, ключи являются "column" или "table.column , если имеются два столбца с одним именем. Используйте SQL-оператор AS для переименования полей.

Транзакцииdb.commit() и db.rollback() мирно сосуществуют вместе и тихо не делают ничего (опасно!)

db.commit() и db.rollback() работают, если сервер MySQL может выполнять транзакции, иначе db.rollback() всегда терпит неудачу.

5.1.6 Zope и ZMySQLDA

Был написан пакет ZMySQLDA для использования с MySQLdb. Это адаптируется из ZOracleDA Digital Creations разработчиков системы Zope.

5.1.7 FAQ

FAQ доступны на http :// dustman . net / andy / python / MySQLdb / faq / MySQLdb - FAQ . html .

5.2. Модуль _mysql

Если Вы хотите писать прикладные программы, которые переносимы между базами данных, избегайте использовать этот модуль непосредственно. Модуль _mysql обеспечивает интерфейс, который обычно осуществляет MySQL C API. Для получения большего количества информации обратитесь к документации на пакет MySQL. Документация для этого модуля преднамеренно слаба потому, что Вы, вероятно, должны использовать более высокий уровень (модуль MySQLdb).

Page 214: 1 MySQL API

5.2.1 Трансляция MySQL C API

MySQL C API был обернут объектно-ориентированным способом. Единственные MySQL структуры данных, которые выполнены в данном интерфейсе, это MYSQL (дескриптор подключения базы данных) и MYSQL_RES (дескриптор результата). Вообще, любая функция, которая берет как параметр MYSQL *mysql, теперь представляет собой метод объекта подключения, и любая функция, которая берет MYSQL_RES *result, теперь метод объекта результата. Функции, не требующие ни одной структуры MySQL, выполнены как функции в модуле. Функции, требующие какую-то из других структур данных MySQL, вообще не выполнены. Во всех случаях префикс mysql_ удален из имени. Большинство перечисленных методов conn также доступно как методы объекта MySQLdb Connection. Их использование не переносимо между базами данных.

C API _mysql

mysql_affected_rows() conn.affected_rows()

mysql_close() conn.close()

mysql_connect() _mysql.connect() mysql_data_seek() result.data_seek()

mysql_debug() _mysql.debug()

mysql_dump_debug_info conn.dump_debug_info()

mysql_escape_string() _mysql.escape_string()

mysql_fetch_row() result.fetch_row()

mysql_get_client_info() _mysql.get_client_info()

mysql_get_host_info() conn.get_host_info()

mysql_get_proto_info() conn.get_proto_info()

mysql_get_server_info() conn.get_server_info()

mysql_info() conn.info()

mysql_insert_id() conn.insert_id() mysql_list_dbs() conn.list_dbs() mysql_list_fields() conn.list_fields()

mysql_list_processes() conn.list_processes()

mysql_list_tables() conn.list_tables()

mysql_num_fields() result.num_fields()

mysql_num_rows() result.num_rows() mysql_options() _mysql.connect() mysql_ping() conn.ping()

mysql_query() conn.query()

mysql_real_connect() _mysql.connect()

mysql_real_query() conn.query() mysql_real_escape_string() conn.escape_string()

mysql_row_seek() result.row_seek()

Page 215: 1 MySQL API

mysql_row_tell() result.row_tell() mysql_select_db() conn.select_db() mysql_stat() conn.stat()

mysql_store_result() conn.store_result()

mysql_thread_id() conn.thread_id() mysql_use_result() conn.use_result()

CLIENT_* MySQLdb.constants.CLIENT.* CR_* MySQLdb.constants.CR.*

ER_* MySQLdb.constants.ER.*

FIELD_TYPE_* MySQLdb.constants.FIELD_TYPE.*

FLAG_* MySQLdb.constants.FLAG.*

5.2.2 Примеры использования _mysql

Допустим, что Вы хотите использовать _mysql. Имеются некоторые примеры.

Самое простое подключение к базе данных:

import _mysqldb=_mysql.connect()

Это создает подключение к серверу MySQL на локальной машине, используя стандартый сокет UNIX, Ваше имя входа в систему (из системной переменной USER), пустой пароль и не применяет команду USE. Возможно, это будет работать у Вас, если Вы установили файл конфигурации (~/.my.cnf ). Но скорее всего Вы должны обеспечить большее количество информации:

db=_mysql.connect("localhost","joebob","moonpie","thangs")

Это создает подключение к серверу MySQL на локальной машине, используя TCP на стандартном порте (3306), имя пользовател joebob, пароль moonpie и выбирает начальную базу данных thangs.

Конечно, Вы должны использовать TCP, если работаете с удаленной системой. Здесь я не рассмотрел часть параметров connect(), и Вы обратите внимание, что, если Вы используете позиционные параметры, настроить связь по TCP не так-то просто. Кроме того, сокеты UNIX быстрее. Я предпочитаю использовать параметры ключевого слова:

db=_mysql.connect(host="localhost",user="joebob", passwd="moonpie",db="thangs")

Page 216: 1 MySQL API

Это делает точно то же, что делал последний пример, но проще для чтения. Теперь, если Вы действительно хотели использовать сокет UNIX, и Ваше имя входа в систему joebob, Вы могли бы сократить этот пример до: db=_mysql.connect(passwd="moonpie",db="thangs")

Имеются некоторые другие параметры, которые Вы можете использовать, и большинство их не так уж и необходимо, кроме одного, о котором чуть ниже. Во всем остальном обратитесь к встроенной документации. Модуль Python 2.1 pydoc представляет собой хороший справочник.

Теперь Вы имеете открытое подключение db и хотите сделать запрос. Не имеется никаких курсоров в MySQL и никакой подстановки параметров, так что Вы должны передать полную строку запроса db.query():

db.query("""SELECT spam, eggs, sausage FROM breakfast WHERE price < 5""")

Не имеется никакого значения возврата, но исключительные ситуации могут быть вызваны. Исключительные ситуации определены в отдельном модуле, _mysql_exceptions, но _mysql экспортирует их. Читайте спецификацию DB API (http://www.python.org/topics/database/DatabaseAPI-2.0.html), чтобы выяснить то, чем они являются, или Вы можете использовать MySQLError.

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

r=db.store_result()# ...или...r=db.use_result()

Оба метода возвращают объект результата. В чем же разница? А в том, что store_result() возвращает весь набор результатов пользователю немедленно. Если Ваш набор результатов действительно большой, это станет проблемой. Один путь обхода этого состоит в том, чтобы добавить предложение LIMIT к Вашему запросу, чтобы ограничить число возвращенных строк. Но можно использовать use_result(), который хранит набор результатов на сервере и посылает его построчно, когда Вы выбираете. Это связывает ресурсы сервера и подключение: Вы не можете делать больше запросов, пока Вы не выбрали все строки. Вообще я рекомендую использовать store_result(), если Ваш набор результатов не огромен, и Вы не можете использовать LIMIT.

Теперь для фактического получения реальных результатов надо:

>>> r.fetch_row()(('3','2','0'),)

Первая вещь, которую Вы должны знать: fetch_row() берет некоторые дополнительные параметры. Первый задает, сколько строк (maxrows) должны быть

Page 217: 1 MySQL API

возвращены. По умолчанию, это возвращает одну строку. Это может возвращать меньшее количество строк, чем Вы просите, но никогда не больше. Если Вы устанавливаете maxrows=0, это возвращает все строки набора результатов. Если Вы когда-либо получаете пустой набор, значит Вы исчерпали строки.

Второй параметр (how) сообщает как строка должна представиться. По умолчанию, это ноль, что означает вернуть как набор. how=1 значит вернуть данные как словарь, где ключи представляют собой имена столбца или table.column, если имеются два столбца с тем же самым именем. how=2 аналогично how=1, кроме того, что ключи всегда table.column, это для совместимости со старым модулем Mysqldb.

Другая причуда: известно, что обрабатываются числовые столбцы, почему они возвращены как строки? Потому, что MySQL возвращает все данные как строки просто по определению и ожидает, что Вы преобразуете их непосредственно. Как я понимаю, все данные в базе хранятся именно как строки, как бы они не выглядели снаружи. Это было бы реальной проблемой, но фактически _mysql может делать это для Вас. MySQLdb делает это для Вас сам. Чтобы иметь автоматическое выполненное преобразование типов, Вы должны создать словарь конвертера типов и передать его в connect() как параметр ключевого слова conv.

Ключи в conv должны быть типами столбцов MySQL, которые в C API являются FIELD_TYPE_*. Вы можете получать эти значения так:

from MySQLdb.constants import FIELD_TYPE

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

my_conv = {FIELD_TYPE.LONG: int}

Это означает, если это FIELD_TYPE_LONG, обработать это встроенной int(). Обратите внимание, что FIELD_TYPE_LONG представляет собой столбец INTEGER, который соответствует C long, который является также типом, используемым для нормального целого числа в Python. Но остерегайтесь: если это столбец UNSIGNED INTEGER, это может вызвать переполнение. По этой причине MySQLdb фактически использует long(), чтобы сделать преобразование.

Затем, если Вы используете db=_mysql.connect(conv=my_conv...), результаты возвратятся в виде ((3, 2, 0),), который является тем, что и ожидается.

5.3. MySQLdb: интерфейс DB API

Page 218: 1 MySQL API

MySQLdb представляет собой тонкую обертку на Python вокруг _mysql. MySQLdb делает его совместимым с интерфейсом Python DB API (version 2). В действительности код, который осуществляет API, находится в _mysql ради эффективности.

5.3.1 Функции и атрибуты

Только несколько высокопоставленных функций и атрибутов определены внутри MySQLdb.

connect(parameters...) Конструктор для создания подключения. Возвращает объект подключения (Connection Object). Параметры те же, как и для MySQL C API. Кроме того, имеются несколько дополнительных ключевых слов, которые соответствуют тому, что Вы передали бы как mysql_options() перед соединением. Обратите внимание, что некоторые параметры должны быть определены как параметры ключевого слова! Значение по умолчанию для каждого параметра: NULL или 0, зависит от типа. Важные параметры: host Имя компьютера, с которым надлежит соединиться Значение по умолчанию: используйте локальный компьютер. user Пользователь, чтобы авторизоваться на сервере. Значение по умолчанию: текущий эффективный пользователь. passwd Пароль, чтобы авторизоваться на сервере. Значение по умолчанию: никакого пароля (пустой пароль). db База данных, которую надо использовать. Значение по умолчанию: никакой заданной по умолчанию базы данных. port TCP-порт сервера MySQL. Значение по умолчанию: стандартный порт (3306). unix_socket Расположение сокета UNIX. Значение по умолчанию: использование TCP. conv Словать преобразования типов. Значение по умолчанию: копия MySQLdb.converters.conversions. compress Включить сжатие протокола. Значение по умолчанию: никакого сжатия. connect_timeout Аварийное прекращение работы, если соединение не завершено в рамках данного числа секунд. Значение по умолчанию: нет тайм-аута. named_pipe Использовать именованный канал (только под Windows). Значение по умолчанию: не делать этого.

Page 219: 1 MySQL API

init_command Начальная команда, которую надо выдать на сервер при подключении. Значение по умолчанию: нет. read_default_file Файл настроек MySQL. Отсюда берутся mysql_options(). read_default_group Заданная по умолчанию группа в файле настроек. Отсюда берутся mysql_options(). cursorclass Класс курсора, который использует cursor(), если не перекрыт. Значение по умолчанию: MySQLdb.cursors.Cursor. Это должно быть параметром ключевого слова.

apilevel Строковая константа, задающая поддерживаемый уровень DB API: '2.0'.

threadsafety Константа типа Integer, устанавливающая уровень поточной безопасности, который поддерживает интерфейс. С MySQLdb version 0.9.0 это установлено в 1, что означает: потоки могут совместно использовать модуль.

Протокол MySQL не может обрабатывать много потоков, использующих то же самое подключение, сразу. Более ранние версии MySQLdb использовали блокировку, чтобы достигнуть threadsafety=2. Несмотря на то, что это не должно активно использовать стандартный класс Cursor (который используется в mysql_store_result()), это усложнено SSCursor (который используется в mysql_use_result(). Здесь Вы должны гарантировать, что все строки прочитались прежде, чем другой запрос сможет быть выполнен. Это далее усложнено добавлением транзакций, начинающихся когда курсор выполняет запрос, и завершающихся выполнением COMMIT или ROLLBACK объектом Connection. Два потока не могут совместно использовать подключение, в то время как транзакция происходит, в дополнение к неспособности совместно использовать его в течение выполнения запроса. К сожалению, это чрезмерно усложнило код.

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

paramstyle Строковая константа, устанавливающая тип маркера параметра, форматирующего ожидаемое интерфейсом. Установите в 'format'=ANSI C printf-коды формата, например '...WHERE name=%s'. Если объект

Page 220: 1 MySQL API

отображения используется для conn.execute(), то интерфейс фактически использует 'pyformat'= расширенные форматные коды Python, например, '...WHERE name=%(name)s'. Однако, API теперь не позволяет спецификацию больше, чем одного стиля в paramstyle.

Примечание о совместимости: старые версии MySQLmodule используют подобную схему задания параметра, но требуют, чтобы кавычки были помещены вокруг строк формата, которые будут содержать строки, даты и подобные символьные данные. Это не требуется для MySQLdb. Рекомендуется, чтобы %s (но не '%s') использовался для всех параметров, независимо от типа. Интерфейс выполняет все необходимое цитирование сам.

conv Словарь, отображающий типы MySQL (из FIELD_TYPE.*) к вызываемым объектам Python (обычно функциям), которые преобразовываются из строк в нужные типы. Это инициализировано с приемлемыми значениями по умолчанию для большинства типов. При создании объекта Connection Вы можете передать Ваш собственный словарь конвертера типа как параметр ключевого слова. Иначе это использует копию MySQLdb.converters.conversions. Словарь включает некоторые из функций модуля DateTime, если это доступно. Несколько ненормативных типов возвращены как строки,

Начиная с MySQL-3.23, MySQL поддерживает различные наборы символов на клиенте и сервере, а также новую функцию цитирования mysql_real_escape_string(). Это требует, чтобы функция цитирования строки была методом, связанным с объектом connection. MySQLdb обрабатывает это для Вас автоматически. Однако, если Вы чувствуете потребность сделать что-то особое со строками, Вы должны изменить словарь после открытия подключения.

5.3.2 Объекты Connection

Объекты Connection возвращены функцией connect().

commit() Если база данных и таблица поддерживают транзакции, это передает текущую транзакцию, Иначе этот метод успешно не делает ничего.

rollback() Если база данных и таблица поддерживают транзакции, это отменяет текущую транзакцию, Иначе этот метод вызывает исключение NotSupportedError.

Page 221: 1 MySQL API

Примечание совместимости: старые версии MySQLmodule определяют этот метод, так что он не далет ничего. Это опасное поведение, поскольку успешная обратная перемотка указывает, что текущая транзакция отменена.

cursor([cursorclass]) MySQL не поддерживает курсоры, однако, курсоры легко эмулируются. Вы можете обеспечивать альтернативный класс курсора как факультативный параметр. Если это не представлено, берется значение по умолчанию данное при создании объекта подключения или стандартного класса Cursor.

begin() Явно запускает транзакции. Обычно Вы не должны использовать это: выполнение запроса начинает новую транзакцию, если ни одной работающей нет. Если включен AUTOCOMMIT, Вы можете использовать begin() для его временного отключения. AUTOCOMMIT продолжит работу после следующего вызова commit() или rollback.

5.3.3 Объекты Cursor

callproc() Не реализован.

close() Закрывает курсор. Будущие операции вызывают исключение ProgrammingError. Если Вы используете курсоры стороны сервера, очень важно закрыть курсор, когда Вы с ним закончили, но перед созданием нового курсора.

insert_id() Возвращает последнее значение поля AUTO_INCREMENT, вставленное в базу данных.

info() Возвращает некоторую информацию относительно последнего запроса. Обычно Вы не должны проверять это. С заданным по умолчанию курсором любое предупреждение MySQL вызовет исключение Warning. Если Вы используете класс курсора без предупреждений, рекомендую проверять info(). Подробности в документации MySQL на mysql_info().

setinputsizes() Не делает ничего.

setoutputsizes() Не делает ничего.

5.3.4 Некоторые примеры использования

Метод connect() работает почти также, как и с _mysql:

import MySQLdbdb=MySQLdb.connect(passwd="moonpie",db="thangs")

Page 222: 1 MySQL API

Чтобы выполнить запрос, Вы сначала нуждаетесь в курсоре, а затем Вы можете выполнять запросы на нем. c=db.cursor()max_price=5c.execute("""SELECT spam, eggs, sausage FROM breakfast WHERE price < %s""", (max_price,))

В этом примере max_price=5. Почему затем в строке использована опция %s? Потому, что MySQLdb преобразует это в литеральное значение SQL, которое является строкой '5'. Когда это закончено, запрос будет фактически таким: "...WHERE price < 5".

Так, а теперь результаты:

>>> c.fetchone()(3L, 2L, 0L)

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

Как упомянуто ранее, в то время как столбец MySQL INTEGER транслируется в Python integer, UNSIGNED INTEGER может вызвать переполнение, так что эти значения преобразованы в Python long integer. До Python 1.6 long integer сохраняли L, когда были преобразованы в строки с помощью str(). В 1.6 и позже str() не включает L. Конечно, L всегда выводится при использовании repr().

Когда Вы закончили работу с транзакцией, Вы должны выполнить db.commit() или db.rollback(). Если сервер и таблицы не поддерживает транзакции, commit() будет работать, но rollback() вызовет исключительную ситуацию. Обратите внимание, что это методы connection, а не cursor, даже при том, что транзакция запускается через c.execute(...).

Если Вы хотели получить большее количество строк, Вы могли бы использовать c.fetchmany(n) или c.fetchall(). На c.fetchmany(n) параметр n факультативный и имеет значение по умолчанию c.arraysize (обычно 100). Оба этих метода возвращают последовательность строк, или пустую последовательность, если строки уже кончились.

Обратите внимание, что в отличие от вышеупомянутого, c.fetchone() вернет None, когда не имеется больше строк для выборки.

Единственный другой метод, который Вы, очень вероятно, используете, это многострочная вставка:

c.execute("""INSERT INTO breakfast (name, spam, eggs, sausage, price) VALUES (%s, %s, %s, %s, %s)""",

Page 223: 1 MySQL API

[ ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ), ("Not So Much Spam Plate", 3, 2, 0, 3.95 ), ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )])

Здесь мы вставляем три строки по пять значений в каждой. Обратите внимание, что имеется смесь типов (строки, int, float), хотя все еще используется только %s. А также обратите внимание, что включили только строки формата для одной строки. MySQLdb выбирает и дублирует их для каждой строки.

5.4. Использование и расширение

Базы данных, даже SQL-базы данных, изменяются по возможностям очень сильно и могут иметь ненормативные свойства. DB API делает хорошую работу по обеспечению приемлемо переносимого интерфейса, но некоторых методов там нет. Специфические параметры для connect()полностью зависимы от реализации.

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

В качестве примера рекомендую изучить модуль SQLDict (http://dustman.net/andy/python), который позволяет стандартным запросам работать, используя объект, который напоминает словарь, а также читать и писать определяемые пользователем дополнительные объекты.

Поскольку объекты MySQLdb Connection и Cursor написаны на Python, Вы можете легко получать Ваши собственные подклассы. Имеются несколько классов Cursor в MySQLdb.cursors:

BaseCursor Основной класс для объектов Cursor. Не вызывает Warning.

CursorWarningMixIn Создает исключительную ситуацию Warning на запросах, которые производят предупреждения.

CursorStoreResultMixIn Заставляет Cursor использовать функцию mysql_store_result(), чтобы получить результат запроса. Весь набор результатов сохранен на стороне пользователя.

CursorUseResultMixIn

Page 224: 1 MySQL API

Заставляет курсор использовать функцию mysql_use_result(), чтобы получить результат запроса. Набор результатов сохранен на стороне сервера и передается построчно.

CursorTupleRowsMixIn Заставляет cursor возвращать строки как блоки значений столбца.

CursorDictRowsMixIn Заставляет cursor возвращать строки как как словарь, где ключи имена столбца, а значения представляют значения столбца. Обратите внимание, что, если имена столбца не уникальны, то есть, Вы выбираете из двух таблиц, которые совместно используют имена столбца, некоторые из них будут переделаны в table.column. Этого можно избежать, используя ключевое слово SQL AS

Cursor Заданный по умолчанию класс курсора. Этот класс составлен из CursorWarningMixIn, CursorStoreResultMixIn, CursorTupleRowsMixIn и BaseCursor, то есть он создает исключительную ситуацию Warning, использует mysql_store_result() и возвращает строки как блоки.

DictCursor Аналогичен Cursor за исключением того, что возвращает строки как словари.

SSCursor Серверный курсор. Похож на Cursor, но использует CursorUseResultMixIn. Используйте только, если Вы имеете дело с потенциально большими наборами результатов.

SSDictCursor Аналогичен SSCursor за исключением того, что возвращает строки как словари.

XXXCursorNW Курсоры с суффиксом NW не создают исключительную ситуацию Warning.

5.5. MySQLdb FAQ

5.5.1. Компиляция _mysql.so

Имеются некоторые общие ошибки, которые случаются в ходе построения пакета. Этот раздел покрывает только проблемы UNIX/Linux, поскольку я не делаю пакетов под Windows. Файлы типа .so представляют собой динамические библиотеки в Linux и большинстве других вариантов UNIX. Windows использует расширение .dll.

5.5.1.1 ImportError: libmysqlclient.so.6: cannot open shared object file: No such file or directory

Вы имеете динамические библиотеки MySQL, и по умолчанию Ваш компилятор линкует _mysql.so с ними, но они не в пути загрузчика, когда Вы запускаете Python. Вы имеете два базисных параметра:

Page 225: 1 MySQL API

1. Модифицируйте setup.py так, чтобы это компоновалось со статической библиотекой: уж ее-то искать не понадобится.

2. Если Ваш компоновщик поддерживает переключатель пути загрузчика во время выполнения, Вы можете также устанавливать это в setup.py.

3. Измените Вашу среду системы так, чтобы MySQL библиотеки нашлись в Вашем пути загрузчика. В Linux Вы можете изменять /etc/ld.so.conf или Вы можете добавить каталог к системной переменной LD_LIBRARY_PATH перед запуском Python.

4. LD_LIBRARY_PATH=/path/to/mysql/libs python ... # Bourne-ish shell

5.5.1.2 ImportError: ./_mysql.so: undefined symbol: PyLong_FromUnsignedLongLong

PyLong_FromUnsignedLongLong() сначала появляется в Python 1.5.2, так что Вы компонуете с более старой версией. Вы можете также иметь больше, чем одну установленную версию. Получите Python 1.5.2 (а лучше посвежее) с python.org.

5.5.1.3 ImportError: ./_mysql.so: undefined symbol: uncompress

Библиотеки пользователей MySQL-3.23 требуют libz для сжатия gzip. Скрипт setup.py должен бы добавить это автоматически.

5.5.1.4 ./_mysql.c:33: mysql.h: No such file or directory

Путь для include-файлов (-I) к Вашим MySQL include-файлам ошибочен. Поправьте скрипт setup.py. Другой вариант: Вы не имеете набора разработчика для MySQL. Если Вы используете Red Hat RPM, Вы нуждаетесь в RPM-пакете MySQL-devel, чтобы откомпилировать _mysql.so. Однако, если Вы компонуетесь со статическими библиотеками MySQL, Вы можете устанавливать _mysql.so на системе, которая не имеет библиотек пользователей MySQL (libmysqlclient).

5.5.1.5 Я использую только Windows...

А я не использую Windows. Скрипт setup.py, как предполагается, работает. Может также быть связь с каким-либо сторонним пакетом.

5.5.2. Проблемы с ZMySQLDA

5.5.2.1 Я установил MySQLdb, но ZMySQLDA его не видит

Вероятно, Вы установили двоичную версию Zope, которая приходит со своим собственным интерпретатором Python. Вы должны компилировать MySQLdb с той специфической установкой Python. Выясните, где находятся двоичные модули python и используйте это, чтобы выполнить setup.py.

5.5.2.2 Я получаю буквы L в столбцах INTEGER

Page 226: 1 MySQL API

Вообще-то они должны быть преобразованы в длинные целых числа, чтобы избежать переполнения на столбцах UNSIGNED INT. Решения: используйте атрибут fmt=%d на элементах dtml-var или поставьте Zope 2.4, который приходит с Python 2.1, который не добавляет L.

5.5.2.3 Я получаю синтаксическую ошибку SQL на предложениях LIMIT, но я не помещал в запрос слово LIMIT!

Z метода SQL имеют параметр max_rows. Если это установлено к значению, отличному от нуля, ZMySQLDA автоматически добавляет предложение LIMIT к инструкции SELECT. Это сильно повышает эффективность, особенно, если набор результатов мог бы быть большим. Если это сталкивается с чем-то, установите max_rows в ноль, и это не будет добавлять предложение LIMIT. В частности, Вы, вероятно, должны будете сделать это при вставке строк со столбцами AUTO_INCREMENT, поскольку обычно Вы используете SELECT, чтобы получить LAST_INSERT_ID(), а LIMIT может блокировать это.

5.5.3. Использование MySQLdb

MySQLdb представляет собой модуль, соответствующий спецификации Python Database API 2.0 (http://www.python.org/topics/database/DatabaseAPI-2.0.html), так что Вы должны быть знакомы с этой спецификацией. Здесь указаны отличия: http://dustman.net/andy/python/MySQLdb/doc/MySQLdb.html.

5.5.3.1 cursor.rollback() всегда падает!

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

cursor.commit(), который пытается завершить транзакцию всегда работает нормально потому, что MySQL по существу всегда в режиме auto-commit mode (если Вы не его не выключили).

5.5.3.2 Как я могу использовать некоторые из специальных свойств СУБД MySQL?

С одной стороны, никак. Не делайте этого, если Вы можете избежать этого. Ваша программа не будет переносима к другим базам данных.

Но если Вас эта переносимость не интересует, то почти все специальные обращения API выполнены в объекте _mysql, и объект связи в MySQLdb может также вызывать их.

Page 227: 1 MySQL API

5.5.3.3 Я все еще хочу использовать _mysql

Хорошо, это может быть необходимо в каком-то случае. ZMySQLDA делает это потому, что Zope-модуль ZRDB сам по себе API, а слишком много уровней API имеют тенденцию к разброду и шатанию. С этим поделать что-либо трудно. Кроме того, было фактически довольно просто сделать это именно таким способом, да и эффективность малость повысилась.

1. Читайте документацию на MySQL, особенно C API для краткого обзора. 2. Читайте документацию на MySQLdb. Это показывает, как C API

транслируется в Python. К тому же, это неплохой пример реализации. 3. Читайте исходники для MySQLdb, особенно рекомендуется для изучения

файл MySQLdb/cursors.py. Этот файл содержит большинство деталей, особенно в реализации методов _query.

5.6. MySQLmodule-1.4

Этот модуль был разработан под Linux (RH50), MySQL 3.21.30 и Python 1.5.1. MySQLmodule-1.x основан на mySQLmodule-0.1.4, разработанном:

Copyright (C) 1997 Joseph Skinner [email protected] Copyright (C) 1997 James Henstridge [email protected]

mySQLmodule-0.1.4 в свою очередь основан на mSQLmodule, разработанном:

Portions copyright (C) 1995 Thawte Consulting, cc Portions copyright (C) 1994 Anthony Baxter

5.6.1 Почему другой интерфейс Python/MySQL?

Была обнаружена проблема при сохранении строк, содержащих ASCII-ноль (\0) в базе данных MySQL. После расследования в языке Python (который создал первоначальную ошибку), был проверен код mySQLmodule и там найден ряд проблем. Некоторые подпрограммы не освобождают распределенную память, некоторые функции MySQL API не были доступны, и многих разработчиков совершенно не устраивал тот факт, что mySQLmodule возвратит различные структуры данных в зависимости от метода. Так что я переделал код. Так как эти изменения включают изменение в методах Python и значениях возврата, был повышен код версии и изменено имя модуля на MySQL, чтобы оно не столкнулось с оригиналом (mySQL).

Рационально возвратить список списков вместо набора или списка наборов. Не стоит создавать ситуацию, когда подпрограммы доступа к DB занимаются обработкой типа возврата, и стоит предусмотреть возможность изменить данные в возвращенной таблице напрямую.

Page 228: 1 MySQL API

Data = DBH['select * from MyTable']if Data: rows = len(Data) cols = len(Data[0]) for i in range(rows): for j in range(cols): if not Data[i][j]: Data[i][j] = DefaultElement() Do_Something(Data)

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

5.6.2 Компиляция и установка модуля MySQL

Скопируйте MySQLmodule.c в подкаталог Modules дерева исходников Python.

Добавьте следующие строки в Ваш файл Setup в этом каталоге: MySQL MySQLmodule.c -L/usr/local/lib/mysql/ -lmysqlclient \ -I/usr/local/include/mysql

Обратите внимание, что расположение библиотеки MySQL и include-каталога может быть иным на Вашей специфической системе. Вы можете формировать разделяемый модуль (вставкой ниже индикатора shared в файле Setup).

Если Вы формировали Python ранее, просто выполните make в Вашем основном каталоге Python. Если нет, следуйте командам о том, как компилировать и установить Python.

Чтобы формировать динамически загружаемый модуль без доступа к дереву исходников python, используйте:

gcc -shared -I/usr/include/python1.5 -I/usr/local/include/mysql \ MySQLmodule.c -lmysqlclient -L/usr/lib/python1.5/config \ -lpython1.5 -o MySQLmodule.so

Переместите возникающий в результате файл MySQLmodule.so в PYTHONPATH. Замените соответствующие расположения Ваших библиотек и include-файлов.

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

Экспортируемые типы, функции и классы

Page 229: 1 MySQL API

Модуль MySQL экспортирует следующее:

DBH_Type:Тип объекта базы данных.

STH_Type:Тип ошибки объекта курсора (исключительная ситуация, выдаваемая в некоторых обстоятельствах вместо TypeError).

__doc__:Версия, доступная из Python

connect([host[,user[,pass]]])Функциональный возврат объекта базы данных. Факультативные параметры: имя компьютера (host), с которым надлежит соединиться, username для связи с MySQL и соответствуюющий пароль password. Если никакой компьютер не задан, функция примет localhost (и будет использовать Unix-сокет для подключения к нему).

escape(string)Вернет правильно экранированную строку, чтобы позволить вставку в DB. Эта подпрограмма вызывает mysql_escape_string(), которая в 3.21.29-gamma не работает. Версия 3.21.30 и выше работают нормально.

Обратите внимание: в следующем "таблица" означает "список списков" (за исключением fetchdict). MySQL.connect() вернет дескриптор базы данных (DBH) со следующими методами:

Table = DBH.listdbs([wild])Возвращает таблицу, дающую имена баз данных на компьютере MySQL, с которым соединился через вызов MySQL.connect(). Факультативный параметр: MySQL-строка с символами подстановки (синтаксис аналогичен LIKE).

DBH.selectdb(DB_Name[,storage])Присоединяет этот объект к специфической базе данных. Выполненные запросы будут направлены к этой базе данных, пока не будет сделано другое обращение метода selectdb. Факультативный параметр storage типа integer может использоваться, чтобы хранить наборы результатов запросов на сервере. Обратите внимание, что это отрицательно воздействует на эффективность сервера, но позволяет клиентуре с маленькой памятью работать с записями по мере надобности. Значение по умолчанию: 0, то есть все записи перемещены пользователю сразу.

Table = DBH.listtables([wild])Возвращает таблицу с именами таблиц в выбранной базе данных. Имеет силу только после того, как было сделано обращение selectdb. Факультативный параметр может использоваться, чтобы ограничить возвращенный набор таблиц (тот же самый синтаксис, какой принят в LIKE).

Table = DBH.listfields(table[,wild])Возвращает таблицу описаний полей в данной таблице. Факультативный

Page 230: 1 MySQL API

параметр может использоваться, чтобы ограничить возвращенный набор полей (тот же самый синтаксис, какой принят в LIKE).

Table = DBH.listprocesses()Возвращает информацию относительно работающих процессов MySQL. Требует соответствующих привилегий (иначе возвращает None).

String = DBH.stat()Возвращает информацию состояния из MySQL.

DBH.create(DB_Definition)Создает новую базу данных.

DBH.drop(DB_Name)Удаляет базу данных.

DBH.reload()Перезагружает таблицы привилегий MySQL.

DBH.shutdown()Завершает сервер MySQL.

DBH.close()Закрывает DB-подключение.

String = DBH.clientinfo()Возвращает информацию о версии MySQLmodule.

String = DBH.serverinfo()Возвращает информацию о сервере MySQL.

String = DBH.hostinfo()Возвращает информацию относительно хоста соединения и типа подключения.

Integer = DBH.protoinfo()Возвращает информацию о версии протокола MySQL.

Table = DBH.do(query) или Table = DBH[query]Возвращает результат запроса SQL или число обработанных строк. Оба метода используют тип памяти, установленный в DBH.selectdb().

Integer = DBH.insert_id()Предоставляет доступ к последнему сгенерированному числу auto_increment. Это число может изменяться, если были запросы между обращениями.

STH = DBH.query(query[,storage])Возвращает операторный дескриптор для методов курсора (см. ниже). Факультативный параметр storage может использоваться, чтобы отменить значение по умолчанию DBH, установленное DBH.selectdb().

Методы для операторных дескрипторов (STH):

Table = STH.fetchrows([n])Возвращает результаты запроса к DB. Если n<0, все строки будут выбраны. Иначе будут возвращены только следующие n строк. Значение по умолчанию должно возвратить все строки.

Page 231: 1 MySQL API

Table = STH.fetchdict([n])Аналогично STH.fetchrows(), за исключением того, что список словарей возвращен с парами tablename.fieldname:data.

Table = STH.fields()Возвращает описания поля результата запроса STH. В настоящее время MySQLmodule понимает "pri", "notnull", "auto_inc", "ukey" и "mkey" .

STH.seek(n)Двигает курсор к строке n (0 определяет первую строку). Доступен только, если результат хранится на стороне пользователя (выбрано в DBH.selectdb). Иначе создает исключительную ситуацию.

Integer = STH.numrows()Возвращает, сколько строк находятся в результате запроса STH. Предупреждение: в действительности это число отражает сколько записей получил клиент. Для методов хранения на стороне сервера, это начинается с 0 и увеличивается по мере того, как пользователь выбирает строки. Для методов хранения на стороне клиента это число немедленно дает общее количество строк для этого запроса.

Integer = STH.numfields()Возвращает, сколько столбцов находятся в результате запроса STH.

Integer = STH.affectedrows()Возвращает данные на сколько строк воздействовал последний запрос. Обратите внимание, что MySQL не всегда возвращает правильное значение.

Integer = STH.insert_id()Возвращает значение auto_increment из STH-запроса insert. Обратите внимание, что это число постоянно, пока STH существует.

Integer = STH.eof()Возвратит 1, если последняя строка читалась, иначе 0. Всегда 1, если выбрано хранение данных на стороне пользователя (значение по умолчанию).

Использование модуля MySQL

import MySQLDBH = MySQL.connect() # localhostprint DBH.listdbs()DBH.selectdb('test')print DBH.serverinfo()print DBH.stat()DBH["create table pytest (x int, y int, s char(20))"]DBH["insert into pytest values (1,2,'abc')"]DBH.do("insert into pytest values (3,4,'def')")STH = DBH.query("insert into pytest values (5,6,'ghi')")print STH.affectedrows()print DBH['select * from pytest']STH = DBH.query("select * from pytest")print STH.numrows()print STH.fields()print STH.fetchrows(-1)STH.seek(0)

Page 232: 1 MySQL API

print STH.fetchrows(1)print STH.fetchrows(1)STH.seek(0)print STH.fetchrows(2)print STH.fetchrows(2)print STH.numfields()STH.seek(0)print STH.fetchdict(1)print STH.fetchdict()STH = DBH.query("select * from pytest",1)print STH.fetchdict(1)print STH.fetchdict() # compare to previous dictsSTH = DBH.query("select * from pytest",1)print STH.fetchrows(1)print STH.eof()print STH.fetchrows()print STH.eof()DBH['drop table pytest']

5.6.3 Примечания относительно хранения на сервере

MySQL предлагает два немного различных пути доступа к данным из базы данных.

Заданный по умолчанию метод в MySQLmodule состоит в том, чтобы использовать хранение на стороне пользователя, то есть все запросы, включая методы курсора (STH), выбирают все данные с сервера. К строкам обращаются через STH.fetchrows(n) или STH.fetchdict(n) индивидуально (n=1), блочно (n>1), все строки забирают одной порцией (n<0) или не обращаются вообще (n=0). STH.numrows() может сообщать после запроса сколько строк находится в результате. STH.seek(k) может использоваться, чтобы обратиться к строкам в произвольном порядке. Недостаток хранения на стороне пользователя состоит в том, что это использует память пользователя, чтобы сохранить все строки. Этот способ учитывает конструкции типа:

STH = DBH.query("select * from Foo")N = STH.numrows()if N > 1000: raise Hell,"You must be joking!"for i in xrange(N): [Data] = STH.fetchdict(1)

Так как пользователь действительно переместил к себе все строки, которые подготовил сервер, все транзакции на этом канале прекратились, и сервер готов принять новые команды. Это также означает, что STH.eof() всегда true (1) для хранения данных на стороне клиента.

Хранение на стороне сервера не требует, чтобы у пользователя было много памяти. Все записи будут перемещены на основании запроса. Однако, этот способ имеет несколько недостатков. Так как теперь возникает возможность того, что пользователь не забрал все строки, каждая новая команда должна проверить, является ли свободным, то есть готов ли он принять новую команду. Если нет,

Page 233: 1 MySQL API

команда должна очистить канал команды, выдавая запросы на чтение в количестве, достаточном, чтобы получить оставшиеся строки. MySQL API 3.21 не предлагает команды abort(). STH.numrows() не знает ничего относительно того, сколько строк были выбраны запросом, так что вышеупомянутый код примера будет падать. STH.numrows() будет, однако, модифицироваться, поскольку строки все-таки читаются, например:

STH = DBH.query("select * from Foo")Data = STH.fetchrows(-1)print "Got",STH.numrows(),"rows." # len(Data) is the same

STH.eof() имеет смысл только при хранении данных на сервере, но даже здесь такой код полезен не всегда:

STH = DBH.query("select 1")print STH.eof() # will print 0Data = STH.fetchrows(1) # retrieve the rowprint STH.eof() # still 0 :-(Data = STH.fetchrows(1) # must repeat. Data will be []print STH.eof() # now we get 1, but we already # knew that we've hit the end

Можно было рассматривать это, как ошибку. STH.seek(k) больше не доступен и создает исключение ("cannot seek on server"), то есть строки должны теперь читаться последовательно.

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

Для тех, кто не может решить, который метод является более подходящим для прикладной программы, MySQLmodule позволяет смешивать оба метода свободно. Заданное по умолчанию поведение может быть установлено через DBH.selectdb() и может быть изменено для индивидуального курсора (STH). Обратите внимание, что незавершенные запросы будут отменены последующими командами:

STH = DBH.query("select * from Foo",1) # use server side storageTables = DBH.listtables() # stomp on previous resultsData = STH.fetchrows() # nothing here anymore vs.STH = DBH.query("select * from Foo",0) # use client side storageTables = DBH.listtables() # won't interfereData = STH.fetchrows() # no problem...

Хранение на стороне сервера также создает более сложный код в MySQLmodule. Обычно при хранении на стороне клиента STH-курсоры независимы от

Page 234: 1 MySQL API

дескриптора базы данных. Немедленно после запроса все данные будут перекачаны клиенту, и пользователь может делать все, что сочтет необходимым с дескриптором DBH. Но при хранении на стороне сервера это становится сложным. С курсорами стороны сервера указатель на дескриптор сохранен в дескрипторе STH. MySQLmodule удостоверится, что этот кусок памяти не освобожден прежде, чем закроются все ожидающие обработки курсоры. Это означает, что mysql_close() не обязательно вызван, если база данных, обрабатываемая DBH, разрушена:

DBH = MySQL.connect() # get a DB handleSTH = DBH.query("select 1",1) # server side cursordel DBH # mysql_close() *not* calledSTH.fetchrows() # will succeed!del STH # now mysql_close() will be called # in DBH_dealloc()

Если Вы должны закрыть дескриптор DB немедленно, используйте DBH.close(). Все дальнейшие попытки работать на этом дескрипторе (даже ожидающие обработки курсоры стороны сервера) получат исключительную ситуацию "... server has gone away". Начиная с того момента, как mySQL не может принимать команды из последовательности, все DBH-методы должны проверить незавершенные STH-курсоры. Чтобы обращаться к ним, дескриптор DBH хранит указатель на STH-курсор.

5.6.4 Установка MySQLmodule-1.4 под Windows NT

Следующие инструкции основаны на информации, предоставленной Nigel Head ([email protected]).

Вы должны получить файл libMySQL.dll из клиентского пакета win32-mysql версии 3.22.8 или выше, более ранние версии не будут работать. Это доступно на www.tcx.se (или зеркалах) для свободной загрузки. Вы должны, вероятно, переместить файл в то же самое расположение, что и Ваша библиотека python15.dll.

Скомпилируйте MySQLmodule-1.4 с включенным переключателем WIN32. VC5 и файлы проекта MySQL.dsp и MySQL.dsw включены (но, вероятно, их придется изменять, чтобы удовлетворить требованиям Вашей среды).

Переместите возникающий в результате файл MySQL.pyd в Ваш каталог Python DLL.

Если что-то пойдет не так, помощь лучше всего поискать в конференции comp.lang.python.

5.7 Спецификация Python Database API 2.0

Этот API был определен, чтобы привести к одному знаменателю модули Python, которые используются, чтобы обратиться к базам данных. Этот документ

Page 235: 1 MySQL API

описывает Python Database API 2.0. Спецификация интерфейса состоит из нескольких разделов:

Интерфейс модулей Объекты подключения Объекты курсоров Типы конструкторов и объектов Хитрости в реализации Изменения при переходе с версии 1.0 на 2.0

Комментарии и вопросы относительно этой спецификации могут быть направлены на db - sig @ python . org .

Для получения большего количества информации относительно связи с помощью интерфейса базы данных с Python и о доступных пакетах изучите руководство на http :// www . python . org / topics / database .

5.7.1 Интерфейс модулей

Доступ к базе данных сделан доступным через объекты подключения. Модуль должен обеспечивать конструктор для них:

connect(parameters...) Конструктор для создания подключения с базой данных. Возвращает объект подключения. Требуется ряд параметров, которые являются зависимыми от базы данных.

Эти глобальные переменные модуля должны быть определены:

apilevel Строковая константа, устанавливающая поддержанный уровень DB API. В настоящее время допустимы только строки '1.0' и '2.0'. Если не задана, предполагается уровень интерфейса Database API 1.0.

threadsafety Целочисленная константа, устанавливающая уровень безопасности потоков, который интерфейс поддерживает. Возможные значения: 0 Потоки не могут совместно использовать модуль.1 Потоки могут совместно использовать модуль, но не подключения.2 Потоки могут совместно использовать модуль и подключения.3 Потоки могут совместно использовать модуль, курсоры и подключения.

Совместное использование в вышеупомянутом контексте означает, что два потока могут использовать ресурс без того, чтобы применять mutex-семафор, чтобы выполнить блокировку ресурса. Обратите внимание, что Вы не можете всегда делать внешние ресурсы поточно-безопасными управляя доступом, использующим mutex: ресурс может полагаться на глобальные

Page 236: 1 MySQL API

переменные или другие внешние источники данных, которые находятся вне Вашего управления!

paramstyle Строковая константа. Устанавливает тип маркера параметра, форматирующего ожидаемый интерфейсом. Возможные значения: 'qmark' Стиль метки запроса, например, '...WHERE name=?''numeric' Числовой, позиционный стиль, например, '...WHERE name=:1''named' Именованный стиль, например, '...WHERE name=:name''format' Формат кодов ANSI C printf, например, '...WHERE name=%s'

'pyformat' Расширенные форматные коды языка Python, например, '...WHERE name=%(name)s'

Модуль должен делать всю информацию об ошибках доступной через эти исключительные ситуации или через подклассы от них:

Warning Исключительная ситуация для важных предупреждений подобно усечениям данных при вставке и т. д. Это должно быть подклассом от Python StandardError.

Error Исключительная ситуация, которая является основным классом для всех других исключительных ситуаций ошибки. Вы можете использовать это, чтобы захватить все ошибки с одиночной частью 'except'. Предупреждения не считаются ошибками и таким образом не должны использовать этот класс как ядро. Это обязательно должно быть подклассом Python StandardError.

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

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

DataError Исключительная ситуация для ошибок, которые появляются из-за проблем с обработанными данными, подобно делению на ноль, числовое значение вне диапазона и т.д. Это должно быть подклассом DatabaseError.

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

IntegrityError

Page 237: 1 MySQL API

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

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

ProgrammingError Исключительная ситуация для ошибок программирования, например, таблица не найдена или уже существует, ошибка синтаксиса в инструкции SQL, неправильное число определенных параметров и т.д. Это должно быть подклассом DatabaseError.

NotSupportedError Исключительная ситуация для ситуации, когда использовался метод или API базы данных, который не поддержан базой данных, например, запрашивается rollback() на подключении, которое не поддерживает транзакции или имеет выключенные транзакции. Это должно быть подклассом DatabaseError.

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

Можно также не реализовывать метод вообще, тогда Python сам сгенерирует исключительную ситуацию AttributeError в случае, если метод запрошен. Это позволяет программисту проверять возможности базы данных, используя функцию hasattr().

Это размещение наследования исключительной ситуации:

StandardError|__Warning|__Error |__InterfaceError |__DatabaseError |__DataError |__OperationalError |__IntegrityError |__InternalError |__ProgrammingError |__NotSupportedError

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

5.7.2 Объекты подключения

Page 238: 1 MySQL API

Объекты подключения должны отвечать на следующие методы:

close() Закрыть подключение немедленно. Подключение будет непригодным, начиная с этого момента. Если с ним попытаться что-то сделать, будет вызвана исключительная ситуация Error (или подкласс от нее). То же самое применяется ко всем объектам курсора, пробующим использовать подключение.

commit() Передать любую ждущую обработки транзакцию на базу данных. Обратите внимание, что если база данных поддерживает auto-commit, это свойство надо заранее выключить. Метод интерфейса можно обеспечивать, чтобы иметь возможность отмены изменений.

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

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

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

Параметры конструктора подключения должны быть выполнены как параметры ключевого слова для более интуитивного использования и следовать этому порядку параметров:

dsn Источник данных как строка обязательноuser Имя пользователя как строка опциональноpassword Пароль пользователя как строка опциональноhost Имя хоста опциональноdatabase Имя базы данных опционально

Например, конструктор подключения мог бы выглядеть следующим образом: connect(dsn='myhost:MYDB',user='guido',password='234+$').

5.7.3 Объекты курсоров

Page 239: 1 MySQL API

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

Объекты курсоров должны отвечать на следующие методы и атрибуты:

description Этот атрибут только для чтения: последовательность последовательностей с 7 элементами. Каждая из этих последовательностей содержит информацию, описывающую один столбец результата: (name, type_code, display_size, internal_size, precision, scale, null_ok). Этот атрибут будет None для операций, которые не возвращают строки, или если курсор не имел операции, вызываемой через метод executeXXX().

Код type_code может интерпретироваться, сравнивая его с Type Objects , определенными в разделе ниже.

rowcount Этот атрибут только для чтения определяет число строк, обработанных последним вызовом executeXXX() (для SQL-инструкций, вроде select) или затронутых запросом (для SQL-инструкций, подобных update или insert). Атрибут равен -1 в случае, если никакой executeXXX() не выполнился на курсоре.

callproc(procname[,parameters]) Этот метод факультативный: все базы данных обеспечивают хранимые процедуры. Вызывает хранимую процедуру базы данных с данным именем. Последовательность параметров должна содержать одну запись для каждого параметра, который процедура ожидает. Результат обращения будет возвращен как изменяемая копия входной последовательности. Входные параметры оставлены нетронутыми, выводимые и вводимо-выводимые параметры будут заменены на возможно новые значения. Процедура может также обеспечивать набор результатов как вывод. Это затем должно быть сделано доступным через стандартные методы fetchXXX().

close() Закрывает курсор немедленно и делает его непригодным, начиная с текущего момента. При попытке что-либо с ним сделать еще, будет вызвана исключительная ситуация Error (или ее подкласс).

execute(operation[,parameters]) Препарирует и выполняет операцию базы данных (запрос или команду). Параметры можно обеспечивать как последовательность или отображение. Переменные определены в специфической для базы данных записи. Значения возврата не определены.

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

Page 240: 1 MySQL API

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

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

executemany(operation,seq_of_parameters) Готовит операцию базы данных (запрос или команду), а затем выполняет это для всех последовательностей параметров или отображений, найденных в последовательности seq_of_parameters.

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

Те же самые комментарии, что касаются execute(), также применяются к этому методу. Значения возврата не определены.

fetchone() Выбирает следующую строку набора результатов запросов, возвращая одиночную последовательность или None, когда больше нет доступных данных. Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов.

fetchmany([size=cursor.arraysize]) Выбирает следующую строку набора результатов запросов, возвращая последовательность последовательностей (например, список tuples). Пустая последовательность будет возвращена, когда больше нет доступных строк. Число строк, которое надо выбрать за обращение, определено параметром. Если это не задано, arraysize курсора определяет число строк, которые будут выбраны. Метод должен пробовать выбирать так много строк, как уаазано параметром. Если это невозможно из-за определенного числа строк, меньшее количество строк может быть возвращено.

Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов.

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

Page 241: 1 MySQL API

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

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

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

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

Исключительная ситуация Error (или ее подкласс) произойдет, если предыдущее обращение к executeXXX() не производило никакого набора результатов.

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

arraysize Этот атрибут для чтения-записи определяет число строк, которое надо выбрать с помощью fetchmany() за раз. Значение по умолчанию 1 (выбрать одиночную строку результатов)

Реализации должны отслеживать это значение применительно к методу fetchmany(), но никто не запрещает реально работать с базой данных каким-либо иным способом. Это может также использоваться в реализации метода executemany().

setinputsizes(sizes) Это может использоваться перед обращением для executeXXX() к предопределенным областям памяти для параметров операции. sizes определен как последовательность: один элемент для каждого входного параметра. Элемент должен быть Type Object, который соответствует вводу, который будет использоваться, или это должно быть целым числом, определяющим максимальную длину параметра строки. Если элемент равен None, то никакая предопределенная область памяти не будет зарезервирована для этого столбца (это полезно, чтобы избегать

Page 242: 1 MySQL API

предопределенных областей для больших вводов). Метод не является обязательным для использования и реализации.

setoutputsize(size[,column]) Устанавливает размер буфера столбца для выборок больших столбцов (например, LONG, BLOB и им подобных). Столбец определен как индекс в последовательности результатов. Отсутствие определения column установит заданный по умолчанию размер для всех больших столбцов в курсоре. Метод не является обязательным для использования и реализации.

5.7.4 Типы конструкторов и объектов

Многие базы данных должны иметь ввод в специфическом формате для связывания с входными параметрами операции. Например, если ввод предназначен для столбца DATE, то это будет связано с базой данных в специфическом формате строки. Подобные проблемы существуют для столбцов "Row ID" или больших двоичных элементов (например, столбцов blob или RAW). Это представляет проблемы для Python, начиная с параметров для метода без контроля типов executeXXX(). Когда модуль базы данных видит строковый объект, он не знает сходу, как с ним быть.

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

Атрибут description объекта курсора возвращает информацию относительно каждого из столбцов результата запроса. Здесь type_code должен быть равен одному из Type Objects, определенных ниже. Эти самые Type Objects могут быть равны больше, чем одному коду типа (например, DATETIME может быть равен кодам типа для столбцов даты, времени и метки времени).

Модуль экспортирует следующие конструкторы:

Date(year,month,day) Эта функция создает объект, хранящий значение даты.

Time(hour,minute,second) Эта функция создает объект, хранящий значение времени.

Timestamp(year,month,day,hour,minute,second) Эта функция создает объект, хранящий значение метки времени.

DateFromTicks(ticks) Эта функция создает объект, хранящий значение даты с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time).

TimeFromTicks(ticks)

Page 243: 1 MySQL API

Эта функция создает объект, хранящий значение времени с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time).

TimestampFromTicks(ticks) Эта функция создает объект, хранящий значение метки времени с данного значения импульсов сигнала времени (число секунд, начиная с epoch, согласно стандартному модулю Python time).

Binary(string) Эта функция создает объект, способный хранить строковое двоичное значение типа long.

STRING Этот объект используется, чтобы описать столбцы в базе данных, которые являются основанными на строках (например, типа CHAR).

BINARY Этот объект используется, чтобы описать двоичные (long) столбцы в базе данных (например, LONG, RAW, BLOB).

NUMBER Этот объект используется, чтобы описать числовые столбцы в базе данных.

DATETIME Этот объект используется, чтобы описать столбцы даты/времени в базе данных.

ROWID Этот объект используется, чтобы описать "Row ID" столбец в базе данных.

SQL-значение NULL представляется на вводе и выводе как Python None.

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

5.7.5 Хитрости в реализации

Привилегированные объектные типы для объектов даты/времени определены в пакете mxDateTime ( http :// starship . python . net /~ lemburg / mxDateTime . html ). Это обеспечивает все необходимые конструкторы и методы на уровнях Python и C.

Привилегированный объектный тип для объектов Binary является буферным типом, доступный в стандартном Python, начиная с версии 1.5.2. Подробности ищите в документации на Python и в дистрибутиве его исходников (файлы Include/bufferobject.h и Objects/bufferobject.c).

Имеется типовая реализация конструкторов для даты/времени, делегирующая работу универсальным конструкторам на основе Unix-импульсов сигнала времени:

import time def DateFromTicks(ticks):

Page 244: 1 MySQL API

return apply(Date,time.localtime(ticks)[:3]) def TimeFromTicks(ticks): return apply(Time,time.localtime(ticks)[3:6]) def TimestampFromTicks(ticks): return apply(Timestamp,time.localtime(ticks)[:6])

Этот класс Python позволяет выполнять вышеупомянутые объекты типа даже при том, что поле кода типа описания выдает много значений для type object:

class DBAPITypeObject: def __init__(self,*values): self.values = values def __cmp__(self,other): if other in self.values: return 0 if other < self.values: return 1 else: return -1

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

Имеется отрывок кода на Python, который реализует иерархию исключительных ситуаций, определенную выше:

import exceptions class Error(exceptions.StandardError): pass class Warning(exceptions.StandardError): pass class InterfaceError(Error): pass class DatabaseError(Error): pass class InternalError(DatabaseError): pass class OperationalError(DatabaseError): pass class ProgrammingError(DatabaseError): pass class IntegrityError(DatabaseError): pass

Page 245: 1 MySQL API

class DataError(DatabaseError): pass class NotSupportedError(DatabaseError): pass

На C Вы можете использовать API PyErr_NewException(fullname,base,NULL), чтобы создать объекты исключительной ситуации.

5.7.6 Изменения при переходе с версии 1.0 на 2.0

Python Database API 2.0 представляет несколько важных нововведений по сравнению с версией 1.0. Некоторые из этих изменений делают невозможным применять старые скрипты с новой версией DB API.

Потребность в отдельном dbi модуле была ликвидирована, и функциональные возможности, объединены непосредственно в интерфейс модуля.

Новые конструкторы и Type Objects были добавлены для значений даты/времени, RAW Type Object переименован в BINARY. Возникающий в результате набор должен покрыть все базисные типы данных, обычно присутствующие в современных базах данных на SQL.

Были добавлены новые константы (apilevel, threadlevel, paramstyle) и методы (executemany, nextset), чтобы обеспечить лучшее взаимодействие с разными базами данных.

Семантика метода callproc(), нужная чтобы вызывать хранимые процедуры, теперь ясно определена.

Определение значения возврата execute() изменилось. Раньше значение возврата было основано на типе инструкции SQL (что было не так-то просто реализовать), теперь же оно неопределенно, используйте более гибкий атрибут rowcount вместо этого. Модули могут использовать старый стиль значений возврата, но они больше не переданы под мандат спецификацией и должны рассматриваться как зависимый интерфейс базы данных.

Классы основных исключительных ситуаций были включены в спецификацию. Можно расширить иерархию исключительных ситуаций, определенную в этой спецификации, подклассифицируя определенные классы исключительных ситуаций.

Известные проблемы

Хотя спецификация версии 2.0 разъясняет много вопросов, которые были оставлены открытыми в версии 1.0, некоторые все еще остаются проблемами:

Определение полезного значения возврата для nextset() для случая, когда новый набор результат доступен.

Page 246: 1 MySQL API

Создание числового типа с фиксированной точкой для использования в качестве типа для пересчета чисел с минимальными потерями.

Замечания

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

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

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

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

6 MySQL DELPHI API

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

Буфер связи должен быть достаточно большим, чтобы хранить одиночную инструкцию SQL (для трафика "клиент-на сервер") и одну строку возвращенных данных (для трафика "сервер-на-клиент"). Буфер связи каждого потока будет динамически расширен до максимального ограничения, чтобы обработать любой запрос или строку. Например, если Вы имеете значения BLOB, которые содержат до 16M данных, Вы должны иметь ограничение буфера связи по крайней мере в 16M (на клиенте и на сервере сразу). Заданный по умолчанию максимум пользователя равен 16M, но заданный по умолчанию максимум сервера равен всего 1M. Вы можете увеличивать это, меняя значение параметра max_allowed_packet при запуске сервера.

Page 247: 1 MySQL API

Сервер MySQL сокращает каждый буфер связи до net_buffer_length байт после каждого запроса. Для клиентуры размер буфера, связанного с подключением, не будет уменьшен, пока подключение не будет закрыто.

6.1 Типы данных в DELPHI API

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

TMYSQL_RES Эта структура представляет результат запроса, который возвращает строки (SELECT, SHOW, DESCRIBE, EXPLAIN). Информация, возвращенная из запроса, названа набором результатов в остатках от этого раздела.

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

TMYSQL_FIELD Эта структура содержит информацию относительно поля, например, имя поля, тип и размер. Члены описаны более подробно ниже. Вы можете получать структуры TMYSQL_FIELD для каждого поля, неоднократно вызывая mysql_fetch_field(). Значения полей не являются частью этой структуры, они содержатся в структуре TMYSQL_ROW.

TMYSQL_FIELD_OFFSET Это тип-безопасное представление смещения в списке полей MySQL. Используются в вызове mysql_field_seek(). Смещения представляют собой номера полей внутри строки, начиная с нуля.

Tmy_ulonglong Тип, используемый для числа строк и для функций mysql_affected_rows(), mysql_num_rows() и mysql_insert_id(). Этот тип обеспечивает диапазон от 0 до 1.84e19. На некоторых системах попытка печатать значение типа Tmy_ulonglong не будет работать. Чтобы отпечатать такое значение, преобразуйте его к типу longint.

Структура TMYSQL_FIELD содержит члены, перечисленные ниже:

name:pchar; Имя поля, как строка с нулевым символом в конце.

table:pchar; Имя таблицы, содержащей это поле, если это не расчетное поле. Для расчетных полей, значение table представлено пустой строкой.

def:pchar; Значение по умолчанию этого поля, как строка с нулевым символом в конце. Это установлено только, если Вы используете mysql_list_fields().

typ:TFIELD_TYPES;

Page 248: 1 MySQL API

Тип поля. Значение typ может быть один из следующего: Значение Typ Используемый тип FIELD_TYPE_TINY TINYINTFIELD_TYPE_SHORT SMALLINTFIELD_TYPE_LONG INTEGERFIELD_TYPE_INT24 MEDIUMINTFIELD_TYPE_LONGLONG BIGINT

FIELD_TYPE_DECIMAL DECIMAL или NUMERICFIELD_TYPE_FLOAT FLOAT

FIELD_TYPE_DOUBLE DOUBLE или REALFIELD_TYPE_TIMESTAMP TIMESTAMPFIELD_TYPE_DATE DATEFIELD_TYPE_TIME TIMEFIELD_TYPE_DATETIME DATETIMEFIELD_TYPE_YEAR YEAR

FIELD_TYPE_STRING Строка (CHAR или VARCHAR)

FIELD_TYPE_BLOB BLOB или TEXT (используйте max_length, чтобы определить максимальную длину поля)

FIELD_TYPE_SET SETFIELD_TYPE_ENUM ENUMFIELD_TYPE_NULL NULL

FIELD_TYPE_CHAR Не рекомендуется: используйте FIELD_TYPE_TINYlength:longword;

Ширина поля, как она определена в описании таблицы. max_length:longword;

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

flags:longword; Различные биты задают флажки для поля. Значение flags может иметь ноль или большее количество из следующего набора битов: Значение Flags Что это значит NOT_NULL_FLAG Поле не может быть NULLPRI_KEY_FLAG Поле часть первичного ключаUNIQUE_KEY_FLAG Поле часть уникального ключа MULTIPLE_KEY_FLAG Поле часть неуникального ключа UNSIGNED_FLAG Поле имеет атрибут UNSIGNEDZEROFILL_FLAG Поле имеет атрибут ZEROFILLBINARY_FLAG Поле имеет атрибут BINARYAUTO_INCREMENT_FLAG Поле имеет атрибут AUTO_INCREMENTENUM_FLAG Поле имеет тип ENUMBLOB_FLAG Поле имеет тип BLOB или TEXTTIMESTAMP_FLAG Поле имеет тип TIMESTAMP

Page 249: 1 MySQL API

Использование BLOB_FLAG, ENUM_FLAG и TIMESTAMP_FLAG не рекомендуется потому, что они указывают тип поля, а не атрибут типа. Предпочтительно проверить field.typ вместо FIELD_TYPE_BLOB, FIELD_TYPE_ENUM или FIELD_TYPE_TIMESTAMP. Пример ниже иллюстрирует типичное использование flags: if (field.flags & NOT_NULL_FLAG) write("Field can't be null");

Вы можете использовать следующие макрокоманды, чтобы определить булево состояние значения flags: IS_NOT_NULL(flags) Истина, если это поле определено как NOT NULL

IS_PRI_KEY(flags) Истина, если это поле первичный ключ

IS_BLOB(flags) Истина, если это поле BLOB или TEXTdecimals:longword;

Число допустимых десятичных чисел для числовых полей.

6.2 Обзор функций Delphi API

Функции, доступные в Delphi API, перечислены ниже и описаны более подробно в следующем разделе. Подробности в разделе "Описание функций Delphi API".

mysql_affected_rows()Возвращает число строк измененных последним запросом UPDATE, DELETE или INSERT.

mysql_close() Закрывает подключение к серверу.mysql_connect() Соединяется с сервером.

mysql_change_user()Меняет пользователя и базу данных на открытом подключении.

mysql_create_db()Создает базу данных. Аналог команды SQL CREATE DATABASE.

mysql_data_seek()Ищет произвольную строку в наборе результатов запросов.

mysql_debug() Делает DBUG_PUSH для заданной строки.

mysql_drop_db()Удаляет базу данных. Эта функция аналогична команде SQL DROP DATABASE.

mysql_dump_debug_info()Заставляет сервер писать информацию отладки в файл регистрации.

mysql_eof()Определяет, читалась или нет последняя строка набора результатов.

mysql_errno()Возвращает код ошибки для вызванной недавно функции MySQL.

mysql_error()Возвращает текстовое сообщение об ошибке для вызванной недавно функции MySQL.

mysql_real_escape_string() Выходит из специальных символов в строке для использования в инструкции SQL, принимающей во внимание текущий набор символов данного

Page 250: 1 MySQL API

подключения.

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

Page 251: 1 MySQL API

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

Page 252: 1 MySQL API

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

Page 253: 1 MySQL API

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

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

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

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

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

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

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

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

Page 254: 1 MySQL API

произошел, вызывая mysql_errno(). Представление строки ошибки может быть получено, вызывая mysql_error().

6.3.1 mysql_affected_rows()

tmy_ulonglong mysql_affected_rows(mysql:PMYSQL):TMY_ULONGLONG; stdcall;

Описание

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

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

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

Если определен флажок CLIENT_FOUND_ROWS, при соединение с mysqld mysql_affected_rows() возвратит число строк, согласованных инструкцией WHERE для UPDATE.

Обратите внимание, что, когда использована команда REPLACE, mysql_affected_rows() вернет 2 потому, что в этом случае одна строка была вставлена, а затем дубликат был удален.

6.3.2 mysql_close()

mysql_close(sock:PMYSQL);stdcall;

Описание

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

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

Нет.

6.3.3 mysql_connect()

mysql_connect(mysql: PMYSQL; const host,user,passwd:pchar):PMYSQL; stdcall;

Page 255: 1 MySQL API

Описание

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

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

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

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

Ошибки

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

6.3.4 mysql_change_user()

mysql_change_user(mysql: PMYSQL; const user,passwd, db:pchar):TMY_BOOL;stdcall;

Описание

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

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

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

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

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

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

Page 256: 1 MySQL API

Ошибки

Аналогично 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 Имя базы данных слишком длинное.

6.3.5 mysql_create_db()

mysql_create_db(mysql:PMYSQL; const db:pchar):integer;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.6 mysql_data_seek()

Page 257: 1 MySQL API

mysql_data_seek(res:PMYSQL_RES;offset:TMY_ULONGLONG); stdcall;

Описание

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

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

6.3.7 mysql_debug()

mysql_debug(const debug:pchar);stdcall;

Описание

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

Пример

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

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

6.3.8 mysql_drop_db()

mysql_drop_db(mysql:PMYSQL; const db:pchar):integer;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR

Page 258: 1 MySQL API

Сервер MySQL занят. CR_SERVER_LOST

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

Произошла неизвестная ошибка.

6.3.9 mysql_dump_debug_info()

mysql_dump_debug_info(mysql:PMYSQL):integer;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.10 mysql_eof()

mysql_eof(res:PMYSQL_RES):TMY_BOOL;stdcall;

Описание

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

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

С другой стороны, если Вы используете mysql_use_result(), чтобы инициализировать поиск набора результата, строки набора получены с сервера по одной, поскольку Вы вызываете mysql_fetch_row() неоднократно. Потому что

Page 259: 1 MySQL API

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

Исторически mysql_eof() предшествует стандартной функции MySQL mysql_errno() и mysql_error(). Так как те функции ошибки обеспечивают ту же самую информацию, их использование предпочтительнее mysql_eof(). Фактически, они обеспечивают большее количество информации потому, что mysql_eof() возвращает только булево значение, в то время как функции ошибки указывают причину.

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

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

6.3.11 mysql_errno()

mysql_errno(mysql:PMYSQL):longword;stdcall;

Описание

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

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

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

6.3.12 mysql_error()

mysql_error(mysql:PMYSQL):pchar;stdcall;

Описание

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

Page 260: 1 MySQL API

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

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

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

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

6.3.13 mysql_escape_string()

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

6.3.14 mysql_fetch_field()

mysql_fetch_field(res:PMYSQL_RES):PMYSQL_FIELD;stdcall;

Описание

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

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

Если Вы вызвали mysql_query() чтобы выполнить SELECT на таблице, но не вызвали mysql_store_result(), MySQL возвращает заданную по умолчанию длину blob (8K), если Вы вызываете mysql_fetch_field(), чтобы спросить о длине поля типа BLOB. Размер в 8K выбран потому, что MySQL не знает максимальную длину для BLOB. Это должно быть сделано с перестраиваемой конфигурацией когда-нибудь. Как только Вы получили набор результатов, field.max_length

Page 261: 1 MySQL API

хранит длину самого большого значения для этого столбца в специфическом запросе.

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

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

6.3.15 mysql_fetch_fields()

mysql_fetch_fields(res:PMYSQL_RES):PMYSQL_FIELDS;stdcall;

Описание

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

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

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

6.3.16 mysql_fetch_field_direct()

mysql_fetch_field_direct(res:PMYSQL_RES; fieldnr:integer):PMYSQL_FIELD;stdcall;

Описание

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

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

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

6.3.17 mysql_fetch_lengths()

mysql_fetch_lengths(res:PMYSQL_RES):longword;stdcall;

Описание

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

Page 262: 1 MySQL API

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

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

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

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

Ошибки

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

6.3.18 mysql_fetch_row()

mysql_fetch_row(res:PMYSQL_RES):PMYSQL_ROW;stdcall;

Описание

Получает следующую строку набора результатов. Когда используется после mysql_store_result(), mysql_fetch_row() возвращает NULL, когда не имеется больше строк, чтобы получить. Когда используется после mysql_use_result(), mysql_fetch_row() вернет NULL, когда не имеется больше строк, чтобы получить, или произошла ошибка.

Число значений в строке задано mysql_num_fields(result). Если row хранит значение возврата от обращения к mysql_fetch_row(), указатели на значения меняются с row[0] на row[mysql_num_fields(result)-1]. Значения NULL в строке обозначены указателями NULL.

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

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

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

Page 263: 1 MySQL API

Ошибки

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.19 mysql_field_count()

mysql_field_count(mysql:PMYSQL):longword;stdcall;

Если Вы используете версию MySQL ранее, чем Version 3.22.24, Вы должны вместо этого использовать mysql_num_fields(res:PMYSQL_RES):longword; stdcall;.

Описание

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

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

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

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

6.3.20 mysql_field_seek()

mysql_field_seek(res:PMYSQL_RES; offset:TMYSQL_FIELD_OFFSET): TMYSQL_FIELD_OFFSET; stdcall;

Описание

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

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

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

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

Page 264: 1 MySQL API

6.3.21 mysql_field_tell()

mysql_field_tell(res:PMYSQL_RES):longword;stdcall;

Описание

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

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

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

6.3.22 mysql_free_result()

mysql_free_result(res:PMYSQL_RES);stdcall;

Описание

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

6.3.23 mysql_get_client_info()

mysql_get_client_info:pchar;stdcall;

Описание

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

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

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

6.3.24 mysql_get_host_info()

mysql_get_host_info(mysql:PMYSQL):pchar;stdcall;

Описание

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

Page 265: 1 MySQL API

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

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

6.3.25 mysql_get_proto_info()

mysql_get_proto_info(mysql:PMYSQL):longword;stdcall;

Описание

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

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

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

6.3.26 mysql_get_server_info()

mysql_get_server_info(mysql:PMYSQL):pchar;stdcall;

Описание

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

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

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

6.3.27 mysql_info()

mysql_info(mysql:PMYSQL):pchar;stdcall;

Описание

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

INSERT INTO ... SELECT ... Формат строки: Records: 100 Duplicates: 0 Warnings: 0

INSERT INTO ... VALUES (...),(...),(...)... Формат строки: Records: 3 Duplicates: 0 Warnings: 0

LOAD DATA INFILE ... Формат строки: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0

ALTER TABLE

Page 266: 1 MySQL API

Формат строки: Records: 3 Duplicates: 0 Warnings: 0 UPDATE

Формат строки: Rows matched: 40 Changed: 40 Warnings: 0

Обратите внимание, что mysql_info() возвращает значение не-NULL для инструкции INSERT ... VALUES только, если много списков значений было определено в инструкции.

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

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

6.3.28 mysql_init()

mysql_init(mysql: PMYSQL):PMYSQL;stdcall;

Описание

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

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

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

Ошибки

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

6.3.29 mysql_insert_id()

mysql_insert_id(mysql:PMYSQL):TMY_ULONGLONG;stdcall;

Описание

Возвращает ID, сгенерированный предыдущим запросом для столбца с поддержкой AUTO_INCREMENT. Используйте эту функцию после того, как Вы выполнили запрос INSERT для таблицы, которая содержит поле AUTO_INCREMENT.

Page 267: 1 MySQL API

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

mysql_insert_id() модифицируется после инструкций INSERT и UPDATE, которые генерируют значение AUTO_INCREMENT, или установки значения столбца с помощью LAST_INSERT_ID(expr).

Также обратите внимание, что значение функции SQL LAST_INSERT_ID() всегда содержит самое последнее сгенерированное значение AUTO_INCREMENT, и оно не будет сброшено между запросами потому, что значение этой функции поддерживается сервером.

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

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

6.3.30 mysql_kill()

mysql_kill(mysql:PMYSQL;pid:longword):integer;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.31 mysql_list_dbs()

mysql_list_dbs(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;

Page 268: 1 MySQL API

Описание

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_OUT_OF_MEMORY Не хватило памяти.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.32 mysql_list_fields()

mysql_list_fields(mysql:PMYSQL;const table,wild:pchar):PMYSQL_RES; stdcall;

Описание

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

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

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

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

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

Page 269: 1 MySQL API

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.33 mysql_list_processes()

mysql_list_processes(mysql:PMYSQL):PMYSQL_RES;stdcall;

Описание

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.34 mysql_list_tables()

mysql_list_tables(mysql:PMYSQL;const wild:pchar):PMYSQL_RES;stdcall;

Описание

Возвращает набор результатов, состоящий из имен таблиц в текущей базе данных, которые соответствуют простому регулярному выражению, определенному параметром wild. Здесь wild может содержать групповые символы % или _, или

Page 270: 1 MySQL API

может быть NULL, чтобы соответствовать всем таблицам. Вызов mysql_list_tables() подобен выполнению запроса SHOW tables [LIKE wild].

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.35 mysql_num_fields()

mysql_num_fields(res:PMYSQL_RES):longword;stdcall;

Описание

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

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

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

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

6.3.36 mysql_num_rows()

mysql_num_rows(res:PMYSQL_RES):TMY_ULONGLONG;stdcall;

Описание

Page 271: 1 MySQL API

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

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

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

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

6.3.37 mysql_options()

mysql_options(mysql: PMYSQL; option: TMYSQL_OPTION; const arg: pchar): integer ;stdcall;

Описание

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

mysql_options() должна быть вызвана после mysql_init(), но перед mysql_connect() или mysql_real_connect().

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

Возможные значения параметров:

ОпцияТип аргумента

Действие

MYSQL_OPT_CONNECT_TIMEOUT longword Время ожидания в секундах.

MYSQL_OPT_COMPRESS TMY_BOOLИспользовать сжатый протокол клиент-сервер.

MYSQL_OPT_NAMED_PIPE TMY_BOOLИспользовать именованные каналы, чтобы соединиться с сервером MySQL под NT.

MYSQL_INIT_COMMAND PCHAR

Команда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически выполнена при повторном соединении.

MYSQL_READ_DEFAULT_FILE PCHAR Читать параметры из указанного файла

Page 272: 1 MySQL API

опций вместо my.cnf.

MYSQL_READ_DEFAULT_GROUP PCHAR

Читать параметры из именованной группы из файла опций my.cnf или файла, определенного в MYSQL_READ_DEFAULT_FILE.

Обратите внимание, что группа client всегда читается, если Вы используете MYSQL_READ_DEFAULT_FILE или MYSQL_READ_DEFAULT_GROUP.

Определенная группа в файле опций может содержать следующие параметры:

connect_timeout Время ожидания в секундах. В Linux это время ожидания также используется для ожидания первого ответа.

compress Использовать сжатый протокол клиент-сервер.

database Соединиться с этой базой данных, если никакая база данных не была определена в команде подключения.

debug Опции для отладки.host Имя сервера по умолчанию.

init-commandКоманда, чтобы выполнить при соединении с сервером MySQL. Будет автоматически заново выполнена при повторном соединении, если связь прервалась.

interactive-timeout

Аналогично указанию опции CLIENT_INTERACTIVE в mysql_real_connect().

password Пароль по умолчанию.

pipe Использовать именованные каналы, чтобы соединиться с сервером MySQL, работая под NT.

port Порт по умолчанию.

return-found-rows

Сообщить mysql_info() о том, что нужно возвратить найденные строки вместо модифицируемых строк при использовании UPDATE.

socket Сокет по умолчанию.user Пользователь по умолчанию.

Обратите внимание, что timeout был заменен на connect_timeout, но timeout будет все еще работать некоторое время для совместимости.

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

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

6.3.38 mysql_ping()

mysql_ping(mysql:PMYSQL):integer;stdcall;

Описание

Page 273: 1 MySQL API

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.39 mysql_query()

mysql_query(mysql:PMYSQL; const q:pchar):integer;stdcall;

Описание

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

CR_SERVER_LOST

Page 274: 1 MySQL API

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

Произошла неизвестная ошибка.

6.3.40 mysql_real_connect()

mysql_real_connect(mysql: PMYSQL; const host,user,passwd,db:pchar; port:longword; const unix_socket:pchar; clientflag:longword):PMYSQL;stdcall;

Описание

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

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

Первый параметр должен быть адресом существующей структуры типа TMYSQL. Перед вызовом mysql_real_connect() Вы должны вызвать mysql_init(), чтобы инициализировать структуру TMYSQL. Вы можете изменять много параметров подключения через вызов mysql_options().

Значением host может быть имя или адрес IP. Если это NULL или строка localhost, выполняется подключение к локальной системе. Если OS поддерживает сокеты (Unix) или именованные каналы (Windows), именно они используются вместо стека протоколов TCP/IP, чтобы соединиться с сервером.

Аргумент user содержит ID пользователя MySQL. Если user равен NULL, предполагается текущий пользователь. Под Unix это текущее (актуальное) имя входа в систему. Под Windows ODBC имя пользователя должно быть определено явно!

Параметр passwd содержит пароль для user. Если passwd равен NULL, только записи в таблице user, которые имеют пустое поле пароля, будут проверены на соответствие. Это позволяет администратору базы данных устанавливать систему привилегий MySQL таким способом, которым пользователи получают различные привилегии в зависимости от того, определили или нет они пароль. ОБРАТИТЕ ВНИМАНИЕ: Не пытайтесь шифровать пароль перед вызовом mysql_real_connect(): шифрование пароля обработано автоматически.

db задает имя базы данных. Если db не NULL, подключение установит заданную по умолчанию базу данных.

Если port не равен 0, значение будет использоваться как номер порта для подключения по TCP/IP. Обратите внимание, что параметр host определяет тип подключения.

Page 275: 1 MySQL API

Если unix_socket не равен NULL, строка определяет сокет или именованный канал, который должен использоваться. Обратите внимание, что параметр host определяет тип подключения.

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

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

CLIENT_FOUND_ROWS Возвратить число найденных, а не обработанных строк.

CLIENT_IGNORE_SPACEПозволить использовать пробелы после имен функций. Делает все зарезервированные слова именами функций.

CLIENT_INTERACTIVEПозволить interactive_timeout секунд (вместо wait_timeout секунд) бездеятельности перед закрытием подключения.

CLIENT_NO_SCHEMA

Не позволять синтаксис db_name.tbl_name.col_name. Это сделано для ODBC. Это заставляет синтаксический анализатор генерировать ошибку, если Вы используете тот синтаксис, который является полезным для заманивания в ловушку ошибок в некоторых программах ODBC.

CLIENT_ODBC Работает клиент ODBC.CLIENT_SSL Использовать шифрованный протокол SSL.

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

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

Ошибки

CR_CONN_HOST_ERROR Не удалось связаться с сервером.

CR_CONNECTION_ERROR Не удалось связаться с локальным сервером.

CR_IPSOCK_ERROR Не удалось создать IP-сокет.

CR_OUT_OF_MEMORY Не хватило памяти.

CR_SOCKET_CREATE_ERROR Не удалось создать Unix-сокет.

CR_UNKNOWN_HOST Не удалось найти IP-адрес для hostname.

CR_VERSION_ERROR

Page 276: 1 MySQL API

Несоответствие протоколов следовало из попытки соединиться с сервером с помощью клиентской библиотеки, которая использует иную версию протокола. Это может случиться, если Вы используете очень старую библиотеку, чтобы соединиться с новым сервером, который не был запущен с параметром --old-protocol.

CR_NAMEDPIPEOPEN_ERROR Не удалось создать именованный канал в Windows.

CR_NAMEDPIPEWAIT_ERROR Не удалось дождаться именованного канала в Windows.

CR_NAMEDPIPESETSTATE_ERROR Не удалось получить дескриптор для именованного канала в Windows.

CR_SERVER_LOST Если connect_timeout> 0 и требуется более, чем connect_timeout секунд, чтобы соединиться с сервером, или если сервер свалился при выполнении init-command, вернется это.

Используя mysql_options(), библиотека клиентов MySQL будет читать группы [client] и your_prog_name в файле my.cnf, что гарантирует, что Ваша программа будет работать, даже если кто-то установил MySQL некоторым ненормативным способом.

Обратите внимание, что на подключение mysql_real_connect() устанавливает флажок reconnect (часть структуры TMYSQL) в значение 1. Этот флажок указывает, что когда запрос не может выполниться из-за потерянного подключения, надо попробовать повторно соединиться с сервером перед отказом.

6.3.41 mysql_real_escape_string()

mysql_real_escape_string(mysql:PMYSQL; wto:pchar; const wfrom:pchar; wfromlength:longword):longword;stdcall;

Описание

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

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

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

Page 277: 1 MySQL API

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

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

6.3.42 mysql_real_query()

mysql_real_query(mysql:PMYSQL; const q:pchar; length:longword):integer;stdcall;

Описание

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

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.43 mysql_reload()

mysql_reload(mysql:PMYSQL):integer;stdcall;

Описание

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

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

Page 278: 1 MySQL API

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.44 mysql_row_seek()

mysql_row_seek(res:PMYSQL_RES; offset:PMYSQL_ROW_OFFSET):PMYSQL_ROW_OFFSET;stdcall;

Описание

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

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

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

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

6.3.45 mysql_row_tell()

mysql_row_tell(res:PMYSQL_RES):PMYSQL_ROWS;stdcall;

Описание

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

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

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

Page 279: 1 MySQL API

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

6.3.46 mysql_select_db()

mysql_select_db(mysql:PMYSQL; const db:pchar):integer;stdcall;

Описание

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.47 mysql_shutdown()

mysql_shutdown(mysql:PMYSQL):integer;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

Page 280: 1 MySQL API

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.48 mysql_stat()

mysql_stat(mysql:PMYSQL):pchar;stdcall;

Описание

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.49 mysql_store_result()

mysql_store_result(mysql:PMYSQL):PMYSQL_RES;stdcall;

Описание

Вы должны вызвать mysql_store_result() или mysql_use_result() для каждого запроса, который успешно получает данные (SELECT, SHOW, DESCRIBE, EXPLAIN).

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

Page 281: 1 MySQL API

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

mysql_store_result() читает весь результат запроса, распределяет структуру TMYSQL_RES и помещает результат в эту структуру.

mysql_store_results() вернет пустой указатель, если запрос не возвращал набор результатов вообще (если запрос был, например, инструкцией INSERT).

mysql_store_results() также возвращает пустой указатель, если чтение набора результатов потерпело неудачу. Вы можете проверить, получили ли Вы ошибку, проверяя возвращает ли mysql_error() пустой указатель. Если mysql_errno() <> 0, или если mysql_field_count() <> 0, значит, есть ошибочка.

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

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

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

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

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_OUT_OF_MEMORY Не хватило памяти.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

6.3.50 mysql_thread_id()

Page 282: 1 MySQL API

mysql_thread_id(mysql:PMYSQL):longword;stdcall;

Описание

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

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

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

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

6.3.51 mysql_use_result()

mysql_use_result(mysql:PMYSQL):PMYSQL_RES;stdcall;

Описание

Вы должны вызвать mysql_store_result() или mysql_use_result() для каждого запроса, который успешно получает данные (SELECT, SHOW, DESCRIBE, EXPLAIN).

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

С другой стороны, Вы не должны использовать mysql_use_result() если Вы делаете много обработки для каждой строки на стороне пользователя, или если вывод послан экрану, на котором пользователь может напечатать ^S (приостановить показ данных). Это свяжет сервер и не даст другим потокам модифицировать любые таблицы, из которых выбираются данные.

При использовании mysql_use_result() Вы должны выполнять mysql_fetch_row() до тех пор, пока значение не вернется значение NULL, иначе невыбранные строки будут возвращены как часть набора результатов для Вашего следующего запроса. API выдает ошибку "Commands out of sync; You can't run this command now", если Вы забываете про это!

Page 283: 1 MySQL API

Вы не можете использовать mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows() или mysql_affected_rows() с результатом, возвращенным из mysql_use_result(), и при этом Вы не можете выдавать другие запросы, пока не закончится mysql_use_result(). Однако, после того, как Вы выбрали все строки, mysql_num_rows() точно возвратит число выбранных строк.

Вы должны вызвать mysql_free_result() как только Вы закончили с этим набором результатов.

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

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

Ошибки

CR_COMMANDS_OUT_OF_SYNC Команды были выполнены в неподходящем порядке.

CR_OUT_OF_MEMORY Не хватило памяти.

CR_SERVER_GONE_ERROR Сервер MySQL занят.

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

CR_UNKNOWN_ERROR Произошла неизвестная ошибка.

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

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

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

Имелся сбой malloc() (например, если набор результатов был слишком большой).

Данные не могли прочитаться (произошла ошибка на подключении). Запрос не возвратил никакие данные (например, это был INSERT, UPDATE или

DELETE).

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

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

Page 284: 1 MySQL API

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

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

mysql_affected_rows() возвращает число строк, на которые воздействует последний запрос при выполнении INSERT, UPDATE или DELETE. Исключительная ситуация: DELETE используется без предложения WHERE, таблица будет пересоздана пустой, что намного быстрее! В этом случае mysql_affected_rows() возвращает ноль для числа записей.

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

mysql_insert_id() возвращает ID, сгенерированный последним запросом, который вставил строку в таблицу с индексом AUTO_INCREMENT. Подробности в разделе "6.3.126 mysql_insert_id()".

Некоторые запросы (LOAD DATA INFILE ..., INSERT INTO ... SELECT ..., UPDATE) возвращают дополнительную информацию. Результат возвращен через mysql_info(). mysql_info() вернет NULL если не имеется никакой дополнительной информации.

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

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

Вы можете также получать ID, используя функцию LAST_INSERT_ID() в строке запроса, которую Вы передаете mysql_query().

Вы можете проверять, используется ли индекс AUTO_INCREMENT, выполняя следующий код. Это также проверит, был ли запрос INSERT с индексом AUTO_INCREMENT:

if (mysql_error(pmysql)[0]=0) && (mysql_num_fields(result)=0) && (mysql_insert_id(pmysql) != 0) then begin used_id := mysql_insert_id(pmysql);end;

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

Page 285: 1 MySQL API

Если Вы хотите использовать ID, который был сгенерирован для одной таблицы и вставлять его во вторую таблицу, Вы можете использовать инструкции SQL подобно этому:

INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULLINSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table

содержание       назад       вперед

6.5 Пакет TmySQL 1.0.0.99XXXX

6.5.1 Введение

TmySQL представляет собой набор классов, которые могут использоваться в delphi наряду с файлом libmysql.dll. Это альтернативный интерфейс, заменяющий собой описанный выше.

6.5.2 Установка

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

Требуемый файл libmysql.dll включен в архив (Version 3.22.14-gamma, ее стоит заменить более свежей).

6.5.3 Интерфейс

unit MySql;

interfaceuses classes, dialogs, sysutils;

type TField = class public Name: String; FieldType: String; Constructor Create(aName: String); end;

TFields = class public Constructor Create(res: pmysql_res); Destructor Destroy; override; Function Count: Integer; Property Fields[Index: Integer]: TField read getField; default; Procedure Add(Value: TField); end;

TTable = class

Page 286: 1 MySQL API

public Name: String; Fields: TFields; Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; end;

TTables = class public Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; Function Count: Integer; Property Tables[Index: Integer]: TTable read getTable; default; Procedure Add(Value: TTable); end;

TDatabase = class public Name: String; Selected: Boolean; Tables: TTables; Constructor Create(aMySql: pmysql; aName: String); Destructor Destroy; override; Function Select: Boolean; end;

TDatabases = class public Constructor Create(aMySql: pmysql); Destructor Destroy; override; Function Count: Integer; Property Databases[Index: Integer]: TDatabase read getDatabase; default; Procedure Add(Value: TDatabase); end;

TRow = class public Constructor Create(aRow: TStringList); Destructor Destroy; override; Function Count: Integer; Property Databases[Index: Integer]: String read getValue; default; Procedure Add(Value: String); end;

TRows = class public Constructor Create(res: pmysql_res; Count: Integer); Destructor Destroy; override; Function Count: Integer; Property Rows[Index: Integer]: TRow read getRow; default; Procedure Add(Value: TRow); end;

TResult = class public Rows: TRows; Fields: TFields; AffectedRows: Integer; Constructor Create(res: pmysql_res; aMySql: pmysql); Destructor Destroy; override; Function lastError: String;

Page 287: 1 MySQL API

end;

TMySql = class public class function ClientVersion: String; constructor CreateConnect(aHost, aUser, aPassword: String; aPort: Integer); destructor Destroy; override; function Connect: Boolean; function Disconnect: Boolean; function Connected: boolean; Property Name: String read getName write setName; Property Host: String read getHost write setHost; Property User: String read getUser write setUser; Property Password: String read getPassword write setPassword; Property Port: Integer read getPort write setPort; function getVersion: String; function getHostInfo: String; function getProtocolVersion: Integer; function getThreadId: Longint; function getStat: String; function getProcesses: TResult; function getDatabases: TDatabases; function Query(sql: String): TResult; function SelectDb(d: String): Boolean; function CreateDb(name: String): Boolean; function DeleteDb(name: String): Boolean; function RefreshGrants: Boolean; end;

6.5.4 Использование

Единственный класс, который должен когда-либо создаваться пользователем: TmySQL. Другие будут созданы и разрушены автоматически.

Чтобы создать TmySQL, используйте Create или CreateConnect, который пробует соединиться сразу же.

TmySQL.getDatabases возвращает: TDatabases, TDatabase, TTables, TTable, TFields, TField.

TmySQL.Query и TmySQL.getProcesses возвращают: TResult, TFields, TField, TRows, TRow, String.

6.5.5 Copyright и распространение

Эта программа имеет статус freeware, for personal use.

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

С разработчиком можно связаться по адресу:

Page 288: 1 MySQL API

Hillware I/SDennis Thrys°eSolvangsvej 6, st, thDK-9000 Aalborgmailto:[email protected]://members.xoom.com/qabi

This product is:Copyright о 1999 by Hillware I/S, Dennis Thrysøe

содержание       назад       вперед

 

Редакция рекомендует: Методы сортировки и поиска Первые шаги к управлению всемирной информацией. Беседа с Патрицией

Селинджер Безопасность в Microsoft SQL Server 2005 Конфигурирование сервера Oracle для сверхбольших баз данных