本稿はデータベースソフトウェア「SQL Anywhere」およびデータベース全般に関する英語ドキュメントを翻訳する形で提供しています。図など、部分的に英語のままになっていますが、製品のSQL Anywhere自体は完全に日本語化されていますのでご安心ください。
概要
SQL Anywhereは、興味深い機能を備えたシンプルで強力なデータベースです。フットプリントが小さく、自己管理能力と実用性に優れており、エンタープライズデータベースに必要とされる多くの機能を持ちながら、ごく普通のハードウェア上で動作させることができ、管理の手間も最小限で済みます。
さらに、SQL Anywhereはパフォーマンスの高い双方向の同期機能を備えているため、データベースアプリケーションと既存のエンタープライズデータセンターとの統合を簡単に実現できます。この最後の利点は、企業のブログインフラストラクチャにおいて特に重要な意味を持つと考えられます。
この技術情報記事では、WordPressの環境を変更して、SQL Anywhereデータベースと連携して動作できるようにする方法を説明します。
はじめに
この記事はWordPressに焦点を絞っていますが、同様の手法を利用して、ほとんどすべてのPHPアプリケーションを移行できます。ここで取り上げるWordPressの例では、標準のWordPress環境にドロップできるSQL Anywhere用のプラグインを作成します。このプラグインを利用すれば、WordPressのコードに他の変更を加えなくても、SQL Anywhereを使用できます。
この記事では、PHPサポートが有効になっているWebサーバが既にあり、そのサーバにSQL Anywhereがインストールされていることを前提としています。今回の設定では、Apache 2、PHP 5、WordPress 2.3.3、SQL Anywhere 10を使用し、WindowsとLinuxの両方でソリューションをテストしました。
手順としては、まず標準のWordPress環境を出発点とし、wp-db.phpをwp-adminからwp-content\db.phpという名前のファイルにコピーします。このファイルの名前と場所は重要です。サイトに対するアクセスがあると、WordPressソフトウェアはこのファイルを探し、ファイルが存在する場合はそれを既定のwp-db.phpファイルの代わりに使用します。この仕組みを利用して、WordPress用の独自のデータベースアクセス層をプラグインできます。
データベース接続のセットアップ
次に、このdb.phpファイルを編集して、SQL Anywhereで使用できるようにします。SQL Anywhere PHPドライバー(ここを参照)はMySQLと同様のAPIをサポートしているため、「mysql_」を検索して「sqlanywhere_」に置き換えるだけで、移行作業の大半が完了します。
つまり、mysql_connect()をsqlanywhere_connect()に変換すればよいのです。
MySQLとSQL Anywhereでは接続文字列の形式が異なりますが、どちらも同じ基本データ(ユーザー、パスワード、サーバの場所、データベース)を使用します。接続文字列を変換する作業は簡単です。
//MySQL connection $this->dbh = @mysql_connect($dbhost, $dbuser, $dbpassword); //SQL Anywhere connection $connstr= "eng=" . $dbhost . ";uid=" . $dbuser . ";pwd=" . $dbpassword . ";dbn=" . $dbname . ";links=shmem,tcpip"; $this->dbh = @sqlanywhere_connect($connstr);
必要な作業はこれだけですと言いたいところですが、実際には、ブログの作成を開始する前に、変更しなければならない項目がいくつかあります。
データベーススキーマの移行
まず、データベーススキーマをSQL Anywhere形式に移行します。この作業は、SQL Anywhere移行ウィザード(PDF)を使用することで簡単に実行できます。
しかし、より汎用性の高いソリューションを構築するためには、つまり標準のWordPress環境でSQL Anywhereをシームレスに使用できるようにし、このWordPressアプリケーション内で新しいWordPressブログをだれでも作成できるようにするためには、あといくつか作業を行って、ブログ作成機能を有効にしなければなりません。
大きな変更点は、WordPressのwp_install()関数を置き換えることです。SQL Anywhereの場合は、既存のwp_install()関数のクローンを作成し、2つの関数を追加して、wp_installから呼び出します。
function wp_install($blog_title, $user_name, $user_email, $public, $meta='') { global $wp_rewrite, $wpdb; wp_cache_flush(); //Reset schema information define_sa_schema(); make_db_current_silent(); create_sa_functions(); ... }
define_sa_schema()プロシージャは基本的にグローバル変数$wp_queriesを再定義し、既定のMySQLの構文の代わりにSQL Anywhereの構文を使用してWordPressのスキーマテーブルが作成されるようにします(この関数の完全なリストについては、こちらを参照ください)。
create_sa_functions()プロシージャは、SQL Anywhereの組み込み関数としては存在しないユーザー定義関数をいくつか作成します。SQL Anywhereはこれらの関数の機能をサポートしているため、ここでは、それらの関数を同じ名前のユーザー定義関数として追加し、SQL Anywhereの機能にマッピングしました。
例えば、次のようにします。
function create_sa_functions() { global $wpdb; $wpdb->query( " IF NOT EXISTS( select * from sysprocedure where proc_name = 'MD5' ) THEN CREATE FUNCTION MD5( str varchar(255) ) RETURNS binary(32) BEGIN return HASH( str, 'MD5' ); END; END IF;"); ... }
この関数の完全なリストは、ここで入手できます。
ここまでの作業を終えると、ブラウザからWordPressのホームページにアクセスし、新しい空のブログを作成できます。
WordPress環境をSQL Anywhere向けに変更する
これで新しいブログができました。実際にブログエントリを作成、表示し、他のWordPressのブログ管理ツールを使用するためには、MySQL固有の構文をSQL Anywhere用に書き換える必要があります。この場合も、一番簡単なのは、WordPressのすべてのインストールファイルを検索し、すべての不適切な構文を適切な構文に書き換えることです。
しかし、ソリューションの汎用性を高めたい場合は、db.phpファイル内部のクエリを書き換えた方が、SQL Anywhereを新しいWordPress環境のDBMSとして簡単にインストールできるようになりますし、WordPressソフトウェアの保守やアップグレードの手間も大幅に軽減されます。
幸い、この問題は簡単に解決できます。SQL AnywhereはWordPressで使用されるMySQLの機能をすべてサポートしているからです。ただ少々厄介なのは、SQL AnywhereはMySQLとは異なる構文を使用するという点です(SQL Anywhereはほぼ全面的にANSIに準拠しており、SQL構造体についてのANSI仕様がない部分ではMySQLの構文よりもMicrosoft SQL Serverの構文に近いものを使用します)。そのため、db.phpファイル内の構文をマッピングする方法を見つけなければなりません。
書き換え関数の作成
そこで役に立つのが検索置換と正規表現です。構文をマッピングする一番簡単な方法は、どのクエリよりも先に呼び出される「書き換え」関数を作成することです。幸いWordPressでは、すべてのクエリがdb.phpファイル内の「クエリ」関数を経由するため、新しい書き換え関数を追加して、それをquery()関数から呼び出せば済みます。
この書き換えを行うrewrite_query()関数は、基本的に特定のクエリ構造体を検索し、それを目的の形式に置換します。例えば、WordPressではLIMIT句を多用しますが、これはSQL AnywhereのTOP N句を使用する動作に対応しています。このようなクエリを書き換えるために、筆者は書き換え関数の中で次のコードを使用しました。
//Find LIMIT clause integer arguments and replace with //TOP N START AT m //MySQL syntax for LIMIT is: // LIMIT {[offset,] row_count | row_count OFFSET offset}] //Note that the LIMIT clause is at the end of the query //The pattern is LIMIT followed by an integer, possibly // followed by a comma and another integer $pattern = "/LIMIT\s*(\d+)((\s*,?\s*)(\d+)*)/i"; $matched = preg_match( $pattern, $query, $limitmatches ); if( $matched == 1 ) { //Remove the LIMIT statement, replace offset 0 with 1 $query = preg_replace( $pattern, '', $query); if( count( $limitmatches ) == 5 ) { if( $limitmatches[1] == '0' ) { $limitmatches[1] = '1'; } $replacement = 'SELECT TOP '.$limitmatches[4].' START AT '.$limitmatches[1].' '; } else { $replacement = 'SELECT TOP '.$limitmatches[1].' '; } $query = preg_replace( '/^\s*SELECT\s*/i', $replacement, $query );
この作業を他のいくつかの構造体についても実行する必要がありました。必要な作業を終えたら、それらをまとめてrewrite_query()関数に挿入しました。書き換え関数の完全なリストについては、ここを参照ください。
SQL Anywhereを使用したブログの実現
ここまでの作業を終えると、ブログは完全に機能するようになります。新しいブログを作成し、すべての管理機能を実行できます。この方法の最大の利点は、1つのファイル(db.php)を任意のWordPress環境に追加するだけで、WordPressをMySQLからSQL Anywhereへ移行できることです。SQL Anywhere移行ウィザードを使用して、既存のブログをブログエントリごとSQL Anywhereデータベースに移行することもできます。同じ手法を利用して、任意のPHPベースのデータベースアプリケーションをSQL Anywhereに移行することもできます。
この修正版WordPressを利用したブログの実例はここで見ることができます。