Tag Archives: SQLite

SQLiteのインメモリDBを異なるPDOオブジェクトから参照するには

このエントリーをはてなブックマークに追加
はてなブックマーク - SQLiteのインメモリDBを異なるPDOオブジェクトから参照するには
Share on Facebook

どうにもSQLiteのインメモリDBの値が取得できなかったので、実験してみました。 いきなり結論を書くと、「あるPDOオブジェクトからは、別のPDOオブジェクトが作成したインメモリDBには接続できない」ようです。

テストコード

<?php
/**
 * SQLiteのオンメモリDBにテストデータを作成し、PDOからアクセスできることを確かめる
 */
try {
    $pdo1 = new PDO('sqlite::memory:', null, null);
    $pdo1->exec('CREATE TABLE uso(id INTEGER PRIMARY KEY, name STRING)');
    $pdo1->exec('INSERT INTO uso VALUES (1, "uhouho");');
    $pdo1->exec('INSERT INTO uso VALUES (2, "mojamoja");');

    // 接続済みのPDOオブジェクトからデータを取得できるか試してみる
    $stmt = $pdo1->query('SELECT * FROM uso');
    if (!$stmt) {
        echo 'Cannot fetch data via $pdo1.';
    } else {
        print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
    }

    // 新たにPDOオブジェクトを作成し、データを取得できるか試してみる
    $pdo2 = new PDO('sqlite::memory:');
    $stmt = $pdo2->query('SELECT * FROM uso');
    if (!$stmt) {
        echo 'Cannot fetch data via $pdo2.';
    } else {
        print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
    }
} catch (Exception $e) {
    exit($e->getMessage());
}

結果

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => uhouho
        )

    [1] => Array
        (
            [id] => 2
            [name] => mojamoja
        )

)
Cannot fetch data via $pdo2.

$pdo1で作成したインメモリDBに、$pdo2からは接続できていません。 どちらも同じ「sqlite::memory:」ですが、見ている領域は異なるようです。

考察

インメモリDB内に作ったテーブルに、複数のPDOオブジェクトからアクセスすることはできませんでした。 アクセスしたければ、テーブルを作ったPDOオブジェクトを使い回すしかなさそうです。

CakePHP公式のブログ作成チュートリアルをSQLite3でやってみる

このエントリーをはてなブックマークに追加
はてなブックマーク - CakePHP公式のブログ作成チュートリアルをSQLite3でやってみる
Share on Facebook

このチュートリアルの目的

一つのCakePHPコアに複数のアプリケーションを同居させる方法を学べます。DBを作ってdatabase.phpを作成すれば、あとはbakeするだけで基本的な画面が出来上がります。

公式チュートリアルと今回のやり方の違い

公式チュートリアル

  • MySQLでなくSQLite3で作る
  • アプリをCakePHP解凍時のappディレクトリ内に作らず、「{インストールディレクトリ}/blog」内にbakeしたファイルを元に作る
    • 一つのCakePHPコアから複数のアプリを併存させる環境を想定
  • Model/View/Controller はbakeして作る

作成環境

  • CakePHP 1.3.2
  • XAMPP Windows
    用途 場所
    ドキュメントルート c:\xampp\htdocs\
    CakePHPインストールディレクトリ c:\xampp\htdocs\cake
    blogアプリの場所 c:\xampp\htdocs\cake\blog

手順

1. SQLite3を使うための dbo_sqlite3.php を導入する

導入先: {インストールディレクトリ}/cake/libs/model/datasources/dbo/dbo_sqlite3.php

2. コンソールからblogアプリをbakeする

cd c:\xampp\htdocs\cake
mkdir blog
cake/console/cake bake blog

対話式コマンドは↓の通り(Databese Configurationは後で直接いじるので適当でよい)

Welcome to CakePHP v1.3.2 Console
---------------------------------------------------------------
App : sandbox
Path: c:\xampp\htdocs\cake
---------------------------------------------------------------
Bake Project
Skel Directory: C:\xampp\htdocs\cake\cake\console\templates\skel
Will be copied to: c:\xampp\htdocs\cake\blog
---------------------------------------------------------------
Look okay? (y/n/q)
[y] > y
Do you want verbose output? (y/n)
[n] >
---------------------------------------------------------------
Created: blog in c:\xampp\htdocs\cake\blog
---------------------------------------------------------------

