Ruby/Qte普及委員会 SimpleZDB

XREAAD
Create  Edit  Diff  FrontPage  Index  Search  Changes  History  RSS  Login

PIMへのアクセス も参照してください。

パッケージ

最新版

インストール用パッケージ
ruby-simplezdb_0.8.1.1-1_arm.ipk (2006-07-02)

テストスクリプト、ソースコード、README
ruby-simplezdb-0.8.1.1.tar.gz (2006-07-02)

旧版

注意: 0.8.0以下はRuby 1.8.3, 1.8.4で動きません。0.8.1はパッケージングのミスのため削除しました。

インストール用パッケージ

ruby-simplezdb_0.8.0-1_arm.ipk (2005-11-26)

テストスクリプト、ソースコード、README

ruby-simplezdb-0.8.0.tar.gz (2005-11-26)

ruby-simplezdb-0.7.1.tar.gz (2005-11-23)

ruby-simplezdb-0.7.tar.gz (2005-11-23)

ruby-simplezdb-0.6.tar.gz (2005-11-21)

ドキュメント

  • RDoc Documentation: SimpleZDB拡張ライブラリが提供するクラス、メソッドの説明。

README.ja

これは何か

SimpleZDB は、シャープ ザウルス(TM) のPIMデータベースにアクセスするための Ruby拡張ライブラリです。

詳しい情報は、ソースコード (simplezdb.cpp) 中のコメントを参照してください。 rdoc コマンドを使って HTML ドキュメントを生成することもできます。

 rdoc simplezdb.cpp

例1

 require 'simplezdb'
 
 include SimpleZDB
 
 DataBase.open(DataBase::ADDRESSBOOK) do |db|
   db.each do |contact|
     if contact.categories.include?("Friend") then
       puts contact["FULL"]
     end
   end
 end

例2 (eachブロックに渡される変数の型をカスタマイズ)

 require 'simplezdb'
 
 module SimpleZDB
   class Contact < Card
     def fullname
       self["FULL"]
     end
   end
   class Addressbook < DataBase
     def initialize(*args)
       is_readonly = args.shift
       super(DataBase::ADDRESSBOOK, is_readonly, Contact, *args)
     end
   end
 end
 
 include SimpleZDB
 
 Addressbook.open(true) do |db|
   db.each do |contact|
     if contact.categories.include?("Friend") then
       puts contact.fullname
     end
   end
 end

例3 (ソートとカテゴリによるフィルタを使う)

 require 'simplezdb'
 
 module SimpleZDB
   class Contact < Card
     def fullname
       self["FULL"]
     end
   end
   
   class Addressbook < DataBase
     def initialize(*args)
       is_readonly = args.shift
       super(DataBase::ADDRESSBOOK, is_readonly, Contact, *args)
     end
   end
 end
 
 include SimpleZDB
 
 Addressbook.open(true) do |db|
   sortkey = SortKey.new
   sortkey.add('LNPR', true, true)
   sortkey.add('FNPR', true, true)
   db.sort!(sortkey)
   category_set = CategorySet.new
   db.enable_filter(category_set.id_of('Friend'))
   db.each do |contact|
     puts contact.fullname
   end
 end

ビルドとインストール

ソースからのビルド

便宜上、ソースパッケージの中にもビルド済みの拡張ライブラリ (simplezdb.so) が同梱されています。もし、ソースを修正して自身でビルドしたい場合は、 次のステップを踏んでください。

  • ザウルス用クロス開発環境を構築する。
  • Rubyのソースコード (ruby-1.8.4.tar.gz) を入手し、ザウルス用にビルドする。
  • このパッケージの extconf.rb を編集し、パスなどを修正する。
  • extconf.rb を実行する。
   ruby extconf.rb --with-qte-dir=/opt/Qtopia/sharp
  • Makeする。
   CXX=arm-linux-g++ make

インストール

Rubyをまだインストールしていない場合は、以下のページから ruby_1.8.4-5_arm.ipk を入手してインストールしておいてください。 http://www.focv.com/ipkg/

続いて、SimpleZDBのipkパッケージをインストールしてください。以上です。

