FIREFOX HACKS' (2)
室内禁煙のため、外に出て喫煙してる、ホタル属です。夕方、外でタバコしてたら、燕がよってきて、ホバリングしてました。煙をもくもくする人が珍しかったのかな? そのうちに、希少人種に指定されるのかしらん。
つばめさんの後を追ったら、軒下に巣がありました。そしてそこには、今にもはみ出しそうになった、雛が4羽けたましく泣いていました。今朝見に行ったら、飛行訓練の真最中。自信なさげに、巣から飛び出し、またすぐに戻ってくるという事を何度も何度も繰り変えていました。それを、両親?達は、近くの木の枝からそっと見守っていましたよ。 訓練の邪魔になっては失礼なので、そっとその場を離れたのでした。
key/value-store
駅ビルの商店街で発行している割引券の使用期限が迫っていたのがあったので、久しぶり に、「Web+DB(祝50)」を買ってきた。Netで評判が良かった、Gitの解説、なかなか良かった 。こりゃ、すぐにでも使わなければ!
後、面白かったのが、最近の key/value-store の動向記事。昔は、BDBとGDBMぐらいしか選択子が無かったけど、目的別にいろんなのが出ているのね。たまには、こういう記事もいいものだ。
key/value-storeで忘れられないのが、 Gaucheのファイルシステムdbm うまい事考えたなあと、感心してしまいます。
sqlite3
さて、いよいよ FIREFOXで使っている sqlite3を暴いていきます。 sqliteを管理するプログラムを参考に ちょっと実験します。SQLite が認識できる SQLも、参考にしましょう。
[sakae@fb ~/DB]$ sqlite3 places.sqlite sqlite> .help ..... sqlite> .tables moz_anno_attributes moz_favicons moz_keywords moz_annos moz_historyvisits moz_places moz_bookmarks moz_inputhistory moz_bookmarks_roots moz_items_annos sqlite> .schema moz_places CREATE TABLE moz_places (id INTEGER PRIMARY KEY, url LONGVARCHAR, title LONGVARC HAR, rev_host LONGVARCHAR, visit_count INTEGER DEFAULT 0, hidden INTEGER DEFAULT 0 NOT NULL, typed INTEGER DEFAULT 0 NOT NULL, favicon_id INTEGER, frecency INTE GER DEFAULT -1 NOT NULL); CREATE INDEX moz_places_faviconindex ON moz_places (favicon_id); CREATE INDEX moz_places_frecencyindex ON moz_places (frecency); CREATE INDEX moz_places_hostindex ON moz_places (rev_host); CREATE UNIQUE INDEX moz_places_url_uniqueindex ON moz_places (url); CREATE INDEX moz_places_visitcount ON moz_places (visit_count); sqlite> .quit
どうやら、何とかなりそうです。でも、こんなにあるテーブルの何処に何が隠れているのやら? いちいち調べるの面倒!
Gauche sqlite
そこで、自動化ですよ。前回はrubyが出てきたので、今回は gaucheにします。 Gauche用のsqlite3-dbd を、公開されている方がおられますので、有難く頂いてきます。
(use dbi) (use gauche.collection) (define sql-get-all-tables "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name;") (define (show-fields tbl) (let ((res (dbi-do con #`"PRAGMA table_info(',tbl')"))) (print tbl) (for-each (lambda (v)(format #t " ~18a ~a\n" (vector-ref v 1) (vector-ref v 2))) res))) (define db-name "places.sqlite") (define con (dbi-connect #`"dbi:sqlite3:,db-name")) (define res (dbi-do con sql-get-all-tables)) (for-each (lambda (v) (show-fields (vector-ref v 0))) res) (dbi-close con)
実行結果は次の通り
moz_anno_attributes id INTEGER name VARCHAR(32) moz_annos id INTEGER place_id INTEGER anno_attribute_id INTEGER mime_type VARCHAR(32) content LONGVARCHAR flags INTEGER expiration INTEGER type INTEGER dateAdded INTEGER lastModified INTEGER moz_bookmarks id INTEGER type INTEGER fk INTEGER parent INTEGER position INTEGER title LONGVARCHAR keyword_id INTEGER folder_type TEXT dateAdded INTEGER lastModified INTEGER moz_bookmarks_roots root_name VARCHAR(16) folder_id INTEGER moz_favicons id INTEGER url LONGVARCHAR data BLOB mime_type VARCHAR(32) expiration LONG moz_historyvisits id INTEGER from_visit INTEGER place_id INTEGER visit_date INTEGER visit_type INTEGER session INTEGER moz_inputhistory place_id INTEGER input LONGVARCHAR use_count INTEGER moz_items_annos id INTEGER item_id INTEGER anno_attribute_id INTEGER mime_type VARCHAR(32) content LONGVARCHAR flags INTEGER expiration INTEGER type INTEGER dateAdded INTEGER lastModified INTEGER moz_keywords id INTEGER keyword TEXT moz_places id INTEGER url LONGVARCHAR title LONGVARCHAR rev_host LONGVARCHAR visit_count INTEGER hidden INTEGER typed INTEGER favicon_id INTEGER frecency INTEGER sqlite_sequence name seq
後は、"select * from table" とかやって、地道に見ていきますか。 でも、DBは、これだけじゃなくて、他にもあるんだよなーー。