2010年4月22日木曜日

OpenFlashChart(php ver5)をちょっとカスタマイズ

どうも、俺@OpenFlashChartでグラフ作成中です。

Flashを使ったキレイなグラフ作成ライブラリOpen Flash Chartを使っています。
pythonとかperlとかjspからも呼び出せて、キレイなグラフを描画してくれるのでかなり使えるやつです。


僕はphpを使ってるので、アーカイブを展開して「/php5-ofc-library」以下のファイルを使ってグラフを作っているのですが、どうもこれが未完成っぽい。
未完成というより、「/php-ofc-library」以下にあるファイル(php4用)の方が色々充実しているみたいですね。

積み上げ棒グラフを作っているのですが、このサンプルにあるようにグラフ上部に凡例を出したいのに出せませんでした。
※php4版ではすぐ出せました。

というわけでphp5版の/OFC/Charts/Bar/OFC_Charts_Bar_Stack.phpをイジっちゃいましょう。

# vim /OFC/Charts/OFC_Charts_Bar.php
// set_keys()メソッドを作成
function set_keys ($keys) {
$this->keys = $keys;
}

# vim /OFC/Charts/Bar/OFC_Charts_Bar_Stack.php
// OFC_Charts_Bar_Stack_Keyクラスを追加
class OFC_Charts_Bar_Stack_Key {
function OFC_Charts_Bar_Stack_Key($color, $text, $font_size) {
$this->colour = $color; // `colour`なことに注意
$this->text = $text;
$this->font-size = $font_size;
}
}


呼び出し側では

<?php
$bar_stack = new OFC_Charts_Bar_Stack();
$bar_stack->set_keys(
array (
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size),
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size),
new OFC_Charts_Bar_Stack_Key($color, $text, $font_size)
)
);
のようにしてやればOKです。


OpenFlashChart(php版)は、最後のtoString()メソッドやprettyString()メソッドでセットされた値を単にjson_encode()して吐き出しているだけ
なので、どんな値をセットしてもjson形式でデータを出力してくれます。
あとは、ライブラリに用意されているswfファイルが読み取ってFlashグラフを作成している、という訳です。

ちゃんちゃん。

MySQLのデータをCSVで出力/入力

どうも、俺@始業しましたです。

ググればすぐ出てきますが、MySQLのデータを簡単にcsv(またはtsv)出力する方法のめもです。
出力
mysql> SELECT * FROM table_name
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY ',';
これで、/tmp/out.csvというファイルに`table_name`テーブルのデータをカンマ区切りで出力できます。
タブ区切りで、各項目を`"(ダブルクォート)`で囲む場合は、
SELECT * FROM table_name
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY '\t'
ENCLOSED BY '"';
と、ENCLOSED BY '"' を追加します。
テーブルを結合した結果をcsv出力し、改行コードは`\r\n`にするには
SELECT * FROM table_name
INNER JOIN join_table ON table_name.f_key = join_table.id
INTO OUTFILE "/tmp/out.csv"
FIELDS TERMINATED BY '\t'
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';
と、LINES TERMINATED BY '\r\n'を追加します。

次にデータを入力する方法です。
これはmysqldumpで取得したデータをリストアするより高速に動作します。(たぶん)
mysql> LOAD DATA INFILE "/tmp/in.csv"
FIELDS TERMINATED BY ',';

もちろんタブ区切りの場合は、
LOAD DATA INFILE "/tmp/in.csv"
FIELDS TERMINATED BY '\t';
になります。
ダブルクォートや改行コードを指定してインポートする場合も、INTO OUTFILE構文のと同様です。

ただ、クライアントマシンとMySQLマシンが別サーバで接続されている場合は、
mysql> LOAD DATA LOCAL INFILE "/tmp/in.csv"
FIELDS TERMINATED BY ',';
と、`LOCAL`キーワードを指定します。


出力する方法
入力する方法


以上でぇぇぇえぇす。

2010年4月6日火曜日

Zend_Db_Selectの便利な使い方

どうも、俺@風呂上りです。

今日はZend Frameworkで用意されているZend_Db_Selectクラスを使った便利な方法をメモします。
ま、ZendFrameworkの公式にあるので、そちらを参考に!

