Palm Programmer's Laboratory
Introduction to Conduit Development601/8
※訳者: 一部未訳
たいていのコンジットの機能はハンドヘルド上の Palm OS データベースを読み書きすることです。この章では、データベースのタイプとレイアウトについて説明します。
この章には、以下の節があります。
データベースの概要 ^TOP^
従来のファイル システムは最初に、メモリ バッファの中の情報を使用または更新して、ファイル全体または一部をディスクからメモリ バッファに読み込み、それから更新されたメモリ バッファをディスクに書き戻します。Palm ハンドヘルドはダイナミック RAM の量が制限されていて、ディスク記憶装置の代わりの不揮発性 RAM を使用するため、従来のファイル システムは Palm OS ユーザ データを保存、取得するのに最適ではありません。それゆえ、拡張メディア(SD カード、メモリ スティックなど)に対して処理を行う場合を除き、Palm OS は従来のファイル システムを使用しません。ファイルではなく、Palm OS アプリケーションは主にデータベースを使用します。
データベースは相互に関連する行(スキーマ データベースに対して)またはレコード(非スキーマ データベースに対して)を組織します; それぞれはただ 1 つのデータベースに属します。あるデータベースはアドレス帳全体、予定表全体などの集合体かもしれません。Palm OS アプリケーションまたはコンジットは必要に応じてデータベースを作成、削除、オープン、クローズすることができます - ちょうど、従来のファイル システムが従来のファイルを作成、削除、オープン、クローズできるように。アプリケーションはこれらの操作を実行するためにデータ マネージャを呼び出します; コンジットはデスクトップ上の 同期マネージャを呼び出します - 同期マネージャはデータベース操作を実行するためにハンドヘルド上のデータ マネージャを呼び出します。
以下の小節では、データベースのいくつかのタイプとそれらの共通機能を比較します:
スキーマデータベース 対 非スキーマ データベース ^TOP^
新たに Palm OS プログラミングを始める人にとって、「データベース」という用語は何か誤解を生じさせる可能性があります。Palm OS Cobalt は 3 タイプのデータベースをサポートします。あるタイプのデータベースは他のものよりも従来通りのデータベースに近いです。スキーマ データベースはリレーショナル データベースと強い類似性を持ちます。データはテーブルの中で組織化され、テーブルは行と列で構成されます。スキーマ データベースはテーブル行の構造を定義するためにスキーマのコンセプトを使用します。しかしながら、リレーショナル データベースとは異なり、スキーマ データベースではあなたは結合や他の複雑な処理を実行することはできません。
他の 2 タイプのデータベースは、スキーマ データベースに比べてはるかに組織化されていないため、「非スキーマ」データベースとして分類されます。サポートされる非スキーマ データベースには 2 タイプあります:
- クラシック データベース - これはより以前の Palm OS のバージョンとの互換性のためにサポートされます。Palm OS 1.0 まで遡るすべてのバージョンの Palm OS はこのデータベース フォーマットをサポートし、Palm OS Cobalt 上で実行されるているアプリケーションはこのフォーマットを PACE を通じて使用します。
- 拡張データベース - これはクラシック データベースの「拡張された」バージョンです。クラシック データベースと拡張データベースには 3 つの主要な違いがあります:
- レコードは 64KB を超えることができます(クラシック データベースのレコードはできません) - 実際、メモリが使用可能ならばレコードはほぼ 64MB になることができます。
- 名前と作成者 ID の組み合わせによって一意に認識されます(クラシック データベースは名前だけで一意に認識されます)。
- プロセッサのネイティブ エンディアンネス(訳者注: 多バイト データの配置順のこと)を使ってデータを保存することができます(クラシック データベースは、以前の Palm OS デバイスで使用されていた 68K-ベース Dragonball CPU との互換性のために、ビッグ エンディアンネスを使ってレコード データを保存しなくてはなりません)。
スキーマ データベースで採用されている関係アプローチ(原文: relational approach)の強みの 1 つは、あなたはデータを情報として扱うことができ、理想的にはそれがデータベースの中でどのように表されるのか、あるいは、物理的に維持されるのかといった詳細に気を配る必要がないということです。拡張データベースとクラシック データベースではこれらの実装の詳細を扱わなければならないため、管理するのがより困難です。
Palm OS Cobalt よりも前の Palm OS との互換性を保たなくてはならないハンドヘルド アプリケーションとコンジット - たぶん、そのアプリケーションのあるバージョンはより以前の Palm OS 上で実行されていて、そのアプリケーションはより以前のバージョンのデータでも機能しなければならない - は、クラシック データベースを使用します。そのような互換性要求に応える必要のないハンドヘルド アプリケーションとコンジットは、拡張データベースかスキーマ データベースを使用すべきです。どちらを使用すべきかはアプリケーションの性質次第です。スキーマ データベースは、データベース コンテンツの組織化とセキュリティに対して高いサポート性能を提供しますが、パフォーマンスは犠牲になります。一方、拡張データベースは読み込みと書き込みは高速ですが、セキュリティと構造化は低いです - つまり、あなたのアプリケーションとコンジットはそれ自身でレコード コンテンツの維持と解釈を行わなければなりません。
非スキーマ データベースはそれ自身のコンテンツをほとんど実体の無い(原文: opaque, 訳者注: 「実体が無い」とはデータの意味を考えずにただのバイトとして扱うという意味だと思われる)レコードのリストとして扱います。Palm OS データ マネージャは各レコードについてカテゴリ、変更状態、削除状態を理解するのに必要される知識だけを持ちます。アプリケーションはデータベース レコード コンテンツの構造化と解釈に対してすべての責任を負います。68K-ベース ハンドヘルドと PACE のために書かれた従来の Palm OS アプリケーションはクラシック データベースに対して排他的に機能します。
スキーマ データベースはレコード コンテンツに抽象的なレイヤを付け加えます。この抽象的なレイヤはアプリケーションとのより進化したデータ共有を提供して、あなたがよりフレキシブルなアプリケーションを作成することを可能にします。データ マネージャは、非スキーマ データベースに対してよりも、データベース行の構造についてより多くの知識を持つので、より詳細な変更追跡を提供することができます。データベースのスキーマ定義、行データ、カテゴリ メンバへの変更はそれぞれ独立して追跡され、同期はより単純により効率的になります。
スキーマ データベースは他にも利点を持ちます:
- より標準化されたデータ記憶装置を提供します。
- スキーマ データベースはフィールドの追加に対してより拡張性を高くすることができます。
- スキーマ データベースのためのコンジットを作成するのはより容易で、スキーマ データベースをデスクトップ コンピュータまたはサーバ上のデータベースと統合するのもより容易です。
レコード データベースとリソース データベース ^TOP^
リソース データベースと指定された非スキーマ データベースはデータの各チャンクに固有のリソース タイプとリソース ID のタグを付加します。これらのタグを付けられたデータ チャンクはリソースと呼ばれます。リソース データベースの構造は、リソース レコードごとのオーバヘッドによる少しの容量増加(2 バイト)を除いて、他の非スキーマ データベースとほぼ同じです。
リソースは通常アプリケーションのユーザ インターフェイス要素 - イメージ、フォント、ダイアログのレイアウトなどのようなもの - を保存するために使用されます。アプリケーションを組み立てるということには、これらのリソースを作成し、それらを実際の実行コードに埋め込むということも含まれます。Palm OS 環境では、実際のところ、アプリケーションは、いくつかのコード リソースとして保存された実行コードと、それと同じデータベースに他のリソース タイプとして保存されたグラフィック要素とその他のデータを持つ単なるリソース データベースです。
さらに、アプリケーションは、アプリケーション設定、保存されるウィンドウの位置、状態情報などを保存と取得を行うのに有用なリソース データベースを見つけるかもしれません。これらの設定はそれぞれ別のリソース データベースに保存することができます。
相互排他データベース特性 ^TOP^
表 8.1 は、データベースのどのタイプがレコードまたはリソースを保持できるのか、それらにセキュリティをかけることはできるのかを示しています。データベース タイプ(スキーマ データベース、拡張データベース、クラシック データベース)の特性は互いに排他的で、データベースはレコードとリソースの両方を保持することはできないということに注意してください。スキーマ データベースだけはセキュリティをかけることができます(「セキュア データベース」 を参照してください)。
データベース タイプ | レコードまたはリソースを保持できるか? | セキュリティをかけることはできるか? |
---|---|---|
スキーマ データベース | レコード(行データ)のみ | Yes |
拡張データベース | どちらか一つ | No |
クラシック データベース | どちらか一つ | No |
データベースの一意認識 ^TOP^
スキーマ データベース、拡張データベース、クラシック データベースは互いにつながりの無い名前空間の中に存在します。それぞれの名前空間につながりが無いので、同じ名前と作成者 ID を持つデータベースの上限は 3 つ - それぞれの名前空間ごとに 1 つ - です。
Palm OS のすべてのバージョンで、クラシック データベースは名前で一意に識別されなければなりません。しかしながら、スキーマ データベースと拡張データベースはデータベースの名前と作成者 ID の組み合わせで一意に識別されます。それゆえ、スキーマ データベースと拡張データベースの名前は単一の作成者 ID に対してのみ固有であれば良いのです: 同じ名前を持つ 2 つのデータベースはそれぞれの作成者 ID が異なる限り同じハンドヘルド上に存在することができます。
データベース属性 ^TOP^
データベースのコンテンツを構成するレコードに加えて - そして、スキーマ データベース テーブルの行の構造を定義するスキーマに加えて - すべての Palm OS データベースは、データベース自体のさまざまな様相を示すフラグのセットを持ち、さらに、データベースが作成された、最後に変更された、最後にバックアップされた時を示す日付のセットを持ちます。同様に、非スキーマ データベースは、アプリケーションの設定とそれと類似のものを保持するアプリケーション情報ブロックとデータベース レコードの順番を制御するソート情報ブロックを持ちます。スキーマ データベースは行の順番を制御するためにアプリケーションのためのカーソルというコンセプトを使用します; コンジットはカーソルにアクセスする手段を持ちません。
スキーマ データベース ^TOP^
スキーマ データベースはいくつかのテーブルで構成されます。あるテーブルの中のすべての行は同じ構造を持ちます。
スキーマ データベース テーブルの中のすべてのデータは 2 次元テーブルのフォームの中で表されます。テーブルは 0 行以上の行と 1 列以上の列で構成されます。テーブルの中のすべての行は同じ列のシークエンス(訳者注: 同じ順番で並んだもの)を持ちます。しかし、各行の列の中の値はそれぞれ異なります。行は列の値を必ずしも持つ必要は無いということに注意してください; 値が定義されていないことを示す特別な値 NULL を使用することができます。図 8.1 を参照してください。
リレーショナル データベースに対して、操作はロジックによって定義されます。テーブル内の行の位置によってではありません。つまり、例えば、あなたはすべての行に対してどの行が (x = 3) なのかを問い合せるのであって、最初と 3 番目と 5 番目の行に問い合せをするわけではありません。スキーマ データベース テーブルの行は任意の順番に並びます - それらの行が現れる順番は必ずしもそれらが入力された順番やソートされた順番を反映するわけではありません。
以下の小節では、スキーマ データベース、セキュア データベース、同時アクセスについてさらに詳述します:
スキーマ データベース ヘッダ ^TOP^
スキーマ データベース ヘッダは情報 - これはデータベースを表し、カテゴリ情報ブロック、行ソート インデックス、テーブル、行へのポインタを含みます - を保持します。スキーマ データベース ヘッダは非スキーマ データベースの中にあるすべての情報 - 各テーブルのためのソート インデックスによって置き換えられるオプションのソート情報ブロックとスキーマ データベースの中には存在しないアプリケーション情報ブロックを除いては - を保持します。スキーマ データベース ヘッダは以下の情報を保持します:
- 名前
- null で終了するデータベースの名前。スキーマ データベース名は null 終端子を含めて 32 文字までの有効な SQL 識別子であるべきです。
- タイプ
- Palm OS が同じ作成者 ID を持つ複数のデータベースを区別することを可能にする 4 バイト文字列。タイプ値は作成者 ID と同じ必須条件を持ちますが、それらは固有なものではないのであなたはそれらを登録することはありません。ある特定のタイプは特別な意味を持ちます - 例えば、'appl' はアプリケーションを表します。
- 作成者
- アプリケーションまたはデータベースの作成者を一意に識別する 4 バイト文字列。あなたは、あなたのアプリケーションが他のものと混同されるのを防ぐために、あなたの作成者 ID を PalmSource に登録しなくてはなりません。値は大文字/小文字の区別があり、32 - 126 (10 進数)の範囲の ASCII 文字で構成されます。すべてが小文字の値は PalmSource 用として予約されています。
- 属性
- フラグ。これらは、データベースがレコードとリソースのどちらを保持するのか、Read-only か、変更されたアプリケーション情報ブロックを持つのか、バックアップされるのか、コピー プロテクトされているのかなどといった特性を示します。
- バージョン
- アプリケーション-指定バージョン番号。
- 作成日付
- データベースが作成された日付。
- 変更日付
- データベースがアプリケーションまたはコンジットによって最後に変更された日付。
- 最終バックアップ日付
- データベースが最後にバックアップされた日付。
- 変更番号
- データベースの中のレコードが削除、追加、変更されるたびに +1 される整数。
- 固有 ID の種
- このデータベースのためのレコード ID を生成するためにデータ マネージャによって割り当てられ、使用される値 - データ マネージャ以外がこれらの値を割り当てたり、使用することはありません。
- DRID
- データベース リセット識別子。データ マネージャが擬似ランダム的にこの識別子を各スキーマ データベースのために生成します。同期でのみ使用されます。デスクトップ同期マネージャは DRID を使って、同期クロック値と変更カウンタが信頼できるかどうかを決定します - 例えば、ハード リセット後にデータベースがレストアされた場合、信頼できません。
- 同期クロック
- 各スキーマ データベースは、変更カウンタを更新するために使用されるローカル同期クロックを持ちます。同期実施の最後に、データ マネージャは同期クロックを +1 します。
- テーブル定義
- データベースの中で定義されているすべてのテーブルのリストへのポインタ。
- デフォルト ソート インデックス
- テーブルの中の行のデフォルトのソートされた順番を示す行ポインタへのポインタ。これはスキーマ同期マネージャによってのみ使用されるソート順番です。
- テーブル数
- データベースの中に保存されているテーブルの数。
- テーブルのリスト
- テーブルへの各エントリ ポイント。各テーブルは行 ID のリストを持ちます。各行は属性、カテゴリ メンバ属性などと、その行の列値のリストへのポインタを持ちます。
スキーマとテーブル ^TOP^
スキーマは単なるテーブルの列の定義の集まりです。各スキーマ データベースはさまざまな性質を持つことができ、その中では複数のテーブルがサポートされます。各テーブルの定義にはそのテーブルの列定義 - スキーマ - が含まれるため、2 つのテーブルが同じスキーマを持つことができます。しかし、あるテーブルのスキーマへの変更は他のテーブル スキーマに影響を与えません。
テーブルはデータベースの作成時に定義することができ、その後に追加することもできます。
スキーマへのアクセスは、データベースのためのアクセス制限によって管理されます。データベースへの Read-only アクセスはデータベースのすべてのスキーマへの Read-only アクセスを暗に示しています(それゆえ、スキーマを変更しようとする試みはすべて失敗します)。データベース アクセス制限についての更なる情報は 「セキュア データベース」 を参照してください。
スキーマは、同期マネージャが物理(内部)ビューからあなたのデータの論理(外部)ビューを分離させることを可能にします。スキーマ データベースに対して処理を行っているとき、あなたは列プロパティ セットの中で定義されているデータ タイプという観点から見た行データを操作します - これが論理データ ビューです。しかしながら、実際は、データ マネージャが内部的に行データを公開されないさまざまなフォーマットで保存します: これが物理データ ビューです。この分離が内部データ フォーマットへの変更を - 既存のデータベース利用者(訳者注: ユーザともデータ マネージャとも解釈できる)に影響を与えることなく - 容易にします。
列プロパティ セットの中で定義されるデータ タイプは Palm OS のプリミティブ型またはベクトル型です。データ マネージャはその物理データ タイプとフィールド取得/セット操作中に施行される論理データ タイプ間の変換を行います。
スキーマは列プロパティ セットの集まりです。各プロパティ セットは以下のビルト-イン プロパティを保持します:
- ID
- 32 ビット アプリケーション-定義識別子です。。この ID はテーブル内で固有でなければなりません。
- 名前
- 列のアプリケーション-定義名です。。列名はテーブル内で固有でなければなりません。上限は null 終端文字を含めて 32 バイトで、7 ビット ASCII 文字だけで構成される有効な SQL 識別子でなければなりません。列名は単一のアプリケーション-定義言語コーディングの中に保存されます。
- データ タイプ
- データベース列内で保持されるデータのタイプです。
- サイズ
- 可変長の文字列、BLOB (Binary Large Object)、ベクトルを保持する列の最大バイト数です。
- 属性
- 列データを変更することはできるか、列はテーブルの作成後に追加されたのか、列データは同期されるのかどうかを示すフラグのセットです。(「同期不可」の列のデータへの変更は行の変更状態を変えることはなく、それゆえそれらによって行に変更されたというフラグが立てられることはありません。)
これらのビルト-イン列プロパティはデータ マネージャによって提供され、削除することはできません。これらのビルト-イン プロパティに加えて、あなたは列のカスタム プロパティを定義することができます: プロパティは列のアプリケーション-指定シマンティック(原文: semantic, 意味)を容易にします。スキーマを構成する列定義の操作についての更なる情報は、「列定義への処理」 を参照してください。
スキーマ データベースは、表 8.2 でリストアップされている列データ タイプをサポートします。
Palm OS プリミティブ/ロジック タイプ | 説明 | 必要な容量 | 範囲/サイズ |
---|---|---|---|
uint8_t | 符号無し文字 | 1 バイト | 0 から 255 |
uint16_t | 符号無し短整数 | 2 バイト | 0 から 65535 |
uint32_t | 符号無し整数 | 4 バイト | 0 から 4294967295 |
uint64_t | 8 バイト | ||
int8_t | 符号付き文字 | 1 バイト | -128 から 127 |
int16_t | 符号付き短整数 | 2 バイト | -32768 から 32767 |
int32_t | 符号付き整数 | 4 バイト | -2147483648 から 2147483647 |
int64_t | 8 バイト | ||
float | 浮動小数点数 | 4 バイト | |
double | 倍精度浮動小数点数 | 8 バイト | |
Booloean | True/False 値 | 1 バイト | 0 または 1 |
DateTimeType | 日付時刻タイプ | 14 バイト | |
DateType | 絶対日付として表現される日付 | 2 バイト | |
TimeType | 2 バイト | ||
time_t | (dbDateTimeSecs)UNIX 時代からの秒数 | 4 バイト | -2147483648 から 2147483647 |
char | 固定長文字列 | m バイト、m は長さが 1 <= m <= 255 の静的に定義される長さ | 1 <= m <= 255、m は定義される最大長 |
VarChar | 可変長文字列 | n+4、n は実際の文字列長であり n <= m。m は定義される最大長であり 1 <= m <= 2^32 | 1 <= m <= 2^32、m は定義される最大長 |
BLOB | 可変長のバイトの配列 | n+4、n は実際の文字列長であり n <= m。m は定義される最大長であり 1 <= m <= 2^32 | 1 <= m <= 2^32、m は定義される最大長 |
ベクトル | Palm プリミティブ数、文字列、日付時刻タイプの可変長ベクトル。サポートされるベクトル タイプのリストは、以下の 表 8.3 を参照 | n+4、n はベクトルを保持するのに必要なバイト数 | 2^32 バイト |
ベクトル タイプ | 使用方法 |
---|---|
uint8_t ベクトル | uint8_t[] |
uint16_t ベクトル | uint16_t[] |
uint32_t ベクトル | uint32_t[] |
uint64_t ベクトル | uint64_t[] |
float ベクトル | float[] |
double ベクトル | double[] |
Boolean ベクトル | Boolean[] |
DateTimeType ベクトル | DateTimeType[] |
DateType ベクトル | DateType[] |
TimeType ベクトル | TimeType[] |
文字列ベクトル | ベクトルの終端となる追加の終端 null 文字を持つ null で終了する文字列。例えば、7 ビット ASCII を使用: "String1\0String2\0String3\0\0" |
- NOTE
- 文字列ベクトルの中で、null 文字は null バイトではなくエンコード依存の null 文字として解釈されなくてはなりません。null 文字はある特定のエンコードのスキーマではマルチ バイトであるかもしれません。
スキーマ データベースはそのデータベースの名前と作成者 ID の組み合わせによって一意に識別されます。
データベース テーブルは名前によって識別されます。数字の「テーブル識別子」である必要はありません。テーブル名は、終端 null 文字を含めて 32 バイトまでの有効な SQL 意識別子であるべきです。
列は列の記述的な名前または 32 ビットの ID のどちらか(どちらも固有でなければなりません)によって一意に識別されます。これらのアプリケーション-定義列名と ID は、与えられたアプリケーション コンテクスト内部の複数のアプリケーションが共通の与えられた列タイプの意味理解を共有することを可能にします。例えば、2 つのアプリケーションは "EMPLOYEE" データベースの従業員番号列として "EMNO" という名前を使用し、"EMNO" 列の中の値の列-ベース検索と取得を使用するかもしれません。設計時の列識別子とテーブル名の両方の指定はデータベースのための公開メタデータ インタフェースの開発を容易にし、これらのインタフェースをベースにした Generic データ交換を促進します。
あなたはデータベースの作成時とその後のどちらでもテーブルを作成することができます。各テーブル定義はテーブル名と列定義の配列を指定します。
あなたは、テーブルが行を持たないか、削除ビットがセットされた行だけを持つ場合にのみ、データベースからテーブルを削除することができます。テーブルが非削除行を保持している場合、まずそれらを削除します。テーブルが空になったら(削除されたというマークを付けられている行を保持することはできます)、あなたがデータベースからそのテーブルを削除することができます。
既存のテーブルに変更を加えるとき、列の追加とカスタム列プロパティへの変更は制限されます。
各テーブルは列定義を維持します。各列定義はテーブル内で固有の列 ID を持ちます。この ID はそれぞれの列を処理するのに必要ですが、スキーマを構成する完全な列定義のセットを取得するためには必要ではありません。
あなたが列定義のために定義するカスタム プロパティに加えて、すべての列はビルト-イン プロパティのセットを持ちます。これらのビルト-イン プロパティは Read-only であり、アプリケーションが他のデータ使用者に影響を与えるような方法で既存のデータ行の列に変更を加えるのを防ぎます。以下に示すのは列のビルト-イン プロパティです:
- 名前(固有でなければなりません)
- データ タイプ
- サイズ(可変長文字列、BLOB、ベクトルの最大バイト数)
- 属性
ビルト-イン プロパティとは異なりカスタム プロパティは読み込み、書き込み、削除されるかもしれません。カスタム プロパティ ID はビルト-イン プロパティ ID の範囲外でなければなりません。
与えられた列に対して、スキーマ同期マネージャはあなたがカスタム プロパティを定義することを可能にします(指定されたプロパティ ID が存在していない限り)。指定されたプロパティ ID が存在している場合、その値は新しい値に更新されます。さらに、あなたはカスタム プロパティまたはビルト-イン プロパティを取得することができますが、削除することができるのはカスタム プロパティだけです。あなたがカスタム列プロパティを削除した場合、プロパティだけが削除され、列の値は削除されません。
スキーマ データベース行は 表 8.4 でリストアップされている属性を持つことができます。
属性 | 説明 |
---|---|
Archive | 行のデータは次の HotSync まで保管されます。アーカイブ ビットがセットされるとき削除ビットもセットされるので、アーカイブされた行は削除された行のように扱われます。 |
Delete | その行は削除されています。 |
Read-only | その行は Read-only であり、書き込むことはできません。 |
Secret (private) | その行はプライベートです。 |
- NOTE
- ハンドヘルド上のデータ マネージャもスキーマ同期マネージャもどちらも Read-only の属性には何の意味も与えません。Read-only の属性に意味を施行するのはアプリケーションとコンジットに限定されています。
Read-only 属性は、ユーザがレコードを閲覧することを可能にするある特定のレコード共有シナリオをサポートするために使用されます。これはレコードを変更するためのものではありません。さらに、スキーマは Read-only の行の中で特定のフィールドが書き込み可能になることを可能にする「常に書き込み可能」列の定義を可能にします。これは、例えば、Read-only の TV 番組表のカレンダー イベントで使用されるかもしれません; アラーム情報を保持しているフィールドは、各ユーザがアラーム設定のオプションを使用できるようにするために、「常に書き込み可能」になります。
カテゴリは、レコードまたは行のグループ化またはフィルタリングするためのユーザ-制御手段です。非スキーマ データベースは、レコードが 15 のカテゴリまたは「非分類」のどれか 1 つだけのメンバになることを許可します。一方、スキーマ データベース行は最大 255 カテゴリの組み合わせのメンバ(または、そのどれでもない - 「未分類」と等価)になることができます。それゆえ、拡張データベースではあるレコードは「パーソナル」カテゴリか「ビジネス」カテゴリのどちらかに属さなければならないかもしれませんが、スキーマ データベースではある行は両方のカテゴリに属することができます。
非スキーマ データベースでは、カテゴリ情報はデータベースの中に置かれます。しかしながら、データベースのカテゴリに着いての情報をアプリケーション情報ブロックの中に保存する非スキーマ データベースとは異なり、スキーマ データベースはこの情報を保持するために内部的な「カテゴリ情報」ブロックを当てにします。
カテゴリの番号や名前といったデータベースのカテゴリについての情報は、UI リストの中でのカテゴリの順番と同様に、ハンドヘルド上のカテゴリ マネージャによって制御されます。データ マネージャは個別のデータベース行のカテゴリ メンバ属性を管理することだけに責任を持ちます。デスクトップ上の同期マネージャは、コンジットがこのカテゴリ情報にアクセスすることを可能にします。
ある行のカテゴリ メンバ属性はスキーマ データベースの中でローカルに定義され得るカテゴリの最大数に制限されます。データベースがサポートできるカテゴリの最大数は 255 までに制限されるため、すべての行が属することができるのは 255 カテゴリまでです。
非スキーマ データベースでは、レコードは常に 1 つのカテゴリの中にあります(「未分類」も 1 つの特別なカテゴリです)。スキーマ データベースでは、行は 1 つのカテゴリの中にあるかもしれませんし、複数のカテゴリの中にあるかもしれませんし、どのカテゴリの中にもないかもしれません。ここではカテゴリとしての「未分類」の概念は意味を持ちません。なぜなら、行は同時に「未分類」カテゴリと他のカテゴリの中に存在できるようにすべきではないからです。アプリケーションとコンジットはどのカテゴリにも属さない行に対して操作を実行することができるので、どのデータベース カテゴリのメンバでもない行は「未分類」であると考えることができます。ハンドヘルド上のカテゴリ マネージャはどのカテゴリにも属さない行がどのようにエンド ユーザに対して表示されるかを制御します。
データ マネージャはカテゴリ ローカル ID をレコードまたは行のためのカテゴリ メンバ属性情報として保存します。カテゴリ ローカル ID を保存することは、カテゴリの追加や削除といった内部カテゴリ構造に加えられる変更からデータ マネージャを抽象化します。
スキーマ同期マネージャは、コンジットがカテゴリや行のカテゴリ メンバ属性を以下のような方法で操作することを可能にします:
- 単一または複数の行のカテゴリ メンバ属性をセット、取得します。
- カテゴリ名を追加、削除、変更します。
- 行がメンバとなっているカテゴリの数を取得します。
- カテゴリから行を削除します。
- カテゴリの数、名前、ID を取得します。
さらに、スキーマ同期マネージャはコンジットに与えられたカテゴリ メンバ属性基準に一致する行を操作させます:
- カテゴリ メンバ属性が指定されたカテゴリ メンバ属性基準に一致するすべての行の数を取得します。
- カテゴリ メンバ属性が指定されたカテゴリ メンバ属性基準に一致するすべての行を削除します。
- すべての行のために指定されたカテゴリを含む 1 つまたはそれ以上のカテゴリを置き換えます。与えられる一致モード基準に依存します。(?原文: Remove category membership in the specified categories from all rows in the database, depending on the match mode criteria. )
- 行が指定されたカテゴリのメンバであるかどうかを決定します。与えられる一致モード基準に依存します。
- 指定されたカテゴリ メンバ属性基準に一致するカテゴリ メンバ属性を持つ変更されたすべての行のリストを取得します。
スキーマ データベースは専用のアプリケーション情報ブロックを持ちません。非スキーマ データベースのアプリケーション情報ブロックの中で見つかるタイプのアプリケーション-指定データに関しては、この目的のために明確にデータベース テーブルを作成してください。(訳者注: スキーマ データベースで非スキーマ データベースのアプリケーション情報ブロックの中で見つかるタイプのアプリケーション-指定データを使用する場合、明確にそのためのデータベース テーブルを作成してください。とすべきか?)
スキーマ データベース行 ^TOP^
「スキーマとテーブル」 で説明したように、スキーマ データベース テーブルは 0 またはそれ以上の行を持つことができ、テーブル内の各行は共通の構造体またはスキーマを共有します。
行はデータベース内で固有の 32 ビットの識別氏によって識別されます。あなたは行の読み込み時、書き込み時、削除時、変更時に行 ID を提供します。あなたがどのテーブルから来たのかわからない行 ID を持つという稀なケースでは、あなたはスキーマ同期マネージャ関数を呼び出してその行がどのテーブルに属するのか決定することができます。
スキーマ同期マネージャは、あなたが新しい行を作成してそれをテーブルに追加することを可能にします; あなたは行をテーブルに追加することなしにそれをテーブルにデータベースに追加することはできません。行がテーブルに成功裏に追加された場合、スキーマ同期マネージャはあなたの新しい行の行 ID を返します。オプションとして、あなたは何のデータも提供しないことによって「空」の行を追加することができます。
- NOTE
- 行 ID はハンドヘルド上のデータ マネージャによって新しい行に代入されます; コンジットは行 ID を代入または変更することはありません。唯一の例外は、ハンドヘルドがハード リセットされた後の HotSync 実施中に起こるレストア時です。
テーブルに追加される行はデータベースの最後に追加されます。あなたにはその行がテーブル内のどの位置になるかを指定する機会を与えられません。さらに、スキーマ同期マネージャ API もテーブル内の行の位置を変更する関数を持ちません。これは、アプリケーションがスキーマ データベースに対して処理を行うとき、それらのアプリケーションはしばしばカーソルのコンテクスト内部で処理を行っていて、そこでアプリケーションはそのような操作を行うことができるからです。スキーマ同期マネージャはコンジットにカーソルへのアクセス手段を提供しません。
ある行の中にある列は 32 ビットのアプリケーション-定義 ID によって識別されます。さらに、データ マネージャはインデックスによってもそれらの行を識別します。しかし、スキーマ同期マネージャは ID によってのみコンジットがそれらの行にアクセスすることを可能にします。
スキーマ同期マネージャは読み込み、書き込みを行うための手段を提供します:
- 列 ID、列値の開始点からオフセット、読み込むバイト数によって指定される部分列値。
- 列 ID によって指定される 1 つまたはそれ以上の完全な列値。
- レコード ID によって指定される列の中にあるすべての列値。
- 単一呼び出しの中の複数の行。
部分列値の読み込みと書き込みは、大きな文字列、BLOB - それらの列のデータの一部分だけを読み込み、書き込みすることは意味があります - に対して有用です。
ユーザがハンドヘルド上のスキーマ データベースの中のある行を「削除」したとき、その行のデータ チャンクは解放され(効率的にそのデータを破壊します)、その行エントリの中に保存されていたローカル ID は 0 にセットされ、削除ビットがその行の属性にセットされます。ユーザがある行を「アーカイブ」したとき、削除ビットがセットされますが、データ チャンクは解放されず、ローカル ID は保管されます。これにより、ユーザが次に HotSync を実行するとき、コンジットはすばやくどのレコードを削除するかを決定することができます(なぜなら、行エントリはまだハンドヘルド上に存在しているからです)。この場面での「削除」は、行のデータ チャンク - がもし存在していれば - と行エントリを処分することを意味します。アーカイブされた行の場合、行エントリとデータをハンドヘルドから永久的に削除する前に、コンジットは行データをデスクトップに保存することができます。削除された行に対しては、行エントリをハンドヘルドから永久的に削除する前に、コンジットは単に同じ行をデスクトップから削除するだけです。
スキーマ同期マネージャ API のテクノロジの使用方法を明らかにします:
- 削除 (Delete)
- 行の削除ビットをセットし、行のエントリはヘッダの中に残して、行のデータを処分します。通常、ハンドヘルド アプリケーションのみが行を削除しますが、コンジットも行を削除することができます。
- 削除 (Remove)
- 行のデータとヘッダの中のデータ エントリを処分します。これにより、その行への追跡は終了します。アプリケーションとコンジットのどちらかが行を削除するかもしれません。
- アーカイブ
- 行の削除ビットをセットし、行のデータとエントリはデータベース ヘッドの中に残します。ハンドヘルド アプリケーションのみが行をアーカイブします。これは、行データをハンドヘルドから削除する前に、コンジットが行データをデスクトップに転送する機会を与えます。
- 削除 (Purge)
- 「削除 (Remove)」と同じ意味ですが、削除ビットがセットされているすべての行を削除します。これは、通常、コンジットが、ハンドヘルド データベースを同期させた後に、ハンドヘルド データベースに対して行うことです。これの使用方法は、クラシック同期マネージャ API や拡張同期マネージャ APIで使用される用語とは異なる点があります。
ハンドヘルド アプリケーションはスキーマ データベースの中の行の順番の決定に責任を負います。アプリケーションはデフォルトのソート インデックスとスキーマ データベースの中のテーブルのための複数のソート インデックスを定義することができます。しかし、コンジットはテーブルに対して処理を行うときデフォルトのソート インデックスを指定することができるだけです。それゆえ、コンジットが複数の行を読み込むとき、それらの行はデータベースのデフォルトのソート インデックスによって指定される順番で取得されます。
セキュア データベース ^TOP^
あるアプリケーションはアクセスが制限されるセキュア データベースを作成する必要があります。データ マネージャは、アプリケーション-定義アクセス ルール - これは、ルール セット としても知られています - によって護られるセキュア スキーマ データベースの作成をサポートします。
セキュア データベースのためのアクセス ルールの作成と定義についての更なる情報は、Exploring Palm OS: Memory, Databases, and Files を参照してください。
データ マネージャはセキュア データベースへのアクセスをそのデータベースのアクセス ルールによって認証されたアプリケーションとユーザに制限します。HotSync 実施時に、ハンドヘルド上の HotSync クライアントはデータ マネージャ 関数を使って、デスクトップ上で実行されているコンジットのために、ハンドヘルド データベースにアクセスします。HotSync クライアントは、同期またはバックアップされる必要があるセキュア データベースにアクセスできなければなりません。
アプリケーションのセキュア データベースが同期可能であることを保証するために、データベース アクセス ルールを変更して HotSync クライアントが AzmLibSetBypass() 関数を使用する特別な「バイパス」アクセスができるようにしなければなりません(Exploring Palm OS: Security and Cryptography を参照してください)。HotSync クライアントがバイパス アクセスを与えられたとき、デスクトップ上のいずれかのコンジットがデータベースにアクセスできます(HotSync プロセスはコンジットごとのアクセス制限を行う手段を提供しません)。バイパス アクセスは必要とされる各アクションのために作成されなければなりません。あなたは HotSync クライアントに対して個々のアクションごとにバイパス アクセスを承諾することができるため、例えば、HotSync クライアントに Read アクセス権限を与えて、Write アクセスと削除アクセスの権限は与えないといったことができます。
HotSync クライアントがバイパス アクセスを与えられない場合、それはアプリケーションによって定義される標準アクセス ルールに支配されます。例えば、あるアプリケーションがそのアプリケーションのデータベースのためのアクセス ルールを署名された(signed)アプリケーションだけがアクセス(Read, Write, または削除)できるように定義した場合、HotSync クライアントはそのデータにアクセスするのに必要とされる適切な署名を持たないため HotSync 実施時にそのデータベースは同期不可になります。それゆえ、データベースの同期を可能にするためにアプリケーションは「バイパス」アクセスを HotSync クライアント - これは本質的に HotSync クライアントと適切な署名を受けたアプリケーションにアクセスを承諾します - に与えなければなりません(訳者注: 原文の構造から推測すると「これは本質的に〜」は「HotSync クライアント」を形容しているが、内容から推測すると「アプリケーション」を形容しているように思える)。
ハンドヘルド上の HotSync クライアントは信任されたデスクトップの概念を維持します。HotSync プロセスはセキュア データベースの同期またはバックアップを信任されたデスクトップにだけ許可します - ユーザがハンドヘルドにパスワード(トークン)をセットしていない限り。パスワードをセットしたユーザが最初にデスクトップと HotSync を実施するときはいつでも、ハンドヘルド上の HotSync クライアントはユーザにそのユーザが同期を行うデスクトップを信任するかどうかを示すよう促します。ユーザがそのデスクトップを信任しない場合、デスクトップ上のコンジットはセキュアでないデータベースにだけアクセスすることができます。HotSync 実施時に、コンジットは同期マネージャを呼び出してハンドヘルドがデスクトップを信任しているかどうか決定することができます。セキュア データベースにアクセスする必要のあるコンジットは信任状態を使ってセキュア データベースが使用できないときに何をするのかを決定することができます。
信任されたデスクトップについての更なる情報は、第 9 章 「信任されたデスクトップの理解」 を参照してください。
コンジット自身は、信任されたデスクトップでの HotSync 実施時であっても、セキュア データベースを作成することはできません。デスクトップでセキュア データベースを作成する同期マネージャ API はありません。セキュア データベースを作成できるのはハンドヘルド上のアプリケーションだけです。
しかしながら、コンジットはハンドヘルド上のアプリケーションを呼び出す C の SyncCallDeviceApplication() または COM の CallDeviceApplication()|COM Sync Suite Reference601/4 API を使用することによってこの制限の周囲で処理を行うことができます。このターゲット アプリケーションはセキュア データベースを作成して、それに適切なアクセス権限を割り当てることができます。ターゲット アプリケーションは、セキュア データベースにアクセスする前にそれ自身に適切な権限を割り当てているということを保証すべきです; さもなければ、HotSync 実施の途中でポップ アップを表示する UI が起動する可能があります(そのアプリケーションは HotSync 実施中に副起動され、同期バイパス ルールの恩恵を受けないからです(訳者: ?))。
この API を使用するとハンドヘルド上の HotSync クライアントはターゲット アプリケーションをローカルに副起動するため、明示的に渡されるアプリケーション コンテクストは HotSync クライアントもためのものの 1 つになります。さらに、HotSync クライアントは、ターゲット アプリケーションを副起動する前に、それ自身のセキュア データベースへのアクセス(バイパス ルール経由での)をすべてオフにします。(そうしないと、副起動されたアプリケーションは HotSync クライアントがアクセスできるすべてのセキュア データベースにアクセスできるため、セキュリティ違反になります。)それゆえ、このように副起動されるターゲット アプリケーションはセキュア データベースを作成し、HotSync 実施の外側からそのデータベースにアクセスするターゲット アプリケーションのために適切なセキュリティ権限をセットアップすることができます。しかし、そのアプリケーションはそれ自身が作成したセキュア データベースをオープンして読み込み/書き込みすることはできません。さらに、そのターゲット アプリケーションは、アプリケーション フィンガープリント(指紋)または署名-ベース トークンで前もってセキュリティをかけられている他のデータベースにアクセスすることもできません。あなたが副起動されるターゲット アプリケーションにセキュア データベースを作成させる - その後、コンジットは他のセキュア データベースと同様に同期マネージャ API を使ってそのデータベースに読み込み/書き込みできる - だけであれば、この制限は問題にならないかもしれません。しかし、副起動されるターゲット アプリケーションが HotSync 実施時にセキュア データベースを作成して、そのデータベースの中にデータを書き込む必要がある場合、以下のようにします:
- セキュア データベースを作成します。
- 一時的に読み込み/書き込み権限を(未訳、原文Temporarily assign read/write privileges to all or only to the sync application, whether it is the HotSync client or another sync application.)(ターゲット アプリケーションは同期アプリケーションのトークン フィンガープリントをハードコードする必要はありません。これは動的に発見され、セットされます。それゆえ、ターゲット アプリケーションは単一の同期ソリューションに限定されません。)
- 必要があればそのデータベースにデータを書き込みます。
- 永久的な権限を割り当てます - つまり、アプリケーションのフィンガープリントまたはそれのディジタル署名をベースにしたトークンを作成、セットします。
Palm OS Cobalt でのセキュリティについての更なる情報は、Exploring Palm OS: Security and Cryptography と Exploring Palm OS: Memory, Databases, and Files を参照してください。
セキュア データベースがデスクトップにバックアップされるとき、そのデータベースはデスクトップに暗号化された形で送られ、デスクトップに暗号化されて保存されます。バックアップ実施時に、データ マネージャはデータを暗号化し、それによりデータ マネージャだけがそれを復号化できるようにします。これは同期実施とは異なります; 同期時にデータがデスクトップに送られるとき、それは「クリアな形」で送られます - 暗号化されません。
デスクトップ同期マネージャは、コンジットがクラシック データベース - セキュア スキーマ データベースあるいは非セキュア スキーマ データベースの両方ともと同様に - をバックアップ、リストアするために使用することができる関数を提供します。しかし、ハンドヘルド データ マネージャだけがセキュア データベースを暗号化、復号化することができます。それゆえ、デスクトップ同期マネージャは、コンジットがセキュリティ データ - これはデータ マネージャがセキュア データベースをハンドヘルドにリストアした後にそれを複合化するのに必要です - をバックアップ、リストアするのに使用することができる関数を含みます。
同期マネージャはデスクトップにバックアップされたセキュア データベースだけをリストアすることができるということに注意してください。デスクトップ上でセキュア データベースを作成し、それをハンドヘルドにインストールするということはできません。ハンドヘルド上のデータ マネージャだけがセキュア データベースを作成することができます。
スキーマ データベースへの同時アクセス ^TOP^
2 タイプのスキーマ データベースへの同時アクセスを考慮します:
- 2 つの構成要素が 1 つのデータベースに同時にアクセスする。
- 1 つの構成要素が 2 対上のデータベースに同時にアクセスする。
あなたが Write アクセスで非スキーマ データベースをオープンしたとき、そのデータベースへのアクセスは排他的です: あなたがそれをオープンしている間、他の何ものもそのデータベースをオープンすることはできません - 例えもし、Read アクセスでそのデータベースをオープンしようとしたとしても。また、あなたが Read アクセスで非スキーマ データベースをオープンしたとき、他の何ものも同じデータベースを Write アクセスでオープンすることはできません。これは何らかの制約になり得ます: 例えば、通信型デバイスで電話が鳴ったときにあなたはアドレス帳のレコードを編集していたとすると、他のプロセスで実行されている電話アプリケーションはアドレス帳をオープンして電話してきた人の ID を探すことができません。
スキーマ データベースではこの問題は生じません。なぜなら、それらは単一のデータベースへの同時アクセスをサポートするからです。スキーマ データベースは同時 Write アクセスをサポートしないことに注意してください: ただ 1 つの書き込みと複数の読み込みが許可されます。
同じデータベースに同時にアクセスする構成要素の例は、マルチ スレッドで実行されて、複数のスレッドで同じデータベースをオープンする必要がある単一のコンジットと、コンジットのアクセスと同時に同じデータベースにアクセスするハンドヘルド上のプロセスです。それゆえ、データ マネージャはアプリケーションに対して施行する同時アクセス ルールと同じものをコンジットに対して施行します。
スキーマ データベースをオープンするとき、あなたはアクセス モード(またはオープン モード)に加えて共有モードを指定します。以下の共有モード定数がスキーマ データベースでサポートされます。あるデータベースをオープンするとき、ただ 1 つの共有モードだけを指定することができます。
- None
- 他の何ものもこのデータベースをオープンできない。
- Read
- 他のものはこのデータベースを Read アクセスでオープンできる。
- Read/Write
- 他のものはこのデータベースを Read アクセスまたは Write アクセスでオープンできる。
同じデータベースへの同時 Write アクセスはサポートされません。つまり、Read/Write アクセス モードと Read/Write 共有モードを指定することはサポートされません: あなたがアクセス モードと共有モードをこの組み合わせにしてデータベースをオープンしようとした場合、エラーが返されます。
表 8.5 は、アクセス モードと共有モードの組み合わせをすべて挙げて、どの組み合わせは一緒に使用することができるのか(使用できるものは Yes とマークを付けられています)を示しています。
Mode=R Share=None |
Mode=R Share=R |
Mode=R Share=R/W |
Mode=R/W Share=None |
Mode=R/W Share=R |
|
---|---|---|---|---|---|
Mode=R Share=None |
No | No | No | No | No |
Mode=R Share=R |
No | Yes | Yes | No | No |
Mode=R Share=R/W |
No | Yes | Yes | No | No |
Mode=R/W Share=None |
No | No | No | No | No |
Mode=R/W Share=R |
No | No | Yes | No | No |
共有が可能なとき(つまり、データベースが共有 Read モードまたは共有 Read/Write モードでオープンされているとき)、データ マネージャ サーバはそのデータベースへのアクセスを同期させます。同期はデータベース レベルで行われます。各データ マネージャ(と、それゆえ、同期マネージャ)呼び出しは基本命令であり、それゆえ、データ統合は関数レベルで提供されます。データ マネージャは複数のアプリケーションが同じデータベースに書き込みを行うことをサポートしないので、同時更新の問題を扱う必要はありません。
同時アクセスが許可されるので、あなたはどのようにデータベースをオープンするか気をつけて、他のプロセスが同じデータベースにアクセスするのを意図せずにブロックしてしまわないようにしなければなりません。例えば、電話アプリケーションは呼び出しに対して電話をかけてきた人の ID を調べるためにアドレス帳データベースにアクセスする必要があります。それと同時に、HotSync が進捗中であり、そこではあるコンジットが同じデータベースをデスクトップと同期させるために読み込み/書き込みする必要がある可能性があります。
あるプロセスが意図せずに同じデータベースにアクセスする他のプロセスを締め出してしまうのを防ぐために、あなたはデータベースをオープンしているときに以下のガイドラインに従うべきです:
- あなたがデータベースへの排他的なアクセスを必要とする場合にのみ、"Share None" モードを使用します: つまり、あなたが他のいずれかのアプリケーションがデータベースに Read-only モードでアクセスすることさえ望まない場合です。
- あなたが他のアプリケーションがデータベースに Read アクセスすることを許可できる場合、"Share Read" モードを使用します。例えば、あるコンジットがアドレス帳データベースを "Open Read/Write" モードと "Share Read" モードでオープンする必要があり、それによりそのコンジットがそのデータベースを読み込み/変更することができ、それと同時に電話アプリケーションのようなあるアプリケーションがアドレス帳データベースを "Open Read Only" モードと "Share Read/Write" モードでオープンして電話を掛けてきた人の情報を調べられるようにします。
- あなたが他のプロセス(PIM アプリケーションやコンジットを通して処理を行う HotSync クライアントなど)がデータベースに Read アクセスと Write アクセスの両方を行うことを許可する場合、"Share Read/Write" モードを使用します。この共有モードでは、あなたは "Open Read Only" モードを使用しなければなりません。
さらに、スキーマ同期マネージャは 1 つの構成要素が 2 つ以上のデータベースに同時にアクセスすることをサポートします。それゆえ、コンジットは複数のスキーマ データベースを同時にオープンすることができます。(同期マネージャは同時にただ 1 つだけの非スキーマ データベースをオープンできるという制限を強います。)けれども、あなたのコンジットはやはり、あなたのコンジットが完了する前に、すべてのオープンされているデータベースをクローズしなければなりません。
スキーマ データベースに対する追跡サービスの変更 ^TOP^
ハンドヘルド上のデータ マネージャは、非スキーマ データベースに対してよりも詳細に、スキーマ データベースでの変更を追跡します。主な重要機能は、あるコンジットがほぼ共通の同期シナリオでスキーマ データベースを複数のデスクトップと高速同期させることを可能にします。一方、非スキーマ データベースでは、ハンドヘルドが異なるデスクトップと同期する場合、コンジットは非スキーマ データベースを常に低速同期させます。
スキーマ データベースが作成されたとき、データ マネージャはそのデータベース ヘッダ内に 16 ビット同期クロック値を保存します。このデータベース同期クロックは、このデータベースが最後に同期をとられたのがいつなのかを示します。作成時に、データベースは 1 から始まる同期クロック値を持ちます。データベースが同期をとられるたびに、スキーマ同期マネージャは HotSync 実施の最後にそのデータベースの同期クロックを +1 します。しかし、そのコンジットがデータベースを特別な "synced all changed" (変更されたものをすべて同期させた)フラグでクローズする場合にのみです。
コンジットにより詳細な変更情報を提供するために、データ マネージャはいくつかの同期単位を定義します。これはスキーマ データベースの情報の単位であり、データ マネージャはこの単位である HotSync 実施と次の HotSync 実施の間の変更を追跡します。スキーマ データベースの以下の要素が同期単位です:
- テーブル スキーマ定義
- カテゴリ定義
- 行の中の列値(個別の列値ではありません)
- 行のカテゴリ メンバ属性
各同期単位に対して、データ マネージャは以下の変更情報を維持します:
- 変更カウンタ
- いずれかの同期単位が変更、追加、アーカイブ、削除されるとき、データ マネージャはこのカウンタを現在のデータベース同期クロック値で更新します。
- 削除(purge)カウンタ
- 削除された(deleted)すべての同期単位のインスタンスがデータベースから削除される(purge、処分/解放と同義)されるとき、データ マネージャはこのカウンタを現在のデータベース同期クロック値で更新します。このカウンタは最後の削除(purge)の相対時間を追跡し、データベース全体に適用します。デスクトップがあるデータベースを削除(purge)するとき、削除された(deleted)同期単位はハンドヘルドから完全に取り除かれます。日付が過ぎたデスクトップ(最後の HotSync 実施の後に削除(purge)が行われた)がハンドヘルドと同期するとき、それは ID のリストを比較することによって削除された(purged)同期単位を識別しなければなりません。
テーブル スキーマは同期不可属性がセットされている 1 つ以上の列を持つことができます。ある行が変更されるとき、それの変更カウンタは、その変更が「同期可能」列に対してのものである場合にのみ、更新されます。ある行で同期不可の列だけが変更された場合、スキーマ同期マネージャは、あなたが「変更された」行に対して処理を行ういずれかの API を使用したときに、その行が変更されているとは認識しません。しかしながら、スキーマ同期マネージャは同期不可列が明示的にデスクトップから読み込みを行われることは許可します。
各スキーマ データベースは同期で使用されるだけの擬似ランダム的に生成される識別子を持ちます。スキーマ同期マネージャは各スキーマ データベースに対して、それが作成される、またはハード リセット後にハンドヘルドにリストアされるとき、新しいデータベース リセット識別子(DRID)を生成します。DRID は、スキーマ同期マネージャが同期クロック値と変更カウンタはもはや信頼できないというシチュエーションを識別することを可能にします - そのような場合、HotSync マネージャはコンジットに高速同期を実行することはできないということを知らせます。例えば、ハンドヘルドがハード リセットされた後にデータベースがリストアされたとき、またはデータベースの同期クロック値がロール オーバ(ある時点の状態に戻されること)したときです。更なる情報は、「同期モードの決定」 を参照してください。
HotSync プロセスはこれらのデータ マネージャ サービスを使ってそれの API 経由でコンジットに情報 - コンジットが実行すべき同期モードと与えられたスキーマ データベースで各同期単位のどのインスタンスが最後の HotSync 実施の後に変更されたかについて - を返します。
これらのスキーマ データベースのための変更追跡サービスは、非スキーマ データベースとレコードで使用できる単純な "Dirty" フラグを超える、以下の利点を提供します:
- 変更カウンタは、変更が永遠に、ハンドヘルドがハード リセットされるまで、またはその変更カウンタが wrap する(訳者: 訳できない)まで追跡されることを可能にします。
- 削除された(deleted)同期単位は、それらが削除(purged)されるまで追跡されます。これは複数のデスクトップで高速同期を可能にします。
- 削除(purge)カウンタは削除(purges)を追跡し続け、それによりコンジットは低速同期であってもパフォーマンスを改善することができます。
- カテゴリはカテゴリ マネージャ(データ マネージャのための)によって管理され、変更カウンタを持ちます。変更カウンタは非スキーマ データベースでは提供されないカテゴリ名変更追跡を提供します。
- エンタープライズ(冒険的な)アプリケーションでは、列レベルでの変更追跡は特に有用です。なぜなら、それはコンジットがハンドヘルドとバックエンド サーバ上のデータベース間で変更された列値だけを同期させることを可能にするからです。
非スキーマ データベース ^TOP^
スキーマ データベースはテーブル、行、列を構成するデータに構造体を押し付けます。一方、非スキーマ データベースはオーバヘッドがより少なく、ずっとフレキシビリティがあります。もちろん、あなたのアプリケーションとコンジットは一般に非スキーマ データベースに対してはより多くの処理を行わなくてはなりません。なぜなら、それらは各レコードの構造の解釈する責任をすべて負うからです。
非スキーマ データベースはレコード データベースかリソース データベースになることができます。レコード データベースはアプリケーション データを保持します。各レコードは、アプリケーションが望むあらゆる形の構造体になることができます。リソース データベースは実行コード、アプリケーション リソースといったものを保持するために使用されます。
Palm OS Cobalt では、非スキーマ データベースは 2 つの「種類」に分けられます: クラシック データベースと拡張データベースです。クラシック データベースはより以前の Palm OS バージョン(それと、PACE を通じて Palm OS Cobalt を実行しているアプリケーション)との互換性のために提供されます。しかしながら、あなたのアプリケーションが 2、3 の長年にわたる制限から来るこのレベルの互換性を必要としないのならば、クラシック データベースの代わりに拡張データベースかスキーマ データベースを使用すべきです。クラシック データベースと拡張データベースは両方ともレコード データベースとリソース データベースのどちらにでもなることができます。
拡張データベースはクラシック データベースととてもよく似ています。表 8.6 はそれらの違いを示しています。
クラシック データベース | 拡張データベース |
---|---|
レコードのサイズは 64 KB よりも小さくなければならない | レコードのサイズは最大 4 GB にまでなることができます |
名前によって一意に識別されます | 名前と作成者 ID の組み合わせによって一意に識別されます |
データはビッグ エンディアン フォーマットで保存されるべきです | データはビッグ エンディアン フォーマットとリトル エンディアン フォーマットのどちらでも保存することができます |
※訳者: スキーマデータベース 対 非スキーマ データベース で、拡張データベースのレコードはほぼ 64 MB になることができると書かれているが、ここでは 4 GB と書かれている。その違いは?
例えもし 2 つの非スキーマ データベース タイプがとてもよく似ていたとしても、デスクトップ同期マネージャは 2 つの別々の API を提供して、それぞれがどちらか 1 つだけのデータベース タイプに対して処理を行います。
以下の小節では、非スキーマ データベースについてのもっと詳細を提供します:
- 非スキーマ データベースの構造
- レコード属性
- カテゴリ情報ブロックとアプリケーション情報ブロック
- 非スキーマ データベース レコードに対する処理
- レコード順番の維持
- 非スキーマ データベースへの同時アクセス
非スキーマ データベースの構造 ^TOP^
図 8.2 は非スキーマ データベースの構造を描いています。データベース ヘッダは、データベースを示し、アプリケーション情報ブロック、ソート情報ブロック、レコードへのポインタを保持する情報を保持します。矢印はデータまたはデータの配列へのポインタを表しています。ヘッダの中の各レコード エントリは、レコード ID、8 つの属性ビット、3 バイトのレコードのための固有の ID を持ちます。
非スキーマ データベースのヘッダは以下の情報を保持します:
- 名前
- データベースの null 出終了する名前。非スキーマ データベースの名前は、0x20 から 0x7E までの 7 ビット ASCII 文字だけで構成されなくてはなりません。名前は null 終端子を含めて 32 文字を超えることはできません。
- 作成者 ID
- アプリケーションまたはデータベースの作成者を一意に示す 4 バイト文字列。あなたは、あなたのアプリケーションが他のアプリケーションと衝突するのを防ぐために、あなたの作成者 ID を PalmSource に登録しなくてはなりません。値は大文字/小文字の区別があり、32 から 126(10 進数)までの ASCII で構成されます。すべてが小文字の値は PalmSource が使用するために予約されています。
- タイプ
- Palm OS が同じ作成者 ID を持つ複数のアプリケーションを区別するための 4 バイト文字列。タイプ値に求められる条件は作成者 ID と同じです。しかし、これらは固有ではないので、あなたはこれらを登録しません。ある特定のタイプは特別な意味を持ちます - 例えば、'appl' はアプリケーションを意味します。
- 属性
- データベースがレコードとリソースのどちらを保持しているのかといった特性を示すフラグ。これらは Read-only であり、変更された情報ブロックを持ち、バックアップされるべきであり、コピー-プロテクトされ、オープンされるなどします。詳細は、「レコード属性」 を参照してください。
- バージョン
- アプリケーション-指定バージョン番号。
- 作成日付
- データベースが作成された日付。
- 変更日付
- アプリケーションまたはコンジットのどちらかによってデータベースが最後に変更された日付。
- 最終バックアップ日付
- データベースが最後にバックアップされた日付。
- 変更番号
- データベースの中のレコードが削除、追加、変更されるたびに +1 される整数。
- 固有 ID の種
- このデータベースのためのレコード ID を生成するためにデータ マネージャによってのみ代入され、使用される値。
- アプリケーション情報
- アプリケーション情報ブロックへのポインタ。この値はオプションです。
- ソート情報
- ソート情報ブロックへのポインタ。この値はオプションです。
- レコード数
- データベース ヘッダの中に保存されているレコード エントリの数。削除されたというマークを付けられているものも含みます。同期マネージャ経由でコンジットに渡されるレコード数はデータベースの中の合計の数です。
- レコードのリスト
- 各レコード エントリはレコードの ID、属性ビット(レコード属性)、レコード データへのポインタを持ちます。レコード ID はデータベース内の各レコードに対して固有でなければなりません。レコードが何回変更されたかに関係なく、そのレコードのレコード ID は同じ値のままでいます。レコード ID は同期時にデスクトップ上に同じレコードがあるハンドヘルド上のレコードを追跡するために使用されます。
レコード属性 ^TOP^
非スキーマ データベース レコードは、表 8.7 でリストアップされている属性を持ちます。
属性 | 説明 |
---|---|
削除 | そのレコードは削除されました。そのレコードのレコード ID と属性だけが残っています。クラシック データベース レコードはアーカイブ ビットを持ちません。その代わり、同期マネージャは、削除ビットがセットされていて、かつ、ハンドヘルド上のレコード データがまだ存在している場合にセットされるアーカイブ属性を提供します。 |
Dirty | そのレコードは最後の HotSync 実施の後に変更されました。 |
Busy | そのレコードは読み込みまたは書き込みのためにハンドヘルドによってロックされています。 |
Secret | そのレコードはプライベートであり、ユーザが望む場合にのみ表示されるべきです。 |
カテゴリ インデックス | レコードが属するカテゴリ。これは 0 から 15 までのインデックスで、アプリケーション情報ブロックの中で定義されているカテゴリの 1 つを参照します。 |
カテゴリ情報ブロックとアプリケーション情報ブロック ^TOP^
カテゴリは単一のデータベースの中の関連するレコードのグループです。アプリケーションは通常、カテゴリを使ってエンド ユーザがレコードを組織化、フィルタリングすることを可能にします。非スキーマ データベースは、レコードが 15 のカテゴリのどれか 1 つだけ、または「未分類」カテゴリのメンバになることを許可します。
非スキーマ データベースでは、アプリケーション情報ブロックはアプリケーション-指定データとカテゴリ情報の両方を保持することができます。同期マネージャはアプリケーション情報ブロックを操作するための関数を提供します。それらの関数を使用しないのならば、他のいずれかの非スキーマ データベース レコードを読み書きするのと大体同じ方法でアプリケーション情報ブロックを読み書きします。
あなたが非スキーマ データベースを使用するアプリケーションの中でハンドヘルドのカテゴリ API を使用することを選択する場合、あなたは適切にデータベースをセットアップしなければなりません。Palm OS カテゴリ関数はアプリケーション情報ブロックのなかである特定のフォーマットの情報を見つけることを期待します。さらに、これらの関数はレコードの属性の中に各レコードが属するカテゴリを見つけることを期待します。同期マネージャはコンジットに同じカテゴリ情報へのアクセスを提供します。
非スキーマ データベース レコードに対する処理 ^TOP^
コンジットは、インデックスまたはデータベース内で固有であるレコード ID のどちらかによって非スキーマ データベース レコードにアクセスすることができます。
非スキーマ データベース レコードの構造はアプリケーション-指定であり、そのため同期マネージャはただの実体の無いデータ(訳者注: ただのバイトであり、型定義・意味づけされていないという意味)としてのレコードの読み込み、書き込みのための手段を提供します。インデックスまたはレコード ID による直接のレコードの読み込み、書き込みに加えて、あなたはすべてのレコード、あるカテゴリに属するすべてのレコード、変更されたレコードだけ、あるカテゴリに属する変更されたレコードだけを始めから終わりまで反復して処理することもできます。
ユーザがハンドヘルド上のレコードを「削除」したとき、レコードのデータ チャンクは解放され(効率的にデータを破壊します)、そのレコード エントリの中に保存されていたローカル ID は 0 にセットされ、削除ビットがその属性の中に送り込まれます。ユーザがレコードを「アーカイブ」したとき、削除ビットはセットされますが、チャンクは解放されず、ローカル ID も保管されています。これにより、ユーザが次に HotSync を実行するとき、コンジットはすばやくどのレコードを削除するのか決定することができます(なぜなら、それらのレコードのレコード エントリはまだハンドヘルド上に存在しているからです)。アーカイブされたレコードの場合、ハンドヘルドから永久的にレコード エントリとデータを削除する前に、コンジットはレコード データをデスクトップに保存することができます。削除されたレコードの場合、ハンドヘルドから永久的にレコード エントリを削除する前に、コンジットは単にデスクトップから同じレコードを削除するだけです。
同期マネージャは ID による 1 つのレコードを削除する手段、あるカテゴリに属するすべてのレコードを削除する手段、削除ビットがセットされているすべてのレコードを削除する手段、データベースの中にあるすべてのレコードを削除する手段を提供します。
レコード順番の維持 ^TOP^
ハンドヘルド アプリケーションは、スキーマ データベースと同様に、非スキーマ データベースの中にあるレコードの順番を決定する責任を負います。それゆえ、コンジットがインデックスでレコードを読み込むとき、レコードはアプリケーションがそれらを保存した順番で取得されます。コンジットが新しいレコードを作成したとき、同期マネージャはそれを最後のレコードの後ろに追加します。
非スキーマ データベースへの同時アクセス ^TOP^
2 タイプの非スキーマ データベースへの同時アクセスを考慮します:
- 2 つの構成要素が 1 つのデータベースに同時にアクセスする(サポートされません)。
- 1 つの構成要素が 2 つ以上のデータベースに同時にアクセスする
ハンドヘルド データ マネージャとデスクトップ同期マネージャは、2 つの構成要素が同時に 1 つの非スキーマ データベースにアクセスすることをサポートしません。あなたが非スキーマ Palm OS データベースを Write アクセスでオープンしたとき、あなたが持つそのデータベースへのアクセスは排他的です: あなたがそのデータベースをオープンしている間、他の何ものもそのデータベースをオープンすることはできません - 例えもし、それらが Read アクセスでそのデータベースをオープンしようとしても。また、あなたが非スキーマ データベースを Read アクセスでオープンした場合、他の何ものも同じデータベースを Write アクセスでオープンすることはできません。あなたがデータベースへのアクセスを共有できるようにする必要がある場合、あなたはスキーマ データベースを使用しなければなりません。「スキーマ データベースへの同時アクセス」 を参照してください。
C/C++ API 経由の同期マネージャは 1 つの構成要素が 2 つ以上のクラシック データベースに同時にアクセスすることをサポートしません。この API で、あなたは一時にただ 1 つのデータベースだけをオープンすることができます。あなたは他のデータベースをオープンする前にそのデータベースをクローズしなければなりません。
しかしながら、COM 同期モジュール - これはコンジットと C/C++ 同期マネージャ API 間のレイヤを提供します - は 1 つの構成要素が 2 つ以上のクラシック データベースに同時にアクセスすることをサポートします。COM 同期モジュールは必要に応じて同期マネージャ API 経由でデータベースを実際にオープン、クローズするので、コンジットを一時にただ 1 つの非スキーマ データベースだけをオープンさせることができるという制約から効果的に解放します。