В популярном веб-фреймверке CodeIgniter с поддержкой БД в формате SQLite 3 всё не слава богу. В устаревшем CodeIgniter (версии 1.7.x) ситуация была настолько запущена, что пришлось делать самодельный драйвер. Спустя пару лет, мы наблюдаем то же самое в CodeIgniter 2.
Давайте разбираться, как включить поддержку SQLite 3 в актуальной на текущий момент версии CodeIgniter 2.1.2.
Как строится работа с SQLite3 в CodeIgniter
Базы SQLite3 поддерживаются в CodeIgniter через механизм PDO. Таким образом, для работы с SQLite3 нам потребуется PDO-драйвер. В CodeIgniter 2 такой драйвер появился только в версии 2.1.x, так что те, кто пользуется стабильной версией 2.0.3 должны знать, что включить в ней поддержку SQLite3 не получится по причине отсутсвия нужного драйвера.
В версии 2.1.x наконец-то появился PDO-драйвер. И судьба его оказалась нелегка. Вначале он не мог работать с SQLite3 базами (портилась строка подключения к базе), потом в версии 2.1.1 отчитались о том, что работу восстановили:
Fixed a bug (#726) - PDO put a 'dbname' argument in it's connection string regardless of the database platform in use, which made it impossible to use SQLite.
А в версии 2.1.2 поддержка SQLite3 опять оказалась разломанной.
Cостояние PDO-драйвера в CodeIgniter 2.1.2
В текущей официальной версии CodeIgniter 2.1.2 PDO-драйвер находится в недоделанном состоянии. Если откроем файл /system/database/driver/pdo/pdo_driver.php, то увидим следующий загадочный код:
empty($this->database) OR $this->hostname .= ';dbname='.$this->database;
Не знаю, что хотели сказать авторы этим кодом, но вставив отладку в место, где происходит инициализация открытыя PDO-хэндла в методе db_connect(), можно наблюдать следующую строку подключения:
";dbname=sqlite:/путь/к/файлу/базы/файл.sqlite"
Может быть, такое имя подключаемой базы данных может переварить какой-нибудь MySQL over DPO, но вот для SQLite3 эта строка непонятна. Строка должна быть такой:
"sqlite:/путь/к/файлу/базы/файл.sqlite"
то есть, в строке должно содержаться именно то, что прописано в конфиге /application/config/database.php:
$db['default']['database'] = 'sqlite:'.APPPATH.'какой_то_путь/db.sqlite';
Исправление PDO-драйвера в CodeIgniter 2.1.2
Поняв в чем проблема, внесем исправление в файл pdo_driver.php. Закомментируем строку:
empty($this->database) OR $this->hostname .= ';dbname='.$this->database;
И вместо нее вставим следующий код:
empty($this->database);
if(strpos($this->database, 'sqlite:') !== FALSE)
$this->hostname .= $this->database;
else
$this->hostname .= ';dbname='.$this->database;
После такого исправления, подключение к SQLite3 базе через PDO драйвер начнет работать. Приведу пример настроек в /application/config/database.php, при которых работает соединение с SQLite3 базой:
$db['default']['hostname'] = '';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = 'sqlite:'.APPPATH.'какой_то_путь/db.sqlite';
$db['default']['dbdriver'] = 'pdo';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = FALSE;
$db['default']['db_debug'] = FALSE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
Соединение с базой будет установлено, казалось бы, все должно работать? Да, но если вы не забудете сделать одну важную вещь. На файл с базой данных нужно установить правильные права на чтение и запись. В UNIX-подобных системах скорее всего по-умолчанию у вас будут установлены права, позволяющие читать базу, но не позволяющие записывать. Самое неприятное, что сообщения об ошибке записи в файл базы показываться не будет, даже если выставить все опции видимости ошибок:
В php.ini:
display_errors = On
error_reporting = E_ALL & ~E_DEPRECATED
В index.php:
define('ENVIRONMENT', 'development');
В APPPATH/config/config.php:
$config['log_threshold'] = 4;
В APPPATH/config/database.php:
$db['default'] = array(
...
'db_debug' => TRUE,
...
То есть, если запись в базу SQLite3 молча не работает, ставьте права
chmod ugo+w файл
на файл базы данных.
Что будет дальше с PDO-драйвером в CodeIgniter 2
В секретных лабораториях EllisLab наконец-то поняли, что одним PDO-механизмом для работы с разными БД не обойдешься. PDO-механизм обеспечивает только универсальность подключения к БД. Но проблема в том, что в разных БД могут отличаться запросы для выполнения стандартных операций. Например, SQL-команда получения количества записей в таблице для MySQL и SQLite сильно отличается. И эти различия нужно учитывать в драйвере, если поверх него наложена абстракция ActiveRecord.
Поэтому, в текущей разрабатываемой версии CodeIgniter, для PDO-драйвера начали создавать механизм субдрайверов. В перспективе это приведет к тому, что поддержка различных баз данных (и файловых и клиент-серверных) наконец-то будет приведена в порядок. Но на появление правильной и безглючной поддержки SQLite3 я бы в настоящее время не расчитывал.
Кроме SQLite-субдрайвера PDO, в разрабатываемой версии CodeIgniter появился отдельный драйвер под названием sqlite3. То есть, предполагается, что для подключения к SQLite3 базе можно будет использовать следующие настройки:
$db['default']['database'] = APPPATH.'какой_то_путь/db.sqlite';
$db['default']['dbdriver'] = 'sqlite3';
Какой драйвер будет лучше, сказать не могу, но о возможном появлении двух разных драйверов для SQLite3 вы должны знать.
UPD: В результате работы над поддержкой SQLite3 в CodeIgniter 2, написан временный SQLite3-драйвер (такой же драйвер я писал и для CodeIgniter 1.7.x). Страничка проекта находится здесь:
Драйвер SQLite3 для CodeIgniter 2.x
Удачи.