Zend Frameworkのコンポーネント達はそのフレームワークを利用せずとも、組み込めるように作られているので、そういう使い方もできますよ(´・ω・`)

インスタンスの生成は、
<?php
$select = new Zend_Db_Select(Zend_Db_Adapter $db);
これでZend_Db_Selectのインスタンスが生成されます。

Where句は、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
// WHERE id=$id_param
で作れます。
続けて書けば、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
$select->where("name = ?", $name_param);
// WHERE id=$id_param AND name='$name_param'
のようになり、
<?php
$select->where("id = ?", $id_param, Zend_Db::INT_TYPE);
$select->orWhere("name = ?", $name_param);
// WHERE id=$id_param OR name='$name_param'
になります。

Order by句は、
<?php
$select->order("id");
// ORDER BY id

<?php
$select->order("id DESC");
// ORDER BY id DESC
になります。

Limit Offset句は、
<?php
$select->limit(30, 10);
// LIMIT 30 OFFSET 10 または LIMIT 30, 10
でできます。

Group by句は、
<?php
$select->group("id");
// GROUP BY id
です。

で、ここがとても感動したポイントですが、取得したカラムやテーブルの指定する方法は、
<?php
$select->from("foo_table");
// SELECT * FROM foo_table

<?php
$select->from(array("foo" => "foo_table"), "id");
// SELECT foo.id FROM foo_table AS foo
となるのです(´・ω・`)
カラムにエイリアス(別名)をつける場合は、
<?php
$select->from(array("foo" => "foo_table"), array("id_aliase" => "id"));
// SELECT foo.id AS id_aliase FROM foo_table AS foo
です。
途中でカラムを追加するには、
<?php
$select->from(array("foo" => "foo_table"), array("id_aliase" => "id"));
$select->columns("name", "name_aliase");
// SELECT foo.id AS id_aliase, foo.name AS name_aliase FROM foo_table AS foo
です。
一気に大量のカラムを書きたい場合は、
<?php
$select->from(array("foo" => "foo_table"), array("id", "name", "birthday", "address",....));
のようにします。



ということは、これらをまとめると、
<?php
$select = new Zend_Db_Select(Zend_Db_Adapter $db);
$select->from(array("foo" => "foo_table"), array("id", "name"));
$select->where("id IN (". implode(",", $id_list).")");
$select->order("id DESC");
$select->limit(30, 10);
// SELECT foo.id, foo.name FROM foo_table AS foo WHERE id IN (x,x,x,x,x) ORDER BY id DESC LIMIT 30 OFFSET 10;
のようになるわけです。

これにZend_Db_Adapterを利用して、
<?php
$result_set = $db->fetchAll($select);
とかやると、一発で配列でデータを取得できたり、
<?php
$stmt = $db->query($select);
while ($rs = $stmt->fetch()) {
// 処理
}
のように1レコードずつデータ処理を行ったりできます。

ちなみに、クエリ文字列を取得するには、
<?php
$query = $select->__toString();
でできますし、Where句だけ取りたいという場合は
<?php
$wheres = $select->getPart(Zend_Db_Select::WHERE);
// where句すべてを配列で取得できるのであとで、implode()とかやれば使える
で取れます。

いやぁ、超便利ーー(´・ω・`)

2010年3月12日金曜日

今さらながらdigの使い方

こんにちわ、おれ@花金仕事中です。
ウキウキしますねー。

今日はLinuxの「dig」コマンドについてメモです。
digコマンドは、DNSの正引き逆引きを行う超便利コマンドです。

例えばgoogle.co.jpの正引きをするには、
shell> dig google.co.jp

; <<>> DiG 9.2.4 <<>> google.co.jp
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38283
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google.co.jp. IN A

;; ANSWER SECTION:
google.co.jp. 1800 IN A 72.14.203.104
google.co.jp. 1800 IN A 74.125.95.104
google.co.jp. 1800 IN A 74.125.91.104

;; Query time: 63 msec
;; SERVER: 192.168.60.1#53(192.168.60.1)
;; WHEN: Fri Mar 12 14:06:35 2010
;; MSG SIZE rcvd: 78
こんな感じです。
この「ANSWER SECTION」セクション内を見て
google.co.jpは、
72.14.203.104
74.125.95.104
74.125.91.104にヒモ付られているという事が分かります。

逆引きをする場合は「-x」オプションを付けます。
shell> dig -x 74.125.91.104


MXレコードやNSレコードを調べる場合は、
shell> dig google.co.jp mx
のようにtypeを指定します。
またネームサーバを指定する場合は、
shell> dig @a.dns.jp google.co.jp
のように「@(アットマーク)ネームサーバ」を指定します。


以上、でぇぇぇぇす。

2010年3月5日金曜日

rubyでASCII-8BIT~のエラーがでる

どうも、俺@仕事モヤモヤ中です。

rubyでWEBアプリを作っている(僕の環境の場合はUTF-8のアプリ)と
incompatible character encodings: ASCII-8BIT and UTF-8
とか
"\\xE3" from ASCII-8BIT to UTF-8...
Encoding::UndefinedConversionError
みたいなエラーが大量発生して泣きそうになっていました。

ログの通り、文字コードに関するエラーなのですが、だいたい
String.force_encoding("UTF-8")
で回避できます。

特に僕の場合は、sqlite3を使っていたのですが、
ruby-sqlite3モジュールでは、取得データを全てASCII-8BITで保持する実装になっているようで、
Rubyで遊ぶよ Rubyのsqlite3-rubyは必ず文字コードASCII-8BITとして返す
ASCIIなバイト文字列をUTF-8にする際におかしなコードに引っかかっちゃってる系でエラーが出るようです。

ruby-sqlite3の場合は、取得したデータをことごとく .force_encoding("UTF-8")すれば何とかなります。


ちなみに、rubyで文字コード対策としてマジックコメントというものがあります。
#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-
とすれば、文字コードを判別して出力してくれます。


以上どえぇぇぇぇす。