Creating file c:\xampp\htdocs\cake\blog\views\pages\home.ctp
Wrote `c:\xampp\htdocs\cake\blog\views\pages\home.ctp`
Welcome page created
Random hash key created for 'Security.salt'
Random seed created for 'Security.cipherSeed'
CAKE_CORE_INCLUDE_PATH set to C:\xampp\htdocs\cake in webroot/index.php
CAKE_CORE_INCLUDE_PATH set to C:\xampp\htdocs\cake in webroot/test.php
Remember to check these value after moving to production server
Your database configuration was not found. Take a moment to create one.
---------------------------------------------------------------
Database Configuration:
---------------------------------------------------------------
Name:
[default] >
Driver: (db2/firebird/mssql/mysql/mysqli/odbc/oracle/postgres/sqlite/sybase)
[mysql] > sqlite3
Driver: (db2/firebird/mssql/mysql/mysqli/odbc/oracle/postgres/sqlite/sybase)
[mysql] > sqlite
Persistent Connection? (y/n)
[n] >
Database Host:
[localhost] >
Port?
[n] >
User:
[root] >
Password:
>
The password you supplied was empty. Use an empty password? (y/n)
[n] > y
Database Name:
[cake] >
Table Prefix?
[n] >
Table encoding?
[n] >

---------------------------------------------------------------
The following database configuration will be created:
---------------------------------------------------------------
Name:         default
Driver:       sqlite
Persistent:   false
Host:         localhost
User:         root
Pass:
Database:     cake
---------------------------------------------------------------
Look okay? (y/n)
[y] >
Do you wish to add another database configuration?
[n] >

Creating file c:\xampp\htdocs\cake\blog\config\database.php
Wrote `c:\xampp\htdocs\cake\blog\config\database.php`

3. DBファイルを作成し、テーブルとテストデータを作成する

DBの作成先: {インストールディレクトリ}/blog/db/blog.sqlite3

DBファイルを開いて、下記SQLを実行する。

-- テーブルを作成する
CREATE TABLE posts (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    title TEXT,
    body TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
);

-- テストデータを流し込む
INSERT INTO posts (title,body,created) VALUES ('The title', 'This is the post body.', datetime("now", "localtime"));
INSERT INTO posts (title,body,created) VALUES ('A title once again', 'And the post body follows.', datetime("now", "localtime"));
INSERT INTO posts (title,body,created) VALUES ('Title strikes back', 'This is really exciting! Not.', datetime("now", "localtime"));

4. database.phpを編集する

編集するファイル: {インストールディレクトリ}/blog/config/database.php

<?php
class DATABASE_CONFIG {

    var $default = array(
        'driver' => 'sqlite3',
        'database' => 'C:/xampp/htdocs/cake/blog/db/blog.sqlite3',
    );
}
?>

ここまでやったら、http://localhost/cake/blog にアクセスして、「Sweet, “Blog” got Baked by CakePHP!」という画面が出ることを確認します。画面に赤か黄色で示されるエラーがあれば、どこか間違っているので直してください。

※画像やCSSが表示されない場合、.htaccessの設定が違う場合があります。下記を手がかりに解決してください。

5. Model/View/Controllerをbakeする

チュートリアルだと「/cake/console/にPATHを設定しろ」と書いていますが、面倒なのでやってません。

コンソールから、下記のように入力してbakeします。

cd c:/xampp/htdocs/cake/blog
../cake/console/cake bake

この後、何をするか対話式ダイアログで聞かれるので、「M」→「C」→「V」の順に作成してください。(Controllerより先にViewを作ろうとすると「まだControllerがないから作れません」と言われます)

6. 完成

http://localhost/cake/blog/posts にアクセスすると、画面ができあがってます。

CakePHP1.3.2でSQLite3を使う(改訂版)

このエントリーをはてなブックマークに追加
はてなブックマーク - CakePHP1.3.2でSQLite3を使う(改訂版)
Share on Facebook

bakeできなかったので、下記を参考にやり直しました。

CakePHP SQLite – Stack Overflow