もし手作業でインストールしたい場合には、次のようにしてください。

  • simplezdb.so, lib/simplezdb/*.rb, test_simplezdb.rb をザウルスにコピーする。
  • simplezdb.so をRubyの機種依存ライブラリディレクトリに入れる。
 /opt/QtPalmtop/lib/ruby/site_ruby/1.8/arm-linux/simplezdb.so
  • lib/simplezdb/*.rb をRubyのライブラリディレクトリに入れる。(0.8.1 では card.rb と filterinfo.rb の二つだけですが、これから増えていく予定です。)
 /opt/QtPalmtop/lib/ruby/site_ruby/1.8/simplezdb/card.rb
 /opt/QtPalmtop/lib/ruby/site_ruby/1.8/simplezdb/filterinfo.rb
  • テストスクリプトを実行する。
   ruby ./test_simplezdb.rb

注記

ザウルスはシャープ株式会社の登録商標です。

作者

黒崎浩行 <noir (at) st . rim . or . jp>

ライセンス

GNU General Public License Version 2

謝辞

Rubyのザウルス用インストールパッケージを公開してくださっている、kenjiさんに感謝します。 http://club.h14m.org/kenji/diary/

Ruby/Qteを公開してくださっている、ひだかたかひろさんに感謝します。 ひだかさんのサイト:Ruby/Qte?

zdbatを公開してくださっている、yaktyさんに感謝します。この拡張ライブラリは zdbatのソースコードと関連Wikiページの掲載情報に多くを負っています。 LinuZauToolBoxWiki:zdbat?

Qualendarを公開してくださっている、ichitokumeiさんに感謝します。 ソースコード中のフィルタ関連の情報を参考にさせていただきました。 http://ichitokumei.hp.infoseek.co.jp/qualendar/

特徴と注意点

特徴

  • Enumerableモジュールをインクルードしているので、RubyのArray、Hashなどのオブジェクトと同じような感覚で、ザウルスのPIMデータにアクセスできます。
  • データにアクセスするさいの処理フローをすべてRubyで記述できるため、効率的なアクセスが可能です。例えば、上の例では、カテゴリに Friend を含んでいるエントリのみ、FULL という識別名の項目を読み出します。

注意点

  • 文字列のエンコーディングは UTF-8 に固定しています。
  • 日付時刻型は date ライブラリの DateTime (とDate) を使用しており、UTC (時差ゼロ) で読み出し、書き込みを行います。読み出した日時のローカル時刻を得たい場合は、次のようにしてください。
 require 'simplezb'
 # simplezdb.so から require しているので不要
 # require 'date'
 ...
 # ローカル時刻のオフセットを得る
 offset = DateTime.now.offset
 ...
 db.each do |event|
   start_time = event["TIM1"]
   if event["ADAY"] == 0 then # 終日日程でない
      start_time = start_time.new_offset(offset)
   end
   puts start_time
 ...
  • ローカル時刻でデータを渡した場合、時差計算を行った上で書き込みます。
  • データベースへの書き込み (Card#save) も可能ですが、まだ十分にテストしていませんので注意してください。また、SL-C3000以降では、次のようにする必要があります (Ruby/Qteが必要)。
 require 'simplezdb'
 require 'qte'
 ...
 # QApplicationをインスタンス化
 qtapp = Qte::QApplication.new([$0]+ARGV)
 ...
 # データベース書き込み
 card.save
  • ザウルスのデータベース関連クラスのすべてのメソッドを網羅しきれていません。たとえば以下のようなものは未対応です。
    • データベースの新規作成には対応していません。
    • データベースの隠し項目の読み書きには対応していません。データの更新日時などを設定する隠し項目があることが知られています。
  • ザウルスのデータベース固有のインデックス情報を使ったソート、検索、フィルタは、詳細が不明なところが多く、さしあたり関連メソッドがほぼそのまま使えるようにしてありますので、いろいろ試してみてください。キー項目指定による昇順・降順ソート、部分一致検索、UCHAR型とTIME型のフィールドの大小比較によるフィルタ、カテゴリによるフィルタはなんとかできるようです。同梱の test_simplezdb.rb を参照してください。
  • Cardオブジェクト (DataBase#each のブロック引数として生成される、もしくは Card.new(db, card_id) で生成する) は、データベースファイル上の実体ではなく、あるカードIDに関するそのつどの計算結果をまとめたものにすぎません。そのため、同じカードIDであっても、同じ Card オブジェクトとはみなさない仕様になっています (ということにしました)。今のところ DataBase#[] がないのもそのためです。database[3] がそのつど違うオブジェクトを返すとしたら、まぎらわしいです (よね)。たとえば、
 module SimpleZDB
   class DataBase
     def to_hash
       tmp = Hash.new
       self.each do |card|
         tmp[card.card_id] = card
       end
       tmp
     end
   end
 end
 ...
 cards = database.to_hash

のようにすれば、cards[3] はいつも同じ Card オブジェクトを返しますが、これでは to_hash の計算量がつねに O(n) となり、非効率的ですし、メモリも余計に消費します。

DataBase#[] を次のように定義すれば、若干ましになるでしょう。ただ、これもメモリを消費するのが心配です。それに、DataBase#each のほうはブロックを実行するたびごとにブロック引数となるオブジェクトを生成し、それを使い捨てにしていますが、そちらと意味的な整合性がとれなくなるように思います。

 module SimpleZDB
   class DataBase
     def [](card_id)
       unless @cards_cache
         @cards_cache = Hash.new
       end
       if @cards_cache.has_key?(card_id) then
         return @cards_cache[card_id]
       end
       new_card = Card.new(self, card_id)
       if card_id != 0 then
         @cards_cache[card_id] = new_card
       end
       new_card
     end
   end
 end

ToDo

  • DataBase#each からブロックに渡されるオブジェクトの型をカスタマイズ可能にする → 0.7 で対応。
  • ザウルスのデータベース固有のソート、検索、フィルタ関連メソッドをサポートする → 0.7 で対応。
  • 実は、CardクラスとItemAttrクラスはC++で書く必要がない (実際、ほとんど rb_funcall() だらけ) ので、Rubyコードに移す → 0.8.0で対応。ItemAttrは廃止。
  • ipkを用意する → 0.8.0で対応。
  • ItemInfo クラス (元の SlZDataBaseItemInfo クラスをラップして、いくつかインスタンス変数などを加えて便利にしたもの) を追加 → 0.8.0で対応。
  • SortKeyクラス (複数のソート条件を加えるためのクラス) の追加 → 0.8.0 で対応。sort_exp! の引数に渡すデータは、SortKey#to_exp で作れるようになります。これを使えば、複数のソート条件を組み合わせて、each ブロック内で適宜 break することで、終了を早めることができるようになります。(0.8.1では sort! メソッドの引数に SortKey オブジェクトを直接渡せるようにしました。)
  • フィルタが使えるようにする → 0.8.1 で FilterInfo クラスを追加しました。filterメソッドの第1引数に渡すバイト列を生成できます。Qualendarのソースを参考にしました。ただし、今のところUCHARとTIME型のフィールドにしか対応していません。
  • 特に複雑な、Datebook (カレンダー) の予定に関する処理を Event クラスにまとめる → 0.8.2 以降。
  • Shift JIS、EUC-JPにも対応 → 0.9 以降。

応用例

  • Clippim - クリップボードの内容を変換してPIMに入れる

コメント

  • 2005-11-24 (木) 11:51:39 hagiwara : これ,すばらしいですね.今まで zdbat 使って datebook と todo のデータを書き込んでいたんですけど,これに代えてみました.確かに早くなったです.ところで,みなさん ruby での utf-8 変換には rbuconv とか使われているんでしょうか? もうちょっと新しい ruby があると良いんですけどね,と思う今日このごろだったり.
  • 2005-11-24 (木) 21:04:53 noir : さっそく使っていただいてありがとうございます。しばらくの間は、仕様が変わるところもあるかと思いますが、ご容赦ください。文字コードについても、とりあえずはテストが楽なようにUTF-8に固定していますが、少し落ちついたらShift JISやEUC-JPにも対応できるようにしたいと思います。
  • 2005-11-24 (木) 23:43:19 noir : UTF-8変換は1.8.0だとIconvがありますね。あとRuby/QteならQTextCodecを使うという手も。
  • 2006-05-05 (金) 17:03:03 水 : SLC-3100で使ってみようと思ったら、initializeでエラーです、って出て動かなかったのが残念てす。念のためソースからのテストもやってみたんですが駄目でした。
  • 2006-05-06 (土) 01:35:27 noir : 水さん、ありがとうございます。よろしければ、どんなエラーメッセージか教えていただけるとありがたいのですが。
  • 2006-05-06 (土) 10:18:17 水 : 例えば、例1のようにDataBase.open(DataBase::ADDRESSBOOK)とやると 'initialize':wrong argument type SimpleZDB::DataBase(expected Cloass)(TypeError)となり、from xxx.rb:5:in 'new',from xxx.rb:5:in 'open'とでます。ちなみにtest_simplezdb.rbの場合、could not create box info 〜... test_simplezdb.rb:386 [BUG] Segmentation faultとなり、zsh: abort ruby test_simplezdb.rbとます。ruby -v は1.8.3です。
  • 2006-05-06 (土) 10:21:34 水 : 余談ですが、ipkのインストールをするとfilterinfo.rbの属性がreadのみの為、エラーとなってましたので、属性追加で再度実行した結果が上記のものです。
  • 2006-05-06 (土) 20:44:19 noir : 水さん、ありがとうございます。インストールの問題のような気もしますが、SL-C3000と3100とで何か違いがあるのかもしれませんし、まずは ruby 1.8.3 を入れてみて、とにかく原因を調べてみます。
  • 2006-05-06 (土) 21:50:26 水 : 正確には、test_simplezdb.rbは「zaurus% ruby test_simplezdb.rb Loaded suite test_simplezdb Started EEEEEEEEEEEEEEEEEEcould not create box info EECheckFileBoxEx error F0:SLFLER.BOX 40 could not open box F0:SLFLER.BOX CheckFileBoxEx error F0:SLFLER.BOX 40 test_simplezdb.rb:386: [BUG] Segmentation fault ruby 1.8.3 (2005-05-12) [arm-linux]
  • 2006-06-15 (木) 08:52:16 noir : お返事が遅れてすみません。なかなか時間がとれなくて…。とりあえず、今までの当方の開発環境と同じ、ruby 1.8.0 で試してみていただけますでしょうか?
  • 2006-06-17 (土) 16:03:29 水 : ご返事ありがとうございます。現在RoRを使っている関係で、すぐには戻せない状態です。1.8.0に戻せたら試してみようと思います。ありがとうございます。
  • 2006-06-19 (月) 18:58:43 水 : http://plaza.rakuten.co.jp/slc3200/diary/200606160000/ の方の記事を読むと1.8.0では動いたようです。うーん、ダウングレードするとRoRが動かなくなるので悩ましい所です
  • 2006-06-20 (火) 17:28:10 noir : 1.8.3や1.8.4だとダメなんですね。どなたか1.8.3や1.8.4のクロスコンパイル環境構築してSimpleZDBのソースからビルドしてみていただけるとありがたいのですが、ちょっと敷居が高いですよね。もうしばらく時間をください。
  • 2006-07-01 (土) 16:03:04 noir : http://noir.s7.xrea.com/rubyqte/simplezdb/simplezdb_so_for_ruby_1.8.4.zip とりあえず、Ruby 1.8.4 用にクロスコンパイルした simplezdb.so を作ってみました。こちらでは試していませんが、これを入れてみてください。
  • 2006-07-01 (土) 16:05:19 noir : ああ、水さんは 1.8.3 なのですね…。
  • 2006-07-01 (土) 16:48:42 noir : http://noir.s7.xrea.com/rubyqte/simplezdb/simplezdb_so_for_ruby_1.8.3.zip こちらは1.8.3用です。
  • 2006-07-01 (土) 21:17:52 nsock : simplezdb.so for ruby1.8.4 作っていただきましてありがとうございます。早速試したのですが、/opt/QtPalmtop/lib/ruby/site_ruby/1.8/arm-linux/simplezdb.so: no such file to load -- simplezdb/version (LoadError) とrequire 'simplezdb'した行でエラーが出て動きませんでした。Ruby1.8.4-5とSimpleZDB0.8.0-1の環境に上記simplezdb.soをコピーして試しました。
  • 2006-07-01 (土) 22:46:57 noir : nsockさん、こんにちは。ちゃんと ipk にしてなくてすみません。simplezdb/version.rb は SimpleZDB 0.8.1で追加したファイルです。(間違えました)
  • 2006-07-01 (土) 23:15:35 noir : すみません、次回公開予定のバージョンをコンパイルしてしまいました。0.8.1 のソースであらためてコンパイルしました。URLは先のものと同じですので、もう一度ダウンロードしてお試しください。
  • 2006-07-02 (日) 00:32:03 nsock : noirさん、早速対応していただきありがとうございます。さきほどのエラーはなくなったのですが、Ruby1.8.4-5だと水さんと同じエラー、1.8.0-1だと動く(1failures, 0errors)という状態です。
  • 2006-07-02 (日) 00:41:49 noir : nsockさん、ありがとうございます。たんに Ruby のクロスビルド環境を 1.8.4 にしただけではダメみたいですね。明日もういちど取り組んでみます。
  • 2006-07-02 (日) 15:49:03 noir : 原因がわかりました (Data_Wrap_Struct の第一引数にクラスでなくDataBaseのインスタンスを渡していた)。修正したものを ipk パッケージ化しましたので、お試しください。
  • 2006-07-02 (日) 16:38:51 nsock : Ruby1.8.4-5でも動きました。ありがとうございました。
  • 2006-07-02 (日) 18:25:00 noir : ありがとうございます。ブログのほう拝見しました。活用していただけてなによりです。これからもよろしくお願いします。
  • 2006-07-03 (月) 23:46:50 水 : 私も1.8.4-5のリリースでverを上げまして、nsockさんと同じ環境になり、動作確認しました。ありがとうございます。
  • 2006-07-04 (火) 22:00:32 noir : 私もひさしぶりにいじってみましたが、データ書き込みを楽に行うための機能が不足している感じがしました。それと、ドキュメントもやっぱり足りないなあ (ブランクがあるので自分も忘れている)…。いずれ機会を見て改善していきます。
{{comment}}

トラックバック

{{trackback}}
Last modified:2009/10/22 11:26:06
Keyword(s):
References:[FrontPage] [PIMへのアクセス] [PIMデータベースの日付時刻] [Clippim] [リンク集]