トップ 一覧 検索 ヘルプ RSS ログイン

【NS Basic/Palm】Keyモードデータベースのソート順の変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
{{category 開発情報}}
!!!【NS Basic/Palm】Keyモードデータベースのソート順

*NS BasicのKeyモードデータベースのソート順についての解説です。

!!概要
NS Basicではデータベースへのアクセス方法に、Keyモードアクセスという便利な機能があります。
レコードの先頭データをキーデータとして一意にすることで、レコード番号などを気にすることなくキーを指定するだけで任意のデータにアクセスできる便利なものです。
キーモードで作成されたDBのレコードは、キーのデータ順にソートされてDBに格納されるので単純にソートを目的として使用する際にも便利です。
しかし、実はあまり知られていないのですがこのキーのソート順に落とし穴があるのです。
ここではその注意点について説明したいと思います。

!!JaPonとJ-OSでのソートアルゴリズムの違い
例えば、以下のようなプログラムがあったとします。

	Sub Project_Startup()
		Dim	rc	as	Integer
		Dim	Db	as	Database
		Dim	i	as	Integer
		Dim	key	as	String
		
		rc = DbCreate( Db, "Test-TestDB", 0, "Test" )
		rc = DbOpen( Db, "Test-TestDB", 0 )
		
		For i=1 to 15
			key=chr(i)
			rc = DbInsert( Db, Key, i )
		Next
		rc = DbClose( Db )
	End Sub

これはキーに0x01〜0x0Fのキャラクタコードを指定してレコードを作成するプログラムです。
このプログラムを実行した際に、レコードの並び順がどのようになるのか見てみると、面白い結果が得られます。
以下は、先のプログラムで作成したDBの各レコードのキー文字列のキャラクタコードを、レコード順に抽出した結果です。
,J-OS,JaPon
,0x01,0x01
,0x02,0x02
,0x03,0x03
,0x04,0x04
,0x05,0x05
,0x06,0x06
,0x07,0x07
,0x08,0x08
,0x09,0x0E
,0x0A,0x0F
,0x0B,0x09
,0x0C,0x0A
,0x0D,0x0B
,0x0E,0x0C
,0x0F,0x0D

ご覧のように、J-OSではキャラクタコード順にきれいに並んでいるのに対し、JaPonでは0x0EとOx0Fが0x09の直前に来ていますね。
このように、2つの環境でデータベースの並び順に差異があるのが分かると思います。
ここだけ見ると、J-OSの並び順のほうが素直に見えますが、実はキャラクタコード全域で比較すると、お互いのソート順ともにキャラクタコードとは微妙に差異があるようです。
さてここで問題なのは、Keyモードのデータベースは、必ずソートされていないといけないと言うことです。
言い換えると、JaPonで作成したデータベースはJ-OS環境にそのままコピーすると、ソートされていないDBとなり、Keyモードでは正常にアクセスできなくなってしまうのです。

実はこれはJaPonやJ-OSに限った問題ではなく、日本語版PalmOSでも、PalmOS4以前とPalmOS5以降でも差異があるようです。
全てを比較したわけではありませんが、僕が調査した限りでは日本語版PalmOS4以前のものは、J-OSと同じようなDBのソート順となり、OS5ではJaPonと同じようなソート順になるようです。

!!回避方法
これを回避するためには、2種類の方法が考えられます。
!1.プログラム設計時にキーのフォーマットを決めてしまう
ソート順が違うと言っても、半角数字を表す0x30〜0x39とか、半角英大文字を表す0x41〜0x5A、同小文字0x61〜0x7Aといったキャラクタコードの範囲の中では、互いの環境でソート順に違いは無いようです。
ですから、Keyデータが文字列(String)の場合に限られますが、Key文字列を半角英大文字のみとか半角数字のみという使い方であれば、双方の環境間でDBをやり取りしても問題なく使える事でしょう。
一応、英文字の大文字と小文字を混在しなければ、半角数字と英文字との混在は大丈夫なようです。

!2.コンバートの仕組みを用意する
Keyのフォーマットを決めてしまえば解決できるとは言っても、既に作ってしまったプログラムの場合、DBのフォーマットを変更するのは大変です。
そのような場合は、異なる環境で作成されたDBを現在の環境にコンバートする仕組みを用意すれば良いでしょう。

ソースコードを書くと煩雑になるので、申し訳ありませんが手順だけ説明したいと思います。

 元のDB(ソートし直したいDB)をオープン
	 ↓
 テンポラリ(一時利用)のDBを新規に作成
	 ↓
 元のDBをNon Keyモードで1レコードづつアクセスし、
 取得したデータをDbInsert命令を使ってテンポラリDBに
 コピーする(全てのレコードのコピーが完了するまで繰り返す)
	 ↓
 元のDBを削除する
	 ↓
 テンポラリDBの名前を元のDB名にリネームするか、元のDB名で
 空のDBを作成し、テンポラリDBの全レコードを新しく作成した
 元のDBにコピーする
	 ↓
 テンポラリDBは削除

少々煩雑ですが、理屈はソートされていないDBでも、Non Keyモードでは読み込むことができるので、とりあえずソート順が狂ってしまっているDBのデータは、Non Keyモードで読み込んで、新規にキーモードでDBを作成してしまえばいいわけです。
この手順を踏めば確実に環境の移行ができるので、プログラムの片隅にメンテナンス機能として潜ませておくのもいいかもしれません。

!!注意点
今回話した内容は、異なる環境にDBを移行した際のみに発生する問題です。
J-OS同士やJaPon同士でDBをコピーした場合、この問題は表面化することはありません。
ただ、KeyモードでのDBアクセスは簡単で便利なので、NS Basicユーザの方は半ば当たり前のように使っていることと思いますので、ある日突然落とし穴に落ちないためにも注意する必要があると思います。

またこの問題に関して、僕も全てを洗い出したわけではありません。
何か新しい発見があったら、随時ここの情報は追加していきたいと思います。

文責:いなあも

!!コメント
このページの情報に関する誤りや追加情報がありましたら、コメントをお願いします。

{{comment}}