Основы программирования в Linux - Нейл Мэтью
Шрифт:
Интервал:
Закладка:
void mysql_close(MYSQL * connection);
Эта подпрограмма разорвет соединение с сервером. Если подключение устанавливалось с помощью mysql_init, память, отведенная под структуру дескриптора, освободится. Указатель станет неопределенным, и его нельзя будет применять в дальнейшем. Открытое ненужное подключение означает расточительное использование ресурсов, но повторное открытие подключения сопряжено с дополнительными накладными расходами, поэтому решайте сами, когда применять описанные подпрограммы.
Подпрограмма mysql_options (которую можно вызвать только между вызовами mysql_init и mysql_real_connect) позволит настроить некоторые параметры.
int mysql_options(MYSQL* connection, enum option_to_set, const char *argument);
Поскольку при каждом вызове mysql_options способна настроить только один параметр, ее следует вызывать отдельно для каждого параметра, который нужно задать. Вы можете применять эту подпрограмму необходимое количество раз, но все вызовы должны находиться между вызовами подпрограмм mysql_init и mysql_real_connect. Не все параметры подпрограммы имеют тип char, который следует приводить как const char*. Три самых часто используемых параметра приведены в табл. 8.11. И как всегда в расширенном интерактивном руководстве приведен полный список параметров.
Таблица 8.11
Enum-параметр Действительный тип аргумента Описание MYSQL_ОРТ_CONNECT_TIMEOUT const unsigned int* Количество секунд ожидания перед закрытием подключения из-за простоя MYSQL_ОРТ_COMPRESS Нет, используйте NULL Применять сжатие при сетевом подключении MYSQL_INIT_COMMAND const char* Команда, отправляемая при каждом установлении подключенияУспешный вызов возвращает ноль. Поскольку эта подпрограмма предназначена для установки флагов, аварийное завершение всегда означает использование неверного параметра.
Для задания времени ожидания, равного семи секундам, используйте следующий фрагмент программного кода:
unsigned int timeout = 7;
...
connection = mysql_init(NULL);
ret = mysql_options(connection, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
if (ret) {
/* Обработка ошибки */
...
}
connection = mysql_real_connect(connection ...)
Теперь, когда вы научились устанавливать, и закрывать ваше подключение, попробуем с помощью короткой программы проверить полученные знания на практике.
Начните с задания нового пароля для пользователя (в приведенном далее коде rick на localhost) и затем создайте базу данных foo, к которой будете подключаться. Вы все это уже знаете, поэтому мы просто приводим последовательность действий:
$ mysql -u root -р
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
mysql> GRANT ALL ON *.* TO [email protected] IDENTIFIED BY 'secret';
Query OK, 0 rows affected (0.01 sec)
mysql> q
Bye
$ mysql -u rick -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
mysql> CREATE DATABASE foo;
Query OK, 1 row affected (0.01 sec)
mysql> q
Вы создали новую базу данных. Вместо ввода подробностей создания таблицы и вставки команд непосредственно в командную строку монитора mysql, что сопряжено с ошибками и не слишком продуктивно при необходимости повторного ввода, вы создадите файл со всеми нужными вам командами.
Далее приведен файл create_children.sql:
--
-- Create the table children
--
CREATE TABLE children (
childno int(11) NOT NULL auto_increment,
fname varchar(30),
age int(11),
PRIMARY KEY (childno)
);
--
--Populate the table 'children'
--
INSERT INTO children(childno, fname, age) VALUES (1,'Jenny',21);
INSERT INTO children(childno, fname, age) VALUES (2,'Andrew',17);
INSERT INTO children(childno, fname, age) VALUES (3,'Gavin',8);
INSERT INTO children(childno, fname, age) VALUES (4,'Duncan', 6);
INSERT INTO children(childno, fname, age) VALUES (5,'Emma',4);
INSERT INTO children(childno, fname, age) VALUES (6,'Alex',15);
INSERT INTO children(childno, fname, age) VALUES (7,'Adrian',9);
Теперь вы можете снова зарегистрироваться в MySQL, выбрав базу данных foo, и выполнить данный файл. Для краткости и как пример для включения при желании в сценарий мы поместили пароль в командную строку:
$ mysql -u rick --password=secret foo
Welcome to the MySQL monitor. Commands end with ; or g.
mysql> . create_children.sql
Query OK, 0 rows affected (0.01 sec)
Query OK, 1 row affected (0.00 sec)
Мы убрали из вывода множество дублирующихся строк, например, строки, созданные в базе данных. Теперь, имея пользователя, базу данных и таблицу с хранящимися данными, самое время посмотреть, как обращаться к данным из программы.
Далее приведен файл connect1.с, который подключается от имени пользователя rick с паролем secret к серверу на локальной машине и базе данных foo.
#include <stdlib.h>
#include <stdio.h>
#include "mysql.h"
int main(int argc, char *argv[]) {
MYSQL *conn_ptr;
conn_ptr = mysqlinit(NULL);
if (!conn_ptr) {
fprintf(stderr, "mysql_init failedn");
return EXIT_FAILURE;
}
conn_ptr = mysql_real_connect(conn_ptr, "localhost", "rick", "secret",
"foo", 0, NULL, 0);
if (conn_ptr) {
printf("Connection successn");
} else {
printf ("Connection failedn");
}
mysql_close(conn_ptr);
return EXIT_SUCCESS;
}
Теперь откомпилируйте программу и посмотрите, как вы это сделали. Возможно, придется вставить путь к файлам include и путь к библиотекам, а также указать, что файл нуждается в компоновке с библиотечным модулем mysqlclient. В некоторых системах может понадобиться опция -lz для компоновки с библиотекой упаковки (compression library). В системе авторов требуемая строка компиляции выглядит следующим образом:
$ gcc -I/usr/include/mysql connect1.с -L/usr/lib/mysql -lmysqlclient -о connect1
Вам, возможно, придется проверить, установлены ли пакеты клиентской части и место их установки, зависящее от применяемого вами дистрибутива, и откорректировать, соответственно, приведенную строку компиляции.
Когда вы запустите программу, должно появиться сообщение об успешном подключении:
$ ./connect1
Connection success $
В главе 9 мы покажем, как создать make-файл и автоматизировать процесс подключения.
Как видите, подключиться к базе данных MySQL очень легко.
Обработка ошибок
Прежде чем мы перейдем к более сложным программам, полезно взглянуть на то, как MySQL обрабатывает ошибки. СУРБД MySQL использует ряд возвращаемых числовых кодов, предоставляемых дескриптором подключения. К двум обязательным подпрограммам относятся следующие:
unsigned int mysql_errno(MYSQL *connection);
и
char *mysql_error(MYSQL *connection);
Вы можете получить код ошибки, обычно любое ненулевое значение, вызвав подпрограмму mysql_errno и передав ей дескриптор подключения. Если никакой код ошибки не установлен, возвращается ноль. Поскольку код обновляется при каждом вызове библиотечной функции, можно извлечь код только последней выполненной команды, за исключением двух подпрограмм обработки ошибок, которые не приводят к обновлению кода ошибки.
Возвращаемое значение — в действительности код ошибки, коды ошибок определены в файле include с именем errmsg.h или в файле mysqld_error.h. Оба файла можно найти в каталоге MySQL с именем include. Первый сообщает об ошибках клиентской стороны, а второй — об ошибках сервера.
Если вы предпочитаете текстовое сообщение об ошибке, можно вызвать подпрограмму mysql_error, которая вместо кода предоставляет осмысленное текстовое сообщение. Текст сообщения пишется в некоторую внутреннюю область статической памяти, поэтому для сохранения текста ошибки его следует скопировать куда- нибудь.
Вы можете вставить элементарную обработку ошибок в вашу программу для того, чтобы увидеть все это в действии. Возможно, вы уже заметили, что можно столкнуться с проблемой, поскольку подпрограмма mysql_real_connect в случае сбоя возвращает указатель NULL, лишая вас кода ошибки. Если дескриптор подключения сделать переменной, его все же можно получить при аварийном завершении mysql_real_connect.
Далее приведен файл connect2.c, демонстрирующий, как применять структуру дескриптора подключения без динамического выделения памяти для нее, а также как написать некоторый базовый программный код обработки ошибок. Внесенные изменения выделены цветом.