iPhone Tips/AddressBookの解析/FW 3.1.2/テーブル構造
出典: Fukudat.com
基本構造はFW 2.0.2時点と変わっていない. 以下のテーブルが存在する.
| テーブル名 | 説明 |
|---|---|
| ABGroup | 不明.多分,連絡先のグループなのだろうが,iPhoneの連絡先アプリにはそのような機能がない. |
| ABGroupChanges | 不明.同上. |
| ABGroupMembers | 不明.同上. |
| ABMultiValue | 連絡先に複数の値をとることができる属性値 |
| ABMultiValueEntry | 上記のサブ属性値(住所で用いる) |
| ABMultiValueEntryKey | サブ属性のラベル.すなわち,Street, State, ZIP, City, CountryCodeが入る.その他の値は入らないと思われるが,初期状態はなぜか空. |
| ABMultiValueLabel | 属性のラベル.自宅, 勤務先, 携帯,iPhoneなど. |
| ABPerson | この1行が1連絡先となる.メインのテーブル. |
| ABPersonChanges | 変更された連絡先を記録する.多分syncのため. |
| ABPersonMultiValueDeletes | 削除された属性値を記録するために使われるのだと思われる. |
| ABPersonSearchKey | 連絡先アプリで使われる検索インデックス. |
| ABPhoneLastFour | 電話番号下4桁と連絡先エントリの対応付け.メールアプリや通話履歴が連絡先を参照するのに使用される. |
| ABRecent | 不明. |
| ABStore | 不明. |
| FirstSortSectionCount | 不明.見出しごとに含まれるエントリの数を数えている? |
| LastSortSectionCount | 不明.同上. |
| _SqliteDatabaseProperties | バージョン番号など |
1 ABMultiValue
FW 2.0.2から変更なし.
| カラム名 | データ型 | コメント |
|---|---|---|
| UID | integer | unique identifier (primary key) |
| record_id | integer | ABPerson の rowid |
| property | integer | 属性種別 (下の表を参照) |
| identifier | integer | 同じrecord_id, 同じpropertyをもつ属性値の中で0から番号が振られる. |
| label | integer | ABMultiValueLabelの行番号 |
| value | text | 値 |
propertyの値はDB中には定義されていない.iPhoneの連絡先アプリで試したところ,以下の値が出現した. ここにない値が何を意味するのかは不明.
| property | 説明 |
|---|---|
| 3 | 電話番号 |
| 4 | メールアドレス |
| 5 | 住所 (値は ABMultiValueEntryに格納される) |
| 12 | 日付 (値は iPhone時間) |
| 13 | メモ? |
| 16 | 着信音 ('itunes:' + 16進数16桁 (64bit)) |
| 22 | URL |
2 ABMultiValueEntry
FW 2.0.2から変更なし.
| カラム名 | データ型 | コメント |
|---|---|---|
| parent_id | integer | ABMultiValue (親属性)テーブルのUIDを参照している |
| key | integer | サブ属性種別 ABMultiValueEntryKeyを参照している |
| value | text | サブ属性の値 |
サブ属性の値と,サブ属性が所属する親属性の関係を格納するテーブル.
サブ属性を持つ属性はすなわち住所で,サブ属性とは国コード,郵便番号,都道府県,市区町村,町名番地のこと.
サブ属性の種類はABMultiValueEntryKeyに格納される.
3 ABMultiValueEntryKey
| カラム名 | データ型 | コメント |
|---|---|---|
| value | text | ABMultiValueEntryのkeyがあらわす属性の種類 |
サブ属性の種別を保持するテーブル.
格納される値は決まっているのだが,DBが初期化された状態では空で,最初の住所データが入力された時点で値が入る.アプリの中に埋め込む定数でもよいような気がするが,なぜか可変である.
4 ABMultiValueLabel
| カラム名 | データ型 | コメント |
|---|---|---|
| value | text | ABMultiValueのpropertyがあらわす属性のラベル |
(親)属性のラベルを保持するテーブル.
ABMultiValueEntryKeyと違って格納される値は決まっていないが,最初のデータが入力された時点で次の値が入力される: iPhone, _$!<Home>!$_, _$!<Work>!$_, _$!<Pager>!$_, _$!<HomePage>!$_, _$!<Anniversary>!$_.この_$!<XXX>!$_はアプリが自宅,勤務先...などに置き換えてくれる模様.
カスタムラベルを定義すると,そのラベルがこのテーブルに格納される.
5 ABPerson
| カラム名 | データ型 | コメント |
|---|---|---|
| ROWID | INTEGER | 行番号 primary key. |
| First | text | ファーストネーム |
| Last | text | ラストネーム |
| Middle | text | ミドルネーム |
| FirstPhonetic | text | ファーストネーム読み |
| MiddlePhonetic | text | ミドルネーム読み |
| LastPhonetic | text | ラストネーム読み |
| Organization | text | 会社 |
| Department | text | 部署 |
| Note | text | メモ |
| Kind | text | 不明 (種類?) |
| Birthday | text | 誕生日 |
| JobTitle | text | 役職 |
| NickName | text | ニックネーム |
| Prefix | text | プレフィックス |
| Suffix | text | サフィックス |
| FirstSort | text | ファーストネームでのソートするためのキー |
| LastSort | text | ファーストネームでソートするためのキー |
| CreationDate | integer | 作成日 |
| ModificationDate | integer | 更新日 |
| CompositeNameFallback | text | 不明 |
| ExternalIdentifier | text | 不明 |
| StoreID | integer | 不明 |
| DisplayName | text | 不明 |
| ExternalRepresentation | text | 不明 |
| FirstSortSection | text | ファーストネームでソートする場合の見出しキー |
| LastSortSection | text | ファーストネームでソートする場合の見出しキー |
| FirstSortLanguageIndex | integer | ファーストネームでソートする場合の見出しの文字種 |
| LastSortLanguageIndex | integer | ファーストネームでソートする場合の見出しの文字種 |
連絡先を格納するメインのテーブルである.
不明とあるカラムはiPhoneの連絡先アプリでは使用されないので,どのような意味があるのか判らない.
それ以外のカラムの大半は,概ね名前から判る自明な役割を持っているが,{First|Last}Sortは({First|Last}Phoneticに格納されている)名・姓の読みを特殊なエンコーディングによって変換した値が入る. このエンコード方法を解析するのには苦労した.以下に詳説する.
5.1 SortKeyのエンコーディング
FirstSort,LastSortは名前の読みを,以下の規則でエンコードしたバイナリを格納する.
- FirstSortは(1)FirstPhonetic,(2)LastPhonetic,(3)First, (4)Last, (5)Organizationの順でエンコードしたものを,0x02で区切ってつなげた値を保持する.未定義のフィールドはスキップする
- LastSortは(1)LastPhonetic,(2)FirstPhonetic,(3)Last, (4)First, (5)Organizationの順でエンコードしたものを,0x02で区切ってつなげた値を保持する.
それぞれのフィールドは以下の規則に従って1文字ずつエンコードされる.
- 空白文字の場合,(0x02)の1バイトに変換(0x02はフィールドのセパレータらしい).
- 数字の場合,(0x29), (0x7c+数値) の2バイトに変換.
- アルファベットの場合,大文字に変換した上で「ABC...XYZ」26文字中の順位をN (N=0..25) として,(0x2c+2N)の1バイトに変換.
- ひらがな・カタカナの場合,濁音・半濁音を取り除き,小文字(ぁぃぅぇぉっゃゅょ)は大文字に変換した後,「あいうえおかきくけこ...らりるれろわゐゑをん」50音中の順位をN (N=0..) として,(0xc2), (0xa3), (0x20+2N) の3バイトに変換.
- 漢字は...試してないので不明.
ABPersonSearchKeyもこれと酷似した(しかし微妙に異なる)エンコーディングを用いている.
6 ABPersonChanges
| カラム名 | データ型 | コメント |
|---|---|---|
| record | INTEGER | 不明 |
| type | INTEGER | 不明 |
| Image | INTEGER | 不明 |
| ExternalIdentifier | TEXT | 不明 |
| StoreID | INTEGER | 不明 |
未調査
7 ABPersonMultiValueDeletes
| カラム名 | データ型 | コメント |
|---|---|---|
| record_id | INTEGER | ABMultiValue.rowid |
| property_id | INTEGER | ABMultiValue.property |
| identifier | INTEGER | ABMultiValue.identifier |
未調査.多分,ABMultiValue から削除されたレコードを記録しているものと思われる.sync のためか.
8 ABPersonSearchKey
| カラム名 | データ型 | コメント |
|---|---|---|
| person_id | INTEGER | ABPerson.ROWID で連絡先を特定. |
| value | BLOB | 連絡先を検索するための検索キー |
valueカラムに格納される値は ABPerson.{First|Last}Sortカラムとよく似たエンコーディングで FirstPhonetic, LastPhonetic, First, Last, Organization を変換した結果(バイナリデータ)である. このエンコーディングは以下の通り.
8.1 SearchKeyのエンコーディング
ABPersonSeachKey.valueカラムには(1)FirstPhonetic,(2)LastPhonetic,(3)First, (4)Last, (5)Organizationを以下の規則でエンコードしたものを,0x02で区切ってつなげた値を保持する.未定義のフィールドはスキップする
- 空白文字の場合,(0x02)の1バイトに変換(0x02はフィールドのセパレータらしい).
- 数字の場合,(0x29), (0x7c+数値) の2バイトに変換.
- アルファベットの場合,大文字に変換した上で「ABC...XYZ」26文字中の順位をN (N=0..25) として,(0x2c+2N)の1バイトに変換.
- ひらがな・カタカナの場合,濁音・半濁音を取り除き,小文字(ぁぃぅぇぉっゃゅょ)は大文字に変換した後,「あいうえおかきくけこ...らりるれろわゐゑをん」50音中の順位をN (N=0..) として,(0xa3), (0x20+2N) の2バイトに変換.
- 漢字の場合,JISコードの区点コードをA区B点として,C=94A+Bを求める.
-
の時(つまり16区1点「亜」から16区11点「茜」までの11文字)は,
の1バイトに変換.
-
の時は,
+ 0xc604を求めて,その上位バイト,下位バイトの2バイトに変換する.
-
9 ABPhoneLastFour
| カラム名 | データ型 | コメント |
|---|---|---|
| multivalue_id | INTEGER | 電話番号を保持しているABMultiValueを参照するforeign key (primary keyでもある) |
| value | TEXT | 電話番号の下4桁 |
このテーブルに電話番号の下4桁を登録しておくと,通話履歴,SMS/MMS, 着信時に連絡先の名前を表示してくれる.
10 ABRecent
未調査
11 ABStore
未調査
12 FirstSortSectionCount
未調査
13 LastSortSectionCount
未調査
14 _SqliteDatabaseProperties
| カラム名 | データ型 | コメント |
|---|---|---|
| key | TEXT | 属性名 (primary key) |
| value | TEXT | 属性値 |
データベースが初期化された際に,次のような値が格納される.
| key | value | コメント |
|---|---|---|
| SortingcacheLanguage | ja | 日本語の場合 |
| SortingCacheICUVersion | 67108864 | ICUライブラリのバージョン? |
| SortingCacheVersion | 12 | キャッシュのバージョン? |
| _ClientVersion | 16 | クライアントのバージョン? |
| _UniqueIdentifier | 16進数 8桁-4桁-4桁-4桁-12桁 | 初期化されるたびに異なる値が生成される |
