ContactsDatabaseHelper.java revision c085b3eeebf13ebdfb197444747354a1d6eced2b
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 2182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.content.ContentResolver; 22619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.ContentValues; 23b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.content.Context; 24619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.ApplicationInfo; 25619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager; 26619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 27d91272b48f97243533c6580981e12a4847b5783fJeff Hamiltonimport android.content.res.Resources; 2836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.database.Cursor; 29b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.DatabaseUtils; 30f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikovimport android.database.SQLException; 31b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDatabase; 32b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDoneException; 33b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikovimport android.database.sqlite.SQLiteException; 34b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteOpenHelper; 35bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.database.sqlite.SQLiteQueryBuilder; 36b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteStatement; 37fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikovimport android.net.Uri; 384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.os.Binder; 39a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.os.Bundle; 40c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamiltonimport android.os.SystemClock; 41b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns; 42a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.provider.ContactsContract; 43e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikovimport android.provider.CallLog.Calls; 44b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 45d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 46de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources; 485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle; 49ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 50d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 51eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings; 5282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates; 53b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 54ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 55b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 57bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 5967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities; 60bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils; 6136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.text.TextUtils; 62b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Token; 63b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Tokenizer; 64b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log; 65b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 66b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap; 675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale; 68b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 69b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/** 70b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Database helper for contacts. Designed as a singleton to make sure that all 71b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * {@link android.content.ContentProvider} users get the same reference. 72b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Provides handy methods for maintaining package and mime-type lookup tables. 73b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 74b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov/* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper { 75b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static final String TAG = "ContactsDatabaseHelper"; 76b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 777109133e650b0b1a69690bda620e64893c027d95Jeff Hamilton static final int DATABASE_VERSION = 309; 78e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 79b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String DATABASE_NAME = "contacts2.db"; 801f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final String DATABASE_PRESENCE = "presence_db"; 81b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 82b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface Tables { 83d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONTACTS = "contacts"; 845ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACTS = "raw_contacts"; 85ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String PACKAGES = "packages"; 86ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPES = "mimetypes"; 87b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PHONE_LOOKUP = "phone_lookup"; 88a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP = "name_lookup"; 89b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; 90eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey public static final String SETTINGS = "settings"; 91b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA = "data"; 92ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS = "groups"; 931f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String PRESENCE = "presence"; 94e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public static final String AGGREGATED_PRESENCE = "agg_presence"; 95b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NICKNAME_LOOKUP = "nickname_lookup"; 96e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov public static final String CALLS = "calls"; 97226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONTACT_ENTITIES = "contact_entities_view"; 98d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public static final String CONTACT_ENTITIES_RESTRICTED = "contact_entities_view_restricted"; 99a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String STATUS_UPDATES = "status_updates"; 100b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public static final String PROPERTIES = "properties"; 101743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov public static final String ACCOUNTS = "accounts"; 102b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 103ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_MIMETYPES = "data " 1041b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id)"; 105b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 10611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov public static final String DATA_JOIN_RAW_CONTACTS = "data " 1078e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 10811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 1095ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPE_RAW_CONTACTS = "data " 110c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 111c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 112bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 113e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 114e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS = "raw_contacts " 115e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN settings ON (" 116e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 117e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 118e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 119e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 120e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID 121e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + ")"; 122e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 123e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 124e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS = "settings " 125e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN raw_contacts ON (" 126e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 127e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 128e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 129e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 130e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 131e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 132d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data " 1331b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1341b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 135d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 136ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1375ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data " 1381b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1391b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 14067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 1419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "; 144ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 145ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES = "groups " 146ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)"; 147ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 148b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 149b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String ACTIVITIES = "activities"; 150b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 151ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String ACTIVITIES_JOIN_MIMETYPES = "activities " 152ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)"; 153b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 154d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS = 1555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov "activities " 15667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) " 157ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) " 1585ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " + 159fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "raw_contacts._id) " 160d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 1617e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1625ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup " 1635ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "INNER JOIN raw_contacts ON (name_lookup.raw_contact_id = raw_contacts._id)"; 164b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 165b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public interface Views { 1674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_ALL = "view_data"; 1684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_RESTRICTED = "view_data_restricted"; 1694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_ALL = "view_raw_contacts"; 1714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_RESTRICTED = "view_raw_contacts_restricted"; 1724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_ALL = "view_contacts"; 1744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_RESTRICTED = "view_contacts_restricted"; 17589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 17689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public static final String GROUPS_ALL = "view_groups"; 1774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 1784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1791f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public interface Clauses { 180e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE + "='" 181e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + GroupMembership.CONTENT_ITEM_TYPE + "'"; 182ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 183e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "=" 184ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupsColumns.CONCRETE_ID; 185ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 18668936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String HAVING_NO_GROUPS = "COUNT(" + DataColumns.CONCRETE_GROUP_ID + ") == 0"; 1879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 18868936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String GROUP_BY_ACCOUNT_CONTACT_ID = SettingsColumns.CONCRETE_ACCOUNT_NAME + "," 18968936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "," + RawContacts.CONTACT_ID; 190e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 191e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String RAW_CONTACT_IS_LOCAL = RawContactsColumns.CONCRETE_ACCOUNT_NAME 192e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + " IS NULL AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL"; 193e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 194e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String ZERO_GROUP_MEMBERSHIPS = "COUNT(" + GroupsColumns.CONCRETE_ID + ")=0"; 195e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 1961a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS = "outer_raw_contacts"; 1971a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS_ID = OUTER_RAW_CONTACTS + "." + RawContacts._ID; 1981a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey 199b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov final String CONTACT_IS_VISIBLE = 200b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "SELECT " + 2011a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey "MAX((SELECT (CASE WHEN " + 202b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "(CASE" + 203b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + RAW_CONTACT_IS_LOCAL + 204b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN 1 " + 205b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + ZERO_GROUP_MEMBERSHIPS + 206b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN " + Settings.UNGROUPED_VISIBLE + 207b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " ELSE MAX(" + Groups.GROUP_VISIBLE + ")" + 208b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "END)=1 THEN 1 ELSE 0 END)" + 209b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS + 2101a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + OUTER_RAW_CONTACTS_ID + "))" + 2111a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " FROM " + Tables.RAW_CONTACTS + " AS " + OUTER_RAW_CONTACTS + 212b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 213b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " GROUP BY " + RawContacts.CONTACT_ID; 214e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 215e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND " 216e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?"; 2171f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 2181f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 219d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public interface ContactsColumns { 2204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * This flag is set for a contact if it has only one constituent raw contact and 2224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * it is restricted. 2234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 22467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String SINGLE_IS_RESTRICTED = "single_is_restricted"; 225ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 226a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String LAST_STATUS_UPDATE_ID = "status_update_id"; 227a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 228d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID; 22967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 230d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "." 231d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED; 232d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "." 233d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.LAST_TIME_CONTACTED; 234d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED; 235d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "." 236d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.CUSTOM_RINGTONE; 237d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "." 238d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.SEND_TO_VOICEMAIL; 2392d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill public static final String CONCRETE_LOOKUP_KEY = Tables.CONTACTS + "." 2402d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill + Contacts.LOOKUP_KEY; 241619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 242619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2436cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov public interface RawContactsColumns { 24433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_ID = 2455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + BaseColumns._ID; 2469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_NAME = 2475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME; 2489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_TYPE = 2495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE; 25033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_SOURCE_ID = 2515ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID; 25233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_VERSION = 2535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.VERSION; 25433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DIRTY = 2555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DIRTY; 25633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DELETED = 2575ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DELETED; 2587a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC1 = 2597a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC1; 2607a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC2 = 2617a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC2; 2627a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC3 = 2637a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC3; 2647a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC4 = 2657a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC4; 266c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey public static final String CONCRETE_STARRED = 267c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.STARRED; 268bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey public static final String CONCRETE_IS_RESTRICTED = 269bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.IS_RESTRICTED; 2708e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 2715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME = RawContacts.DISPLAY_NAME_PRIMARY; 2725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME_SOURCE = RawContacts.DISPLAY_NAME_SOURCE; 2738e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov public static final String AGGREGATION_NEEDED = "aggregation_needed"; 274fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONTACT_IN_VISIBLE_GROUP = "contact_in_visible_group"; 275fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 276fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_DISPLAY_NAME = 277fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + DISPLAY_NAME; 278fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_CONTACT_ID = 279fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID; 280f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov public static final String CONCRETE_NAME_VERIFIED = 281f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED; 282619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 283619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 284619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface DataColumns { 28567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 286b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 287ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 288ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID; 289226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID; 290d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "." 291d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Data.RAW_CONTACT_ID; 292ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_GROUP_ID = Tables.DATA + "." 293ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupMembership.GROUP_ROW_ID; 294e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 295e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1; 296e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2; 297e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3; 298e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4; 299e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5; 300e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6; 301e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7; 302e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8; 303e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9; 304e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10; 3050f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11; 3060f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12; 3070f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13; 3080f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14; 3090f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15; 310e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY; 311226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID; 312e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 313e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 3140f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov // Used only for legacy API support 3150f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface ExtensionsColumns { 3160f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String NAME = Data.DATA1; 3170f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String VALUE = Data.DATA2; 3180f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3190f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 3200f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface GroupMembershipColumns { 3215ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID; 3220f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID; 3230f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3240f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 325e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public interface PhoneColumns { 326e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String NORMALIZED_NUMBER = Data.DATA4; 327e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4; 328ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 329ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 330ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface GroupsColumns { 33167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 33267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 333ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID; 33467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID; 335341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.GROUPS + "." + Groups.ACCOUNT_NAME; 336341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.GROUPS + "." + Groups.ACCOUNT_TYPE; 337341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey } 338b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 339b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface ActivitiesColumns { 340b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE_ID = "package_id"; 341b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 342b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 343b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 344b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface PhoneLookupColumns { 345b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 346b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA_ID = "data_id"; 3475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 348b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String NORMALIZED_NUMBER = "normalized_number"; 34936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public static final String MIN_MATCH = "min_match"; 350b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 351b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 352a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public interface NameLookupColumns { 3535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 35414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public static final String DATA_ID = "data_id"; 355a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NORMALIZED_NAME = "normalized_name"; 356a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_TYPE = "name_type"; 357a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 358a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 359a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public final static class NameLookupType { 3602a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_EXACT = 0; 3612a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_VARIANT = 1; 3622a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_COLLATION_KEY = 2; 3632a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NICKNAME = 3; 3642a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int EMAIL_BASED_NICKNAME = 4; 365a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka public static final int ORGANIZATION = 5; 3664cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao public static final int NAME_SHORTHAND = 6; 367f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee public static final int NAME_CONSONANTS = 7; 368a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 369a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov // This is the highest name lookup type code plus one 3705086b63bf3de5f26f495b640e85259c0ebf5ca47Dmitri Plotnikov public static final int TYPE_COUNT = 8; 371a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov 372a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static boolean isBasedOnStructuredName(int nameLookupType) { 3732a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov return nameLookupType == NameLookupType.NAME_EXACT 3742a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_VARIANT 3752a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_COLLATION_KEY; 376a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov } 377a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 378a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 379ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface PackagesColumns { 380b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 381b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE = "package"; 382226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 383226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID; 384b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 385b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 386ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface MimetypesColumns { 387b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 388b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE = "mimetype"; 389ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 390ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID; 391ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE; 392b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 393b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 394b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public interface AggregationExceptionColumns { 395b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 396b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 397b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 398b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public interface NicknameLookupColumns { 399b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NAME = "name"; 400b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String CLUSTER = "cluster"; 401b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 402b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 403e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public interface SettingsColumns { 404e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.SETTINGS + "." 405e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_NAME; 406e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.SETTINGS + "." 407e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_TYPE; 408e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 409e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 4104dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov public interface PresenceColumns { 4114dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov String RAW_CONTACT_ID = "presence_raw_contact_id"; 412bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4134dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 4144dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 415e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public interface AggregatedPresenceColumns { 416e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4173296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4183296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_CONTACT_ID = Tables.AGGREGATED_PRESENCE + "." + CONTACT_ID; 419e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 420e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 421a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public interface StatusUpdatesColumns { 422a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov String DATA_ID = "status_update_data_id"; 4233296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4243296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = Tables.STATUS_UPDATES + "." + DATA_ID; 4253296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4263296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = Tables.STATUS_UPDATES + "." + StatusUpdates.PRESENCE; 4273296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS; 4283296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = Tables.STATUS_UPDATES + "." 4293296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_TIMESTAMP; 4303296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = Tables.STATUS_UPDATES + "." 4313296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_RES_PACKAGE; 4323296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_LABEL; 4333296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_ICON; 4343296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey } 4353296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4363296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey public interface ContactsStatusUpdatesColumns { 4373296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String ALIAS = "contacts_" + Tables.STATUS_UPDATES; 4383296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4393296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = ALIAS + "." + StatusUpdatesColumns.DATA_ID; 4403296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4413296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = ALIAS + "." + StatusUpdates.PRESENCE; 4423296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = ALIAS + "." + StatusUpdates.STATUS; 4433296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = ALIAS + "." + StatusUpdates.STATUS_TIMESTAMP; 4443296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = ALIAS + "." + StatusUpdates.STATUS_RES_PACKAGE; 4453296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = ALIAS + "." + StatusUpdates.STATUS_LABEL; 4463296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = ALIAS + "." + StatusUpdates.STATUS_ICON; 447a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov } 448a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 449b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public interface PropertiesColumns { 450b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_KEY = "property_key"; 451b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_VALUE = "property_value"; 452b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 453b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 4543296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey /** In-memory cache of previously found MIME-type mappings */ 455bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 456b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 457bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 458b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 459b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 460b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 461b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 462b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 463d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private SQLiteStatement mContactIdQuery; 464f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 465b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 466b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 467b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 468b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 469b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 470b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 47135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 472f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov 473b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 474d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Compiled statements for updating {@link Contacts#IN_VISIBLE_GROUP}. */ 475ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private SQLiteStatement mVisibleSpecificUpdate; 476fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov private SQLiteStatement mVisibleUpdateRawContacts; 477fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov private SQLiteStatement mVisibleSpecificUpdateRawContacts; 478ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 479f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private boolean mReopenDatabase = false; 480f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 481b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static ContactsDatabaseHelper sSingleton = null; 482b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 48336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private boolean mUseStrictPhoneNumberComparison; 4843a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa 485d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton /** 486d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton * List of package names with access to {@link RawContacts#IS_RESTRICTED} data. 487d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton */ 488d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton private String[] mUnrestrictedPackages; 489d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton 490b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov public static synchronized ContactsDatabaseHelper getInstance(Context context) { 491b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 492b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov sSingleton = new ContactsDatabaseHelper(context); 493b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 494b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 495b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 496b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 4971f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 49831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 49935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 5001f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 501b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov ContactsDatabaseHelper(Context context) { 502b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey super(context, DATABASE_NAME, null, DATABASE_VERSION); 503b5a3163481794babda78716e576e35818de0cc03Dianne Hackborn if (false) Log.i(TAG, "Creating OpenHelper"); 504d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton Resources resources = context.getResources(); 505619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 506b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 50728b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 50836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov mUseStrictPhoneNumberComparison = 509d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton resources.getBoolean( 510d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton com.android.internal.R.bool.config_use_strict_phone_number_comparation); 5110f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov int resourceId = resources.getIdentifier("unrestricted_packages", "array", 5120f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov context.getPackageName()); 5130f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov if (resourceId != 0) { 5140f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = resources.getStringArray(resourceId); 5150f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } else { 5160f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = new String[0]; 5170f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } 518b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 519b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 520b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 521b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 52235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.onDatabaseOpened(db); 52335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 524b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Create compiled statements for package and mimetype lookups 525ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM " 526ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 527ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM " 528ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?"); 529d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mContactIdQuery = db.compileStatement("SELECT " + RawContacts.CONTACT_ID + " FROM " 5305ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 5316cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov mAggregationModeQuery = db.compileStatement("SELECT " + RawContacts.AGGREGATION_MODE 5325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 533ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "(" 534ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + MimetypesColumns.MIMETYPE + ") VALUES (?)"); 535ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "(" 536ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + PackagesColumns.PACKAGE + ") VALUES (?)"); 537ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 538ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM " 539ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 540ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE 541ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "." 542b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + Activities._ID + "=?"); 5431f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 5448be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Change visibility of a specific contact 5458be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleSpecificUpdate = db.compileStatement( 5468be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 5478be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " SET " + Contacts.IN_VISIBLE_GROUP + "=(" + Clauses.CONTACT_IS_VISIBLE + ")" + 5488be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + ContactsColumns.CONCRETE_ID + "=?"); 549ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 5508be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Return visibility of the aggregate contact joined with the raw contact 5518be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov String contactVisibility = 5528be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 5538be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " FROM " + Tables.CONTACTS + 5548be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID; 555ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 5568be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Set visibility of raw contacts to the visibility of corresponding aggregate contacts 5578be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleUpdateRawContacts = db.compileStatement( 558fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 559d6e233be3f6b822510db079d3f7a5f89ca11167cDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(CASE WHEN (" 560d6e233be3f6b822510db079d3f7a5f89ca11167cDmitri Plotnikov + contactVisibility + ")=1 THEN 1 ELSE 0 END)" + 5618be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + RawContacts.DELETED + "=0" + 5628be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " AND " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "!=(" 5638be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov + contactVisibility + ")=1"); 5648be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 5658be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Set visibility of a raw contact to the visibility of corresponding aggregate contact 5668be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleSpecificUpdateRawContacts = db.compileStatement( 5678be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 5688be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(" 5698be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov + contactVisibility + ")" + 5708be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + RawContacts.DELETED + "=0 AND " + RawContacts.CONTACT_ID + "=?"); 571fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 5721f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 573e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+ 57482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 57582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PROTOCOL + " INTEGER NOT NULL," + 57682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + 57782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_HANDLE + " TEXT," + 57882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_ACCOUNT + " TEXT," + 579a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 580a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 58182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE + " INTEGER," + 58282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL 58382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + 5841f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 5851f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 586e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON " 5874dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");"); 588e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 589e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " 590e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+ 591e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov AggregatedPresenceColumns.CONTACT_ID 592e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," + 59382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE_STATUS + " INTEGER" + 594e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov ");"); 595bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 596bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 597bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted" 598bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 599bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 600bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATED_PRESENCE 601bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " + 602bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.CONTACT_ID + 603bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 604bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.RAW_CONTACT_ID 605bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.RAW_CONTACT_ID + 606bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND NOT EXISTS" + 607bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.RAW_CONTACT_ID + 608bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 609bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 610bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.CONTACT_ID + 611bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND " + PresenceColumns.RAW_CONTACT_ID 612bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));" 613bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 614bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 615bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String replaceAggregatePresenceSql = 616bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 617bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + AggregatedPresenceColumns.CONTACT_ID + ", " 61882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + StatusUpdates.PRESENCE_STATUS + ")" + 619bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " SELECT " + PresenceColumns.CONTACT_ID + "," 62082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + "MAX(" + StatusUpdates.PRESENCE_STATUS + ")" + 621bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 622bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 623bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=NEW." + PresenceColumns.CONTACT_ID + ";"; 624bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 625bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted" 626bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 627bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 628bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 629bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 630bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 631bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated" 632bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 633bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 634bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 635bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 636b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 637b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 638b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 639b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 640b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 641b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 64235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 64335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 644b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 645d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 646b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 647fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 648d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 649d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 650d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 651d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 652d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 653d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 654cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 1," + 655f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + 6565870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + " TEXT," + 657a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + 6584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0" + 659b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 660b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 66154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 662fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 66354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 66454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 66554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" + 66654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov Contacts.HAS_PHONE_NUMBER + 66754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 66854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 66954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_restricted_index ON " + Tables.CONTACTS + " (" + 67054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + 67154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 67254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 673fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 674fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 675fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 676fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 677b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 6785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" + 6796cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 6806cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 6816cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 6826cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 6836cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID + " TEXT," + 6846cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 68573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 68633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + 68754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 6886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 6896cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DEFAULT + "," + 6908e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + 6916cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + " TEXT," + 6926cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 6936cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 6946cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED + " INTEGER," + 69533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 6965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + 6975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + 6985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + 69925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.UNDEFINED + "," + 7005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + " TEXT," + 7015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + " TEXT," + 702de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " + 703de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 704de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " + 705de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 706f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + 707fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 0," + 7083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC1 + " TEXT, " + 7093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC2 + " TEXT, " + 7103cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC3 + " TEXT, " + 7113cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC4 + " TEXT " + 712b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 713b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 71454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" + 71554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + 71654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 71754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 7185f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" + 7195f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.SOURCE_ID + ", " + 7205f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + ", " + 7215f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + 7225f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 7235f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 724f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // TODO readd the index and investigate a controlled use of it 725f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" + 726f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// RawContactsColumns.AGGREGATION_NEEDED + 727f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// ");"); 7288e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 729b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 730ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 731ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 732ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 733b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 734b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 735ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 736ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 737ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 738ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 739b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 740b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 74108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov // Mimetype table requires an index on mime type 74208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX mime_type ON " + Tables.MIMETYPES + " (" + 74308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov MimetypesColumns.MIMETYPE + 74408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov ");"); 74508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 746b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 747b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 748b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 74967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 750b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 75111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 752f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 753f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 754f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 755f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 756f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 757f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 758f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 759f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 760f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 761f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 762f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 763f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 76467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 76567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 76667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 76767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 76867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 7693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.DATA15 + " TEXT," + 7703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC1 + " TEXT, " + 7713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC2 + " TEXT, " + 7723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC3 + " TEXT, " + 7733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC4 + " TEXT " + 774b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 775b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 77611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" + 77711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + 77811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 77911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 78011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov /** 78111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov * For email lookup and similar queries. 78211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov */ 783f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" + 78411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov DataColumns.MIMETYPE_ID + "," + 785f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov Data.DATA1 + 78611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 78711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 788b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 789b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 790f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.DATA_ID 791f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES data(_id) NOT NULL," + 7925ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 7935ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 79436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 79536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 796b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 797b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 798b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 799f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 800f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 801b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 802b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 803b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 80436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 80536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 80636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 80736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 80836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 80936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 810a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 811a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 81214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.DATA_ID 81314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 8145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID 8155ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 81611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," + 81711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," + 81814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "PRIMARY KEY (" 81914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + NameLookupColumns.DATA_ID + ", " 82011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ", " 82111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + ")" + 822a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 823a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 82414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" + 82514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + 82614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov ");"); 82714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 828b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 829b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 830b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 831b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 832b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 833b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 834b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 835b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 836b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 837b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 838ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 839ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 840ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 84167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 842035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 843035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 844ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 8459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 84673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 847ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 84867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 8490f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 8500f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 85194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + 852eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 853ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + 8543cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC1 + " TEXT, " + 8553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC2 + " TEXT, " + 8563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC3 + " TEXT, " + 8573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC4 + " TEXT " + 858ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 859ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 8605f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" + 8615f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.SOURCE_ID + ", " + 8625f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_TYPE + ", " + 8635f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_NAME + 8645f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 8655f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 866b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 867b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 868b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 8690c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 8705ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id), " + 8710c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 8725ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id)" + 873b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank ");"); 874b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 875b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 876b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8770c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + ", " + 8780c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + 879b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 880b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 881b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 882b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8830c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + ", " + 8840c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + 885b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 886b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 887eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" + 888eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_NAME + " STRING NOT NULL," + 889eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_TYPE + " STRING NOT NULL," + 890eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 891eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1, " + 892eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey "PRIMARY KEY (" + Settings.ACCOUNT_NAME + ", " + 893e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey Settings.ACCOUNT_TYPE + ") ON CONFLICT REPLACE" + 894eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey ");"); 895eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 896e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // The table for recent calls is here so we can do table joins 897e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // on people, phones, and calls all in one place. 898e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CALLS + " (" + 899e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 900e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NUMBER + " TEXT," + 901e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DATE + " INTEGER," + 902e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DURATION + " INTEGER," + 903e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.TYPE + " INTEGER," + 904e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NEW + " INTEGER," + 905e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NAME + " TEXT," + 906e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_TYPE + " INTEGER," + 907e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_LABEL + " TEXT" + 908e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov ");"); 909e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov 910b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 911b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 912b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 91367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 914b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 915b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 916499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 9175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 9185ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 919b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 920499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 921b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 922b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 923adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 924b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 925b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 926b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 927a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" + 928a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 9290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS + " TEXT," + 9300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + 9310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + 9320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_LABEL + " INTEGER, " + 9330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_ICON + " INTEGER" + 934a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ");"); 935a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 936b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" + 937b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " + 938b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_VALUE + " TEXT " + 939b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 940b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 941743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" + 942743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " TEXT, " + 943743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " TEXT " + 944743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov ");"); 945743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 946743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // Allow contacts without any account to be created for now. Achieve that 947743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // by inserting a fake account with both type and name as NULL. 948743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // This "account" should be eliminated as soon as the first real writable account 949743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // is added to the phone. 950743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("INSERT INTO accounts VALUES(NULL, NULL)"); 951743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 952a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createContactsViews(db); 953a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createGroupsView(db); 95446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana createContactEntitiesView(db); 955fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov createContactsTriggers(db); 956916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 9574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 958a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov loadNicknameLookupTable(db); 959a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 960a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // Add the legacy API support views, etc 961a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov LegacyApiSupport.createDatabase(db); 962a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 963a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // This will create a sqlite_stat1 table that is used for query optimization 964a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("ANALYZE;"); 965a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 966a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateSqliteStats(db); 967a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 968a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // We need to close and reopen the database connection so that the stats are 969a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // taken into account. Make a note of it and do the actual reopening in the 970a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // getWritableDatabase method. 971a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov mReopenDatabase = true; 972a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 973a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContentResolver.requestSync(null /* all accounts */, 974a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContactsContract.AUTHORITY, new Bundle()); 975a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 976a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 977916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsTriggers(SQLiteDatabase db) { 978fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 979fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 980fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Automatically delete Data rows when a raw contact is deleted. 981fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 982fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;"); 983fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted " 984fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEFORE DELETE ON " + Tables.RAW_CONTACTS 985fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 986fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.DATA 987fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data.RAW_CONTACT_ID 988fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 989fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS 990fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 991fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID 992fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " OR " + AggregationExceptions.RAW_CONTACT_ID2 993fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 994fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.CONTACTS 995fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 996fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 997fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 998fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " )=1;" 999fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1000fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1001fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1002fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;"); 10036c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;"); 1004fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1005fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1006fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Triggers that update {@link RawContacts#VERSION} when the contact is 1007fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * marked for deletion or any time a data row is inserted, updated or 1008fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * deleted. 1009fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1010fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;"); 1011fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted " 10127f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.RAW_CONTACTS 1013fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1014fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1015fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1016fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 " 1017fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID 1018fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";" 1019fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1020fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1021fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;"); 10227f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 1023fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1024fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.DATA 1025fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 1026fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 1027fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1028fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1029fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1030fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1031fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1032fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;"); 1033fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 1034fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1035fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1036fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1037fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1038fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.PHONE_LOOKUP 1039fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1040fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.STATUS_UPDATES 1041fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";" 1042fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.NAME_LOOKUP 1043fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1044fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1045fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1046fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1047fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;"); 1048fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 10497f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.GROUPS 1050fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1051fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.GROUPS 1052fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1053fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + Groups.VERSION + "=OLD." + Groups.VERSION + "+1" 1054fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 1055fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1056fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1057fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1058916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsIndexes(SQLiteDatabase db) { 1059916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 1060916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 1061916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + "," + 1062916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NAME_TYPE + ", " + 1063916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + ", " + 1064916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.DATA_ID + 1065916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov ");"); 106604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 106704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index"); 106804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 106904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 107004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 107104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 107204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 107304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index"); 107404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 107504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 107604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 107704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 1078916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1079916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1080a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createContactsViews(SQLiteDatabase db) { 1081a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_ALL + ";"); 1082a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_RESTRICTED + ";"); 1083a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_ALL + ";"); 1084a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_RESTRICTED + ";"); 1085a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_ALL + ";"); 1086a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_RESTRICTED + ";"); 1087a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 10884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataColumns = 10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Data.IS_PRIMARY + ", " 10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.IS_SUPER_PRIMARY + ", " 10914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA_VERSION + ", " 10924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 10934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", " 10944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA1 + ", " 10954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA2 + ", " 10964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA3 + ", " 10974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA4 + ", " 10984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA5 + ", " 10994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA6 + ", " 11004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA7 + ", " 11014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA8 + ", " 11024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA9 + ", " 11034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA10 + ", " 11044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA11 + ", " 11054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA12 + ", " 11064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA13 + ", " 11074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA14 + ", " 11084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA15 + ", " 11094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC1 + ", " 11104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC2 + ", " 11114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC3 + ", " 11124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC4; 11134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String syncColumns = 11154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 11164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 11174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 1118f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 11194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 11204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 11214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," 11224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + "," 11234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + "," 11244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4; 11254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactOptionColumns = 11274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 11284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.CUSTOM_RINGTONE + "," 11294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 11304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.SEND_TO_VOICEMAIL + "," 11314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 11324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.LAST_TIME_CONTACTED + "," 11334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 11344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.TIMES_CONTACTED + "," 11354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 11364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.STARRED; 11374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String contactNameColumns = 11395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE 11405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", " 11415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY 11425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", " 11435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE 11445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", " 11455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME 11465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME + ", " 11475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE 11485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME_STYLE + ", " 11495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY 11505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_PRIMARY + ", " 11515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE 11525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_ALTERNATIVE + ", " 11535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP 11545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.IN_VISIBLE_GROUP; 11555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 11564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataSelect = "SELECT " 11574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Data._ID + "," 11584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.RAW_CONTACT_ID + ", " 1159fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 11604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns + ", " 11614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + dataColumns + ", " 11624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + contactOptionColumns + ", " 11635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 11645870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 11654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Contacts.PHOTO_ID + ", " 1166afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann + Contacts.NAME_RAW_CONTACT_ID + "," 1167a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID + ", " 11684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 11694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA 1170a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.MIMETYPES + " ON (" 11714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1172a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " ON (" 11734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1174a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1175fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1176fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1177fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1178a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1179a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 11804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 11814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1182f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1183a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 11844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_ALL + " AS " + dataSelect); 11864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_RESTRICTED + " AS " + dataSelect + " WHERE " 1187fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 11884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactOptionColumns = 11904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + "," 11914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.SEND_TO_VOICEMAIL + "," 11924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "," 11934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "," 11944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.STARRED; 11954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactsSelect = "SELECT " 11974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + "," 11984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 11994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.AGGREGATION_MODE + ", " 12004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.DELETED + ", " 12015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + ", " 12025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_PRIMARY + ", " 12035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_ALTERNATIVE + ", " 12045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME + ", " 12055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME_STYLE + ", " 12065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_PRIMARY + ", " 12075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_ALTERNATIVE + ", " 12084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + rawContactOptionColumns + ", " 12094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns 12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS; 12114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_ALL + " AS " + rawContactsSelect); 12134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_RESTRICTED + " AS " + rawContactsSelect 12144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 12154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsColumns = 12174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 12184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.CUSTOM_RINGTONE + ", " 12195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 1220f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + Contacts.HAS_PHONE_NUMBER + ", " 12215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 12225870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.PHOTO_ID + ", " 12234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 12244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED + ", " 12254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 12264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL + ", " 12274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 12284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.STARRED + ", " 12294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 1230a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + " AS " + Contacts.TIMES_CONTACTED + ", " 1231a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID; 12324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsSelect = "SELECT " 12344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + "," 1235f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + contactsColumns 12364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.CONTACTS 1237fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1238fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"; 12394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_ALL + " AS " + contactsSelect); 1241fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_RESTRICTED + " AS " + contactsSelect 1242fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " WHERE " + ContactsColumns.SINGLE_IS_RESTRICTED + "=0"); 1243a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 12444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1245a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createGroupsView(SQLiteDatabase db) { 1246a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS_ALL + ";"); 124789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsColumns = 124889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov Groups.ACCOUNT_NAME + "," 124989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.ACCOUNT_TYPE + "," 125089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SOURCE_ID + "," 125189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.VERSION + "," 125289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DIRTY + "," 125389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE + "," 125489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE_RES + "," 125589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.NOTES + "," 125689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYSTEM_ID + "," 125789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DELETED + "," 125889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.GROUP_VISIBLE + "," 125989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SHOULD_SYNC + "," 126089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC1 + "," 126189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC2 + "," 126289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC3 + "," 126389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC4 + "," 126489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE; 126589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 126689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsSelect = "SELECT " 126789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + "," 126889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + groupsColumns 126989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + " FROM " + Tables.GROUPS_JOIN_PACKAGES; 127089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 127189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.GROUPS_ALL + " AS " + groupsSelect); 1272b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1273b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 127446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana private static void createContactEntitiesView(SQLiteDatabase db) { 1275a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Tables.CONTACT_ENTITIES + ";"); 1276a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Tables.CONTACT_ENTITIES_RESTRICTED + ";"); 1277a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 127846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana String contactEntitiesSelect = "SELECT " 127946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 128046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 128146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 128246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 128346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 128446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1285f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 128646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 128746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContacts.CONTACT_ID + ", " 128846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + ", " 128946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + ", " 129046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + ", " 129146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4 + ", " 129246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.MIMETYPE + ", " 129346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA1 + ", " 129446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA2 + ", " 129546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA3 + ", " 129646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA4 + ", " 129746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA5 + ", " 129846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA6 + ", " 129946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA7 + ", " 130046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA8 + ", " 130146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA9 + ", " 130246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA10 + ", " 130346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA11 + ", " 130446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA12 + ", " 130546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA13 + ", " 130646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA14 + ", " 130746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA15 + ", " 130846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC1 + ", " 130946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC2 + ", " 131046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC3 + ", " 131146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC4 + ", " 131246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", " 131346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.IS_PRIMARY + ", " 131446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.IS_SUPER_PRIMARY + ", " 131546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA_VERSION + ", " 131646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + "," 131746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + "," 1318bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey + RawContactsColumns.CONCRETE_IS_RESTRICTED + " AS " 1319bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey + RawContacts.IS_RESTRICTED + "," 132046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 132146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " FROM " + Tables.RAW_CONTACTS 132246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 132346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 132446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 132546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 132646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 132746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 132846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 132946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 133046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + "' AND " + GroupsColumns.CONCRETE_ID + "=" 133146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 133246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 133346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("CREATE VIEW " + Tables.CONTACT_ENTITIES + " AS " 133446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + contactEntitiesSelect); 133546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("CREATE VIEW " + Tables.CONTACT_ENTITIES_RESTRICTED + " AS " 133646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + contactEntitiesSelect + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 133746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 133846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1339b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 1340b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 134146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion < 99) { 134246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 134346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + ", data will be lost!"); 134446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 134546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 134646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";"); 134746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 134846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 134946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 135046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 135146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 135246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 135346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 135446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 135546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";"); 135646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";"); 135746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";"); 135846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 135946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // TODO: we should not be dropping agg_exceptions and contact_options. In case that 136046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // table's schema changes, we should try to preserve the data, because it was entered 136146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // by the user and has never been synched to the server. 136246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 136346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 136446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana onCreate(db); 136546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana return; 136646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1367f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 136846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion); 1369a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 137008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov boolean upgradeViewsAndTriggers = false; 137104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov boolean upgradeNameLookup = false; 137208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 137346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion == 99) { 137408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 137546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana oldVersion++; 137646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 137746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1378a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov if (oldVersion == 100) { 1379a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON " 1380a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.MIMETYPES + " (" 1381a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns.MIMETYPE + "," 1382a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns._ID + ");"); 1383a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateIndexStats(db, Tables.MIMETYPES, 1384a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov "mimetypes_mimetype_index", "50 1 1"); 1385a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 138608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1387a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov oldVersion++; 1388a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1389a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1390fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov if (oldVersion == 101) { 139108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1392fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov oldVersion++; 1393fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1394fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 139547ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov if (oldVersion == 102) { 139608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 139747ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov oldVersion++; 139847ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov } 139947ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov 140036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (oldVersion == 103) { 140108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1402bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey oldVersion++; 1403bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey } 1404bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey 140571037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 104 || oldVersion == 201) { 140671037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov LegacyApiSupport.createSettingsTable(db); 140708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 14083410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion++; 14093410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov } 14103410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov 141171037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 105) { 14125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion202(db); 141304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov upgradeNameLookup = true; 14143410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion = 202; 141536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 141636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 1417fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov if (oldVersion == 202) { 14185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion203(db); 141908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1420fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov oldVersion++; 1421fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1422fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 14239b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori if (oldVersion == 203) { 142408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 14259b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori oldVersion++; 14269b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori } 14279b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori 14285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (oldVersion == 204) { 14295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion205(db); 143008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 14315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov oldVersion++; 14325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 14335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1434f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov if (oldVersion == 205) { 1435f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgrateToVersion206(db); 1436f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgradeViewsAndTriggers = true; 1437f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov oldVersion++; 1438f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1439f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 144031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (oldVersion == 206) { 1441b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeToVersion300(db); 144234469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov oldVersion = 300; 144331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 144431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 14456c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook if (oldVersion == 300) { 14466c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook upgradeViewsAndTriggers = true; 14476c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook oldVersion = 301; 14486c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook } 14496c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook 1450916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov if (oldVersion == 301) { 1451916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov upgradeViewsAndTriggers = true; 1452916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov oldVersion = 302; 1453916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1454916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1455b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (oldVersion == 302) { 1456b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeEmailToVersion303(db); 1457b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeNicknameToVersion303(db); 1458b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov oldVersion = 303; 1459b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1460b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 146108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (oldVersion == 303) { 146208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov upgradeToVersion304(db); 146308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov oldVersion = 304; 146408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 146508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 1466f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee if (oldVersion == 304) { 1467f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee upgradeNameLookup = true; 1468f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee oldVersion = 305; 1469f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee } 1470f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee 147160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (oldVersion == 305) { 147260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann upgradeToVersion306(db); 147360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann oldVersion = 306; 147460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 147560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 1476b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (oldVersion == 306) { 1477b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov upgradeToVersion307(db); 1478b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov oldVersion = 307; 1479b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 1480b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 1481743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov if (oldVersion == 307) { 1482743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov upgradeToVersion308(db); 1483743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov oldVersion = 308; 1484743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 1485743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 1486afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann if (oldVersion == 308) { 1487afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann upgradeViewsAndTriggers = true; 1488afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann oldVersion = 309; 1489afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann } 1490afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann 149108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov if (upgradeViewsAndTriggers) { 149208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsViews(db); 149308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createGroupsView(db); 149408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactEntitiesView(db); 149508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsTriggers(db); 1496916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 149708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov LegacyApiSupport.createViews(db); 1498916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov updateSqliteStats(db); 1499916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov mReopenDatabase = true; 150008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov } 150108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 150204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (upgradeNameLookup) { 150304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rebuildNameLookup(db); 150404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 150504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 150646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion != newVersion) { 150746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana throw new IllegalStateException( 150846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana "error upgrading the database to version " + newVersion); 150946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1510b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1511b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 15125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion202(SQLiteDatabase db) { 151336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL( 151436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "ALTER TABLE " + Tables.PHONE_LOOKUP + 151536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;"); 151636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 151736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 151836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 151936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 152036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 152136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 152236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 152336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 152436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 152536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 152636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov SQLiteStatement update = db.compileStatement( 152736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "UPDATE " + Tables.PHONE_LOOKUP + 152836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " SET " + PhoneLookupColumns.MIN_MATCH + "=?" + 152936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " WHERE " + PhoneLookupColumns.DATA_ID + "=?"); 153036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 153136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov // Populate the new column 153236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA + 153336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")", 153436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null); 153536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov try { 153636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov while (c.moveToNext()) { 153736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov long dataId = c.getLong(0); 153836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String number = c.getString(1); 153936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 154036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number)); 154136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindLong(2, dataId); 154236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.execute(); 154336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 154436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 154536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } finally { 154636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov c.close(); 154736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 154836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 154936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 15505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion203(SQLiteDatabase db) { 1551758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // Garbage-collect first. A bug in Eclair was sometimes leaving 1552758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // raw_contacts in the database that no longer had contacts associated 1553758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // with them. To avoid failures during this database upgrade, drop 1554758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // the orphaned raw_contacts. 1555758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov db.execSQL( 1556758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov "DELETE FROM raw_contacts" + 1557758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " WHERE contact_id NOT NULL" + 1558758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " AND contact_id NOT IN (SELECT _id FROM contacts)"); 1559758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov 1560fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1561fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.CONTACTS + 1562fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)"); 1563fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1564fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.RAW_CONTACTS + 1565fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP 1566fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " INTEGER NOT NULL DEFAULT 0"); 1567fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1568fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // For each Contact, find the RawContact that contributed the display name 1569fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1570fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1571fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1572fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1573fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1574fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1575fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" + 1576fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.CONTACTS + "." + Contacts.DISPLAY_NAME + 1577fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1578fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" 1579fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1580fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1581fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 1582fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 1583fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1584fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1585fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // If for some unknown reason we missed some names, let's make sure there are 1586fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // no contacts without a name, picking a raw contact "at random". 1587fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1588fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1589fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1590fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1591fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1592fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1593fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1594fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" + 1595fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL" 1596fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1597fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1598fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use. 1599fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1600fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1601fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.DISPLAY_NAME + "=NULL" 1602fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1603fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1604fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow 1605fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // indexing on (display_name, in_visible_group) 1606fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1607fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 1608fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(" + 1609fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 1610fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.CONTACTS + 1611bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" + 1612bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " NOT NULL" 1613fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1614fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1615fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 1616fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 1617fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" + 1618fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1619fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1620fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 1621fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 1622fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 1623fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1624fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1625fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 16265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion205(SQLiteDatabase db) { 16275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 16285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;"); 16295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 16305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;"); 16315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 16325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;"); 16335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1634de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_PRIMARY 1635de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 16365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1637de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE 1638de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 16395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov final Locale locale = Locale.getDefault(); 16415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 164251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov NameSplitter splitter = createNameSplitter(); 16435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate = db.compileStatement( 16455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 16465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 16475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 16485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 16495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 16505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 16515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 16525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 16535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 16545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter); 16565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter); 16575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 16595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 16605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 16615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 16625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 16635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 16655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 16665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 16675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 16685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface StructName205Query { 16715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 16725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 16745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 16755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 16765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE, 16775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY, 16785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PREFIX, 16795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.GIVEN_NAME, 16805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.MIDDLE_NAME, 16815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FAMILY_NAME, 16825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.SUFFIX, 16835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_FAMILY_NAME, 16845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_MIDDLE_NAME, 16855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_GIVEN_NAME, 16865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 16875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 16895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 16905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME_SOURCE = 2; 16915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME = 3; 16925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PREFIX = 4; 16935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int GIVEN_NAME = 5; 16945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int MIDDLE_NAME = 6; 16955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int FAMILY_NAME = 7; 16965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int SUFFIX = 8; 16975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_FAMILY_NAME = 9; 16985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_MIDDLE_NAME = 10; 16995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_GIVEN_NAME = 11; 17005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeStructuredNamesToVersion205(SQLiteDatabase db, 17035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 17045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // Process structured names to detect the style of the full name and phonetic name 17065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long mMimeType; 17085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 17095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mMimeType = DatabaseUtils.longForQuery(db, 17105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 17115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 17125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 17135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null); 17145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } catch (SQLiteDoneException e) { 17155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // No structured names in the database 17165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return; 17175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate = db.compileStatement( 17205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 17215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 17225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FULL_NAME_STYLE + "=?," + 17235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.DISPLAY_NAME + "=?," + 17245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_NAME_STYLE + "=?" + 17255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 17265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 17285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 17295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(StructName205Query.TABLE, 17305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructName205Query.COLUMNS, 17315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null); 17325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 17335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 17345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(StructName205Query.ID); 17355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID); 17365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE); 17375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = cursor.getString(StructName205Query.DISPLAY_NAME); 17385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.clear(); 17405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.prefix = cursor.getString(StructName205Query.PREFIX); 17415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME); 17425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME); 17435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.familyName = cursor.getString(StructName205Query.FAMILY_NAME); 17445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.suffix = cursor.getString(StructName205Query.SUFFIX); 17455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME); 17465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME); 17475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME); 17485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name, 17505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate, rawContactUpdate, splitter, sb); 17515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 17535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 17545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource, 17585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String currentDisplayName, NameSplitter.Name name, 17595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate, 17605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter, StringBuilder sb) { 17615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov splitter.guessNameStyle(name); 1763ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao int unadjustedFullNameStyle = name.fullNameStyle; 17645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle); 17655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = splitter.join(name, true); 17665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1767ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // Don't update database with the adjusted fullNameStyle as it is locale 1768ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // related 1769ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao structuredNameUpdate.bindLong(1, unadjustedFullNameStyle); 17705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName); 17715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(3, name.phoneticNameStyle); 17725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(4, dataId); 17735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.execute(); 17745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) { 17765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayNameAlternative = splitter.join(name, false); 17775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = splitter.joinPhoneticName(name); 17785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 17795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKeyAlternative = null; 17805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName != null) { 17825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = phoneticName; 1783ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao } else if (name.fullNameStyle == FullNameStyle.CHINESE || 1784ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao name.fullNameStyle == FullNameStyle.CJK) { 1785ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = sortKeyAlternative = ContactLocaleUtils.getIntance() 1786ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(displayName, name.fullNameStyle); 17875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 17905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = displayName; 17915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative = displayNameAlternative; 17925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, displayName, 17955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey, 17965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative); 17975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface Organization205Query { 18015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 18025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 18045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 18055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 18065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.COMPANY, 18075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME, 18085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 18095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 18115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 18125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int COMPANY = 2; 18135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_NAME = 3; 18145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeOrganizationsToVersion205(SQLiteDatabase db, 18175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 1818b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 18195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement organizationUpdate = db.compileStatement( 18215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 18225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 18235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME_STYLE + "=?" + 18245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 18255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS, 1827b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mimeType + " AND " 18285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION, 18295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov null, null, null, null); 18305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 18315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 18325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(Organization205Query.ID); 18335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID); 18345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String company = cursor.getString(Organization205Query.COMPANY); 18355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME); 18365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName); 18385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(1, phoneticNameStyle); 18405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(2, dataId); 18415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.execute(); 18425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 18445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName == null && company != null) { 18455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int nameStyle = splitter.guessFullNameStyle(company); 18465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov nameStyle = splitter.getAdjustedFullNameStyle(nameStyle); 1847ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao if (nameStyle == FullNameStyle.CHINESE || 1848ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao nameStyle == FullNameStyle.CJK ) { 1849ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = ContactLocaleUtils.getIntance() 1850ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(company, nameStyle); 18515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 18555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = company; 18565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, company, 18595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov company, phoneticNameStyle, phoneticName, sortKey, sortKey); 18605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 18625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 18635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId, 18675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName, String displayNameAlternative, int phoneticNameStyle, 18685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName, String sortKeyPrimary, String sortKeyAlternative) { 18695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 1, displayName); 18705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 2, displayNameAlternative); 18715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 3, phoneticName); 18725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(4, phoneticNameStyle); 18735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 5, sortKeyPrimary); 18745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 6, sortKeyAlternative); 18755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(7, rawContactId); 18765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.execute(); 18775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1879f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov private void upgrateToVersion206(SQLiteDatabase db) { 1880f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1881f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); 1882f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1883f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 188431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov private interface Organization300Query { 188531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String TABLE = Tables.DATA; 188631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 188731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String SELECTION = DataColumns.MIMETYPE_ID + "=?"; 188831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 188931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String COLUMNS[] = { 189031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization._ID, 189131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.RAW_CONTACT_ID, 189231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.COMPANY, 189331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.TITLE 189431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov }; 189531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 189631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int ID = 0; 189731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int RAW_CONTACT_ID = 1; 189831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int COMPANY = 2; 189931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int TITLE = 3; 190031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 190131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 190231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov /** 190331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * Fix for the bug where name lookup records for organizations would get removed by 190431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * unrelated updates of the data rows. 190531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov */ 1906b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeToVersion300(SQLiteDatabase db) { 1907b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 1908b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeType == -1) { 190931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov return; 191031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 191131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 191231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov ContentValues values = new ContentValues(); 191331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 191431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Find all data rows with the mime type "organization" 191531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Cursor cursor = db.query(Organization300Query.TABLE, Organization300Query.COLUMNS, 1916b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Organization300Query.SELECTION, new String[] {String.valueOf(mimeType)}, 191731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov null, null, null); 191831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov try { 191931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov while (cursor.moveToNext()) { 192031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long dataId = cursor.getLong(Organization300Query.ID); 192131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long rawContactId = cursor.getLong(Organization300Query.RAW_CONTACT_ID); 192231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String company = cursor.getString(Organization300Query.COMPANY); 192331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String title = cursor.getString(Organization300Query.TITLE); 192431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 192531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // First delete name lookup if there is any (chances are there won't be) 192631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.delete(Tables.NAME_LOOKUP, NameLookupColumns.DATA_ID + "=?", 192731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov new String[]{String.valueOf(dataId)}); 192831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 192931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Now insert two name lookup records: one for company name, one for title 193031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 193131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 193231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.ORGANIZATION); 193331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 193431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(company)) { 193531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 193631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(company)); 193731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 193831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 193931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 194031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(title)) { 194131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 194231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(title)); 194331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 194431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 194531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 194631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } finally { 194731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov cursor.close(); 194831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 194931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 195031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 1951b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final class Upgrade303Query { 1952b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String TABLE = Tables.DATA; 1953b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1954b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String SELECTION = 1955b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=?" + 1956b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data._ID + " NOT IN " + 1957b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" + 1958b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data.DATA1 + " NOT NULL"; 1959b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1960b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String COLUMNS[] = { 1961b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data._ID, 1962b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.RAW_CONTACT_ID, 1963b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.DATA1, 1964b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov }; 1965b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1966b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int ID = 0; 1967b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 1968b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int DATA1 = 2; 1969b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1970b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1971b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 1972b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 1973b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * emails during the sync. We need to restore the lost name lookup rows. 1974b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 1975b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeEmailToVersion303(SQLiteDatabase db) { 1976b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 1977b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 1978b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 1979b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1980b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1981b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 1982b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1983b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "email" that are missing name lookup 1984b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 1985b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 1986b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 1987b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 1988b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 1989b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 1990b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 1991b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 1992b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov value = extractHandleFromEmailAddress(value); 1993b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1994b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (value != null) { 1995b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 1996b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 1997b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME); 1998b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 1999b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2000b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2001b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2002b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2003b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2004b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2005b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2006b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2007b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2008b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2009b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * nicknames during the sync. We need to restore the lost name lookup rows. 2010b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2011b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeNicknameToVersion303(SQLiteDatabase db) { 2012b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 2013b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2014b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2015b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2016b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2017b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2018b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2019b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "nickname" that are missing name lookup 2020b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2021b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2022b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2023b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2024b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2025b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2026b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2027b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2028b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2029b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2030b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2031b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME); 2032b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2033b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2034b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2035b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2036b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2037b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2038b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2039b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 204051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void upgradeToVersion304(SQLiteDatabase db) { 204151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Mimetype table requires an index on mime type 204251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS mime_type ON " + Tables.MIMETYPES + " (" + 204351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov MimetypesColumns.MIMETYPE + 204451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov ");"); 204551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 204651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 204760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann private void upgradeToVersion306(SQLiteDatabase db) { 204860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // Fix invalid lookup that was used for Exchange contacts (it was not escaped) 204960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // It happened when a new contact was created AND synchronized 205060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final StringBuilder lookupKeyBuilder = new StringBuilder(); 205160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final SQLiteStatement updateStatement = db.compileStatement( 205260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "UPDATE contacts " + 205360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SET lookup=? " + 205460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE _id=?"); 205560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor contactIdCursor = db.rawQuery( 205660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT DISTINCT contact_id " + 205760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 205860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE deleted=0 AND account_type='com.android.exchange'", 205960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann null); 206060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 206160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (contactIdCursor.moveToNext()) { 206260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final long contactId = contactIdCursor.getLong(0); 206360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann lookupKeyBuilder.setLength(0); 206460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor c = db.rawQuery( 206560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT account_type, account_name, _id, sourceid, display_name " + 206660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 206760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE contact_id=? " + 206860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "ORDER BY _id", 206960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann new String[] { String.valueOf(contactId) }); 207060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 207160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (c.moveToNext()) { 207260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann ContactLookupKey.appendToLookupKey(lookupKeyBuilder, 207360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(0), 207460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(1), 207560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getLong(2), 207660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(3), 207760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(4)); 207860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 207960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 208060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.close(); 208160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 208260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 208360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (lookupKeyBuilder.length() == 0) { 208460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindNull(1); 208560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } else { 208660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindString(1, Uri.encode(lookupKeyBuilder.toString())); 208760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 208860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindLong(2, contactId); 208960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 209060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.execute(); 209160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 209260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 209360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.close(); 209460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann contactIdCursor.close(); 209560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 209660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 209760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 2098b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov private void upgradeToVersion307(SQLiteDatabase db) { 2099b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE properties (" + 2100b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_key TEXT PRIMARY_KEY, " + 2101b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_value TEXT" + 2102b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 2103b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2104b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2105743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov private void upgradeToVersion308(SQLiteDatabase db) { 2106743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("CREATE TABLE accounts (" + 2107743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov "account_name TEXT, " + 2108743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov "account_type TEXT " + 2109743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov ");"); 2110743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 2111743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("INSERT INTO accounts " + 2112743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov "SELECT DISTINCT account_name, account_type FROM raw_contacts"); 2113743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 2114743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 211551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildNameLookup(SQLiteDatabase db) { 211651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 211751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 211851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 211951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 212051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 212104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 212251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates all locale-sensitive data: nickname_lookup, name_lookup and sort keys. 212304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 212451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov public void setLocale(ContactsProvider2 provider, Locale locale) { 212551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.i(TAG, "Switching to locale " + locale); 212604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2127c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton long start = SystemClock.uptimeMillis(); 212851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 212951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setLocale(locale); 213051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.beginTransaction(); 213151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 213251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 213351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key2_index"); 213451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 213551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 213651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov loadNicknameLookupTable(db); 213751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 213851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov rebuildSortKeys(db, provider); 213951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 214051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setTransactionSuccessful(); 214151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 214251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.endTransaction(); 214351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 214451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 2145c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton Log.i(TAG, "Locale change completed in " + (SystemClock.uptimeMillis() - start) + "ms"); 214651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 214751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 214851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov /** 214951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates sort keys for all contacts. 215051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov */ 215151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildSortKeys(SQLiteDatabase db, ContactsProvider2 provider) { 215251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Cursor cursor = db.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID}, 215351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov null, null, null, null, null); 215451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 215551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov while (cursor.moveToNext()) { 215651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov long rawContactId = cursor.getLong(0); 215751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov provider.updateRawContactDisplayName(db, rawContactId); 215851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 215951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 216051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov cursor.close(); 216151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 216251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 216351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 216451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void insertNameLookup(SQLiteDatabase db) { 216504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP); 216604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 216704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov SQLiteStatement nameLookupInsert = db.compileStatement( 216804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 216904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 217004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 217104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 217204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + 217304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ") VALUES (?,?,?,?)"); 217404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 217551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 217651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertStructuredNameLookup(db, nameLookupInsert); 217751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertOrganizationLookup(db, nameLookupInsert); 217851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertEmailLookup(db, nameLookupInsert); 217951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNicknameLookup(db, nameLookupInsert); 218051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 218151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nameLookupInsert.close(); 218251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 218304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 218404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 218504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class StructuredNameQuery { 218604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 218704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 218804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 218904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 219004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 219104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 219204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName._ID, 219304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.RAW_CONTACT_ID, 219404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.DISPLAY_NAME, 219504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 219604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 219704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 219804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 219904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int DISPLAY_NAME = 2; 220004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 220104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 220204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private class StructuredNameLookupBuilder extends NameLookupBuilder { 220304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 220404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final SQLiteStatement mNameLookupInsert; 220504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final CommonNicknameCache mCommonNicknameCache; 220604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 220704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public StructuredNameLookupBuilder(NameSplitter splitter, 220804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) { 220904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov super(splitter); 221004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mCommonNicknameCache = commonNicknameCache; 221104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mNameLookupInsert = nameLookupInsert; 221204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 221304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 221404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 221504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected void insertNameLookup(long rawContactId, long dataId, int lookupType, 221604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name) { 221704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (!TextUtils.isEmpty(name)) { 221804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert, 221904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rawContactId, dataId, lookupType, name); 222004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 222104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 222204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 222304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 222404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected String[] getCommonNicknameClusters(String normalizedName) { 222504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return mCommonNicknameCache.getCommonNicknameClusters(normalizedName); 222604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 222704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 222804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 222904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 223004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all structured names in the database. 223104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 223204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 2233d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameSplitter nameSplitter = createNameSplitter(); 2234d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(nameSplitter, 223504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov new CommonNicknameCache(db), nameLookupInsert); 223604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE); 223704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS, 223804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 223904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 224004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 224104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 224204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(StructuredNameQuery.ID); 224304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID); 224404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME); 2245d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov int fullNameStyle = nameSplitter.guessFullNameStyle(name); 224651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov fullNameStyle = nameSplitter.getAdjustedFullNameStyle(fullNameStyle); 2247d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov nameLookupBuilder.insertNameLookup(rawContactId, dataId, name, fullNameStyle); 224804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 224904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 225004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 225104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 225204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 225304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 225404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class OrganizationQuery { 225504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 225604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 225704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 225804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 225904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 226004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 226104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization._ID, 226204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.RAW_CONTACT_ID, 226304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.COMPANY, 226404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.TITLE, 226504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 226604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 226704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 226804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 226904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int COMPANY = 2; 227004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int TITLE = 3; 227104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 227204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 227304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 227404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all organizations in the database. 227504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 227604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertOrganizationLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 227704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 227804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(OrganizationQuery.TABLE, OrganizationQuery.COLUMNS, 227904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov OrganizationQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 228004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 228104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 228204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 228304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(OrganizationQuery.ID); 228404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(OrganizationQuery.RAW_CONTACT_ID); 228504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String organization = cursor.getString(OrganizationQuery.COMPANY); 228604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String title = cursor.getString(OrganizationQuery.TITLE); 228704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 228804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, organization); 228904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 229004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, title); 229104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 229204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 229304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 229404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 229504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 229604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 229704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class EmailQuery { 229804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 229904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 230004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 230104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 230204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 230304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 230404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email._ID, 230504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.RAW_CONTACT_ID, 230604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.ADDRESS, 230704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 230804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 230904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 231004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 231104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ADDRESS = 2; 231204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 231304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 231404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 231504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all email addresses in the database. 231604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 231704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 231804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 231904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS, 232004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 232104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 232204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 232304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 232404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(EmailQuery.ID); 232504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID); 232604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String address = cursor.getString(EmailQuery.ADDRESS); 232704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov address = extractHandleFromEmailAddress(address); 232804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 232904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, address); 233004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 233104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 233204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 233304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 233404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 233504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 233604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class NicknameQuery { 233704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 233804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 233904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 234004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 234104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 234204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 234304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname._ID, 234404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.RAW_CONTACT_ID, 234504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.NAME, 234604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 234704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 234804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 234904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 235004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int NAME = 2; 235104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 235204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 235304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 235404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all nicknames in the database. 235504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 235604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 235704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 235804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS, 235904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 236004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 236104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 236204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 236304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(NicknameQuery.ID); 236404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID); 236504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String nickname = cursor.getString(NicknameQuery.NAME); 236604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 236704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.NICKNAME, nickname); 236804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 236904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 237004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 237104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 237204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 237304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 237404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 237504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 237604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 237704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 237804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String name) { 237904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 238004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 238104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 238204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String normalized = NameNormalizer.normalize(name); 238404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(normalized)) { 238504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 238604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 238704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized); 238904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 239004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 239204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String normalizedName) { 239304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(1, rawContactId); 239404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(2, dataId); 239504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(3, lookupType); 239604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindString(4, normalizedName); 239704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.executeInsert(); 239804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 239904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2400b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public String extractHandleFromEmailAddress(String email) { 2401b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 2402b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (tokens.length == 0) { 2403b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2404b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2405b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2406b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String address = tokens[0].getAddress(); 2407b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov int at = address.indexOf('@'); 2408b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (at != -1) { 2409b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return address.substring(0, at); 2410b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2411b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2412b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2413b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 241408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov public String extractAddressFromEmailAddress(String email) { 241508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 241608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (tokens.length == 0) { 241708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return null; 241808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 241908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 242008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return tokens[0].getAddress(); 242108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 242208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 2423b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private long lookupMimeTypeId(SQLiteDatabase db, String mimeType) { 2424b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2425b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return DatabaseUtils.longForQuery(db, 2426b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 2427b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 2428b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 2429b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov + "='" + mimeType + "'", null); 2430b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } catch (SQLiteDoneException e) { 2431b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // No rows of this type in the database 2432b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return -1; 2433b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2434b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2435b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 24365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void bindString(SQLiteStatement stmt, int index, String value) { 24375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (value == null) { 24385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindNull(index); 24395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else { 24405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindString(index, value); 24415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 24425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 24435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2444a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 2445f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Adds index stats into the SQLite database to force it to always use the lookup indexes. 2446f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 2447f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private void updateSqliteStats(SQLiteDatabase db) { 2448f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2449f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // Specific stats strings are based on an actual large database after running ANALYZE 2450f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov try { 24518fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 24528fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_restricted_index", "10000 9000"); 24538fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 24548fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_has_phone_index", "10000 500"); 24558fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 2456737858a04a157a0afad9ec81372c75d14bf68788Jeff Hamilton "contacts_visible_index", "10000 500 1"); 24578fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24588fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 24598fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_source_id_index", "10000 1 1 1"); 24608fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 24618fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_contact_id_index", "10000 2"); 24628fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24638fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 24648fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "name_lookup_raw_contact_id_index", "10000 3"); 24658fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 2466916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov "name_lookup_index", "10000 3 2 2 1"); 24678fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 24688fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "10000 3 2 1"); 24698fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24708fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 24718fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "phone_lookup_index", "10000 2 2 1"); 247236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 247336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 24748fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24758fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 24768fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_mimetype_data1_index", "60000 5000 2"); 24778fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 24788fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_raw_contact_id", "60000 10"); 24798fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24808fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.GROUPS, 24818fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "groups_source_id_index", "50 1 1 1"); 24828fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 24838fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NICKNAME_LOOKUP, 24848fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "500 2 1"); 24858fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 2486f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } catch (SQLException e) { 2487f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov Log.e(TAG, "Could not update index stats", e); 2488f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2489f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2490f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2491f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2492f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Stores statistics for a given index. 2493f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * 2494f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * @param stats has the following structure: the first index is the expected size of 2495f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * the table. The following integer(s) are the expected number of records selected with the 2496f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * index. There should be one integer per indexed column. 2497f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 24985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateIndexStats(SQLiteDatabase db, String table, String index, 24995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String stats) { 2500f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';"); 2501f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)" 2502f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " VALUES ('" + table + "','" + index + "','" + stats + "');"); 2503f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2504f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2505f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov @Override 2506f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov public synchronized SQLiteDatabase getWritableDatabase() { 2507f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov SQLiteDatabase db = super.getWritableDatabase(); 2508f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov if (mReopenDatabase) { 2509f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov mReopenDatabase = false; 2510f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov close(); 2511f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db = super.getWritableDatabase(); 2512f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2513f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov return db; 2514f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2515f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2516f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2517a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 2518a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 2519a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 2520a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 25213d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 252233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACCOUNTS + ";"); 252369cc3a2b09e2ffb606c6e52a71b604bba526d225Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL)"); 252433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov 2525d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 25265ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";"); 2527a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 2528a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 2529a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 2530ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 2531b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 2532eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("DELETE FROM " + Tables.SETTINGS + ";"); 2533a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 25343d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CALLS + ";"); 2535b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2536b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 2537a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 2538b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 253904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public NameSplitter createNameSplitter() { 254004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return new NameSplitter( 254104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 254204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 254304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 254404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 254504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Locale.getDefault()); 254604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2548b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2549619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 2550619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2551619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 2552619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 2553619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 2554619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 2555619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 2556619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 2557619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2558619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2559619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2560619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2561b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 2562b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 2563b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 2564b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 2565b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 2566b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 2567b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 2568b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 2569b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 2570b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 2571b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 2572b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2573f4a3b7e523e36679b68edd2af632e26648758ff2Dmitri Plotnikov private long getCachedId(SQLiteStatement query, SQLiteStatement insert, 2574b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 2575b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 2576b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 2577b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 2578b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2579b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2580b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey long id = -1; 2581b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2582b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try searching database for mapping 2583b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(query, 1, value); 2584b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = query.simpleQueryForLong(); 2585b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2586b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Nothing found, so try inserting new mapping 2587b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(insert, 1, value); 2588b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = insert.executeInsert(); 2589b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2590b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2591b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (id != -1) { 2592b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Cache and return the new answer 2593b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey cache.put(value, id); 2594b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return id; 2595b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } else { 2596b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Otherwise throw if no mapping found or created 2597b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey throw new IllegalStateException("Couldn't find or create internal " 2598b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + "lookup table entry for value " + value); 2599b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2600b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2601b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2602b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2603ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 2604b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2605b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2606b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 2607b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2608b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2609b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 2610b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2611b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2612b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2613ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 2614b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2615b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2616b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 2617b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2618b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 26195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return getMimeTypeIdNoDbCheck(mimetype); 26205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 26215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 26225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private long getMimeTypeIdNoDbCheck(String mimetype) { 2623b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 2624b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2625b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2626b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2627ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 2628b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2629b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 2630b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2631b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2632b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2633b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2634b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 2635b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 2636b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2637b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2638b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2639b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2640b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2641b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2642b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2643b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2644b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 2645b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2646b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 2647b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2648b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2649b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2650b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2651b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 2652b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 2653b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2654b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2655b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2656b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2657b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2658b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 26596bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 26606bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 2661d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts. 2662ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 2663ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 26648be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 2665ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 26668be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)}; 26678be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 26688be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // There are a couple questions that can be asked regarding the 26698be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // following two update statements: 26708be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 26718be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Q: Why do we run these two queries separately? They seem like they could be combined. 26728be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // A: This is a result of painstaking experimentation. Turns out that the most 26738be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // important optimization is to make sure we never update a value to its current value. 26748be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Changing 0 to 0 is unexpectedly expensive - SQLite actually writes the unchanged 26758be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // rows back to disk. The other consideration is that the CONTACT_IS_VISIBLE condition 26768be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // is very complex and executing it twice in the same statement ("if contact_visible != 26778be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // CONTACT_IS_VISIBLE change it to CONTACT_IS_VISIBLE") is more expensive than running 26788be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // two update statements. 26798be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 26808be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Q: How come we are using db.update instead of compiled statements? 26818be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // A: This is a limitation of the compiled statement API. It does not return the 26828be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // number of rows changed. As you will see later in this method we really need 26838be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // to know how many rows have been changed. 26848be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 26858be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // First update contacts that are currently marked as invisible, but need to be visible 26868be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov ContentValues values = new ContentValues(); 26878be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov values.put(Contacts.IN_VISIBLE_GROUP, 1); 26888be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov int countMadeVisible = db.update(Tables.CONTACTS, values, 26898be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + "=0" + " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1", 26908be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov selectionArgs); 26918be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 26928be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Next update contacts that are currently marked as visible, but need to be invisible 26938be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov values.put(Contacts.IN_VISIBLE_GROUP, 0); 26948be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov int countMadeInvisible = db.update(Tables.CONTACTS, values, 26958be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + "=1" + " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=0", 26968be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov selectionArgs); 26978be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 26988be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov if (countMadeVisible != 0 || countMadeInvisible != 0) { 26998be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // TODO break out the fields (contact_in_visible_group, sort_key, sort_key_alt) into 27008be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // a separate table. 27018be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Rationale: The following statement will take a very long time on 27028be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // a large database even though we are only changing one field from 0 to 1 or from 27038be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 1 to 0. The reason for the slowness is that SQLite will need to write the whole 27048be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // page even when only one bit on it changes. Changing the visibility of a 27058be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // significant number of contacts will likely read and write almost the entire 27068be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // raw_contacts table. So, the solution is to break out into a separate table 27078be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // the changing field along with the sort keys used for index-based sorting. 27088be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // That table will occupy a smaller number of pages, so rewriting it would 27098be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // not be as expensive. 27108be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleUpdateRawContacts.execute(); 27118be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov } 2712ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2713ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2714ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 2715d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for a specific contact. 2716ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 2717fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public void updateContactVisible(long contactId) { 2718ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 2719ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.bindLong(1, groupMembershipMimetypeId); 2720fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdate.bindLong(2, contactId); 2721ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.execute(); 2722fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 2723fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdateRawContacts.bindLong(1, contactId); 2724fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdateRawContacts.execute(); 2725ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2726ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2727ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 2728d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Returns contact ID for the given contact or zero if it is NULL. 27296bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 2730d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public long getContactId(long rawContactId) { 27316bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov getReadableDatabase(); 27326bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 2733d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId); 2734d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactIdQuery.simpleQueryForLong(); 27356bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 2736a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana // No valid mapping found, so return 0 27376bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 27386bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 27396bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 274061bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 27415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int getAggregationMode(long rawContactId) { 2742f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov getReadableDatabase(); 2743f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 27445ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId); 2745f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 2746f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 27476cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // No valid row found, so return "disabled" 27486cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.AGGREGATION_MODE_DISABLED; 2749f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2750f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2751f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 2752e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public void buildPhoneLookupAndRawContactQuery(SQLiteQueryBuilder qb, String number) { 275336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2754f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov qb.setTables(Tables.DATA_JOIN_RAW_CONTACTS + 2755f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov " JOIN " + Tables.PHONE_LOOKUP 2756f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " ON(" + DataColumns.CONCRETE_ID + "=" + PhoneLookupColumns.DATA_ID + ")"); 2757f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2758e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 275936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(PhoneLookupColumns.MIN_MATCH + "='"); 276036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 276136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("' AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", "); 2762f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 276336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)"); 2764e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2765e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 2766e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2767e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2768e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public void buildPhoneLookupAndContactQuery(SQLiteQueryBuilder qb, String number) { 276936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2770e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 277136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, true); 2772e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setTables(sb.toString()); 2773e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2774e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb = new StringBuilder(); 2775e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov appendPhoneLookupSelection(sb, number); 2776e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 2777bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 2778bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 2779e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public String buildPhoneLookupAsNestedQuery(String number) { 2780e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 278136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2782e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id" + " FROM "); 278336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, false); 2784e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(" WHERE "); 2785e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov appendPhoneLookupSelection(sb, number); 2786e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(")"); 2787e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov return sb.toString(); 2788e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2789e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 279036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private void appendPhoneLookupTables(StringBuilder sb, final String minMatch, 2791e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov boolean joinContacts) { 2792e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(Tables.RAW_CONTACTS); 2793e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov if (joinContacts) { 2794fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov sb.append(" JOIN " + getContactView() + " contacts_view" 2795fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " ON (contacts_view._id = raw_contacts.contact_id)"); 2796e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2797e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(", (SELECT data_id FROM phone_lookup " 279836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov + "WHERE (" + Tables.PHONE_LOOKUP + "." + PhoneLookupColumns.MIN_MATCH + " = '"); 279936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 280036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("')) AS lookup, " + Tables.DATA); 2801e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2802e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2803e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov private void appendPhoneLookupSelection(StringBuilder sb, String number) { 2804e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id" 2805fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov + " AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", "); 2806fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 280736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)"); 280836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 280936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 281036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public String getUseStrictPhoneNumberComparisonParameter() { 281136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov return mUseStrictPhoneNumberComparison ? "1" : "0"; 2812fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov } 2813bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 2814619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2815b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 2816b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 2817b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 281851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP); 281951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 282028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 282128f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 2822b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 2823b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 2824b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2825b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2826b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 2827b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 2828b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 2829b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 283051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 283151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 283251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String[] names = strings[clusterId].split(","); 283351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int j = 0; j < names.length; j++) { 283451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 283551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 283651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 283751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 283851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String.valueOf(clusterId)); 283951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.executeInsert(); 284051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } catch (SQLiteException e) { 284151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 284251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Print the exception and keep going - this is not a fatal error 284351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 284451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 2845b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2846b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 284751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 284851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.close(); 2849b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2850b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2851b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2852f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 2853f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 2854f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 2855f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 2856f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2857f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2858f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 2859f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 2860f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 2861f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 2862f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 2863f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 2864f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 2865f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 2866f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 2867f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 2868f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 2869f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 28701b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov } else if (value instanceof String) { 28711b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = Long.parseLong((String)value); 2872f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 28731b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = ((Number)value).longValue(); 2874f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2875f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 2876f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2877f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2878f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 287935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 288035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 288135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 2882c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2883c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov /** 2884c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Delete the aggregate contact if it has no constituent raw contacts other 2885c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * than the supplied one. 2886c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 2887c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov public void removeContactIfSingleton(long rawContactId) { 2888c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 2889c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2890c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Obtain contact ID from the supplied raw contact ID 2891c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM " 2892c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")"; 2893c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2894c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Find other raw contacts in the same aggregate contact 2895c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM " 2896c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON (" 2897c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID 2898c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + "" 2899c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")"; 2900c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2901c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS 2902c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId 2903c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND NOT EXISTS " + otherRawContacts + ";"); 2904c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 29054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 29064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2907b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Returns the value from the {@link Tables#PROPERTIES} table. 2908b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 2909b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public String getProperty(String key, String defaultValue) { 2910b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov Cursor cursor = getReadableDatabase().query(Tables.PROPERTIES, 2911b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{PropertiesColumns.PROPERTY_VALUE}, 2912b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + "=?", 2913b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{key}, null, null, null); 2914b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String value = null; 2915b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov try { 2916b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (cursor.moveToFirst()) { 2917b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov value = cursor.getString(0); 2918b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2919b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } finally { 2920b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov cursor.close(); 2921b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2922b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2923b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov return value != null ? value : defaultValue; 2924b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2925b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2926b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 2927b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Stores a key-value pair in the {@link Tables#PROPERTIES} table. 2928b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 2929b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public void setProperty(String key, String value) { 2930b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ContentValues values = new ContentValues(); 2931b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_KEY, key); 2932b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_VALUE, value); 2933b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov getWritableDatabase().replace(Tables.PROPERTIES, null, values); 2934b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2935b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2936b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 29374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Check if {@link Binder#getCallingUid()} should be allowed access to 29384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * {@link RawContacts#IS_RESTRICTED} data. 29394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 2940d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData() { 29414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 29424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(Binder.getCallingUid()); 29434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 29444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Has restricted access if caller matches any packages 29454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov for (String callerPackage : callerPackages) { 2946d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (hasAccessToRestrictedData(callerPackage)) { 2947763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return true; 2948763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2949763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2950763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return false; 2951763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2952763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 2953763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar /** 2954763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * Check if requestingPackage should be allowed access to 2955763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * {@link RawContacts#IS_RESTRICTED} data. 2956763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar */ 2957d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData(String requestingPackage) { 2958d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (mUnrestrictedPackages != null) { 2959d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton for (String allowedPackage : mUnrestrictedPackages) { 2960d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (allowedPackage.equals(requestingPackage)) { 2961d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return true; 2962d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton } 29634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov return false; 29664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 29684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getDataView() { 2969d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getDataView(false); 2970d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 2971d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 2972d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getDataView(boolean requireRestrictedView) { 2973d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2974d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Views.DATA_ALL : Views.DATA_RESTRICTED; 29754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 29774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getRawContactView() { 2978763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getRawContactView(false); 2979763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2980763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 2981763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getRawContactView(boolean requireRestrictedView) { 2982d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2983763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.RAW_CONTACTS_ALL : Views.RAW_CONTACTS_RESTRICTED; 29844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 29864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getContactView() { 2987763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getContactView(false); 29884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 29894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2990763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getContactView(boolean requireRestrictedView) { 2991d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2992763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.CONTACTS_ALL : Views.CONTACTS_RESTRICTED; 2993f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey } 2994f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey 299589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public String getGroupView() { 299689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov return Views.GROUPS_ALL; 299789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov } 299889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 2999d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getContactEntitiesView() { 3000d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getContactEntitiesView(false); 3001d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3002d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3003d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getContactEntitiesView(boolean requireRestrictedView) { 3004d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3005d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Tables.CONTACT_ENTITIES : Tables.CONTACT_ENTITIES_RESTRICTED; 3006d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3007d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3008ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** 3009ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov * Test if any of the columns appear in the given projection. 3010ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov */ 3011ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov public boolean isInProjection(String[] projection, String... columns) { 301282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (projection == null) { 301382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 301482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 3015ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 301682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov // Optimized for a single-column test 301782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (columns.length == 1) { 301882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov String column = columns[0]; 301982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 302082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (column.equals(test)) { 302182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 302282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 302382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 302482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } else { 302582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 302682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String column : columns) { 3027ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (column.equals(test)) { 3028ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return true; 3029ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3030ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3031ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3032ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3033ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return false; 30344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 3035fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3036fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3037fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3038fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3039fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3040fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(Uri uri) { 3041fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return exceptionMessage(null, uri); 3042fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3043fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3044fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3045fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3046fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3047fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3048fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(String message, Uri uri) { 3049fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 3050fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (message != null) { 3051fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(message).append("; "); 3052fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3053fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("URI: ").append(uri); 3054fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 3055fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov int callingUid = Binder.getCallingUid(); 3056fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling user: "); 3057fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov String userName = pm.getNameForUid(callingUid); 3058fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (userName != null) { 3059fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(userName); 3060fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3061fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callingUid); 3062fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3063fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3064fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(callingUid); 3065fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages != null && callerPackages.length > 0) { 3066fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages.length == 1) { 3067fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package:"); 3068fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[0]); 3069fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3070fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package is one of: ["); 3071fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov for (int i = 0; i < callerPackages.length; i++) { 3072fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (i != 0) { 3073fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", "); 3074fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3075fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[i]); 3076fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3077fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("]"); 3078fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3079fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3080fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3081fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return sb.toString(); 3082fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3083b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 3084