MT(MovableType)4.2xのカスタムフィールド

仕事でMTのカスタムフィールドに入っているデータを移すっていう仕事を引き受けました。
かなり昔のお話になってしまいましたが、時間ができたのでアップします。
※こんな話にいまさら需要があるのかなぁと疑念を抱きつつ・・・です。

その当時blogはnucleusとwordpress しかデータベースを覗いたことが無いって言う状況ですが頑張ってみてみました。

xx_entry_meta テーブルに保存されているようですね。
※後で知ったのですが、MT4.1.x だとxx_entryのentry_metaフィールドにバイナリ(vlob型)で入っているとか。この形だと追加や修正がSQLでできないので非常に面倒くさかったです。

4.1はさておき、4.2のテーブル構造はこんな感じ。

| entry_meta_entry_id | entry_meta_type | entry_meta_vchar | entry_meta_vchar_idx | entry_meta_vdatetime | entry_meta_vdatetime_idx | entry_meta_vinteger | entry_meta_vinteger_idx | entry_meta_vfloat | entry_meta_vfloat_idx | entry_meta_vblob | entry_meta_vclob |
+———————+———————-+——————+———————-+———————-+————————–+———————+————————-+——————-+———————–+——————+——————+
| 9687 | field.old_book_en | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |

1テーブルにまとまっているので、1レコードで1つのデータという構造は分かりやすいです。
増やそうと思ったらいくらでも増えるデータなので、この形しか無いでしょうね。
entry_meta_type 重要なのはこのカラムで、ここが各記事から呼ぶための名前が入っているのです。

実際にfield名がold_book_en っていうデータがいくつあるのか探した時のSQLです。

mysql> select count(*) from mt_entry_meta where entry_meta_type = ‘field.old_book_en’ AND entry_meta_vclob != ”;

次に大事なのは各データの保存形式。数値なのか文字型なのか・・・カスタムフィールドを作った時に指定したデータ型のカラムにデータが入ります。だから、1レコードの中で複数のカラムにデータが入ることは無いのです。

| entry_meta_vchar | entry_meta_vchar_idx |

entry_meta_entry_id あとはこのカラムが記事IDに対応しているので、1つの記事に対してのカスタムフィールドを探す場合には、このIDとフィールド名でWHERE句を作らねばならないということが分かりました。

カスタムフィールドの型を変えたり、名前を変えたりしたい場合には、UPDATE文で大丈夫だと思ったんですが、型を覚えているテーブルも書き換えなくちゃいけないので、面倒ですが新しいフィールドをINSERT文で追加しちゃいました。
※作業前、作業後の比較もしたいので。

INSERT文を作るプロシージャです。初めて実用的なものを作ったので、お手本のMysql本家にいろいろ追加しただけというエラーハンドリングも何も考慮されていないバッチ処理のようなものです。

delimiter //

CREATE PROCEDURE topic_day_hidden_en()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE myName int(11);
DECLARE myFlag int(11);
DECLARE myDatasource varchar(30);
DECLARE myEntryID CURSOR FOR
SELECT t.entry_meta_entry_id FROM mt_entry_meta AS t
WHERE t.entry_meta_type = ‘field.topics_day_en’ AND t.entry_meta_vchar_idx = ”;
DECLARE CONTINUE HANDLER FOR SQLSTATE ‘02000’ SET done = 1;

OPEN myEntryID;
SELECT COUNT(t.entry_meta_entry_id)INTO @myCounter FROM mt_entry_meta AS t
WHERE t.entry_meta_type = ‘field.topics_day_en’ AND t.entry_meta_vchar_idx = ”;

SET myFlag = ‘1’;
SET myDatasource = ‘field.topics_day_hidden_en’;

SET @pos = 0;
WHILE @myCounter > @pos DO
FETCH myEntryID INTO myName;

INSERT INTO mt_entry_meta(`entry_meta_entry_id` , `entry_meta_type` , `entry_meta_vinteger_idx`)
VALUES (myName,myDatasource,myFlag);

SET @pos = @pos +1;

END WHILE;

CLOSE myEntryID;

END
//
delimiter ;