スタッフブログ

なおとです。
今日の帰り道、もしくは次の出勤日の朝に起こるかもしれないこと。
- 乗った電車に電車が衝突
- いつも最後尾車両に乗っています
- 夜道で暴漢に襲われて動作不能になる
- 夜道を歩きまわる習慣があります
- 会社の開発用PCがどうしてもブートしない
- VMのイメージを定期的にバックアップしたいけれど、前回いつ行ったかすぐに思い出せない
ちょと大げさな例を挙げましたが、リリース前に限って体調を崩すなどはあり得そうです。 こういったときに、プロジェクトに与える影響を低くする方法、それが、「いつも、コミットしてから帰る」です。
言い換えると「作業中のものでも、手元に抱え込まない」ということです。
既に以前、私はこのブログで「開発でのバージョン管理の秘訣」という記事を書いています。
実は今日、社内の発表会で上記のようなことを話しました。 どうやらうまく伝えることができたようです。 こういった考えをチームの中で共有できるということは、とても大事なことだと思っています。
以前に、MySQLのストアドプロシージャの使い方を紹介しましたが、MySQL5.0では他にもトリガが実装されています。
■トリガとは
トリガ(trigger)とは、名前の通り、何らかの条件によって実行されるイベントのことです。
例えば、「ユーザーをINSERTしたときに特定のグループメンバーにもINSERTする」のようなことをRDBMSレベルで行うことができるようになります。
■簡単な例
トリガとは別物ですが、「このテーブルのレコードを削除したときに、外部キーとしてこのテーブルを参照している他のテーブルのレコードも同時に削除する」というのであれば、MySQL4.1から対応しています。
具体的には、
CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name TEXT
) ENGINE=InnoDB;
CREATE TABLE entries (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
body TEXT NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;
とすると、usersテーブルのレコードを削除すると、そのidが入っているentriesテーブルのレコードも同時に削除されます。
INSERT INTO users(name) VALUES('sato');
INSERT INTO users(name) VALUES('ryuji');
SELECT * FROM users;
+----+-------+
| id | name |
+----+-------+
| 1 | sato |
| 2 | ryuji |
+----+-------+
3 rows in set (0.00 sec)
INSERT INTO entries(user_id, title, body) VALUES(1, 'タイトル1', '本文1');
INSERT INTO entries(user_id, title, body) VALUES(1, 'タイトル2', '本文2');
INSERT INTO entries(user_id, title, body) VALUES(2, 'タイトル3', '本文3');
INSERT INTO entries(user_id, title, body) VALUES(2, 'タイトル4', '本文4');
SELECT * FROM entries;
+----+---------+---------------+---------+
| id | user_id | title | body |
+----+---------+---------------+---------+
| 1 | 1 | タイトル1 | 本文1 |
| 2 | 1 | タイトル2 | 本文2 |
| 3 | 2 | タイトル3 | 本文3 |
| 4 | 2 | タイトル4 | 本文4 |
+----+---------+---------------+---------+
4 rows in set (0.01 sec)
DELETE FROM users WHERE id = 1;
SELECT * FROM users;
+----+-------+
| id | name |
+----+-------+
| 2 | ryuji |
+----+-------+
1 row in set (0.00 sec)
SELECT * FROM entries;
+----+---------+---------------+---------+
| id | user_id | title | body |
+----+---------+---------------+---------+
| 3 | 2 | タイトル3 | 本文3 |
| 4 | 2 | タイトル4 | 本文4 |
+----+---------+---------------+---------+
2 rows in set (0.00 sec)
ON UPDATE/DELETEが、”親のテーブルが”更新または削除が行われた時にどうするかというのを指定します。
・RESTRICT:子のテーブルにデータが残っている場合はエラーにする(デフォルト)
・CASCADE:子のテーブルに結果を反映する(削除されたら削除)
・SET NULL:子の該当カラムをNULLにする
なお、外部キー制約自体がMySQLではInnoDBのみの機能なので、InnoDB以外では使えません。
■トリガ
この要領で、INSERT、UPDATE、DELETE時に更に複雑な処理をできるようにしたのがトリガです。
上記のことと同じ内容をトリガで行うと、
CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
name TEXT
);
CREATE TABLE entries (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
body TEXT NOT NULL
);
DELIMITER //
CREATE TRIGGER user_delete_trigger BEFORE DELETE ON users
FOR EACH ROW BEGIN
DELETE FROM entries WHERE user_id = OLD.id;
END;
//
DELIMITER ;
INSERT INTO users(name) VALUES('sato');
INSERT INTO users(name) VALUES('ryuji');
SELECT * FROM users;
+----+-------+
| id | name |
+----+-------+
| 1 | sato |
| 2 | ryuji |
+----+-------+
3 rows in set (0.00 sec)
INSERT INTO entries(user_id, title, body) VALUES(1, 'タイトル1', '本文1');
INSERT INTO entries(user_id, title, body) VALUES(1, 'タイトル2', '本文2');
INSERT INTO entries(user_id, title, body) VALUES(2, 'タイトル3', '本文3');
INSERT INTO entries(user_id, title, body) VALUES(2, 'タイトル4', '本文4');
SELECT * FROM entries;
+----+---------+---------------+---------+
| id | user_id | title | body |
+----+---------+---------------+---------+
| 1 | 1 | タイトル1 | 本文1 |
| 2 | 1 | タイトル2 | 本文2 |
| 3 | 2 | タイトル3 | 本文3 |
| 4 | 2 | タイトル4 | 本文4 |
+----+---------+---------------+---------+
4 rows in set (0.01 sec)
DELETE FROM users WHERE id = 1;
SELECT * FROM users;
+----+-------+
| id | name |
+----+-------+
| 2 | ryuji |
+----+-------+
1 row in set (0.00 sec)
SELECT * FROM entries;
+----+---------+---------------+---------+
| id | user_id | title | body |
+----+---------+---------------+---------+
| 3 | 2 | タイトル3 | 本文3 |
| 4 | 2 | タイトル4 | 本文4 |
+----+---------+---------------+---------+
2 rows in set (0.00 sec)
このようになります。
DELIMITERについては前回の記事を参照してください。
トリガの箇所だけ抜き出すと以下になります。
CREATE TRIGGER user_delete_trigger BEFORE DELETE ON users
FOR EACH ROW BEGIN
DELETE FROM entries WHERE user_id = OLD.id;
END;
トリガはCREATE TRIGGER文で作成します。
CREATE TRIGGER [トリガ名] [実行タイミング] [対象命令] ON [対象テーブル]
トリガ名は自由に命名して構いません。
実行タイミングは、BEFOREとAFTERがあり、対象命令が実行される前か後かを指定します。通常は挿入系は後、削除系は前、になると思います。
対象命令は、INSERT、UPDATE、DELETEを指定します。どれかの操作が行われた場合にこのトリガが実行されます。複数指定はできないようです。
対象テーブルは、対象命令が行われるテーブルを指定します。
後は、FOR EACH ROW BEGIN〜END;の間に、ストアドと同様にSQL文を書いていきます。
この際、OLDとNEWという疑似テーブルが既に用意されており、このトリガ操作が処理される前の対象テーブルのレコードの状態がOLD、後の状態がNEWになります。通常は、DELETEの場合はOLD、INSERTの場合はNEWを参照することになります。
トリガは制約とは直接関係しないので、InnoDB以外でも使用することが可能です。
ちなみにトリガを削除する場合は、DROP TRIGGER [トリガ名];で削除が可能です。また、SHOW TRIGGERS;でトリガの一覧を確認することができます。
最近のO/Rマッパーでは、擬似的なトリガを用意していることが多く、RDBMSレベルのトリガを使用することは少ないですが、アプリケーション側を修正したくない場合や、そのような仕組みが存在しない環境での開発においてはトリガは有効な選択肢になります。
ただし、トリガを使用するとアプリケーションのコードを読むだけでは挙動を追跡することができなくなるため、状況に応じて適切に利用するようにしましょう。

先週の金曜日にPHP勉強会に参加してきたので、今日は勉強会を楽しむために心がけていることについて書こうと思います。
(と言っても、実際のところそんなに多くを心がけている訳ではなかったりするのですが
)自分流としては、「話せるようなら自分から発言する」「発表にも出来る限りトライする」「なるべく懇親会にも参加する」だったりします。
勉強会と聞くと、発表者と受講者的なイメージを持つ人も多いかと思いますが、完全に受講者になってしまうよりも意見のやり取りが出来た方が濃い話になりやすいです。
同じような取り組みをしている人と意見を交換することで、知識だけでなく経験談も聞くことが出来たりします。
発表の方は、「これは誰でも知ってるよね」と自分が思っていることでも、実際にやってみたことを踏まえてみると、聞く人には結構新鮮だったりすることが多々あります。
また、自分の発表に対して「それって、こういう方法もあるよ」という話を聞いたり、発表の資料を作ったりすることで自分の知識を整理できたりします。
最後に、懇親会についてですが、個人的には勉強会の醍醐味の一つだと思っています。
発表に対する質疑応答などに比べると格段に会話がしやすいですし、技術だとか仕事のネタじゃなくても「これ、美味しいですよね」など、話しかける切っ掛けを見つけやすいです。
最近は、(特に東京近辺では)多くの勉強会が開催されています。
もし、自分の興味のある勉強会が近くで開催されていて、時間の都合が付くようでしたら、一度参加してみると面白いですよ

Linuxコンソーシアムに参加されてる方はシステム会社さんが多いだろうと思いましたので、できるだけシステム会社さん向けにお話しさせてもらったつもりです。
さて、このCMSパネルディスカッションでモデレータさんから「どんな使い方がおすすめか?」というような質問がありました。
私なりの考えとして、システム屋さんとしておすすめのXOOPSの使い方は、システム開発のベースとしてXOOPSを使ってしまうことです。
以前、PHPカンファレンスでもお話しましたが、XOOPSのモジュールを開発するために覚えることは非常に少ないため、PHPとMySQLでプログラミングできる方ならほとんど誰でも短期間でXOOPSのモジュールを開発出来るようになると思っています。
新規にシステム開発をするときに最初からXOOPSのモジュールとして開発しておくと、あとで「ちょっとお知らせを掲載する機能もちょっと欲しいなぁ」「使い方の説明ページもつけてほしいんだけど」という要望がでたときに、既存のモジュールをいれるだけで対応できるのでおすすめです。
RYUSでこれまで構築させてもらったWebサイト、イントラサイトでも、この
・メインの機能は新規開発
・補助的な機能は既存XOOPSモジュールを利用
というパターンで構築しているケースが多いです。
これから開発するシステムについて上記のようなパターンで構築できないか是非検討していただければと思います。

とはいえこのblogで確認したところ、このThinkPadを購入したのはまだ昨年の5月あたり。1年ちょっとでだいぶ使ってしまいました。
そんなときにMacでしか使えないソフトやi-phoneで動くアプリケーション開発の話を聞くにつけ少しずつマック方面への関心が出てきました。
i-macは24インチのディスプレイ付きで本体もハイスペック、Windowsとの共存もできるようだということを聞いてもはやほぼi-macを買おうと決意しました。日々持ち歩くノートの重さと自分の体力のなさという組み合わせに、ちょっと辟易してきたのも事実で、、などといういろんな要素が相まって、新環境にチャレンジするつもりです。
いつも同じ環境を持ち歩いていたので、データやメール管理の点ではとても楽でした。デスクトップだと自宅や出先でどのように必要なデータを共有したらいいかということを考慮しないといけなそうです。メールも既読や送信済みメールをどの環境でも同じように見たいし。
ということから(おそらく)
・DropBox有料版でデータを共有する
どのマシンでも自分のIDとパスワードで同じデータを共有できるのとローカルにも同期したファイルが置けるというのがいいです。
・g-mailをメインとしてメーラーは使う
の2点を導入しようと思っています。
マック環境になれば、新しい環境で自分の作ったソフトの検証もできるし何よりよく分からないインターフェースが新鮮そうです。
いつ導入するか、ということだけが問題なのですが現在のメインマシンのデータ移動が1日ぐらいかかりそうなので時間が取れずなかなか予定が立たないのが残念です。いずれはi-phoneもと思ってますが、環境構築のことを考えると少しずつになりそうです。
少なくとも…、7月までにはi-mac導入したいと思っています。
Ubuntu体験記です。今回もベクターグラフィックソフトのInkscapeについて書こうと思います。

自分は普段はこの手のベクターグラフィックソフトは定番のAdobeのIllustratorを使っているのですが
Inkscapeも同じ感覚で使おうとしてしまうのですが、基本的な所はほとんど同じように使えるのですが細かい部分で結構違います。
違うところで中々良いなと思ったところは、四角形を作成すると、ただ四角形なだけでなく、角を丸める事ができる点です。この角丸の量は後からでも調整可能です。
逆にちょっと分かりづらいなと思ったところは。まずレイヤーの表示関係。Illustratorなどと同様にレイヤーの概念があるのですが切り替える場所等のUIの配置が良くない感じです。
それと、面の塗りのグラデーションの設定関係です。細かい設定までできるところは良いのですが、これも調整するUIが結構分かりづらいです。
全体的には、それほど長くは触っていないですが基本的な機能はほぼ網羅していると思います。
UIが分かりづらく思ったのですが、この辺は使い続ければ慣れてくる部分かもしれません。
ですので、慣れればこのInkscapeを使ってロゴの作成やベクトルデータの作成等も問題なく行えると思います。
最後にいまさらですが、Inkscapeは普通にWindows版もあることに気づきました…orz
窓の杜 - Inkscape
RubyやC#をはじめとした,純粋なオブジェクト指向言語を使ってプログラミングをした経験がある人は,PHPの適当さにクラクラしつつ「もっとオブジェクト指向したいなー」と思うのではないでしょうか.
そういった人の夢を少しだけ叶えてくれるのが今日紹介する.PHP_Object ( http://openpear.org/package/PHP_Object ) です.
インストールはいつものようにpearコマンドでインストールしたあと require_once 'PHP/Object.php'; を追加するだけです.
PHP_Objectは,文字や配列をオブジェクトとして扱えるようにしてくれます.
言葉で説明するよりも,実際のコードを見てもらう方が早いでしょう.
以下は,文字列を編集しているコードです.両端の「|」を削除したあと,中心にある「ZZZ」を削除して「ABCDEF」という文字列を作るというシンプルなものです.
まずは普通の書き方の場合.
$message = '|ABCZZZDEF|';
$message = trim($message, '|');
$message = str_replace('ZZZ', '', $message);
var_dump($message);
という感じになります.これをPHP_Objectを使ってかくと.
require_once 'PHP/Object.php';
$message = PHP_Object::factory('|ABCZZZDEF|')->trim('|')->replace('ZZZ', '')->var_dump;
というように書く事ができます.
PHP_Object::factoryによって,文字列が文字列オブジェクトとなり,PHPの関数を自らのメソッドとして呼ぶ事ができます.
このメソッドは通常のPHPのオブジェクトと同じ仕組みで動作しているので当然ながらメソッドチェーンも使えるようになります.メソッドチェーンのメリットは,文字通り鎖のように,最初の処理の結果が次の処理につながっていく事で読みやすくなる事です.
また,PHP_Object経由で文字列オブジェクトを作成すると,メソッド名の先頭にあるstrやstr_を省略する事ができます.上記コードで呼ばれているreplaceメソッドはstr_replaceです.これで,strposやstr_repeatのような,統一感のない関数名からも距離を置く事ができるようになります.
当然ながら,通常の文字列を操作するよりも,文字列オブジェクトを作って操作する方がメモリ消費が大きいので,使う場所についてはよく考える必要がありますが,非常におもしろいライブラリなので一度は使ってみると良いでしょう.

こんばんわ。なおとです。
先日から社内で開発に使っている環境を少し変えました。 Ubuntuで使うデスクトップ環境を、「LXDE」にしたのです。

スクリーンショットを取るために、わざとらしくアプリを広げています。 いつもは仮想デスクトップを2枚使って、Firefoxで1面、もう一方にemacs、ターミナルという配置で使っています。
朝ログインするとき、デスクトップが使えるようになるまでが速くなりました。
どうやらいままではNautilusが時間かかっていたようです。
いっぽう、Firefoxの起動はさほど変わりませんでした。
ターミナルも、タブが使いたいがためにGnome-Terminalを使いつづけていますが、これはおいおい乗り換えも検討します。
ネットで調べながらインストールして、乗り換えはさほど難しくなかったです。 自宅ではfluxboxを使っているので、パネルやメニューの設定は似た感じで、つまづくことなくできました。 また、以前自分で調べたKnowlegeも生かしながら、emacsでscimをオフにするといったこともそのまま移行できました。
違ったことといえば、emacsで一部キーバインドが変わっていたことです。 具体的には「ALT + <(バッファの先頭へカーソルを移動)」と「ALT + >(同末尾へ)」。 今は別のキーコンビネーションを使って凌いでいます。 どうしてそうなったのかは、まだ調べていません。
あとはアップデート通知パネルが表示できていないので、これも何とかしたいと思っています。 また、不意にビープがなるのが気になるのでオフにしたいのですが、設定箇所がよくわかっていません。 困ったなぁ……。
思考を整理する手法として、数年前からマインドマップが流行っております。
このスタッフブログでも、過去に何度か紹介しております。
しかし、マインドマップは真面目にやると実はルールが細かく、とっつきにくい部分があります。
普段からアウトラインプロセッサ(Story EditorやNami2000など)は使っていたので、こういうツリー上のメモを平面に展開できる程度があればなーと思っていました。
そこでFrieve Editorというソフトがあります。
これはアイデアプロセッサの一種で(アウトラインプロセッサもアイデアプロセッサの一種ですが)、KJ法と呼ばれる手法に若干近い感じで、カードを並べてリンクさせることによって整理するツールです。

このような図を簡単に作ることができます。
各カードには個別に長文も書けるので、詳しい内容を書きたい場合にもすぐ書くことができます。
主な使い方としては、
・ENTER:兄弟ノードを伸ばす
・Insert:子ノードを伸ばす
・カーソルキー:カード間移動(リンクの関係性に左右されない)
・PageUp/PageDown:距離拡大/縮小
となります。マウスでポチポチ操作してもいいですが、キーボードでさくさく入力したほうが快適です。
マインドマップ的な使い方もできますが、普通のメモ用途に使ったり、資料作成に使ったりと、様々な使い方に対応できると思います。
基本的には、あまり深く考えずに書いていくのがいいと思います。
自動整理をONにしておくとグリグリ動いて面白いですが、スムーズに動かすにはそれなりにスペックが必要になります。
また、Frieve Editorをプレゼンに使うこともできます。先日のCakePHP勉強会で、実際にFrieve Editorを使ってプレゼンをした方もいるようです。
他の勉強会とかでも、マインドマップ系のツールを使ってプレゼンをする人を最近は見かけるようになりました。話の流れが見えるので使いやすいようです。
ちなみにこの作者様は、他に音楽関係の高機能なソフトを公開しており、これらも非常に便利なので、音楽関係に興味のある方は是非試してみてください。

今日は、つい先日発表されたiモードブラウザ2.0について簡単に書かせて頂こうと思います。
既に色々な場所で書かれてはいますが、今年の夏モデルからDoCoMo端末に搭載されているiモードブラウザの仕様が大きく変わります。
今までのiモードブラウザでは、COOKIEが使えないためにセッションを維持するためにはGET/POST変数として引き渡す必要がありました。
また、外部CSSに対応していないためにスタイル指定は全てインラインで記入する必要があるなど、色々と制限がありました。
しかし、夏モデル以降ではCOOKIEや外部CSSに対応するだけでなく、今までの携帯ブラウザでは想定できなかったJavaScriptにも対応するそうです。
これは非常にありがたいことなのですが、既に携帯サイトを作成している場合には状況が変わります。
一つは、セッションIDが漏洩するリスクが発生します。
前述のように、DoCoMo端末でセッションを利用する場合はセッションIDをGET/POST変数として引き渡していました。
ただし、iモードブラウザはリファラを送信しない仕様であったため、外部サイトにセッションIDが漏れることも早々ありませんでした。
しかし、夏モデルからはリファラも送信されるようになるため、今までのようにURLにセッションIDが含まれていた場合は外部サイトに漏洩してしまいます。
もう一つは、外部CSSに対応していないことを逆手に取ったDoCoMo専用ハックが利用できなくなります。
これからの携帯サイト開発は、これらのデメリットも踏まえつつ最適化していくことが重要になりそうです



