インストーラ改修(4) テーブルprefix対応

DBのprefix設定に対応してみました。


2010/04/19
1つのDBに複数をインストールする場合のために、外部キ−名にもprefixを適用追加が必要でした



SQL実行は、
1.SQLダンプファイルを__executeSQLScript()でファイルに読み込み、stringで取得
2. ; でSQL一文ごとの配列に区切り
3.逐次実行

なので、2と3の間に正規表現置換を入れました。


ダンプファイルの形式細部が違うと無効ですが、 mysqldumpで作成したダンプを使う前提にしました。

--- a/app/plugins/install/controllers/install_controller.php
+++ b/app/plugins/install/controllers/install_controller.php
@@ -126,7 +126,7 @@ class InstallController extends InstallAppController {
                        $content = str_replace('{default_password}', $this->data['Install']['password']
                        $content = str_replace('{default_database}', $this->data['Install']['database']
                        // The database import script does not support prefixes at this point
-                       $content = str_replace('{default_prefix}', ''/*$this->data['Install']['prefix']
+                       $content = str_replace('{default_prefix}', $this->data['Install']['prefix'], $c

                        if($file->write($content) ) {
                                $this->redirect(array('action' => 'data'));
@@ -200,8 +200,22 @@ class InstallController extends InstallAppController {
         $statements = file_get_contents($fileName);
         $statements = explode(';', $statements);

+       $prefix = $db->config["prefix"];
+
         foreach ($statements as $statement) {
             if (trim($statement) != '') {
+
+               // table prefix
+               $pattern = array(
+                       '/(DROP TABLE IF EXISTS `)([a-z_]+)(`)/i', // DROP TABLE
+                       '/(CREATE TABLE `)([a-z_]+)(`)/i', // CREATE TABLE
+                       '/(FOREIGN KEY \(`[a-z_]+`\) REFERENCES `)([a-z_]+)(`)/i', // FOREIGN KEY
+                       '/(LOCK TABLES `)([a-z_]+)(`)/i', // TABLE LOCK
+                       '/(INSERT INTO `)([a-z_]+)(` VALUES)/i', // INSERT
+                       '/(ALTER TABLE `)([a-z_]+)(`)/i', // ALTER TABLE
+               );
+               $statement = preg_replace($pattern, '$1'.$prefix.'$2$3', $statement);
+
                 $db->query($statement);
             }
         }


(追記分)
上記改修のみでは、1つのDBにprefixを違えて複数インストールしようとすると、 errorno 121が発生しました。
これは、同一のデータベースで複数のテーブルで同じ外部キー名を用いた時に発生するエラーだそうです。
MySQL errno 121 – K blog


以下の追加改修で、解消しました。

--- a/app/plugins/install/controllers/install_controller.php
+++ b/app/plugins/install/controllers/install_controller.php
@@ -280,6 +280,7 @@ class InstallController extends InstallAppController {
                        $pattern = array(
                                '/(DROP TABLE IF EXISTS `)([a-z_]+)(`)/i', // DROP TABLE
                                '/(CREATE TABLE `)([a-z_]+)(`)/i', // CREATE TABLE
+                               '/(CONSTRAINT `fk_)([-a-z_]+)(`)/i', // CONSTRAINT
                                '/(FOREIGN KEY \(`[a-z_]+`\) REFERENCES `)([a-z_]+)(`)/i', // FOREIGN KEY
                                '/(LOCK TABLES `)([a-z_]+)(`)/i', // TABLE LOCK
                                '/(INSERT INTO `)([a-z_]+)(` VALUES)/i', // INSERT