bake all するとWarningが続々出ますが、一応動きました。

  1. cakephp’s datasources at master – GitHub から「CakePHP Datasources Plugin v0.2」をダウンロードする
  2. 「cakePHPディレクトリ/app/plugins/datasources」内に解凍する
  3. プラグイン内の「models/datasources/dbo/dbo_sqlite3.php」を編集し、「class DboSqlite3 extends DboSource {」より前の行に「App::import(‘Datasource’,'DboSource’);」を追加する
<?php
/**
 * SQLite layer for DBO.
 *
 * PHP versions 4 and 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright 2005-2009, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       datasources
 * @subpackage    datasources.models.datasources.dbo
 * @since         CakePHP Datasources v 0.1
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */

App::import('Datasource','DboSource');

/**
 * DBO implementation for the SQLite3 DBMS.
 *
 * A DboSource adapter for SQLite 3 using PDO
 *
 * @package datasources
 * @subpackage datasources.models.datasources.dbo
 */
class DboSqlite3 extends DboSource {
  1. 「/app/config/database.php」を以下のように設定する
    var $default = array(
        'driver' => 'Datasources.DboSqlite3',
        'database' => '/full/path/to/db/db.sqlite',
    );

これで何とかbakeできるようになる。ただし、何かにつけ「Warning: FIXME: Can’t parse field: in C:\xampp\htdocs\cake\sandbox\cake\libs\model\datasources\dbo_source.php on line 2510」みたいなエラーが出てくる。

とりあえずCakePHP1.3の公式チュートリアルをやってみたけど、一応普通に動きました。

CodeIgniter1.7.2でSQLite3のカラム名を取得できるようにする

このエントリーをはてなブックマークに追加
はてなブックマーク - CodeIgniter1.7.2でSQLite3のカラム名を取得できるようにする
Share on Facebook

CodeIgniterのSQLite3に対する迫害と、引き続き奮闘しています。

CIでSQLite3を使えるようにする方法は 先日 紹介しました。

CIにはテーブルのカラム名を取得する「$this->db->list_fields()」というメソッドがありますが、上の方法で導入したPDOドライバでは使えません。どうやら list_fields() メソッドから呼び出されるローカル関数が定義されていないようです。

ちょっと改造すれば使えるようになったので、やり方を共有します。

手順

  1. /system/database/drivers/pdo/pdo_driver.php 内に、下記メソッドを追加する。(このメソッドはMySQLドライバ内の同一メソッドをSQLite用に修正したものです)
/**
 * Show column query
 *
 * Generates a platform-specific query string so that the column names can be fetched
 *
 * @access  public
 * @param   string  the table name
 * @return  string
 */
function _list_columns($table = '')
{
    return "PRAGMA table_info(" . $table . ");";
}
  1. /system/database/DB_driver.php 内の l.833-835 を下記のように書き換えます。
if (isset($row['COLUMN_NAME']))
{
    $retval[] = $row['COLUMN_NAME'];
}

 ↓

if (isset($row['COLUMN_NAME']) || isset($row['name']))
{
    $retval[] = isset($row['COLUMN_NAME']) ? $row['COLUMN_NAME'] : $row['name'];
}

これで、SQLite3でも 「$this->db->list_fields()」 を使ってカラム名が取得できるようになります。

[CodeIgniter] CodeIgniter1.7.2 で SQLite3 のDBを使う

このエントリーをはてなブックマークに追加
はてなブックマーク - [CodeIgniter] CodeIgniter1.7.2 で SQLite3 のDBを使う
Share on Facebook

CodeIgniterはPHP4との下位互換性を保っているせいか、標準で入っているSQLiteドライバーはSQLite2用のものらしい。PDOでのアクセス時は、その古いSQLiteドライバーに基づいているらしく、まともに動かない。

そういうわけで、有志が作成したPDOドライバーを導入しないとSQLite3のDBにはアクセスできない。

以下に、ドライバーの導入手順を示します。

手順

※CodeIgniter 1.7.2 用です。それより前のバージョンだと導入するドライバが違うかもしれないので、Wiki | CodeIgniterあたりを読んでください。

  1. Wiki | CodeIgniter から、「pdo driver 0 02 by xi.zip」をダウンロード
  2. CodeIgniter/system/database/drivers/pdo というディレクトリを作成し、その中に解凍する
  3. CodeIgniter/system/application/config/database.php を下記のように編集する
// DBファイルが /system/appilication/db/hige.sqlite3 にある場合
$db['default']['hostname'] = "";
$db['default']['username'] = "";
$db['default']['password'] = "";
$db['default']['database'] = "sqlite:".APPPATH."db/hige.sqlite3";
$db['default']['dbdriver'] = "pdo";
$db['default']['dbprefix'] = "";

これでアクセスできるようになります。

ちゃんとロードできているか確かめたい場合は、適当なviewファイルに

<?php echo $this->db->platform() . " ". $this->db->version(); ?>

と書いてみて、「pdo 3.6.20」などと出力されればOK。

参考