BLOG

Go to top


Movable Type の SQL を見てみませんか

December 19, 2013 9:01 AM

この記事は Movable Type Advent Calendar 2013 の19日目の記事です。


Movable Type が発行している SQL を見てみると、Movable Type がデータベースに対して何をしているのか、どういう情報がどこに格納されているのかについて知ることができます。これは、Movable Type を扱う仕事をしている、もしくは趣味をお持ちなら、Movable Type への理解を一歩前に進め、Movable Type を Enjoy! するにはとっても有用です。だって、理解しているツールを使うのとそうじゃないツールを使うのって全然気分違うでしょ。

また、SQL は文なので、Perl とか PHP とかプログラミングがわからなくても、なんとなく意味合いを推し量ることができます。phpMyAdmin などのツールでデータベースと照らし合わせて見てみると(多少)面白くなるでしょう。

これから紹介する方法は、Movable Type が発行する SQL について、特別に理解する時間をとる必要はありません。設定しておいて、管理画面を使っている時にたまに見てみれば、そのうち理解が深まってきます(※ 個人差あります)。

管理画面上で SQL を表示する

現在の Movable Type は mt-config.cgi に DebugMode 1 と書くか、システムの全般設定で「デバッグモード」を設定すると、Django Debug Toolbar によるデバッグ表示が出てきます。これは、数年前に(今のところたった一度だけ)大阪で MTDDC が開催された翌日にアルファサードにて行われたハンズオンで、某氏が「デバッグツールが充実してるっていいよね」と発表していたものがベースになっているものです。

DebugMode 4 にすれば、ツールバーの「SQL」の項目に SQL が表示されます。これは、Data::ObjectDriver レベルで計測された SQL なので、管理画面下の「警告とメッセージ」に表示される SQL とは少し異なります。どう異なるかについては本題ではありませんが、Movable Type を理解するためには、「警告とメッセージ」の内容の方が有用です。

img_nukamiso_alertmessage1.jpgデフォルト状態の警告とメッセージ

しかし、標準状態では SQL の具体的な数値や値は「?」になっています。いわゆるプレースホルダの状態です。このままではいまいちピンとこないので、以下のプラグインを入れましょう。

Nukamiso プラグイン(約 8 kb)

これを設置すると、プレースホルダを置換して具体的な内容にしてくれます。一部カバーしていない形式もありますが、まあだいたいカバーしています。以下は記事編集画面を開いた時に表示された内容のキャプチャです。

img_nukamiso_alertmessage2.jpgプレースホルダが置換された状態

具体的な値になると、何やってるかずいぶんイメージしやすくなりますね(視認性は大差ありませんけどね)。たとえば、ログイン画面を表示すると以下のような内容が表示されます。

QUERY: SELECT field_id FROM mt_field
QUERY: SELECT failedlogin_id FROM mt_failedlogin WHERE (failedlogin_remote_ip = '61.205.62.101') AND (failedlogin_ip_locked = 1) AND (failedlogin_start >= 1387167232) LIMIT 1

カスタムフィールドを初期化してるのかなーとか、拒否対象でないかとか調べてそうですね。同じログイン画面を表示するケースでも、ログアウトした状態の場合にはもう少し違った表示がなされます。

QUERY: SELECT field_id FROM mt_field
QUERY: SELECT author_id FROM mt_author WHERE (author_name = 'okayama') AND (author_type = 1) LIMIT 1
QUERY: SELECT author_id, author_api_password, author_auth_type, author_basename, author_can_create_blog, author_can_view_log, author_created_by, author_created_on, author_date_format, author_email, author_entry_prefs, author_external_id, author_hint, author_is_superuser, author_locked_out_time, author_modified_by, author_modified_on, author_name, author_nickname, author_password, author_preferred_language, author_public_key, author_remote_auth_token, author_remote_auth_username, author_status, author_text_format, author_type, author_url, author_userpic_asset_id FROM mt_author WHERE (author_id IN (1))
QUERY(see also BIND): INSERT INTO mt_log (log_author_id, log_blog_id, log_category, log_class, log_created_by, log_created_on, log_ip, log_level, log_message, log_metadata, log_modified_by, log_modified_on) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
BIND: { 'author_id' => '1', 'blog_id' => '0', 'category' => 'logout_user', 'class' => 'author', 'created_on' => '2013-12-16 04:47:57', 'ip' => '61.205.62.101', 'level' => '1', 'message' => "ユーザー'okayama'(ID1)がサインアウトしました。", 'modified_on' => '2013-12-16 04:47:57' }
QUERY: DELETE from mt_session WHERE (session_kind = 'US') AND (session_name = 1)
QUERY(see also BIND): SELECT session_id FROM mt_session WHERE (session_id = ?) LIMIT 1
BIND: [ undef ]
QUERY: SELECT failedlogin_id FROM mt_failedlogin WHERE (failedlogin_remote_ip = '61.205.62.101') AND (failedlogin_ip_locked = 1) AND (failedlogin_start >= 1387167477) LIMIT 1

※「BIND」とあるのは、プレースホルダの置換ができてないものについて、こういうものが入る予定ですよという意味程度に考えてください。「QUERY(see also BIND)」の行と照らし合わせて読んでみましょう。

先ほどのものに加えて、ユーザを読み込んだり、サインアウトしたログを保存したり、セッションを削除したりしていますね。


なお、もっと!見たいあなた向けに、mottto=1 をつけると、呼び出し元の処理を遡ることができます。DebugMode 6 にしても同じようなことができるのですが、あまり見やすくありません。SQL とその呼び出し元を確認する用途であれば、DebugMode 4 + パラメータ motto=1 が見やすいでしょう。以下、記事編集画面を開いた時に表示された内容のキャプチャです。

img_nukamiso_alertmessage2.jpgパラメータ motto=1

motto=1 で遡れるのは 5 つ前までです。もっともっと!遡りたいあなたは、URL パラメータに mottomotto=1 をつけてください。もっともっともっと!遡りたいあなたは、mottomottomotto=1 をつけてください。

img_nukamiso_alertmessage2.jpgパラメータ mottomotto=1

上記ではログイン画面のみ触れましたが、ブログ記事編集画面など、もっとたくさんの SQL が発行される場面でも使ってみてください。あと、エラーで赤い帯のメッセージが出た時にも、何しててエラーになったか把握するのに有効だったりします。イヤですねあの画面。

ダイナミック・パブリッシングの場合

ダイナミック・パブリッシングでも SQL を表示することができます。/path/to/mt/php/extlib/adodb5/adodb.inc.php 内の「var $debug = false;」を「true」にしてやることで、SQL が表示されます(表示ページ内に出てくるので、運用中のウェブサイトでは行わないようにしましょう)。

img_nukamiso_sql_dynamic.jpgダイナミック・パブリッシングでの SQL 表示

画像では少し見づらいかもしれませんが、こちらはプレースホルダではないので、初めから具体的な内容が見えていますね。この部分では、blog_id が 2 のインデックステンプレートのうち、テンプレート名、出力ファイル名、identifier のいずれかが「JavaScript」であるテンプレートを探しているようです。そのあと、template_meta_template_id が 456 の mt_template_meta を探しているので、「JavaScript」なテンプレートの ID は 456 だったのかな、と想像できます。

また、今回利用した Nukamiso プラグインにはこの他、管理画面を使いやすくしたり、デバッグや開発を行うための複数の機能が盛り込まれています。詳しくはこちらの記事をご覧ください

Comments


Contact me

Copyright © 2005 - 2017 okayama All rights reserved.