ContactsDatabaseHelper.java revision 0f8f3b3e4a6ad18c5868d0215cc137845a2ddc74
1b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/* 2b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Copyright (C) 2009 The Android Open Source Project 3b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 4b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * you may not use this file except in compliance with the License. 6b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * You may obtain a copy of the License at 7b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 8b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 10b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * See the License for the specific language governing permissions and 14b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * limitations under the License 15b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 16b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts; 18b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport com.android.internal.content.SyncStateContentProviderHelper; 2067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 21619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.ContentValues; 22b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.content.Context; 23619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.ApplicationInfo; 24619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager; 25619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 26619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.database.Cursor; 27b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.DatabaseUtils; 28b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDatabase; 29b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDoneException; 30b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikovimport android.database.sqlite.SQLiteException; 31b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteOpenHelper; 32bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.database.sqlite.SQLiteQueryBuilder; 33b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteStatement; 34b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns; 35de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Aggregates; 36b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 37de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Contacts; 38de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 39ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 401f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkeyimport android.provider.ContactsContract.Presence; 411f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Email; 42ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 431f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.Im; 44bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 4567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities; 46bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils; 47b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log; 48b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 49b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap; 50b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 51b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/** 52b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Database open helper for contacts and social activity data. Designed as a 537e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana * singleton to make sure that all {@link android.content.ContentProvider} users get the same 54b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * reference. Provides handy methods for maintaining package and mime-type 55b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookup tables. 56b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 57b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/* package */ class OpenHelper extends SQLiteOpenHelper { 58b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String TAG = "OpenHelper"; 59b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 600f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov private static final int DATABASE_VERSION = 48; 61b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String DATABASE_NAME = "contacts2.db"; 621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final String DATABASE_PRESENCE = "presence_db"; 63b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 64b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface Tables { 657e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana public static final String ACCOUNTS = "accounts"; 66b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String AGGREGATES = "aggregates"; 67b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String CONTACTS = "contacts"; 68ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String PACKAGES = "packages"; 69ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPES = "mimetypes"; 70b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PHONE_LOOKUP = "phone_lookup"; 71a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP = "name_lookup"; 72b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; 73b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA = "data"; 74ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS = "groups"; 751f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String PRESENCE = "presence"; 76b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NICKNAME_LOOKUP = "nickname_lookup"; 77b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 781f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE = "aggregates " 79fb241add950ad1314dff339805cb9eb2d6136f96Jeff Sharkey + "LEFT OUTER JOIN presence ON (aggregates._id = presence.aggregate_id) " 80619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey + "LEFT OUTER JOIN data ON (primary_phone_id = data._id)"; 8100d71133c63c882fb41729ddc3a52f66fb155374Evan Millar 82ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_MIMETYPES = "data " 83ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id)"; 84b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 85bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPE_CONTACTS = "data " 8628f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 87bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id)"; 88bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 89ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_CONTACTS_GROUPS = "data " 90ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id)" 91ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID 92ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + ")"; 93ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 9467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String DATA_JOIN_PACKAGES_MIMETYPES_CONTACTS = "data " 9567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 9667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 9767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id)"; 9867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 9967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String DATA_JOIN_PACKAGES_MIMETYPES_CONTACTS_AGGREGATES = "data " 10067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 101ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 102619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) " 10367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)"; 1047e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 10567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES = "data " 106ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 107ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) " 108ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)"; 109ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 11067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String DATA_JOIN_PACKAGES_MIMETYPES_CONTACTS_AGGREGATES_GROUPS = "data " 11167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 1129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") " 1169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) " 1179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)"; 1189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 11967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String DATA_JOIN_PACKAGES_MIMETYPES_CONTACTS_GROUPS = "data " 12067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 121ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 122ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) " 1239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "; 126ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 127ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES = "groups " 128ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)"; 129ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 130ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES_DATA_CONTACTS_AGGREGATES = "groups " 131ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id) " 1329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN data " 1339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (groups._id = data." + GroupMembership.GROUP_ROW_ID + ") " 1349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) " 135619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)"; 136b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 137b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String ACTIVITIES = "activities"; 138b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 139ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String ACTIVITIES_JOIN_MIMETYPES = "activities " 140ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)"; 141b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 14267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_CONTACTS_AGGREGATES = "activities " 14367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) " 144ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) " 145619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey + "LEFT OUTER JOIN contacts ON (activities.author_contact_id = contacts._id) " 146619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)"; 1477e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 148a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP_JOIN_CONTACTS = "name_lookup " 149a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov + "INNER JOIN contacts ON (name_lookup.contact_id = contacts._id)"; 150b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 151127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS_JOIN_CONTACTS = "agg_exceptions " 152b86b7796abc1a980d7e87afd6c1f05fe0fabe4fdDmitri Plotnikov + "INNER JOIN contacts contacts1 " 153127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov + "ON (agg_exceptions.contact_id1 = contacts1._id) "; 154127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov 155b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS_JOIN_CONTACTS_TWICE = "agg_exceptions " 156d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov + "INNER JOIN contacts contacts1 " 157d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov + "ON (agg_exceptions.contact_id1 = contacts1._id) " 158d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov + "INNER JOIN contacts contacts2 " 159d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov + "ON (agg_exceptions.contact_id2 = contacts2._id) "; 160b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 161b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public interface Clauses { 163ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String WHERE_IM_MATCHES = MimetypesColumns.MIMETYPE + "=" + Im.MIMETYPE 1641f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey + " AND " + Im.PROTOCOL + "=? AND " + Im.DATA + "=?"; 1651f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 166ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String WHERE_EMAIL_MATCHES = MimetypesColumns.MIMETYPE + "=" 1671f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey + Email.MIMETYPE + " AND " + Email.DATA + "=?"; 168ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 169ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE 170ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "='" + GroupMembership.CONTENT_ITEM_TYPE + "'"; 171ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 172ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "=" 173ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupsColumns.CONCRETE_ID; 174ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 175ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String HAS_PRIMARY_PHONE = "(" 176ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID + " IS NOT NULL OR " 177ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID + " IS NOT NULL)"; 178ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 179ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // TODO: add in check against package_visible 180ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String IN_VISIBLE_GROUP = "SELECT MIN(COUNT(" + DataColumns.CONCRETE_ID 181ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "),1) FROM " + Tables.DATA_JOIN_CONTACTS_GROUPS + " WHERE " 182ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + DataColumns.MIMETYPE_ID + "=? AND " + Contacts.AGGREGATE_ID + "=" 183ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + AggregatesColumns.CONCRETE_ID + " AND " + Groups.GROUP_VISIBLE + "=1"; 1849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 1859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = 1869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.SOURCE_ID + "=? AND " 1879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + Groups.ACCOUNT_NAME + "=? AND " 1889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + Groups.ACCOUNT_TYPE + "=?"; 1899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 1901f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 1911f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 192619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface AggregatesColumns { 193619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static final String OPTIMAL_PRIMARY_PHONE_ID = "optimal_phone_id"; 19467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED = "optimal_phone_is_restricted"; 195619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static final String FALLBACK_PRIMARY_PHONE_ID = "fallback_phone_id"; 196619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 197619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static final String OPTIMAL_PRIMARY_EMAIL_ID = "optimal_email_id"; 19867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED = "optimal_email_is_restricted"; 199619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static final String FALLBACK_PRIMARY_EMAIL_ID = "fallback_email_id"; 200619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 20167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String SINGLE_IS_RESTRICTED = "single_is_restricted"; 202ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 203ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.AGGREGATES + "." + BaseColumns._ID; 20467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_DISPLAY_NAME = Tables.AGGREGATES + "." 20567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + Aggregates.DISPLAY_NAME; 20667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 20767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_TIMES_CONTACTED = Tables.AGGREGATES + "." 20867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + Aggregates.TIMES_CONTACTED; 20967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.AGGREGATES + "." 21067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + Aggregates.LAST_TIME_CONTACTED; 21167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_STARRED = Tables.AGGREGATES + "." + Aggregates.STARRED; 21267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_CUSTOM_RINGTONE = Tables.AGGREGATES + "." 21367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + Aggregates.CUSTOM_RINGTONE; 21467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.AGGREGATES + "." 21567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + Aggregates.SEND_TO_VOICEMAIL; 216619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 217619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 218619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface ContactsColumns { 219ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID; 2209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_NAME = 2219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Tables.CONTACTS + "." + Contacts.ACCOUNT_NAME; 2229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_TYPE = 2239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Tables.CONTACTS + "." + Contacts.ACCOUNT_TYPE; 2249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_SOURCE_ID = Tables.CONTACTS + "." + Contacts.SOURCE_ID; 2259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_VERSION = Tables.CONTACTS + "." + Contacts.VERSION; 2269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_DIRTY = Tables.CONTACTS + "." + Contacts.DIRTY; 2273cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov public static final String DISPLAY_NAME = "display_name"; 228619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 229619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 230619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface DataColumns { 23167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 232b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 233ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 234ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID; 235ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_CONTACT_ID = Tables.DATA + "." + Data.CONTACT_ID; 236ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_GROUP_ID = Tables.DATA + "." 237ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupMembership.GROUP_ROW_ID; 238e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 239e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1; 240e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2; 241e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3; 242e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4; 243e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5; 244e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6; 245e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7; 246e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8; 247e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9; 248e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10; 2490f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11; 2500f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12; 2510f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13; 2520f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14; 2530f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15; 254e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY; 255e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 256e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 2570f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov // Used only for legacy API support 2580f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface ExtensionsColumns { 2590f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String NAME = Data.DATA1; 2600f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String VALUE = Data.DATA2; 2610f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 2620f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 2630f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface GroupMembershipColumns { 2640f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONTACT_ID = Data.CONTACT_ID; 2650f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID; 2660f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 2670f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 268e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public interface PhoneColumns { 269e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String NORMALIZED_NUMBER = Data.DATA4; 270e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4; 271ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 272ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 273ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface GroupsColumns { 27467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 27567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 276ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID; 27767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID; 27867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey} 279b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 280b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface ActivitiesColumns { 281b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE_ID = "package_id"; 282b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 283b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 284b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 285b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface PhoneLookupColumns { 286b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 287b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA_ID = "data_id"; 288b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String CONTACT_ID = "contact_id"; 289b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String NORMALIZED_NUMBER = "normalized_number"; 290b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 291b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 292a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public interface NameLookupColumns { 293a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 294a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String CONTACT_ID = "contact_id"; 295a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NORMALIZED_NAME = "normalized_name"; 296a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_TYPE = "name_type"; 297a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 298a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 299a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public final static class NameLookupType { 300a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final int FULL_NAME = 0; 301a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final int FULL_NAME_CONCATENATED = 1; 302a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final int FULL_NAME_REVERSE = 2; 303a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final int FULL_NAME_REVERSE_CONCATENATED = 3; 304b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int FULL_NAME_WITH_NICKNAME = 4; 305b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int FULL_NAME_WITH_NICKNAME_REVERSE = 5; 306b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int GIVEN_NAME_ONLY = 6; 307b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int GIVEN_NAME_ONLY_AS_NICKNAME = 7; 308b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int FAMILY_NAME_ONLY = 8; 309b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int FAMILY_NAME_ONLY_AS_NICKNAME = 9; 310b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final int NICKNAME = 10; 311a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static final int EMAIL_BASED_NICKNAME = 11; 312a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 313a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov // This is the highest name lookup type code plus one 314a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static final int TYPE_COUNT = 12; 315a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov 316a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static boolean isBasedOnStructuredName(int nameLookupType) { 317a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov return nameLookupType != NameLookupType.EMAIL_BASED_NICKNAME 318a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov && nameLookupType != NameLookupType.NICKNAME; 319a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov } 320a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 321a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 322ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface PackagesColumns { 323b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 324b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE = "package"; 325b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 326b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 327ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface MimetypesColumns { 328b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 329b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE = "mimetype"; 330ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 331ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID; 332ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE; 333b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 334b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 335b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public interface AggregationExceptionColumns { 336b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 337127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov public static final String CONTACT_ID1 = "contact_id1"; 338127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov public static final String CONTACT_ID2 = "contact_id2"; 339b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 340b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 341b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public interface NicknameLookupColumns { 342b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NAME = "name"; 343b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String CLUSTER = "cluster"; 344b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 345b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 346b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private static final String[] NICKNAME_LOOKUP_COLUMNS = new String[] { 347b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER 348b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov }; 349b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 350b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private static final int COL_NICKNAME_LOOKUP_CLUSTER = 0; 351b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 352b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found mimetype mappings */ 353bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 354b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 355bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 356b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 357b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 358b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 359b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 360b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 3616bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov private SQLiteStatement mAggregateIdQuery; 362f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 36361bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov private SQLiteStatement mAggregateIdUpdate; 364b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 365b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 36661bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov private SQLiteStatement mNameLookupInsert; 367b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 368b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 369b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 370b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 371b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 37235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 373b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private HashMap<String, String[]> mNicknameClusterCache; 374b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 375ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** Compiled statements for updating {@link Aggregates#IN_VISIBLE_GROUP}. */ 376ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private SQLiteStatement mVisibleAllUpdate; 377ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private SQLiteStatement mVisibleSpecificUpdate; 378ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 379b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static OpenHelper sSingleton = null; 380b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 381b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static synchronized OpenHelper getInstance(Context context) { 382b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 383b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey sSingleton = new OpenHelper(context); 384b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 385b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 386b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 387b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 3881f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 38931b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 39035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 3911f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 39231b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov /* package */ OpenHelper(Context context) { 393b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey super(context, DATABASE_NAME, null, DATABASE_VERSION); 394b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Creating OpenHelper"); 395619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 396b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 39728b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 398b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 399b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 400b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 401b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 40235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.onDatabaseOpened(db); 40335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 404b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Create compiled statements for package and mimetype lookups 405ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM " 406ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 407ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM " 408ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?"); 4096bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov mAggregateIdQuery = db.compileStatement("SELECT " + Contacts.AGGREGATE_ID + " FROM " 4106bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov + Tables.CONTACTS + " WHERE " + Contacts._ID + "=?"); 41161bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov mAggregateIdUpdate = db.compileStatement("UPDATE " + Tables.CONTACTS + " SET " 41261bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov + Contacts.AGGREGATE_ID + "=?" + " WHERE " + Contacts._ID + "=?"); 413f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov mAggregationModeQuery = db.compileStatement("SELECT " + Contacts.AGGREGATION_MODE + " FROM " 414f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov + Tables.CONTACTS + " WHERE " + Contacts._ID + "=?"); 415ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "(" 416ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + MimetypesColumns.MIMETYPE + ") VALUES (?)"); 417ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "(" 418ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + PackagesColumns.PACKAGE + ") VALUES (?)"); 419ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 420ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM " 421ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 422ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE 423ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "." 424b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + Activities._ID + "=?"); 42561bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov mNameLookupInsert = db.compileStatement("INSERT INTO " + Tables.NAME_LOOKUP + "(" 42661bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov + NameLookupColumns.CONTACT_ID + "," + NameLookupColumns.NAME_TYPE + "," 42761bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ") VALUES (?,?,?)"); 4281f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 429ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final String visibleUpdate = "UPDATE " + Tables.AGGREGATES + " SET " 430ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Aggregates.IN_VISIBLE_GROUP + "= (" + Clauses.IN_VISIBLE_GROUP + ")"; 431ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 432ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleAllUpdate = db.compileStatement(visibleUpdate); 433ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate = db.compileStatement(visibleUpdate + " WHERE " 434ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + AggregatesColumns.CONCRETE_ID + "=?"); 435ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 4361f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey // Make sure we have an in-memory presence table 4371f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final String tableName = DATABASE_PRESENCE + "." + Tables.PRESENCE; 4381f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey final String indexName = DATABASE_PRESENCE + ".presenceIndex"; 4391f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 4401f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 4411f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + " ("+ 4421f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY," + 4431f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.AGGREGATE_ID + " INTEGER REFERENCES aggregates(_id)," + 4441f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.DATA_ID + " INTEGER REFERENCES data(_id)," + 4451f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.IM_PROTOCOL + " TEXT," + 4461f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.IM_HANDLE + " TEXT," + 4471f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.IM_ACCOUNT + " TEXT," + 4481f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.PRESENCE_STATUS + " INTEGER," + 4491f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey Presence.PRESENCE_CUSTOM_STATUS + " TEXT," + 4501f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey "UNIQUE(" + Presence.IM_PROTOCOL + ", " + Presence.IM_HANDLE + ", " + Presence.IM_ACCOUNT + ")" + 4511f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 4521f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 453fb241add950ad1314dff339805cb9eb2d6136f96Jeff Sharkey db.execSQL("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + Tables.PRESENCE + " (" 4541f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey + Presence.AGGREGATE_ID + ");"); 455b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 456b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 457b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 458b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 459b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 460b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 46135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 46235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 463b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 464b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.AGGREGATES + " (" + 465b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 466b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Aggregates.DISPLAY_NAME + " TEXT," + 467f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 468f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.CUSTOM_RINGTONE + " TEXT," + 469f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 470f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 471b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Aggregates.LAST_TIME_CONTACTED + " INTEGER," + 472f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.STARRED + " INTEGER NOT NULL DEFAULT 0," + 473f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Aggregates.IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 1," + 474619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," + 47567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey AggregatesColumns.OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED + " INTEGER DEFAULT 0," + 476619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," + 477619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," + 47867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED + " INTEGER DEFAULT 0," + 479619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," + 48067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey AggregatesColumns.SINGLE_IS_RESTRICTED + " INTEGER REFERENCES package(_id)" + 481b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 482b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 483b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 484b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 485b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Contacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 48667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Contacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 487035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Contacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 488035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Contacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 4897e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Contacts.SOURCE_ID + " TEXT," + 4907e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Contacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 4917e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Contacts.DIRTY + " INTEGER NOT NULL DEFAULT 1," + 492f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.AGGREGATE_ID + " INTEGER," + 493f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 494f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.AGGREGATION_MODE_DEFAULT + "," + 495f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 496f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 497f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 498f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 4993cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov Contacts.STARRED + " INTEGER INTEGER NOT NULL DEFAULT 0," + 5003cebbf7141252768d3e272e049e9c5b0cb9d710eDmitri Plotnikov ContactsColumns.DISPLAY_NAME + " TEXT" + 501b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 502b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 503b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 504ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 505ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 506ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 507b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 508b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 509ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 510ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 511ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 512ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 513b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 514b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 515b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 516b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 517b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 51867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 519b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 520b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data.CONTACT_ID + " INTEGER NOT NULL," + 521f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 522f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 523f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 524f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 525f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 526f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 527f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 528f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 529f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 530f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 531f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 532f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 53367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 53467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 53567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 53667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 53767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 53867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA15 + " TEXT" + 539b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 540b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 541f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana /** 542f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * set contact.dirty whenever the contact is updated and the new version does not explicity 543f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * clear the dirty flag 544f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * 545f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * Want to have a data row that has the server version of the contact. Then when I save 546f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * an entry from the server into the provider I will set the server version of the data 547f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * while also clearing the dirty flag of the contact. 548f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * 549f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana * increment the contact.version whenever the contact is updated 550f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana */ 551f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana db.execSQL("CREATE TRIGGER " + Tables.CONTACTS + "_updated1 " 552f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEFORE UPDATE ON " + Tables.CONTACTS 553f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEGIN " 554f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " UPDATE " + Tables.CONTACTS 555f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " SET " 556f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + Contacts.VERSION + "=OLD." + Contacts.VERSION + "+1, " 557f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + Contacts.DIRTY + "=1" 558f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";" 559f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " END"); 560f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 561f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana db.execSQL("CREATE TRIGGER " + Tables.CONTACTS + "_deleted " 562f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEFORE DELETE ON " + Tables.CONTACTS 563f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEGIN " 564f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " DELETE FROM " + Tables.DATA 565f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + Data.CONTACT_ID + "=OLD." + Contacts._ID + ";" 566f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " DELETE FROM " + Tables.PHONE_LOOKUP 567f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + PhoneLookupColumns.CONTACT_ID + "=OLD." + Contacts._ID + ";" 568f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " END"); 569f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 570f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 571f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEGIN " 572f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " UPDATE " + Tables.DATA 573f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 574f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 575f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " UPDATE " + Tables.CONTACTS 576f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " SET " + Contacts.DIRTY + "=1" 577f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";" 578f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " END"); 579f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 580f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 581f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " BEGIN " 582f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " UPDATE " + Tables.CONTACTS 583f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " SET " + Contacts.DIRTY + "=1" 584f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";" 585f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " DELETE FROM " + Tables.PHONE_LOOKUP 586f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 587f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana + " END"); 588f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana 589b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 590b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 591b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns._ID + " INTEGER PRIMARY KEY," + 592b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + " INTEGER REFERENCES data(_id) NOT NULL," + 593b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL," + 594b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL" + 595b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 596b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 597b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 598b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.NORMALIZED_NUMBER + " ASC, " + 599b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.CONTACT_ID + ", " + 600b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 601b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 602b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 603a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 604a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 605a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov NameLookupColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 606a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov NameLookupColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL," + 607619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey NameLookupColumns.NORMALIZED_NAME + " TEXT," + 608a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER" + 609a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 610a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 611a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 612a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " ASC, " + 613a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " ASC, " + 61461bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov NameLookupColumns.CONTACT_ID + 615a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 616a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 617b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 618b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 619b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 620b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 621b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 622b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 623b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 624b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 625b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 626b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 627ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 628ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 629ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 63067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 631035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 632035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 633ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 6349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 6359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.DIRTY + " INTEGER NOT NULL DEFAULT 1," + 636ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 63767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 6380f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 6390f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 640ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER" + 641ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 642ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 6439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 6449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " BEFORE UPDATE ON " + Tables.GROUPS 6459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " BEGIN " 6469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " UPDATE " + Tables.GROUPS 6479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " SET " 6489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + Groups.VERSION + "=OLD." + Groups.VERSION + "+1, " 6499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + Groups.DIRTY + "=1" 6509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 6519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " END"); 6529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 653b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 654b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 655b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 656127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID1 + " INTEGER REFERENCES contacts(_id), " + 657127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID2 + " INTEGER REFERENCES contacts(_id)" + 658b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 659b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 660b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 661b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 662127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID1 + ", " + 663127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID2 + 664b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 665b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 666b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 667b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 668127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID2 + ", " + 669127071b6305023a79b7d8f473ef6887843389f6eDmitri Plotnikov AggregationExceptionColumns.CONTACT_ID1 + 670b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 671b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 672b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 673b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 674b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 67567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 676b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 677b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 678499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 679b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 680b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 681b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 682499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 683b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 684b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 685adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 686b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 687b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 688b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 689b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov loadNicknameLookupTable(db); 690b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 691b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 692b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 693b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 6947e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 695b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + ", data will be lost!"); 696b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 6977e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACCOUNTS + ";"); 698b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATES + ";"); 699b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 700ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 701ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 702b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 703b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 704a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 705b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 706ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 707b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 708b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 709d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // TODO: we should not be dropping agg_exceptions and contact_options. In case that table's 710d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // schema changes, we should try to preserve the data, because it was entered by the user 711d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov // and has never been synched to the server. 712d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 713b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 714b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey onCreate(db); 71535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 716f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov // TODO: eventually when this supports upgrades we should do something like the following: 71735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana// if (!upgradeDatabase(db, oldVersion, newVersion)) { 71835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana// mSyncState.discardSyncData(db, null /* all accounts */); 71935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana// ContentResolver.requestSync(null /* all accounts */, 72035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana// mContentUri.getAuthority(), new Bundle()); 72135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana// } 722b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 723b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 724a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 725a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 726a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 727a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 728a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 729a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATES + ";"); 730a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 731a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 732a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 733a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 734ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 735b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 736a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 737b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 738b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 739b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 740a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("VACUUM;"); 741a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 742b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 743b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 744619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 745619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 746619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 747619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 748619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 749619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 750619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 751619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 752619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 753619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 754619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 755619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 756b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 757b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 758b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 759b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 760b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 761b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 762b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 763b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 764b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 765b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 766b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 767b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 768b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private synchronized long getCachedId(SQLiteStatement query, SQLiteStatement insert, 769b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 770b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 771b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 772b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 773b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 774b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 775b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey long id = -1; 776b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 777b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try searching database for mapping 778b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(query, 1, value); 779b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = query.simpleQueryForLong(); 780b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 781b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Nothing found, so try inserting new mapping 782b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(insert, 1, value); 783b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = insert.executeInsert(); 784b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 785b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 786b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (id != -1) { 787b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Cache and return the new answer 788b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey cache.put(value, id); 789b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return id; 790b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } else { 791b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Otherwise throw if no mapping found or created 792b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey throw new IllegalStateException("Couldn't find or create internal " 793b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + "lookup table entry for value " + value); 794b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 795b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 796b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 797b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 798ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 799b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 800b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 801b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 802b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 803b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 804b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 805b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 806b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 807b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 808ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 809b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 810b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 811b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 812b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 813b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 814b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 815b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 816b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 817b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 818ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 819b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 820b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 821b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 822b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 823b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 824b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 825b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 826b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 827b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 828b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 829b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 830b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 831b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 832b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 833b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 834b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 835b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 836b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 837b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 838b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 839b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 840b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 841b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 842b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 843b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 844b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 845b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 846b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 847b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 848b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 849b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 8506bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 8516bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 852ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Update {@link Aggregates#IN_VISIBLE_GROUP} for all aggregates. 853ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 854ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 855ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 856ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleAllUpdate.bindLong(1, groupMembershipMimetypeId); 857ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleAllUpdate.execute(); 858ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 859ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 860ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 861ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Update {@link Aggregates#IN_VISIBLE_GROUP} for a specific aggregate. 862ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 863ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAggregateVisible(long aggId) { 864ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 865ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.bindLong(1, groupMembershipMimetypeId); 866ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.bindLong(2, aggId); 867ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.execute(); 868ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 869ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 870ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 87161bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov * Updates the aggregate ID for the specified contact. 87261bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov */ 87361bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov public void setAggregateId(long contactId, long aggregateId) { 87461bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov getWritableDatabase(); 87561bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregateIdUpdate, 1, aggregateId); 87661bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregateIdUpdate, 2, contactId); 87761bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov mAggregateIdUpdate.execute(); 87861bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov } 87961bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 88061bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov /** 8816bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov * Returns aggregate ID for the given contact or zero if it is NULL. 8826bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 8836bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov public long getAggregateId(long contactId) { 8846bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov getReadableDatabase(); 8856bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 8866bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregateIdQuery, 1, contactId); 8876bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return mAggregateIdQuery.simpleQueryForLong(); 8886bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 8896bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov // No valid mapping found, so return -1 8906bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 8916bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 8926bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 89361bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 894f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public int getAggregationMode(long contactId) { 895f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov getReadableDatabase(); 896f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 897f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, contactId); 898f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 899f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 900f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov // No valid mapping found, so return "disabled" 901f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return Contacts.AGGREGATION_MODE_DISABLED; 902f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 903f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 904f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 90561bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov /** 90661bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 90761bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov */ 90861bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov public void insertNameLookup(long contactId, int lookupType, String name) { 90961bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov getWritableDatabase(); 91061bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 1, contactId); 91161bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 2, lookupType); 91261bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 3, name); 91361bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov mNameLookupInsert.executeInsert(); 91461bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov } 915619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 916bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov public static void buildPhoneLookupQuery(SQLiteQueryBuilder qb, final String number) { 917bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov final String normalizedNumber = PhoneNumberUtils.toCallerIDMinMatch(number); 918bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov final StringBuilder tables = new StringBuilder(); 919bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov tables.append("contacts, (SELECT data_id FROM phone_lookup " 920bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov + "WHERE (phone_lookup.normalized_number GLOB '"); 921bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov tables.append(normalizedNumber); 922ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey tables.append("*')) AS lookup, " + Tables.DATA_JOIN_MIMETYPES); 923bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov qb.setTables(tables.toString()); 924bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov qb.appendWhere("lookup.data_id=data._id AND data.contact_id=contacts._id AND "); 925bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov qb.appendWhere("PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", "); 926bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov qb.appendWhereEscapeString(number); 927bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov qb.appendWhere(")"); 928bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 929bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 930bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 931619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 932b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 933b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 934b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 93528f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 93628f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 937b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 938b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 939b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 940b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 941b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 942b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 943b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 944b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 945b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 946b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String[] names = strings[clusterId].split(","); 947b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov for (int j = 0; j < names.length; j++) { 948b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 949b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov try { 950b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 951b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 952b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String.valueOf(clusterId)); 953b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov nicknameLookupInsert.executeInsert(); 954b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } catch (SQLiteException e) { 955b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 956b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Print the exception and keep going - this is not a fatal error 957b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 958b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 959b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 960b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 961b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 962b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 963b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov /** 964b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Returns common nickname cluster IDs for a given name. For example, it 965b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * will return the same value for "Robert", "Bob" and "Rob". Some names belong to multiple 966b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * clusters, e.g. Leo could be Leonard or Leopold. 967b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * 968b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * May return null. 969b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * 970b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * @param normalizedName A normalized first name, see {@link NameNormalizer#normalize}. 971b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 972b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public String[] getCommonNicknameClusters(String normalizedName) { 973b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (mNicknameClusterCache == null) { 974b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mNicknameClusterCache = new HashMap<String, String[]>(); 975b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 976b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 977b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov synchronized (mNicknameClusterCache) { 978b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (mNicknameClusterCache.containsKey(normalizedName)) { 979b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return mNicknameClusterCache.get(normalizedName); 980b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 981b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 982b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 983b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String[] clusters = null; 984b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteDatabase db = getReadableDatabase(); 985b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 986b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov Cursor cursor = db.query(Tables.NICKNAME_LOOKUP, NICKNAME_LOOKUP_COLUMNS, 987b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + "=?", new String[] { normalizedName }, 988b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov null, null, null); 989b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov try { 990b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov int count = cursor.getCount(); 991b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (count > 0) { 992b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov clusters = new String[count]; 993b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov for (int i = 0; i < count; i++) { 994b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov cursor.moveToNext(); 995b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov clusters[i] = cursor.getString(COL_NICKNAME_LOOKUP_CLUSTER); 996b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 997b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 998b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } finally { 999b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov cursor.close(); 1000b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 1001b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 1002b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov synchronized (mNicknameClusterCache) { 1003b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mNicknameClusterCache.put(normalizedName, clusters); 1004b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 1005b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 1006b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return clusters; 1007b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 1008b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 1009f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 1010f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 1011f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 1012f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 1013f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1014f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1015f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 1016f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 1017f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 1018f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 1019f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 1020f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 1021f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 1022f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 1023f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 1024f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 1025f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 1026f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1027f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 1028f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = ((Number) value).longValue(); 1029f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1030f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 1031f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1032f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 1033f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 103435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 103535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 103635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 1037b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 1038