解剖配置指令碼
讓我們來分析一下上面的代碼。【譯者註:作者在文中混用了“install script”,“upgrade script”和“setup script”。我在翻譯的時候盡量分清。配置指令碼包含了安裝指令碼和升級指令碼。】先看第一行
$installer = $this;
這個“$this”是什麼呢?每一個配置指令碼都是屬於某個資源配置類(Setup Resource
class),比如上面我們建立的“Zhlmmc_Helloworld_Model_Setup_Mysql4_Setup”。這些指令碼都是在這個資源
配置類的上下文環境中啟動並執行。所以“$this”就是指資源配置類的執行個體。雖然不是強制的,但是大多數核心模組的資源配置類都用“$installer”
來代替“$this”,就和我們這裡做的一樣。雖然我們說不是強制的,但是我們最好還是遵守這個約定,除非你有一個很好的理由。
接下來看下面兩個調用
$installer->startSetup();
//…
$installer->endSetup();
如果你開啟“Mage_Core_Model_Resource_Setup”類(也就是我們建立的資源配置類的父類)的源碼,你將會看到這兩個方法做了一些SQL準備工作
public function startSetup()
{
$this->_conn->multi_query("SET SQL_MODE='';
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO';
");
return $this;
}
public function endSetup()
{
$this->_conn->multi_query("
SET SQL_MODE=IFNULL(@OLD_SQL_MODE,'');
SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS,0);
");
return $this;
}
真正的配置邏輯是在“run”方法中
$installer->run(…);
這個方法的參數就是你要啟動並執行SQL。你可以包含任意數量的SQL,用分號隔開。你可能注意到了以下語句
$installer->getTable('helloworld/blogpost')
【譯者註:你的第一反應是什嗎?是不是聯想到config.xml裡面下面這段代碼?
<helloworld_mysql4>
<class>Zhlmmc_Helloworld_Model_Resource_Mysql4</class>
<entities>
<blogpost>
<table>blog_posts</table>
</blogpost>
</entities>
</helloworld_mysql4>
這裡“helloworld/blogpost”就是我們要建立的資料表的URI。Magento先用“helloworld”找到模組,得到資源模組
“helloworld_mysql4”,然後在資源模組下面通過“blogpost”找到類名“blog_posts”。】很顯然,你可以用常量
“blog_posts”來代替調用“getTable”,但是調用這個方法可以保證即使使用者更改了設定檔中的資料表名字,你的配置指令碼依然能運行。
“Mage_Core_Model_Resource_Setup”類有很多類似這樣的協助函數。學習這些函數最好的方法就是閱讀Magento核心模組
的資源配置類代碼。
模組升級指令碼
上面我們說過配置指令碼包括安裝指令碼和升級指令碼。講完了安裝指令碼,我們來講升級指令碼。安裝指令碼是在第一次安裝模組的時候使用的,而升級指令碼顧名思義就是在升級模組的時候使用。Magento的資源配置系統使用了版本化的方式來升級模組。
首先要說明的是,在安裝模組的時候Magento會執行一次安裝指令碼,然後Magento再也不會為該模組執行任何安裝指令碼了。如果你要更新模組的資料表就要通過升級指令碼來執行。除了命名方式以外,升級指令碼和安裝指令碼並沒有太大的不同。
建立升級指令碼如下
File: app/code/local/Zhlmmc/Helloworld/sql/helloworld_setup/mysql4-upgrade-0.1.0-0.2.0.php
echo 'Testing our upgrade script (mysql4-upgrade-0.1.0-0.2.0.php) and halting execution to avoid updating the system version number ';
die();
升級指令碼和安裝指令碼是放在相同目錄下面的,但是命名方式不同。首先是“upgrade”關鍵詞。其次,你會發現這裡我們有兩個版本號碼,用“-”分開。第一
個版本號碼“0.1.0”是指從哪個版本升級(起始版本),第二個版本號碼“0.2.0”是指要升級到哪個版本(目標版本)。
清空Magento緩衝,請求任何一個URL,你會發現沒有任何配置指令碼被運行。那是因為,第一,我們已經運行過安裝指令碼,第二,目前我們模組的版本是
“0.1.0”,所以Magento不會運行我們要升級到“0.2.0”的升級指令碼。要讓Magento運行這個升級指令碼,我們得修改設定檔中的版本號碼
<modules>
<zhlmmc_helloworld>
<version>0.2.0</version>
</zhlmmc_helloworld>
</modules>
清空Magento緩衝,重新請求頁面,你會看到升級指令碼的輸出。【譯者註:作者在這裡引入了第二個升級到“0.1.5”的升級指令碼,我覺得並沒有必要,我來直接總結一下Magento升級的步驟
- 從資料表“core_resource”中獲得當前模組的安裝版本
- 從設定檔中獲得當前模組的版本
- 如果兩個版本一樣,那麼什麼都不做
- 如果#2的版本號碼小於#1的版本號碼,我也不知道Magento會幹什麼,理論上是不可能出現的情況
- 如果#2的版本號碼大於#1的版本號碼,那麼開始升級程式
- 在配置指令檔夾內(在上面的例子中是“helloworld_setup”)把所有升級指令碼排入佇列
- 在隊列內,按照升級指令碼的起始版本排序,升序
- 迴圈隊列
- 如果隊列中當前指令碼的起始版本不等於“core_resource”資料表中當前模組的版本號碼,那麼跳過該指令碼
- 如果隊列中當前指令碼的起始版本等於“core_resource”資料表中當前模組的版本號碼並且目標版本小於等於#2的版本號碼,那麼執行該指令碼。
- 迴圈隊列結束,升級結束
值得注意的是第10步,每次執行一個升級指令碼,“core_resource”資料表中的版本號碼都會被更新。所以如果我們有兩個升級檔案“0.1.0-0.1.5”和“0.1.0-0.2.0”,只有一個升級檔案會被執行。
】
下面我們來為升級指令碼添加實質內容
$installer = $this;
$installer->startSetup();
$installer->run("
ALTER TABLE `{$installer->getTable('helloworld/blogpost')}`
CHANGE post post text not null;
");
$installer->endSetup();
清空Magento緩衝,重新整理頁面,你應該看到升級指令碼的輸出。如果沒有,請你對照上面講的Magento升級的步驟尋找錯誤。
總結
這一章我們講解了Magento是如何處理模組資料表的安裝和升級的。Magento的資源配置系統使用版本化的升
級指令碼,這樣就保證了不同版本的
模組可以使用同一套的升級指令碼,便於維護。我們後面的章節也會提到這種升級方式的優點,特別是對於使用EAV模型的模組來說,這個優點更為明顯。
為了您的安全,請只開啟來源可靠的網址
開啟網站
取消
來自: http://hi.baidu.com/190420456/blog/item/5d677fd2208f680f3bf3cf15.html