Perl всегда славился своими безграничными возможностями по причине наличия дополнительных модулей для самых различных нужд. Все эти модули хранятся в единой базе данных CPAN (Comprehensive Perl Archive Network, www.cpan.org).
Сейчас мы поговорим об одном из этих модулей — модуле для взаимодействия с СУБД SQLite.
Основными достоиствами SQLite являются следующие:
- В отличие от MySQL и MSSQL это встраиваемый движок баз данных, то есть для его функционирования не требуется никаких серверов баз данных;
- Хранение данных в едином файле на диске, что позволяет легко переносить базу данных с одной машины на другую;
- Полная поддержка транзакций запросов
Оффициальный сайт СУБД — http://www.sqlite.org/
Сама библиотека SQLite написана на C. Существует огромное количество интерфейсов для взаимодействия с различными языками программирования, в том числе C++, Java, .NET, Python, Perl, PHP.
В Perl для взаимодействия с базами данных SQLite используется пакет DBD::SQLite.
Прежде, чем начать взаимодейсвовать с SQLite из Perl создадим новую базу данных. Для этого в Linux существует специальная программа sqlite:
sqlite database.name
Если передаваемого в качестве параметра программе файла базы данных не существует, то он будет создан автоматически.
lxx@sabayonx86 ~ $ sqlite users.db
SQLite version 2.8.16
Enter ".help" for instructions
sqlite>
После запуска программы откроется консоль, подобная клиенту MySQL. Для выполнения некоторого запроса достаточно просто ввести его и нажать Enter.
Создадим новую таблицу пользователей для нашей будущей perl-программы, содержащую только одно поле (имя пользователя):
sqlite> create table users(user_name text);
sqlite>
Теперь можно закрывать базу данных:
sqlite> .quit
Также процедуру создания новой базы данных и таблиц в ней можно выполнить непосредственно в Perl маленьким скриптом:
#!/usr/bin/perl
use DBI;
$db = DBI->connect("dbi:SQLite:dbname=users.db","",""); # Подключаемся к базе данных. Если файла users.db не существует, то он будет создан автоматически
$db->do("create table users (user_name text);"); # Создаем новую таблицу в базе данных
$db->disconnect;
Если файла users.db не существует, то он будет создан скриптом автоматически.
Все, наша база данных создана, теперь можно переходить непосредственно к работе с данными.
Для взаимодействия Perl-программ с SQLite необходимо к программе подключить модуль DBI:
use DBI;
Далее подключаемся к нашей базе данных:
$db = DBI->connect("dbi:SQLite:dbname=users.db","","");
После dbname= следует указать файл Вашей базы данных. Путь может быть как абсолютным, так и относительным.
Если Вы собираетесь добавлять в базу текстовые данные в формате UTF-8, то следует перевести свойсво соединения unicode в 1:
$db->{unicode} = 1;
Пример кода для добавления данных в таблицу:
my $query = $db->do("INSERT INTO users VALUES('$user')");
$query > 0 ? print "$user added\n" : print "$user not added\n"; # Если в результате запроса затронуто больше 0 рядов, значит запрос выполнен успешно, а если нет, то неудачно.
Метод do используется в тех случаях, когда Вам нужно получить только количество затронутых рядов в таблице. Поэтому его и следует использовать для вставки, изменения или удаления данных.
А если Вам нужно получить данные из таблицы, то следует использовать методы prepare и execute:
my $query = $db->prepare("SELECT * FROM users WHERE (user_name LIKE 'A%')"); # Формируем запрос на выборку
$query->execute() or die($db->errstr); # Выполняем запрос. В случае неаозможности выполнения запроса умираем с выводом причины
while (($user) = $query->fetchrow_array()){л
print $user."\n";
}
Функций для получения количества возвращаемых SELECT'ом рядов, увы, нет, поэтому если Вам нужно получить количество рядов, то придется выполнить дополнительный запрос с count ():
$query = $db->prepare("SELECT count(*) FROM users WHERE (user_name LIKE 'A%')");
$query->execute() or die($db->errstr);
($users_count) = $query->fetchrow_array;
print "Query will return $users_count records\n\n";
Этот код можно записать короче с помощью метода selectrow_array:
($query) = $db->selectrow_array("SELECT count(*) FROM users WHERE (user_name LIKE 'A%')");
Метод selectrow_array () объединяет выполнение методов prepare, execute и fetchrow_array в один вызов. Выходными данными метода является массив, содержащий первый ряд возвращаемых запросом данных.
После завершения работы с базой данных следует закрыть соединение:
$db->disconnect; # Отключаемся от базы данных
Скачать исходный код программы, демонстрирующей взаимодействие SQLite с Perl можно тут.
Транзакции
Для использования транзакций необходимо при подключении к базе данных установить параметр AutoCommit в 0:
$db = DBI->connect("dbi:SQLite:dbname=users.db","","",{AutoCommit => 0});
Теперь можно подтверждать и откатывать транзакции методами commit и rollback:
$db->commit; $db->rollback;
BLOB-поля
Теоретически BLOB-поля в SQLite должны работать как простые текстовые ячейки. Но на практике это приводит к тому, что данные представляются в виде незавершенной строки, в результате чего появляются ошибки в определении размера blob'а. Ниже представлен пример правильной процедуры хранения данных в BLOB-полях:
use DBI qw(:sql_types);
my $dbh = DBI->connect("dbi:SQLite:dbfile","","");
my $blob = `cat /bin/sh`;
my $sth = $dbh->prepare("INSERT INTO mytable VALUES (1, ?)");
$sth->bind_param(1, $blob, SQL_BLOB);
$sth->execute();
$sth = $dbh->prepare("SELECT * FROM mytable WHERE id = 1");
$sth->execute();
my $row = $sth->fetch;
my $blobo = $row->[1];
Дополнительные функции
Пакет DBD::SQLite имеет еще несколько интересных методов, о которых нельзя не упомянуть:
$db->func('last_insert_rowid')
Этот метод возвращает идентификатор последнего вставленного ряда в таблице. Если в качестве первой колонки Вашей таблицы Вы укажите INTEGER PRIMARY KEY, то его значение и будет возвращено. Эсли этого поля нет, то будет возвращено значение скрытого поля ROWID (оно по умолчанию неявно создается для каждой таблицы).
Также для этих целей можно использовать метод $db->last_insert_id.
$db->func('busy_timeout')
Возвращает значение таймаута соединения.
$db->func( $ms, 'busy_timeout' )
Устанавливает значение таймаута соединения в $ms миллисекунд.
$db->func( $name, $argc, $code_ref, "create_function" )
Этот метод создает новую функцию, которая может быть использована в SQL-запросе
$name — имя функции. Оно будет использоваться в SQL-запросе.
$argc — количество аргументов, принимаемых функцией. Если этот параметр равен -1, то функция может принимать неограниченное число аргументов.
$code_ref — Ссылка непосредственно на функцию.
Пример создания новой функции:
$db->func( 'now', 0, sub { return time }, 'create_function' );
В SQL-запросе можно ее использовать следующим образом:
INSERT INTO mytable ( now() );
$dbh->func( $name, $code_ref, "create_collation" )
Аналогичен предыдущему методу, но создает COLLATE-функцию для сортировки.
Если что-то пошло не так
Для получения кодов и описаний ошибок, которые могут возникнуть в ходе работы с базой данных следует использовать методы err, errstr или state.
Метод err возвращает числовой код ошибки сервера баз данных.
Метод errstr возвращает текстовое описание произошедшей ошибки. Вы можете задать свои описания для различных кодов ошибки с помощью метода set_err ():
$db->set_err($err, $errstr)
Метод state возвращает 5-символьный код SQLSTATE.
Остались вопросы? Задавайте!
ЗЫ: