T-34 – Wikipedia

アメリカの戦車発明家、ジョン・W・クリスティーが開発したクリスティー快速戦車はアメリカでは評価されず、陸軍がM1931を5輌発注、これを37mm砲装備のT3中戦車、12.7mm機銃搭載のT1戦闘車として試験した程度に終わった。

クリスティー快速戦車

いい名前だなーおい。

どうやってこのページに辿り着いたのかは全然分からない。

神の子どもたちはみな腕を磨く: 第3回Piece Framework勉強会開催のお知らせ

10月28日(土)神戸はキー・ポイント株式会社様にてPiece Framework勉強会を開催いたします。

聞きたいなあ。レポや資料に期待です。

plnet.jpをだいぶ修正しました。

専用サーバになってinnoDBが使えるようになってトランザクションやFK制約、ON DELETE CASCADEが使えるのでテーブル構成やロジックを一から直しました。

今までエントリーが重複してたり、付けてないタグが付いてたりしていまいち信頼性が低かったんですが、innodb化と一緒にガチガチ目指してみました。

mixi_support

それとmixiに対応しました。ソース毎のRSSも吐いているので“全体に公開”にしていれば手軽にmixiのRSSも利用できます。

・・・。

連休中にコードばっか書いてるのバレバレかよ。

グーグル・アマゾン化する社会

オハイオ州ダブリンで制定されたからダブリンコアって言うのか…。(そういう内容の本じゃありません)

503が出まくっていたplnet.jpを新しい専用サーバへ移行しました。

はえー、はえー。

これで止められまくりのだったcronも動かせます。

さくらインターネットの500円のヤツ、安くてかなり便利ですがアクセス増えるとやっぱり厳しいです。503ってことはプログラムの負荷というより単に共有してるApacheのMaxClients、MaxRequestsPerChildかなと思います。

1万PV/1日ぐらいで503出初めて、2万PV/1日以上はまともに使えないって感じなのでニート(俺)以外ははじめっから専用サーバ借りたほうが良さそうです。あたりまえか。

PHP4でDB系のテストがやりたくてrake db:fixtures:load的にテーブル毎のファイルからDBへロード/ダンプするクラスを書いてみました。

<?php
require_once 'INILoader.php';
dump_ini('/path/to/fixtures', 'mysql://user:pass@localhost/dbname');
?>

(magpieみたいにグローバルにいい加減なファサード作っちゃうquick & dirtyさ加減)

こんな感じで書くと、

% cat fixtures/member.ini
[member1]
id = "1" 
design_id = "1" 
account = "komagata" 
password = "aaa" 
email = "komagata@p0t.jp" 
createdtime = "2006-08-12 15:36:51" 
[member2]
id = "2" 
design_id = "2" 
account = "tom" 
password = "iii" 
email = "tom@gmail.com" 
createdtime = "2006-08-12 11:36:51" 
[member3]
id = "3" 
design_id = "3" 
account = "bob" 
password = "uuu" 
email = "bob@gmail.com" 
createdtime = "2006-08-12 12:36:51"

こんな感じの中身を指定したディレクトリに“テーブル名.ini”で吐く。yamlだとまんま過ぎなので何故かiniです。

<?php
require_once 'INILoader.php';
load_ini('/path/to/fixtures', 'mysql://user:pass@localhost/dbname');
?>

こう書くと逆にiniファイルを読んでテーブルにロードする。

以下コード。(さっとパッケージ化できる人になりたい)

<?php
require_once 'DB.php';

class INILoader
{
    var $fixtures_dir;
    var $dsn;
    var $key_check;
    var $db;

    function INILoader($fixtures_dir, $dsn, $key_check = true)
    {
        $this->fixtures_dir = $fixtures_dir;
        $this->dsn = $dsn;
        $this->key_check = $key_check;
        $this->db =& DB::connect($dsn);
        $this->db->autoCommit(false);
        $this->db->setFetchMode(DB_FETCHMODE_ASSOC);
    }

    function load($name = null)
    {
        if (is_null($name)) {
            $this->db->query('BEGIN');
            $this->_truncate_all();
            $this->_load_all();
            $this->db->commit();
        } else {
            $this->db->query('BEGIN');
            $this->_truncate($name);
            $this->_load($name);
            $this->db->commit();
        }
    }

    function dump($name = null)
    {
        if (is_null($name)) {
            $this->_remove_all();
            $this->_dump_all();
        } else {
            $this->_remove($name);
            $this->_dump($name);
        }
    }

    function _load_all()
    {
        if (!$this->key_check and preg_match("/^mysql/", $this->dsn)) {
            $this->db->query('SET FOREIGN_KEY_CHECKS = 0');
        }

        foreach ($this->_get_ini_files() as $file) {
            list($name, $ext) = split("\.", $file);
            $this->_load($name);
        }

        if (!$this->key_check and preg_match("/^mysql/", $this->dsn)) {
            $this->db->query('SET FOREIGN_KEY_CHECKS = 1');
        }
    }

    function _truncate_all()
    {
        foreach ($this->_get_ini_files() as $file) {
            list($name, $ext) = split("\.", $file);
            $this->_truncate($name);
        }
    }

    function _load($name)
    {
        echo "Load table {$name}... ";
        $data = parse_ini_file("{$this->fixtures_dir}/{$name}.ini", true);
        foreach ($data as $fields) {
            if (DB::isError($res = $this->db->autoExecute($name, $fields))) {
                $this->db->rollback();
                echo "failed\n";
                trigger_error('INILoader::_load(): Failed to load. '
                .$res->toString(), E_USER_ERROR);
            }
        }
        echo "succeed\n";
    }

    function _truncate($name)
    {
        echo "Truncate table {$name}... ";
        $sql = "TRUNCATE $name";
        if (DB::isError($res = $this->db->query($sql))) {
            $this->db->rollback();
            echo "failed\n";
            trigger_error('INILoader::_truncate(): Failed to truncate. '
            .$res->toString(), E_USER_ERROR);
        }
        echo "succeed\n";
    }

    function _dump_all()
    {
        foreach ($this->db->getTables() as $table) {
            $this->_dump($table);
        }
    }

    function _remove_all()
    {
        foreach ($this->db->getTables() as $table) {
            $this->_remove($table);
        }
    }

    function _dump($name)
    {
        echo "Dump table {$name}... ";
        $file = "{$this->fixtures_dir}/{$name}.ini";
        $handle = fopen($file, 'a');
        $sql = "SELECT * FROM $name";
        foreach ($this->db->getAll($sql) as $index => $fields) {
            $line = "[{$name}".++$index."]\n";
            foreach ($fields as $key => $value) {
                $line .= "{$key} = \"{$value}\"\n";
            }

            if (!fwrite($handle, $line)) {
                trigger_error("INILoader::dump(): Failed to write $file",
                E_USER_ERROR);
            }
        }
        fclose($handle);
        echo "succeed\n";
    }

    function _remove($name)
    {
        echo "Remove file {$name}.ini ... ";
        unlink("{$this->fixtures_dir}/{$name}.ini");
        echo "succeed\n";
    }

    function _get_ini_files()
    {
        $files = array();
        $d = dir($this->fixtures_dir);
        while ($entry = $d->read()) {
            if (preg_match("/\.ini$/", $entry)) {
                $files[] = $entry;
            }
        }
        $d->close();
        return $files;
    }
}

function load_ini($fixtures_dir, $dsn, $key_check = false)
{
    $loader =& new INILoader($fixtures_dir, $dsn, $key_check);
    $loader->load();
}

function dump_ini($fixtures_dir, $dsn)
{
    $loader =& new INILoader($fixtures_dir, $dsn);
    $loader->dump();
}
?>

パソコンに関しては“なるべくデフォルト派”(あまりソフトを入れない)の俺です。結構多いと思われますが、デフォルト派のランチャーといえばやはり、

shell

“ファイル名を指定して実行”(以下ファ実)

コレ。

そして、

quick_start

“クイック起動”

コレですよ。

ファ実といえば、“ウィンドウズキー + R”。

「最近のThinkPadは良くなった。」

とはあるデフォルト派の言葉です。(ウィンドウズキーが付いた。)

こういうエントリが話題になるほど便利で便利でしょうがねえファ実ですが、ファイル名の補完ができないのが難点。

そこで、「補完が効くヤツを使おう」ではなく、「補完が効かないなら短い名前を付ければ良い」と考えてしまうのがデフォルト派。

bin

PATHを通したフォルダに短い名前のショートカットを沢山置いておけっ・・・・・・・・・!!!

UbuntuとWindowsをデュアルブートで使ったりしてたんですが、開発に関してWindowsで不便だと感じてた点がこれ。

「開発環境に入りたい時に、“PuttyをWクリック → セッション名をWクリック”という2アクションが必要。」

UbuntuやMacならTerminal立ち上げてすぐコマンド打ち始められるじゃないすか。不便じゃないですか。

…。

「何を言ってるんだこいつは。別に不便じゃない」という方、ありがとうございます。話が終わってしまいます。

やり方は簡単です。

shell_property

こういうショートカットを作っておけば1クリでこうです。

shell_putty

Using PuTTY

In order to start an existing saved session called sessionname, use the -load option (described in section 3.7.3.1).

putty.exe -load ””session name”“

puttyは—helpとかやっても何も出ないんですが、-loadでセッション名を指定出来るんだそうです。パスフレーズ無しの鍵(NATなら外から入れないので問題ないと思う)でcoLinuxに入るセッションを作って、指定すればまるでGNOME Terminalでローカルの開発環境を使ってるみたいになります。

shell_icon

ついでにさっきの画像の様にショートカットキーを設定したショートカットをデスクトップに置けばマウス無しで開けて便利です。

p0t: Webサービスのライセンス

でもブラウザがプラットフォームになると、Webサービスの利用規約とWeb APIの利用規約がGPL、LGPLの変わりになってどうでもよくなっちゃうのかな。

それぞれ標準のライセンスがあれば簡単なのに。ちょっとググったけど出てこなかった。

この問題。

【レポート】European Open Source Convention 2006 – Tim O’Reilly氏、Open Source 2.0を語る (2) Web 2.0時代のライセンス (MYCOMジャーナル)

「インターネットがプラットフォームとなった時代は、はじまったばかりだ」とO’Reilly氏は言う。まだどんなビジネスチャンスがあるのか、どんなロックインが出てくるのかは分からない。「Webサービスがオープンになるというのはどういうことか、データが本当にフリーになるというのはどういうことか、考えることはたくさんある」と課題提起した。

考え中ってことみたいです。APIだけじゃなく、データについても考えなくちゃいけないんですな。

Flickr Services

Serialized PHP Response Format

PHP has a built-in serialized data structure format, using the serialize() and unserialize() functions.

To return an API response in PHP serialized format, send a parameter ””format”” in the request with a value of ””php_serial””.

来てる!来てる!

p0t: PHPRPC

このフォーマットを汎用データ形式として広めようって剛の者はいないかな?