I have a full mirror of my iphone (3g) filesystem, created using rsync+ssh from within my jailbroken phone. It is way cooler to backup over wifi than through a tethered cable; I had no other choice as the data connector died after 14 months. so I had no other option to make backups. I was able to charge from a wall adapter but not from any USB hosts. This crippled setup worked long enough for me to escape my AT&T contract.
Useful tidbits:
- contacts are stored in AddressBook.sqlitedb
- file is stored in /private/var/mobile/Library/AddressBook/AddressBook.sqlitedb
- There is a second, bare-schema database in /private/var/root/Library/AddressBook/
- The database is in sqlite3 format.
- Person entries are stored in ABPerson table
- Phone number/email/etc entries are stored in ABMultiValue table
The following snippet will copy the database to /tmp,open it in sqlite3 and export to contacts.csv.
# copy the db to /tmp, then open it
cp /private/var/mobile/Library/AddressBook/AddressBook.sqlitedb /tmp
cd /tmp
sqlite3 AddressBook.sqlitedb
sqlite> .mode csv
sqlite> .output contacts.csv
sqlite> select ROWID, first, last, identifier, value, record_id from ABPerson p join ABMultiValue mv on (ROWID=record_id)
sqlite > .quit
The file locations and names was surprisingly hard to find. On the bright side, I didn't need to decode any plist files.
There are some more interesting fields in ABPerson and ABMultiValue, feel free to update the select to grab more fields.
sqlite> .tables
ABGroup ABPersonMultiValueDeletes
ABGroupChanges ABPersonSearchKey
ABGroupMembers ABPhoneLastFour
ABMultiValue ABRecent
ABMultiValueEntry ABStore
ABMultiValueEntryKey FirstSortSectionCount
ABMultiValueLabel LastSortSectionCount
ABPerson _SqliteDatabaseProperties
ABPersonChanges
sqlite> .schema ABPerson
CREATE TABLE ABPerson (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, First TEXT, Last TEXT, Middle TEXT, FirstPhonetic TEXT, MiddlePhonetic TEXT, LastPhonetic TEXT, Organization TEXT, Department TEXT, Note TEXT, Kind INTEGER, 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 BLOB, FirstSortSection TEXT, LastSortSection TEXT, FirstSortLanguageIndex INTEGER DEFAULT 2147483647, LastSortLanguageIndex INTEGER DEFAULT 2147483647);
sqlite> .schema ABMultiValue
CREATE TABLE ABMultiValue (UID INTEGER PRIMARY KEY, record_id INTEGER, property INTEGER, identifier INTEGER, label INTEGER, value TEXT);
4 comments:
Thanks a lot and don't forget the ";" after the select statement.
A variant, showing labels (mobile/home/main etc.), removing the ID columns and sorting by first name and then last name is:
select p.first, p.last, lbl.value, mv.value from ABPerson p join ABMultiValue mv on (p.ROWID=mv.record_id) join ABMultiValueLabel lbl on (mv.label=lbl.ROWID) order by p.first, p.last;
awesome saved my butt
Is there a way to UNDELETE previously deleted records in the SQLite DB? My sister in law overwrote her contacts with 5 new records coming from the phone's SIM Card, and these new records went in with Record IDs that were in sequence above the number of contacts she previously had. This led me to believe that the old records may still be in the DB. Am I right? Is there a way to recover them?
Risco, I don't know for certain but I'd guess it unlikely that your sister-in-law's overwritten contacts are recoverable. The ID number is likely an auto incrementing field, so the old ID's won't get reused.
Post a Comment