ContactsDatabaseHelper.java revision fa4a38c9d54f3e3aad4674867bb1250f450c0b95
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; 40b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns; 41a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.provider.ContactsContract; 42e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikovimport android.provider.CallLog.Calls; 43b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 44d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 45de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources; 475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle; 48ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 49d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 50eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings; 5182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates; 52b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 53ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 54b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 56bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 5867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities; 59bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils; 6036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.text.TextUtils; 61b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Token; 62b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Tokenizer; 63b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log; 64b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 65b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap; 665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale; 67b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 68b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/** 69b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Database helper for contacts. Designed as a singleton to make sure that all 70b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * {@link android.content.ContentProvider} users get the same reference. 71b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Provides handy methods for maintaining package and mime-type lookup tables. 72b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 73b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov/* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper { 74b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static final String TAG = "ContactsDatabaseHelper"; 75b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 76b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final int DATABASE_VERSION = 303; 77e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 78b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String DATABASE_NAME = "contacts2.db"; 791f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final String DATABASE_PRESENCE = "presence_db"; 80b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 81b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface Tables { 82d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONTACTS = "contacts"; 835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACTS = "raw_contacts"; 84ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String PACKAGES = "packages"; 85ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPES = "mimetypes"; 86b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PHONE_LOOKUP = "phone_lookup"; 87a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP = "name_lookup"; 88b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; 89eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey public static final String SETTINGS = "settings"; 90b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA = "data"; 91ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS = "groups"; 921f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String PRESENCE = "presence"; 93e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public static final String AGGREGATED_PRESENCE = "agg_presence"; 94b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NICKNAME_LOOKUP = "nickname_lookup"; 95e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov public static final String CALLS = "calls"; 96226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONTACT_ENTITIES = "contact_entities_view"; 97d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public static final String CONTACT_ENTITIES_RESTRICTED = "contact_entities_view_restricted"; 98a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String STATUS_UPDATES = "status_updates"; 99b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 100ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_MIMETYPES = "data " 1011b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id)"; 102b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 10311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov public static final String DATA_JOIN_RAW_CONTACTS = "data " 1048e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 10511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 1065ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPE_RAW_CONTACTS = "data " 107c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 108c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 109bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 110e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 111e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS = "raw_contacts " 112e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN settings ON (" 113e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 114e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 115e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 116e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 117e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID 118e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + ")"; 119e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 120e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 121e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS = "settings " 122e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN raw_contacts ON (" 123e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 124e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 125e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 126e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 127e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 128e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 129d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data " 1301b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1311b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 132d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 133ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data " 1351b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1361b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 13767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 1389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "; 141ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 142ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES = "groups " 143ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)"; 144ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 145b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String ACTIVITIES = "activities"; 146b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 147ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String ACTIVITIES_JOIN_MIMETYPES = "activities " 148ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)"; 149b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 150d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS = 1515ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov "activities " 15267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) " 153ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) " 1545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " + 155fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "raw_contacts._id) " 156d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 1577e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1585ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup " 1595ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "INNER JOIN raw_contacts ON (name_lookup.raw_contact_id = raw_contacts._id)"; 160b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 161b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public interface Views { 1634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_ALL = "view_data"; 1644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_RESTRICTED = "view_data_restricted"; 1654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_ALL = "view_raw_contacts"; 1674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_RESTRICTED = "view_raw_contacts_restricted"; 1684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_ALL = "view_contacts"; 1704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_RESTRICTED = "view_contacts_restricted"; 17189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 17289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public static final String GROUPS_ALL = "view_groups"; 1734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 1744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1751f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public interface Clauses { 176e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE + "='" 177e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + GroupMembership.CONTENT_ITEM_TYPE + "'"; 178ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 179e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "=" 180ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupsColumns.CONCRETE_ID; 181ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 18268936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String HAVING_NO_GROUPS = "COUNT(" + DataColumns.CONCRETE_GROUP_ID + ") == 0"; 1839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 18468936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String GROUP_BY_ACCOUNT_CONTACT_ID = SettingsColumns.CONCRETE_ACCOUNT_NAME + "," 18568936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "," + RawContacts.CONTACT_ID; 186e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 187e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String RAW_CONTACT_IS_LOCAL = RawContactsColumns.CONCRETE_ACCOUNT_NAME 188e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + " IS NULL AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL"; 189e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 190e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String ZERO_GROUP_MEMBERSHIPS = "COUNT(" + GroupsColumns.CONCRETE_ID + ")=0"; 191e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 1921a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS = "outer_raw_contacts"; 1931a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS_ID = OUTER_RAW_CONTACTS + "." + RawContacts._ID; 1941a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey 195b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov final String CONTACT_IS_VISIBLE = 196b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "SELECT " + 1971a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey "MAX((SELECT (CASE WHEN " + 198b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "(CASE" + 199b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + RAW_CONTACT_IS_LOCAL + 200b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN 1 " + 201b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + ZERO_GROUP_MEMBERSHIPS + 202b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN " + Settings.UNGROUPED_VISIBLE + 203b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " ELSE MAX(" + Groups.GROUP_VISIBLE + ")" + 204b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "END)=1 THEN 1 ELSE 0 END)" + 205b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS + 2061a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + OUTER_RAW_CONTACTS_ID + "))" + 2071a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " FROM " + Tables.RAW_CONTACTS + " AS " + OUTER_RAW_CONTACTS + 208b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 209b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " GROUP BY " + RawContacts.CONTACT_ID; 210e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 211e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND " 212e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?"; 2131f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 2141f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 215d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public interface ContactsColumns { 2164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * This flag is set for a contact if it has only one constituent raw contact and 2184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * it is restricted. 2194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 22067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String SINGLE_IS_RESTRICTED = "single_is_restricted"; 221ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 222a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String LAST_STATUS_UPDATE_ID = "status_update_id"; 223a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 224d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID; 22567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 226d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "." 227d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED; 228d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "." 229d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.LAST_TIME_CONTACTED; 230d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED; 231d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "." 232d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.CUSTOM_RINGTONE; 233d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "." 234d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.SEND_TO_VOICEMAIL; 2352d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill public static final String CONCRETE_LOOKUP_KEY = Tables.CONTACTS + "." 2362d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill + Contacts.LOOKUP_KEY; 237619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 238619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2396cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov public interface RawContactsColumns { 24033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_ID = 2415ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + BaseColumns._ID; 2429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_NAME = 2435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME; 2449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_TYPE = 2455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE; 24633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_SOURCE_ID = 2475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID; 24833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_VERSION = 2495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.VERSION; 25033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DIRTY = 2515ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DIRTY; 25233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DELETED = 2535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DELETED; 2547a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC1 = 2557a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC1; 2567a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC2 = 2577a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC2; 2587a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC3 = 2597a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC3; 2607a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC4 = 2617a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC4; 262c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey public static final String CONCRETE_STARRED = 263c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.STARRED; 264bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey public static final String CONCRETE_IS_RESTRICTED = 265bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.IS_RESTRICTED; 2668e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 2675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME = RawContacts.DISPLAY_NAME_PRIMARY; 2685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME_SOURCE = RawContacts.DISPLAY_NAME_SOURCE; 2698e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov public static final String AGGREGATION_NEEDED = "aggregation_needed"; 270fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONTACT_IN_VISIBLE_GROUP = "contact_in_visible_group"; 271fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 272fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_DISPLAY_NAME = 273fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + DISPLAY_NAME; 274fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_CONTACT_ID = 275fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID; 276f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov public static final String CONCRETE_NAME_VERIFIED = 277f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED; 278619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 279619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 280619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface DataColumns { 28167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 282b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 283ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 284ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID; 285226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID; 286d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "." 287d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Data.RAW_CONTACT_ID; 288ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_GROUP_ID = Tables.DATA + "." 289ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupMembership.GROUP_ROW_ID; 290e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 291e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1; 292e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2; 293e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3; 294e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4; 295e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5; 296e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6; 297e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7; 298e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8; 299e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9; 300e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10; 3010f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11; 3020f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12; 3030f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13; 3040f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14; 3050f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15; 306e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY; 307226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID; 308e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 309e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 3100f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov // Used only for legacy API support 3110f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface ExtensionsColumns { 3120f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String NAME = Data.DATA1; 3130f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String VALUE = Data.DATA2; 3140f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3150f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 3160f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface GroupMembershipColumns { 3175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID; 3180f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID; 3190f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3200f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 321e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public interface PhoneColumns { 322e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String NORMALIZED_NUMBER = Data.DATA4; 323e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4; 324ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 325ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 326ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface GroupsColumns { 32767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 32867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 329ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID; 33067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID; 331341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.GROUPS + "." + Groups.ACCOUNT_NAME; 332341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.GROUPS + "." + Groups.ACCOUNT_TYPE; 333341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey } 334b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 335b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface ActivitiesColumns { 336b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE_ID = "package_id"; 337b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 338b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 339b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 340b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface PhoneLookupColumns { 341b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 342b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA_ID = "data_id"; 3435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 344b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String NORMALIZED_NUMBER = "normalized_number"; 34536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public static final String MIN_MATCH = "min_match"; 346b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 347b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 348a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public interface NameLookupColumns { 3495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 35014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public static final String DATA_ID = "data_id"; 351a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NORMALIZED_NAME = "normalized_name"; 352a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_TYPE = "name_type"; 353a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 354a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 355a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public final static class NameLookupType { 3562a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_EXACT = 0; 3572a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_VARIANT = 1; 3582a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_COLLATION_KEY = 2; 3592a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NICKNAME = 3; 3602a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int EMAIL_BASED_NICKNAME = 4; 361a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka public static final int ORGANIZATION = 5; 3624cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao public static final int NAME_SHORTHAND = 6; 363a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 364a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov // This is the highest name lookup type code plus one 3654cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao public static final int TYPE_COUNT = 7; 366a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov 367a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static boolean isBasedOnStructuredName(int nameLookupType) { 3682a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov return nameLookupType == NameLookupType.NAME_EXACT 3692a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_VARIANT 3702a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_COLLATION_KEY; 371a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov } 372a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 373a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 374ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface PackagesColumns { 375b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 376b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE = "package"; 377226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 378226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID; 379b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 380b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 381ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface MimetypesColumns { 382b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 383b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE = "mimetype"; 384ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 385ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID; 386ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE; 387b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 388b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 389b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public interface AggregationExceptionColumns { 390b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 391b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 392b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 393b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public interface NicknameLookupColumns { 394b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NAME = "name"; 395b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String CLUSTER = "cluster"; 396b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 397b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 398e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public interface SettingsColumns { 399e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.SETTINGS + "." 400e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_NAME; 401e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.SETTINGS + "." 402e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_TYPE; 403e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 404e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 4054dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov public interface PresenceColumns { 4064dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov String RAW_CONTACT_ID = "presence_raw_contact_id"; 407bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4084dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 4094dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 410e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public interface AggregatedPresenceColumns { 411e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4123296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4133296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_CONTACT_ID = Tables.AGGREGATED_PRESENCE + "." + CONTACT_ID; 414e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 415e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 416a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public interface StatusUpdatesColumns { 417a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov String DATA_ID = "status_update_data_id"; 4183296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4193296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = Tables.STATUS_UPDATES + "." + DATA_ID; 4203296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4213296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = Tables.STATUS_UPDATES + "." + StatusUpdates.PRESENCE; 4223296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS; 4233296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = Tables.STATUS_UPDATES + "." 4243296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_TIMESTAMP; 4253296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = Tables.STATUS_UPDATES + "." 4263296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_RES_PACKAGE; 4273296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_LABEL; 4283296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_ICON; 4293296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey } 4303296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4313296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey public interface ContactsStatusUpdatesColumns { 4323296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String ALIAS = "contacts_" + Tables.STATUS_UPDATES; 4333296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4343296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = ALIAS + "." + StatusUpdatesColumns.DATA_ID; 4353296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4363296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = ALIAS + "." + StatusUpdates.PRESENCE; 4373296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = ALIAS + "." + StatusUpdates.STATUS; 4383296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = ALIAS + "." + StatusUpdates.STATUS_TIMESTAMP; 4393296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = ALIAS + "." + StatusUpdates.STATUS_RES_PACKAGE; 4403296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = ALIAS + "." + StatusUpdates.STATUS_LABEL; 4413296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = ALIAS + "." + StatusUpdates.STATUS_ICON; 442a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov } 443a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 4443296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey /** In-memory cache of previously found MIME-type mappings */ 445bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 446b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 447bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 448b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 449b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 450b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 451b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 452b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 453d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private SQLiteStatement mContactIdQuery; 454f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 455b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 456b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 457b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 458b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 459b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 460b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 46135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 462f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov 463b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 464d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov /** Compiled statements for updating {@link Contacts#IN_VISIBLE_GROUP}. */ 465ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey private SQLiteStatement mVisibleSpecificUpdate; 466fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov private SQLiteStatement mVisibleUpdateRawContacts; 467fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov private SQLiteStatement mVisibleSpecificUpdateRawContacts; 468ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 469f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private boolean mReopenDatabase = false; 470f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 471b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static ContactsDatabaseHelper sSingleton = null; 472b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 47336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private boolean mUseStrictPhoneNumberComparison; 4743a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa 475d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton /** 476d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton * List of package names with access to {@link RawContacts#IS_RESTRICTED} data. 477d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton */ 478d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton private String[] mUnrestrictedPackages; 479d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton 480b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov public static synchronized ContactsDatabaseHelper getInstance(Context context) { 481b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 482b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov sSingleton = new ContactsDatabaseHelper(context); 483b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 484b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 485b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 486b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 4871f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 48831b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 48935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 4901f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 491b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov ContactsDatabaseHelper(Context context) { 492b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey super(context, DATABASE_NAME, null, DATABASE_VERSION); 493b5a3163481794babda78716e576e35818de0cc03Dianne Hackborn if (false) Log.i(TAG, "Creating OpenHelper"); 494d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton Resources resources = context.getResources(); 495619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 496b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 49728b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 49836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov mUseStrictPhoneNumberComparison = 499d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton resources.getBoolean( 500d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton com.android.internal.R.bool.config_use_strict_phone_number_comparation); 5010f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov int resourceId = resources.getIdentifier("unrestricted_packages", "array", 5020f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov context.getPackageName()); 5030f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov if (resourceId != 0) { 5040f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = resources.getStringArray(resourceId); 5050f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } else { 5060f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = new String[0]; 5070f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } 508b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 509b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 510b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 511b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 51235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.onDatabaseOpened(db); 51335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 514b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Create compiled statements for package and mimetype lookups 515ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM " 516ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 517ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM " 518ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?"); 519d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mContactIdQuery = db.compileStatement("SELECT " + RawContacts.CONTACT_ID + " FROM " 5205ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 5216cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov mAggregationModeQuery = db.compileStatement("SELECT " + RawContacts.AGGREGATION_MODE 5225ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 523ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "(" 524ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + MimetypesColumns.MIMETYPE + ") VALUES (?)"); 525ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "(" 526ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + PackagesColumns.PACKAGE + ") VALUES (?)"); 527ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 528ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM " 529ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 530ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE 531ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "." 532b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + Activities._ID + "=?"); 5331f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 5348be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Change visibility of a specific contact 5358be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleSpecificUpdate = db.compileStatement( 5368be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 5378be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " SET " + Contacts.IN_VISIBLE_GROUP + "=(" + Clauses.CONTACT_IS_VISIBLE + ")" + 5388be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + ContactsColumns.CONCRETE_ID + "=?"); 539ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 5408be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Return visibility of the aggregate contact joined with the raw contact 5418be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov String contactVisibility = 5428be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 5438be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " FROM " + Tables.CONTACTS + 5448be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID; 545ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 5468be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Set visibility of raw contacts to the visibility of corresponding aggregate contacts 5478be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleUpdateRawContacts = db.compileStatement( 548fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 5498be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(" 5508be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov + contactVisibility + ")" + 5518be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + RawContacts.DELETED + "=0" + 5528be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " AND " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "!=(" 5538be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov + contactVisibility + ")=1"); 5548be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 5558be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Set visibility of a raw contact to the visibility of corresponding aggregate contact 5568be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleSpecificUpdateRawContacts = db.compileStatement( 5578be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 5588be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(" 5598be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov + contactVisibility + ")" + 5608be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov " WHERE " + RawContacts.DELETED + "=0 AND " + RawContacts.CONTACT_ID + "=?"); 561fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 5621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 563e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+ 56482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 56582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PROTOCOL + " INTEGER NOT NULL," + 56682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + 56782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_HANDLE + " TEXT," + 56882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_ACCOUNT + " TEXT," + 569a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 570a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 57182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE + " INTEGER," + 57282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL 57382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + 5741f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 5751f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 576e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON " 5774dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");"); 578e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 579e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " 580e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+ 581e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov AggregatedPresenceColumns.CONTACT_ID 582e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," + 58382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE_STATUS + " INTEGER" + 584e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov ");"); 585bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 586bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 587bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted" 588bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 589bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 590bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATED_PRESENCE 591bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " + 592bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.CONTACT_ID + 593bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 594bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.RAW_CONTACT_ID 595bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.RAW_CONTACT_ID + 596bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND NOT EXISTS" + 597bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.RAW_CONTACT_ID + 598bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 599bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 600bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.CONTACT_ID + 601bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND " + PresenceColumns.RAW_CONTACT_ID 602bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));" 603bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 604bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 605bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String replaceAggregatePresenceSql = 606bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 607bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + AggregatedPresenceColumns.CONTACT_ID + ", " 60882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + StatusUpdates.PRESENCE_STATUS + ")" + 609bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " SELECT " + PresenceColumns.CONTACT_ID + "," 61082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + "MAX(" + StatusUpdates.PRESENCE_STATUS + ")" + 611bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 612bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 613bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=NEW." + PresenceColumns.CONTACT_ID + ";"; 614bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 615bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted" 616bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 617bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 618bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 619bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 620bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 621bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated" 622bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 623bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 624bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 625bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 626b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 627b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 628b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 629b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 630b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 631b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 63235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 63335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 634b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 635d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 636b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 637fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 638d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 639d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 640d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 641d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 642d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 643d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 644cdbd854decda3f493b395c8867f2cd131d95d09fDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 1," + 645f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + 6465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + " TEXT," + 647a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + 6484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0" + 649b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 650b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 65154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 652fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 65354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 65454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 65554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" + 65654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov Contacts.HAS_PHONE_NUMBER + 65754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 65854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 65954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_restricted_index ON " + Tables.CONTACTS + " (" + 66054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + 66154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 66254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 663fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 664fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 665fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 666fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 667b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 6685ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" + 6696cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 6706cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 6716cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 6726cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 6736cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID + " TEXT," + 6746cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 67573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 67633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + 67754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 6786cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 6796cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DEFAULT + "," + 6808e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + 6816cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + " TEXT," + 6826cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 6836cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 6846cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED + " INTEGER," + 68533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 6865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + 6875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + 6885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + 68925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.UNDEFINED + "," + 6905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + " TEXT," + 6915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + " TEXT," + 6925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE LOCALIZED," + 6935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE LOCALIZED," + 694f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + 695fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 0," + 6963cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC1 + " TEXT, " + 6973cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC2 + " TEXT, " + 6983cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC3 + " TEXT, " + 6993cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC4 + " TEXT " + 700b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 701b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 70254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" + 70354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + 70454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 70554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 7065f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" + 7075f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.SOURCE_ID + ", " + 7085f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + ", " + 7095f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + 7105f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 7115f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 712f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // TODO readd the index and investigate a controlled use of it 713f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" + 714f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// RawContactsColumns.AGGREGATION_NEEDED + 715f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// ");"); 7168e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 717b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 718ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 719ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 720ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 721b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 722b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 723ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 724ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 725ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 726ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 727b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 728b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 729b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 730b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 731b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 73267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 733b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 73411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 735f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 736f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 737f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 738f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 739f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 740f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 741f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 742f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 743f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 744f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 745f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 746f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 74767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 74867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 74967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 75067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 75167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 7523cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.DATA15 + " TEXT," + 7533cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC1 + " TEXT, " + 7543cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC2 + " TEXT, " + 7553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC3 + " TEXT, " + 7563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC4 + " TEXT " + 757b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 758b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 75911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" + 76011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + 76111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 76211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 76311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov /** 76411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov * For email lookup and similar queries. 76511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov */ 766f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" + 76711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov DataColumns.MIMETYPE_ID + "," + 768f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov Data.DATA1 + 76911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 77011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 771b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 772b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 773f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.DATA_ID 774f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES data(_id) NOT NULL," + 7755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 7765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 77736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 77836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 779b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 780b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 781b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 782f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 783f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 784b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 785b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 786b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 78736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 78836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 78936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 79036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 79136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 79236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 793a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 794a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 79514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.DATA_ID 79614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 7975ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID 7985ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 79911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," + 80011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," + 80114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "PRIMARY KEY (" 80214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + NameLookupColumns.DATA_ID + ", " 80311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ", " 80411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + ")" + 805a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 806a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 80714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" + 80814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + 80914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov ");"); 81014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 811b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 812b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 813b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 814b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 815b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 816b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 817b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 818b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 819b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 820b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 821ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 822ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 823ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 82467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 825035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 826035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 827ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 8289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 82973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 830ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 83167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 8320f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 8330f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 83494021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + 835eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 836ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + 8373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC1 + " TEXT, " + 8383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC2 + " TEXT, " + 8393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC3 + " TEXT, " + 8403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC4 + " TEXT " + 841ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 842ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 8435f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" + 8445f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.SOURCE_ID + ", " + 8455f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_TYPE + ", " + 8465f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_NAME + 8475f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 8485f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 849b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 850b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 851b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 8520c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 8535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id), " + 8540c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 8555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id)" + 856b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank ");"); 857b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 858b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 859b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8600c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + ", " + 8610c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + 862b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 863b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 864b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 865b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8660c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + ", " + 8670c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + 868b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 869b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 870eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" + 871eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_NAME + " STRING NOT NULL," + 872eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_TYPE + " STRING NOT NULL," + 873eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 874eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1, " + 875eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey "PRIMARY KEY (" + Settings.ACCOUNT_NAME + ", " + 876e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey Settings.ACCOUNT_TYPE + ") ON CONFLICT REPLACE" + 877eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey ");"); 878eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 879e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // The table for recent calls is here so we can do table joins 880e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // on people, phones, and calls all in one place. 881e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CALLS + " (" + 882e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 883e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NUMBER + " TEXT," + 884e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DATE + " INTEGER," + 885e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DURATION + " INTEGER," + 886e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.TYPE + " INTEGER," + 887e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NEW + " INTEGER," + 888e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NAME + " TEXT," + 889e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_TYPE + " INTEGER," + 890e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_LABEL + " TEXT" + 891e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov ");"); 892e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov 893b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 894b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 895b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 89667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 897b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 898b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 899499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 9005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 9015ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 902b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 903499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 904b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 905b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 906adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 907b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 908b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 909b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 910a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" + 911a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 9120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS + " TEXT," + 9130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + 9140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + 9150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_LABEL + " INTEGER, " + 9160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_ICON + " INTEGER" + 917a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ");"); 918a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 919a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createContactsViews(db); 920a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createGroupsView(db); 92146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana createContactEntitiesView(db); 922fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov createContactsTriggers(db); 923916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 9244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 925a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov loadNicknameLookupTable(db); 926a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 927a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // Add the legacy API support views, etc 928a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov LegacyApiSupport.createDatabase(db); 929a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 930a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // This will create a sqlite_stat1 table that is used for query optimization 931a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("ANALYZE;"); 932a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 933a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateSqliteStats(db); 934a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 935a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // We need to close and reopen the database connection so that the stats are 936a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // taken into account. Make a note of it and do the actual reopening in the 937a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // getWritableDatabase method. 938a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov mReopenDatabase = true; 939a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 940a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContentResolver.requestSync(null /* all accounts */, 941a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContactsContract.AUTHORITY, new Bundle()); 942a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 943a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 944916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsTriggers(SQLiteDatabase db) { 945fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 946fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 947fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Automatically delete Data rows when a raw contact is deleted. 948fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 949fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;"); 950fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted " 951fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEFORE DELETE ON " + Tables.RAW_CONTACTS 952fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 953fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.DATA 954fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data.RAW_CONTACT_ID 955fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 956fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS 957fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 958fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID 959fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " OR " + AggregationExceptions.RAW_CONTACT_ID2 960fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 961fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.CONTACTS 962fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 963fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 964fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 965fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " )=1;" 966fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 967fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 968fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 969fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;"); 9706c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;"); 971fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 972fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 973fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Triggers that update {@link RawContacts#VERSION} when the contact is 974fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * marked for deletion or any time a data row is inserted, updated or 975fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * deleted. 976fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 977fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;"); 978fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted " 9797f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.RAW_CONTACTS 980fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 981fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 982fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 983fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 " 984fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID 985fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";" 986fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 987fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 988fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;"); 9897f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 990fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 991fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.DATA 992fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 993fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 994fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 995fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 996fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 997fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 998fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 999fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;"); 1000fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 1001fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1002fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1003fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1004fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1005fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.PHONE_LOOKUP 1006fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1007fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.STATUS_UPDATES 1008fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";" 1009fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.NAME_LOOKUP 1010fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1011fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1012fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1013fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1014fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;"); 1015fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 10167f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.GROUPS 1017fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1018fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.GROUPS 1019fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1020fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + Groups.VERSION + "=OLD." + Groups.VERSION + "+1" 1021fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 1022fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1023fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1024fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1025916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsIndexes(SQLiteDatabase db) { 1026916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 1027916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 1028916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + "," + 1029916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NAME_TYPE + ", " + 1030916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + ", " + 1031916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.DATA_ID + 1032916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov ");"); 103304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 103404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index"); 103504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 103604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 103704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 103804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 103904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 104004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index"); 104104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 104204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 104304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 104404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 1045916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1046916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1047a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createContactsViews(SQLiteDatabase db) { 1048a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_ALL + ";"); 1049a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_RESTRICTED + ";"); 1050a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_ALL + ";"); 1051a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_RESTRICTED + ";"); 1052a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_ALL + ";"); 1053a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_RESTRICTED + ";"); 1054a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 10554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataColumns = 10564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Data.IS_PRIMARY + ", " 10574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.IS_SUPER_PRIMARY + ", " 10584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA_VERSION + ", " 10594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 10604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", " 10614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA1 + ", " 10624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA2 + ", " 10634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA3 + ", " 10644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA4 + ", " 10654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA5 + ", " 10664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA6 + ", " 10674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA7 + ", " 10684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA8 + ", " 10694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA9 + ", " 10704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA10 + ", " 10714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA11 + ", " 10724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA12 + ", " 10734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA13 + ", " 10744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA14 + ", " 10754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA15 + ", " 10764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC1 + ", " 10774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC2 + ", " 10784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC3 + ", " 10794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC4; 10804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 10814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String syncColumns = 10824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 10834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 10844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 1085f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 10864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 10874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 10884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," 10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + "," 10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + "," 10914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4; 10924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 10934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactOptionColumns = 10944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 10954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.CUSTOM_RINGTONE + "," 10964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 10974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.SEND_TO_VOICEMAIL + "," 10984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 10994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.LAST_TIME_CONTACTED + "," 11004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 11014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.TIMES_CONTACTED + "," 11024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 11034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.STARRED; 11044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String contactNameColumns = 11065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE 11075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", " 11085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY 11095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", " 11105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE 11115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", " 11125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME 11135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME + ", " 11145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE 11155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME_STYLE + ", " 11165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY 11175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_PRIMARY + ", " 11185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE 11195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_ALTERNATIVE + ", " 11205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP 11215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.IN_VISIBLE_GROUP; 11225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 11234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataSelect = "SELECT " 11244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Data._ID + "," 11254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.RAW_CONTACT_ID + ", " 1126fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 11274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns + ", " 11284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + dataColumns + ", " 11294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + contactOptionColumns + ", " 11305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 11315870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 11324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Contacts.PHOTO_ID + ", " 1133a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID + ", " 11344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 11354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA 1136a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.MIMETYPES + " ON (" 11374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1138a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " ON (" 11394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1140a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1141fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1142fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1143fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1144a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1145a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 11464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 11474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1148f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1149a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 11504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_ALL + " AS " + dataSelect); 11524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_RESTRICTED + " AS " + dataSelect + " WHERE " 1153fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 11544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactOptionColumns = 11564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + "," 11574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.SEND_TO_VOICEMAIL + "," 11584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "," 11594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "," 11604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.STARRED; 11614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactsSelect = "SELECT " 11634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + "," 11644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 11654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.AGGREGATION_MODE + ", " 11664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.DELETED + ", " 11675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + ", " 11685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_PRIMARY + ", " 11695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_ALTERNATIVE + ", " 11705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME + ", " 11715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME_STYLE + ", " 11725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_PRIMARY + ", " 11735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_ALTERNATIVE + ", " 11744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + rawContactOptionColumns + ", " 11754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns 11764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS; 11774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_ALL + " AS " + rawContactsSelect); 11794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_RESTRICTED + " AS " + rawContactsSelect 11804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 11814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsColumns = 11834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 11844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.CUSTOM_RINGTONE + ", " 11855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 1186f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + Contacts.HAS_PHONE_NUMBER + ", " 11875870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 11885870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov + Contacts.PHOTO_ID + ", " 11894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 11904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED + ", " 11914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 11924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL + ", " 11934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 11944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.STARRED + ", " 11954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 1196a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + " AS " + Contacts.TIMES_CONTACTED + ", " 1197a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID; 11984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsSelect = "SELECT " 12004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + "," 1201f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov + contactsColumns 12024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.CONTACTS 1203fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1204fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"; 12054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_ALL + " AS " + contactsSelect); 1207fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_RESTRICTED + " AS " + contactsSelect 1208fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " WHERE " + ContactsColumns.SINGLE_IS_RESTRICTED + "=0"); 1209a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1211a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createGroupsView(SQLiteDatabase db) { 1212a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS_ALL + ";"); 121389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsColumns = 121489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov Groups.ACCOUNT_NAME + "," 121589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.ACCOUNT_TYPE + "," 121689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SOURCE_ID + "," 121789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.VERSION + "," 121889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DIRTY + "," 121989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE + "," 122089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE_RES + "," 122189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.NOTES + "," 122289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYSTEM_ID + "," 122389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DELETED + "," 122489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.GROUP_VISIBLE + "," 122589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SHOULD_SYNC + "," 122689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC1 + "," 122789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC2 + "," 122889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC3 + "," 122989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC4 + "," 123089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE; 123189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 123289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsSelect = "SELECT " 123389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + "," 123489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + groupsColumns 123589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + " FROM " + Tables.GROUPS_JOIN_PACKAGES; 123689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 123789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.GROUPS_ALL + " AS " + groupsSelect); 1238b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1239b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 124046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana private static void createContactEntitiesView(SQLiteDatabase db) { 1241a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Tables.CONTACT_ENTITIES + ";"); 1242a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Tables.CONTACT_ENTITIES_RESTRICTED + ";"); 1243a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 124446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana String contactEntitiesSelect = "SELECT " 124546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 124646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 124746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 124846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 124946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 125046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1251f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 125246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 125346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContacts.CONTACT_ID + ", " 125446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + ", " 125546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + ", " 125646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + ", " 125746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4 + ", " 125846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.MIMETYPE + ", " 125946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA1 + ", " 126046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA2 + ", " 126146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA3 + ", " 126246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA4 + ", " 126346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA5 + ", " 126446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA6 + ", " 126546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA7 + ", " 126646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA8 + ", " 126746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA9 + ", " 126846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA10 + ", " 126946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA11 + ", " 127046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA12 + ", " 127146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA13 + ", " 127246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA14 + ", " 127346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA15 + ", " 127446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC1 + ", " 127546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC2 + ", " 127646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC3 + ", " 127746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.SYNC4 + ", " 127846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", " 127946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.IS_PRIMARY + ", " 128046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.IS_SUPER_PRIMARY + ", " 128146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Data.DATA_VERSION + ", " 128246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + "," 128346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + "," 1284bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey + RawContactsColumns.CONCRETE_IS_RESTRICTED + " AS " 1285bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey + RawContacts.IS_RESTRICTED + "," 128646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 128746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " FROM " + Tables.RAW_CONTACTS 128846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 128946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 129046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 129146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 129246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 129346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 129446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 129546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 129646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + "' AND " + GroupsColumns.CONCRETE_ID + "=" 129746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 129846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 129946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("CREATE VIEW " + Tables.CONTACT_ENTITIES + " AS " 130046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + contactEntitiesSelect); 130146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("CREATE VIEW " + Tables.CONTACT_ENTITIES_RESTRICTED + " AS " 130246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + contactEntitiesSelect + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 130346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 130446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1305b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 1306b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 130746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion < 99) { 130846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 130946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + ", data will be lost!"); 131046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 131146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 131246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";"); 131346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 131446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 131546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 131646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 131746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 131846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 131946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 132046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 132146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";"); 132246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";"); 132346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";"); 132446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 132546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // TODO: we should not be dropping agg_exceptions and contact_options. In case that 132646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // table's schema changes, we should try to preserve the data, because it was entered 132746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // by the user and has never been synched to the server. 132846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 132946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 133046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana onCreate(db); 133146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana return; 133246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1333f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 133446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion); 1335a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 133608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov boolean upgradeViewsAndTriggers = false; 133704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov boolean upgradeNameLookup = false; 133808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 133946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion == 99) { 134008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 134146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana oldVersion++; 134246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 134346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1344a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov if (oldVersion == 100) { 1345a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON " 1346a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.MIMETYPES + " (" 1347a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns.MIMETYPE + "," 1348a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns._ID + ");"); 1349a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateIndexStats(db, Tables.MIMETYPES, 1350a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov "mimetypes_mimetype_index", "50 1 1"); 1351a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 135208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1353a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov oldVersion++; 1354a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1355a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1356fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov if (oldVersion == 101) { 135708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1358fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov oldVersion++; 1359fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1360fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 136147ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov if (oldVersion == 102) { 136208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 136347ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov oldVersion++; 136447ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov } 136547ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov 136636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (oldVersion == 103) { 136708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1368bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey oldVersion++; 1369bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey } 1370bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey 137171037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 104 || oldVersion == 201) { 137271037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov LegacyApiSupport.createSettingsTable(db); 137308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 13743410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion++; 13753410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov } 13763410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov 137771037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 105) { 13785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion202(db); 137904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov upgradeNameLookup = true; 13803410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion = 202; 138136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 138236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 1383fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov if (oldVersion == 202) { 13845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion203(db); 138508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1386fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov oldVersion++; 1387fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1388fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 13899b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori if (oldVersion == 203) { 139008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 13919b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori oldVersion++; 13929b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori } 13939b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori 13945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (oldVersion == 204) { 13955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion205(db); 139608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 13975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov oldVersion++; 13985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 13995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1400f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov if (oldVersion == 205) { 1401f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgrateToVersion206(db); 1402f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgradeViewsAndTriggers = true; 1403f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov oldVersion++; 1404f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1405f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 140631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (oldVersion == 206) { 1407b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeToVersion300(db); 140834469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov oldVersion = 300; 140931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 141031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 14116c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook if (oldVersion == 300) { 14126c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook upgradeViewsAndTriggers = true; 14136c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook oldVersion = 301; 14146c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook } 14156c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook 1416916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov if (oldVersion == 301) { 1417916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov upgradeViewsAndTriggers = true; 1418916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov oldVersion = 302; 1419916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1420916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1421b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (oldVersion == 302) { 1422b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeEmailToVersion303(db); 1423b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeNicknameToVersion303(db); 1424b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov oldVersion = 303; 1425b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1426b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 142708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov if (upgradeViewsAndTriggers) { 142808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsViews(db); 142908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createGroupsView(db); 143008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactEntitiesView(db); 143108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsTriggers(db); 1432916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 143308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov LegacyApiSupport.createViews(db); 1434916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov updateSqliteStats(db); 1435916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov mReopenDatabase = true; 143608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov } 143708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 143804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (upgradeNameLookup) { 143904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rebuildNameLookup(db); 144004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 144104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 144246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion != newVersion) { 144346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana throw new IllegalStateException( 144446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana "error upgrading the database to version " + newVersion); 144546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1446b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1447b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 14485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion202(SQLiteDatabase db) { 144936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL( 145036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "ALTER TABLE " + Tables.PHONE_LOOKUP + 145136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;"); 145236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 145336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 145436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 145536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 145636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 145736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 145836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 145936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 146036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 146136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 146236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov SQLiteStatement update = db.compileStatement( 146336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "UPDATE " + Tables.PHONE_LOOKUP + 146436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " SET " + PhoneLookupColumns.MIN_MATCH + "=?" + 146536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " WHERE " + PhoneLookupColumns.DATA_ID + "=?"); 146636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 146736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov // Populate the new column 146836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA + 146936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")", 147036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null); 147136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov try { 147236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov while (c.moveToNext()) { 147336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov long dataId = c.getLong(0); 147436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String number = c.getString(1); 147536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 147636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number)); 147736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindLong(2, dataId); 147836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.execute(); 147936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 148036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 148136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } finally { 148236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov c.close(); 148336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 148436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 148536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 14865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion203(SQLiteDatabase db) { 1487fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1488fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.CONTACTS + 1489fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)"); 1490fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1491fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.RAW_CONTACTS + 1492fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP 1493fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " INTEGER NOT NULL DEFAULT 0"); 1494fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1495fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // For each Contact, find the RawContact that contributed the display name 1496fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1497fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1498fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1499fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1500fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1501fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1502fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" + 1503fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.CONTACTS + "." + Contacts.DISPLAY_NAME + 1504fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1505fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" 1506fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1507fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1508fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 1509fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 1510fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1511fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1512fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // If for some unknown reason we missed some names, let's make sure there are 1513fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // no contacts without a name, picking a raw contact "at random". 1514fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1515fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1516fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1517fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1518fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1519fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1520fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1521fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" + 1522fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL" 1523fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1524fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1525fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use. 1526fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1527fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1528fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.DISPLAY_NAME + "=NULL" 1529fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1530fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1531fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow 1532fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // indexing on (display_name, in_visible_group) 1533fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1534fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 1535fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "=(" + 1536fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 1537fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.CONTACTS + 1538bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" + 1539bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " NOT NULL" 1540fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1541fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1542fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 1543fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 1544fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" + 1545fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1546fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1547fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 1548fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 1549fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 1550fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1551fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1552fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 15535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion205(SQLiteDatabase db) { 15545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 15555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;"); 15565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 15575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;"); 15585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 15595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;"); 15605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 15615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE LOCALIZED;"); 15625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 15635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE LOCALIZED;"); 15645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov final Locale locale = Locale.getDefault(); 15665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter = new NameSplitter( 15685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 15695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 15705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 15715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 15725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov locale); 15735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate = db.compileStatement( 15755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 15765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 15775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 15785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 15795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 15805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 15815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 15825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 15835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 15845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter); 15865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter); 15875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 15895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 15905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 15915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 15925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 15935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 15945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 15955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContactsColumns.CONTACT_IN_VISIBLE_GROUP + "," + 15965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 15975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 15985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 15995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface StructName205Query { 16015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 16025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 16045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 16055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 16065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE, 16075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY, 16085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PREFIX, 16095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.GIVEN_NAME, 16105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.MIDDLE_NAME, 16115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FAMILY_NAME, 16125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.SUFFIX, 16135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_FAMILY_NAME, 16145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_MIDDLE_NAME, 16155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_GIVEN_NAME, 16165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 16175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 16195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 16205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME_SOURCE = 2; 16215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME = 3; 16225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PREFIX = 4; 16235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int GIVEN_NAME = 5; 16245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int MIDDLE_NAME = 6; 16255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int FAMILY_NAME = 7; 16265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int SUFFIX = 8; 16275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_FAMILY_NAME = 9; 16285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_MIDDLE_NAME = 10; 16295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_GIVEN_NAME = 11; 16305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeStructuredNamesToVersion205(SQLiteDatabase db, 16335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 16345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // Process structured names to detect the style of the full name and phonetic name 16365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long mMimeType; 16385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 16395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mMimeType = DatabaseUtils.longForQuery(db, 16405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 16415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 16425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 16435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null); 16445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } catch (SQLiteDoneException e) { 16455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // No structured names in the database 16465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return; 16475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate = db.compileStatement( 16505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 16515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 16525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FULL_NAME_STYLE + "=?," + 16535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.DISPLAY_NAME + "=?," + 16545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_NAME_STYLE + "=?" + 16555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 16565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 16585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 16595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(StructName205Query.TABLE, 16605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructName205Query.COLUMNS, 16615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null); 16625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 16635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 16645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(StructName205Query.ID); 16655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID); 16665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE); 16675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = cursor.getString(StructName205Query.DISPLAY_NAME); 16685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.clear(); 16705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.prefix = cursor.getString(StructName205Query.PREFIX); 16715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME); 16725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME); 16735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.familyName = cursor.getString(StructName205Query.FAMILY_NAME); 16745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.suffix = cursor.getString(StructName205Query.SUFFIX); 16755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME); 16765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME); 16775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME); 16785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name, 16805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate, rawContactUpdate, splitter, sb); 16815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 16835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 16845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 16865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource, 16885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String currentDisplayName, NameSplitter.Name name, 16895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate, 16905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter, StringBuilder sb) { 16915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov splitter.guessNameStyle(name); 16935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle); 16945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = splitter.join(name, true); 16955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 16965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(1, name.fullNameStyle); 16975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName); 16985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(3, name.phoneticNameStyle); 16995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(4, dataId); 17005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.execute(); 17015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) { 17035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayNameAlternative = splitter.join(name, false); 17045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = splitter.joinPhoneticName(name); 17055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 17065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKeyAlternative = null; 17075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName != null) { 17095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = phoneticName; 17105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else if (name.fullNameStyle == FullNameStyle.CHINESE) { 17115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = splitter.convertHanziToPinyin(displayName); 17125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 17155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = displayName; 17165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative = displayNameAlternative; 17175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, displayName, 17205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey, 17215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative); 17225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface Organization205Query { 17265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 17275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 17295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 17305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 17315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.COMPANY, 17325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME, 17335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 17345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 17365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 17375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int COMPANY = 2; 17385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_NAME = 3; 17395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeOrganizationsToVersion205(SQLiteDatabase db, 17425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 1743b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 17445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement organizationUpdate = db.compileStatement( 17465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 17475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 17485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME_STYLE + "=?" + 17495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 17505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS, 1752b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mimeType + " AND " 17535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION, 17545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov null, null, null, null); 17555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 17565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 17575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(Organization205Query.ID); 17585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID); 17595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String company = cursor.getString(Organization205Query.COMPANY); 17605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME); 17615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName); 17635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(1, phoneticNameStyle); 17655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(2, dataId); 17665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.execute(); 17675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 17695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName == null && company != null) { 17705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int nameStyle = splitter.guessFullNameStyle(company); 17715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov nameStyle = splitter.getAdjustedFullNameStyle(nameStyle); 17725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (nameStyle == FullNameStyle.CHINESE) { 17735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = splitter.convertHanziToPinyin(company); 17745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 17785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = company; 17795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, company, 17825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov company, phoneticNameStyle, phoneticName, sortKey, sortKey); 17835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 17855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 17865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 17885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 17895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId, 17905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName, String displayNameAlternative, int phoneticNameStyle, 17915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName, String sortKeyPrimary, String sortKeyAlternative) { 17925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 1, displayName); 17935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 2, displayNameAlternative); 17945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 3, phoneticName); 17955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(4, phoneticNameStyle); 17965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 5, sortKeyPrimary); 17975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 6, sortKeyAlternative); 17985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(7, rawContactId); 17995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.execute(); 18005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1802f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov private void upgrateToVersion206(SQLiteDatabase db) { 1803f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1804f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); 1805f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1806f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 180731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov private interface Organization300Query { 180831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String TABLE = Tables.DATA; 180931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 181031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String SELECTION = DataColumns.MIMETYPE_ID + "=?"; 181131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 181231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String COLUMNS[] = { 181331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization._ID, 181431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.RAW_CONTACT_ID, 181531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.COMPANY, 181631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.TITLE 181731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov }; 181831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 181931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int ID = 0; 182031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int RAW_CONTACT_ID = 1; 182131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int COMPANY = 2; 182231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int TITLE = 3; 182331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 182431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 182531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov /** 182631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * Fix for the bug where name lookup records for organizations would get removed by 182731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * unrelated updates of the data rows. 182831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov */ 1829b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeToVersion300(SQLiteDatabase db) { 1830b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 1831b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeType == -1) { 183231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov return; 183331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 183431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 183531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov ContentValues values = new ContentValues(); 183631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 183731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Find all data rows with the mime type "organization" 183831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Cursor cursor = db.query(Organization300Query.TABLE, Organization300Query.COLUMNS, 1839b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Organization300Query.SELECTION, new String[] {String.valueOf(mimeType)}, 184031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov null, null, null); 184131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov try { 184231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov while (cursor.moveToNext()) { 184331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long dataId = cursor.getLong(Organization300Query.ID); 184431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long rawContactId = cursor.getLong(Organization300Query.RAW_CONTACT_ID); 184531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String company = cursor.getString(Organization300Query.COMPANY); 184631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String title = cursor.getString(Organization300Query.TITLE); 184731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 184831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // First delete name lookup if there is any (chances are there won't be) 184931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.delete(Tables.NAME_LOOKUP, NameLookupColumns.DATA_ID + "=?", 185031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov new String[]{String.valueOf(dataId)}); 185131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 185231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Now insert two name lookup records: one for company name, one for title 185331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 185431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 185531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.ORGANIZATION); 185631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 185731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(company)) { 185831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 185931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(company)); 186031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 186131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 186231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 186331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(title)) { 186431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 186531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(title)); 186631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 186731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 186831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 186931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } finally { 187031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov cursor.close(); 187131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 187231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 187331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 1874b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final class Upgrade303Query { 1875b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String TABLE = Tables.DATA; 1876b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1877b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String SELECTION = 1878b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=?" + 1879b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " AND " + Data._ID + " NOT IN " + 1880b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" + 1881b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " AND " + Data.DATA1 + " NOT NULL"; 1882b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1883b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String COLUMNS[] = { 1884b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data._ID, 1885b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.RAW_CONTACT_ID, 1886b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.DATA1, 1887b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov }; 1888b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1889b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int ID = 0; 1890b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 1891b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int DATA1 = 2; 1892b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1893b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1894b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 1895b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 1896b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * emails during the sync. We need to restore the lost name lookup rows. 1897b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 1898b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeEmailToVersion303(SQLiteDatabase db) { 1899b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 1900b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 1901b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 1902b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1903b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1904b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 1905b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1906b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "email" that are missing name lookup 1907b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 1908b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 1909b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 1910b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 1911b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 1912b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 1913b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 1914b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 1915b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov value = extractHandleFromEmailAddress(value); 1916b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1917b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (value != null) { 1918b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 1919b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 1920b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME); 1921b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 1922b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 1923b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1924b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1925b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 1926b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 1927b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1928b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1929b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1930b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 1931b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 1932b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * nicknames during the sync. We need to restore the lost name lookup rows. 1933b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 1934b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeNicknameToVersion303(SQLiteDatabase db) { 1935b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 1936b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 1937b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 1938b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1939b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1940b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 1941b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1942b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "nickname" that are missing name lookup 1943b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 1944b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 1945b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 1946b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 1947b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 1948b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 1949b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 1950b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 1951b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 1952b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 1953b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 1954b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME); 1955b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 1956b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 1957b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1958b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 1959b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 1960b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1961b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1962b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 196304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 196404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Regenerate all rows in the nickname_lookup and name_lookup tables, 196504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * because sort key generation algorithm has been modified, e.g. as a result of 196604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * locale change. 196704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 196804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void rebuildNameLookup(SQLiteDatabase db) { 196904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP); 197004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov loadNicknameLookupTable(db); 197104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 197204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 197304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP); 197404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 197504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov SQLiteStatement nameLookupInsert = db.compileStatement( 197604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 197704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 197804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 197904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 198004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + 198104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ") VALUES (?,?,?,?)"); 198204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 198304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertStructuredNameLookup(db, nameLookupInsert); 198404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertOrganizationLookup(db, nameLookupInsert); 198504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertEmailLookup(db, nameLookupInsert); 198604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNicknameLookup(db, nameLookupInsert); 198704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 198804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov createContactsIndexes(db); 198904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 199004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 199104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class StructuredNameQuery { 199204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 199304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 199404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 199504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 199604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 199704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 199804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName._ID, 199904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.RAW_CONTACT_ID, 200004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.DISPLAY_NAME, 200104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 200204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 200304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 200404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 200504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int DISPLAY_NAME = 2; 200604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 200704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 200804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private class StructuredNameLookupBuilder extends NameLookupBuilder { 200904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 201004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final SQLiteStatement mNameLookupInsert; 201104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final CommonNicknameCache mCommonNicknameCache; 201204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 201304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public StructuredNameLookupBuilder(NameSplitter splitter, 201404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) { 201504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov super(splitter); 201604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mCommonNicknameCache = commonNicknameCache; 201704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mNameLookupInsert = nameLookupInsert; 201804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 201904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 202004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 202104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected void insertNameLookup(long rawContactId, long dataId, int lookupType, 202204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name) { 202304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (!TextUtils.isEmpty(name)) { 202404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert, 202504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rawContactId, dataId, lookupType, name); 202604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 202704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 202804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 202904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 203004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected String[] getCommonNicknameClusters(String normalizedName) { 203104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return mCommonNicknameCache.getCommonNicknameClusters(normalizedName); 203204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 203304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 203404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 203504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 203604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all structured names in the database. 203704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 203804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 203904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(createNameSplitter(), 204004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov new CommonNicknameCache(db), nameLookupInsert); 204104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE); 204204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS, 204304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 204404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 204504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 204604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 204704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(StructuredNameQuery.ID); 204804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID); 204904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME); 205004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov nameLookupBuilder.insertNameLookup(rawContactId, dataId, name); 205104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 205204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 205304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 205404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 205504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 205604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 205704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class OrganizationQuery { 205804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 205904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 206004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 206104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 206204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 206304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 206404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization._ID, 206504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.RAW_CONTACT_ID, 206604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.COMPANY, 206704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.TITLE, 206804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 206904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 207004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 207104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 207204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int COMPANY = 2; 207304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int TITLE = 3; 207404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 207504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 207604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 207704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all organizations in the database. 207804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 207904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertOrganizationLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 208004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 208104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(OrganizationQuery.TABLE, OrganizationQuery.COLUMNS, 208204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov OrganizationQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 208304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 208404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 208504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 208604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(OrganizationQuery.ID); 208704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(OrganizationQuery.RAW_CONTACT_ID); 208804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String organization = cursor.getString(OrganizationQuery.COMPANY); 208904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String title = cursor.getString(OrganizationQuery.TITLE); 209004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 209104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, organization); 209204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 209304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, title); 209404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 209504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 209604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 209704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 209804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 209904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 210004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class EmailQuery { 210104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 210204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 210304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 210404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 210504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 210604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 210704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email._ID, 210804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.RAW_CONTACT_ID, 210904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.ADDRESS, 211004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 211104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 211204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 211304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 211404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ADDRESS = 2; 211504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 211604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 211704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 211804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all email addresses in the database. 211904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 212004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 212104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 212204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS, 212304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 212404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 212504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 212604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 212704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(EmailQuery.ID); 212804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID); 212904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String address = cursor.getString(EmailQuery.ADDRESS); 213004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov address = extractHandleFromEmailAddress(address); 213104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 213204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, address); 213304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 213404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 213504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 213604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 213704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 213804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 213904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class NicknameQuery { 214004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 214104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 214204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 214304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 214404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 214504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 214604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname._ID, 214704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.RAW_CONTACT_ID, 214804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.NAME, 214904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 215004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 215104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 215204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 215304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int NAME = 2; 215404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 215504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 215604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 215704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all nicknames in the database. 215804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 215904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 216004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 216104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS, 216204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 216304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 216404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 216504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 216604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(NicknameQuery.ID); 216704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID); 216804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String nickname = cursor.getString(NicknameQuery.NAME); 216904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 217004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.NICKNAME, nickname); 217104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 217204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 217304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 217404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 217504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 217604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 217704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 217804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 217904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 218004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 218104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String name) { 218204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 218304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 218404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 218504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 218604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String normalized = NameNormalizer.normalize(name); 218704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(normalized)) { 218804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 218904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 219004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 219104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized); 219204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 219304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 219404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 219504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String normalizedName) { 219604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(1, rawContactId); 219704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(2, dataId); 219804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(3, lookupType); 219904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindString(4, normalizedName); 220004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.executeInsert(); 220104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 220204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2203b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public String extractHandleFromEmailAddress(String email) { 2204b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 2205b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (tokens.length == 0) { 2206b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2207b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2208b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2209b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String address = tokens[0].getAddress(); 2210b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov int at = address.indexOf('@'); 2211b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (at != -1) { 2212b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return address.substring(0, at); 2213b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2214b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2215b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2216b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2217b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private long lookupMimeTypeId(SQLiteDatabase db, String mimeType) { 2218b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2219b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return DatabaseUtils.longForQuery(db, 2220b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 2221b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 2222b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 2223b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov + "='" + mimeType + "'", null); 2224b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } catch (SQLiteDoneException e) { 2225b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // No rows of this type in the database 2226b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return -1; 2227b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2228b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2229b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 22305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void bindString(SQLiteStatement stmt, int index, String value) { 22315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (value == null) { 22325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindNull(index); 22335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else { 22345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindString(index, value); 22355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 22365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 22375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2238a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 2239f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Adds index stats into the SQLite database to force it to always use the lookup indexes. 2240f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 2241f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private void updateSqliteStats(SQLiteDatabase db) { 2242f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2243f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // Specific stats strings are based on an actual large database after running ANALYZE 2244f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov try { 22458fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 22468fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_restricted_index", "10000 9000"); 22478fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 22488fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_has_phone_index", "10000 500"); 22498fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 2250737858a04a157a0afad9ec81372c75d14bf68788Jeff Hamilton "contacts_visible_index", "10000 500 1"); 22518fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22528fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 22538fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_source_id_index", "10000 1 1 1"); 22548fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 22558fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_contact_id_index", "10000 2"); 22568fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22578fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 22588fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "name_lookup_raw_contact_id_index", "10000 3"); 22598fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 2260916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov "name_lookup_index", "10000 3 2 2 1"); 22618fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 22628fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "10000 3 2 1"); 22638fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22648fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 22658fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "phone_lookup_index", "10000 2 2 1"); 226636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 226736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 22688fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22698fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 22708fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_mimetype_data1_index", "60000 5000 2"); 22718fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 22728fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_raw_contact_id", "60000 10"); 22738fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22748fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.GROUPS, 22758fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "groups_source_id_index", "50 1 1 1"); 22768fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 22778fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NICKNAME_LOOKUP, 22788fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "500 2 1"); 22798fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 2280f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } catch (SQLException e) { 2281f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov Log.e(TAG, "Could not update index stats", e); 2282f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2283f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2284f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2285f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2286f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Stores statistics for a given index. 2287f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * 2288f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * @param stats has the following structure: the first index is the expected size of 2289f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * the table. The following integer(s) are the expected number of records selected with the 2290f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * index. There should be one integer per indexed column. 2291f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 22925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateIndexStats(SQLiteDatabase db, String table, String index, 22935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String stats) { 2294f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';"); 2295f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)" 2296f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " VALUES ('" + table + "','" + index + "','" + stats + "');"); 2297f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2298f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2299f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov @Override 2300f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov public synchronized SQLiteDatabase getWritableDatabase() { 2301f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov SQLiteDatabase db = super.getWritableDatabase(); 2302f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov if (mReopenDatabase) { 2303f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov mReopenDatabase = false; 2304f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov close(); 2305f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db = super.getWritableDatabase(); 2306f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2307f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov return db; 2308f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2309f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2310f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2311a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 2312a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 2313a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 2314a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 23153d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 2316d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 23175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";"); 2318a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 2319a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 2320a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 2321ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 2322b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 2323eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("DELETE FROM " + Tables.SETTINGS + ";"); 2324a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 23253d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CALLS + ";"); 2326b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2327b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 2328a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 2329b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 233004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public NameSplitter createNameSplitter() { 233104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return new NameSplitter( 233204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 233304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 233404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 233504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 233604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Locale.getDefault()); 233704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 233804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2339b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2340619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 2341619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2342619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 2343619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 2344619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 2345619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 2346619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 2347619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 2348619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2349619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2350619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2351619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2352b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 2353b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 2354b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 2355b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 2356b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 2357b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 2358b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 2359b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 2360b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 2361b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 2362b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 2363b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2364f4a3b7e523e36679b68edd2af632e26648758ff2Dmitri Plotnikov private long getCachedId(SQLiteStatement query, SQLiteStatement insert, 2365b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 2366b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 2367b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 2368b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 2369b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2370b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2371b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey long id = -1; 2372b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2373b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try searching database for mapping 2374b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(query, 1, value); 2375b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = query.simpleQueryForLong(); 2376b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2377b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Nothing found, so try inserting new mapping 2378b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(insert, 1, value); 2379b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = insert.executeInsert(); 2380b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2381b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2382b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (id != -1) { 2383b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Cache and return the new answer 2384b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey cache.put(value, id); 2385b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return id; 2386b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } else { 2387b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Otherwise throw if no mapping found or created 2388b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey throw new IllegalStateException("Couldn't find or create internal " 2389b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + "lookup table entry for value " + value); 2390b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2391b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2392b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2393b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2394ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 2395b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2396b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2397b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 2398b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2399b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2400b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 2401b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2402b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2403b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2404ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 2405b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2406b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2407b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 2408b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2409b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 24105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return getMimeTypeIdNoDbCheck(mimetype); 24115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 24125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 24135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private long getMimeTypeIdNoDbCheck(String mimetype) { 2414b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 2415b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2416b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2417b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2418ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 2419b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2420b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 2421b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2422b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2423b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2424b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2425b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 2426b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 2427b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2428b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2429b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2430b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2431b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2432b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2433b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2434b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2435b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 2436b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2437b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 2438b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2439b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2440b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2441b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2442b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 2443b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 2444b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2445b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2446b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2447b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2448b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2449b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 24506bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 24516bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 2452d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts. 2453ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 2454ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 24558be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 2456ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 24578be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)}; 24588be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 24598be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // There are a couple questions that can be asked regarding the 24608be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // following two update statements: 24618be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 24628be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Q: Why do we run these two queries separately? They seem like they could be combined. 24638be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // A: This is a result of painstaking experimentation. Turns out that the most 24648be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // important optimization is to make sure we never update a value to its current value. 24658be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Changing 0 to 0 is unexpectedly expensive - SQLite actually writes the unchanged 24668be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // rows back to disk. The other consideration is that the CONTACT_IS_VISIBLE condition 24678be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // is very complex and executing it twice in the same statement ("if contact_visible != 24688be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // CONTACT_IS_VISIBLE change it to CONTACT_IS_VISIBLE") is more expensive than running 24698be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // two update statements. 24708be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 24718be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Q: How come we are using db.update instead of compiled statements? 24728be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // A: This is a limitation of the compiled statement API. It does not return the 24738be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // number of rows changed. As you will see later in this method we really need 24748be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // to know how many rows have been changed. 24758be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 24768be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // First update contacts that are currently marked as invisible, but need to be visible 24778be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov ContentValues values = new ContentValues(); 24788be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov values.put(Contacts.IN_VISIBLE_GROUP, 1); 24798be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov int countMadeVisible = db.update(Tables.CONTACTS, values, 24808be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + "=0" + " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1", 24818be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov selectionArgs); 24828be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 24838be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Next update contacts that are currently marked as visible, but need to be invisible 24848be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov values.put(Contacts.IN_VISIBLE_GROUP, 0); 24858be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov int countMadeInvisible = db.update(Tables.CONTACTS, values, 24868be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + "=1" + " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=0", 24878be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov selectionArgs); 24888be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov 24898be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov if (countMadeVisible != 0 || countMadeInvisible != 0) { 24908be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // TODO break out the fields (contact_in_visible_group, sort_key, sort_key_alt) into 24918be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // a separate table. 24928be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // Rationale: The following statement will take a very long time on 24938be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // a large database even though we are only changing one field from 0 to 1 or from 24948be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // 1 to 0. The reason for the slowness is that SQLite will need to write the whole 24958be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // page even when only one bit on it changes. Changing the visibility of a 24968be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // significant number of contacts will likely read and write almost the entire 24978be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // raw_contacts table. So, the solution is to break out into a separate table 24988be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // the changing field along with the sort keys used for index-based sorting. 24998be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // That table will occupy a smaller number of pages, so rewriting it would 25008be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov // not be as expensive. 25018be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov mVisibleUpdateRawContacts.execute(); 25028be93f4d062ad3919ba48245dd147a49715db82dDmitri Plotnikov } 2503ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2504ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2505ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 2506d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for a specific contact. 2507ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 2508fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public void updateContactVisible(long contactId) { 2509ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 2510ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.bindLong(1, groupMembershipMimetypeId); 2511fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdate.bindLong(2, contactId); 2512ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mVisibleSpecificUpdate.execute(); 2513fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 2514fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdateRawContacts.bindLong(1, contactId); 2515fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov mVisibleSpecificUpdateRawContacts.execute(); 2516ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 2517ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 2518ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 2519d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Returns contact ID for the given contact or zero if it is NULL. 25206bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 2521d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public long getContactId(long rawContactId) { 25226bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov getReadableDatabase(); 25236bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 2524d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId); 2525d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactIdQuery.simpleQueryForLong(); 25266bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 2527a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana // No valid mapping found, so return 0 25286bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 25296bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 25306bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 253161bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 25325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int getAggregationMode(long rawContactId) { 2533f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov getReadableDatabase(); 2534f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 25355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId); 2536f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 2537f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 25386cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // No valid row found, so return "disabled" 25396cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.AGGREGATION_MODE_DISABLED; 2540f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2541f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2542f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 2543e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public void buildPhoneLookupAndRawContactQuery(SQLiteQueryBuilder qb, String number) { 254436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2545f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov qb.setTables(Tables.DATA_JOIN_RAW_CONTACTS + 2546f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov " JOIN " + Tables.PHONE_LOOKUP 2547f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " ON(" + DataColumns.CONCRETE_ID + "=" + PhoneLookupColumns.DATA_ID + ")"); 2548f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2549e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 255036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(PhoneLookupColumns.MIN_MATCH + "='"); 255136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 255236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("' AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", "); 2553f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 255436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)"); 2555e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2556e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 2557e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2558e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2559e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public void buildPhoneLookupAndContactQuery(SQLiteQueryBuilder qb, String number) { 256036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2561e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 256236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, true); 2563e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setTables(sb.toString()); 2564e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2565e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb = new StringBuilder(); 2566e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov appendPhoneLookupSelection(sb, number); 2567e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 2568bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 2569bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 2570e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public String buildPhoneLookupAsNestedQuery(String number) { 2571e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 257236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 2573e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id" + " FROM "); 257436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, false); 2575e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(" WHERE "); 2576e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov appendPhoneLookupSelection(sb, number); 2577e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(")"); 2578e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov return sb.toString(); 2579e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2580e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 258136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private void appendPhoneLookupTables(StringBuilder sb, final String minMatch, 2582e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov boolean joinContacts) { 2583e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(Tables.RAW_CONTACTS); 2584e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov if (joinContacts) { 2585fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov sb.append(" JOIN " + getContactView() + " contacts_view" 2586fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " ON (contacts_view._id = raw_contacts.contact_id)"); 2587e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2588e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(", (SELECT data_id FROM phone_lookup " 258936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov + "WHERE (" + Tables.PHONE_LOOKUP + "." + PhoneLookupColumns.MIN_MATCH + " = '"); 259036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 259136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("')) AS lookup, " + Tables.DATA); 2592e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 2593e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 2594e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov private void appendPhoneLookupSelection(StringBuilder sb, String number) { 2595e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id" 2596fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov + " AND PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", "); 2597fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 259836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(mUseStrictPhoneNumberComparison ? ", 1)" : ", 0)"); 259936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 260036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 260136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public String getUseStrictPhoneNumberComparisonParameter() { 260236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov return mUseStrictPhoneNumberComparison ? "1" : "0"; 2603fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov } 2604bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 2605619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2606b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 2607b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 2608b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 260928f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 261028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 2611b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 2612b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 2613b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2614b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2615b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 2616b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 2617b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 2618b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2619b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 2620b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String[] names = strings[clusterId].split(","); 2621b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov for (int j = 0; j < names.length; j++) { 2622b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 2623b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov try { 2624b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 2625b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 2626b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov String.valueOf(clusterId)); 2627b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov nicknameLookupInsert.executeInsert(); 2628b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } catch (SQLiteException e) { 2629b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2630b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Print the exception and keep going - this is not a fatal error 2631b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 2632b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2633b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2634b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2635b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 2636b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2637f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 2638f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 2639f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 2640f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 2641f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2642f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2643f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 2644f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 2645f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 2646f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 2647f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 2648f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 2649f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 2650f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 2651f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 2652f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 2653f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 2654f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 26551b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov } else if (value instanceof String) { 26561b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = Long.parseLong((String)value); 2657f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 26581b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = ((Number)value).longValue(); 2659f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2660f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 2661f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2662f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 2663f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 266435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 266535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 266635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 2667c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2668c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov /** 2669c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Delete the aggregate contact if it has no constituent raw contacts other 2670c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * than the supplied one. 2671c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 2672c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov public void removeContactIfSingleton(long rawContactId) { 2673c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 2674c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2675c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Obtain contact ID from the supplied raw contact ID 2676c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM " 2677c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")"; 2678c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2679c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Find other raw contacts in the same aggregate contact 2680c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM " 2681c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON (" 2682c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID 2683c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + "" 2684c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")"; 2685c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 2686c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS 2687c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId 2688c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND NOT EXISTS " + otherRawContacts + ";"); 2689c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 26904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 26914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 26924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Check if {@link Binder#getCallingUid()} should be allowed access to 26934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * {@link RawContacts#IS_RESTRICTED} data. 26944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 2695d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData() { 26964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 26974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(Binder.getCallingUid()); 26984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 26994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Has restricted access if caller matches any packages 27004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov for (String callerPackage : callerPackages) { 2701d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (hasAccessToRestrictedData(callerPackage)) { 2702763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return true; 2703763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2704763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2705763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return false; 2706763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2707763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 2708763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar /** 2709763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * Check if requestingPackage should be allowed access to 2710763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * {@link RawContacts#IS_RESTRICTED} data. 2711763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar */ 2712d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData(String requestingPackage) { 2713d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (mUnrestrictedPackages != null) { 2714d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton for (String allowedPackage : mUnrestrictedPackages) { 2715d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (allowedPackage.equals(requestingPackage)) { 2716d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return true; 2717d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton } 27184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov return false; 27214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 27234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getDataView() { 2724d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getDataView(false); 2725d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 2726d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 2727d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getDataView(boolean requireRestrictedView) { 2728d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2729d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Views.DATA_ALL : Views.DATA_RESTRICTED; 27304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 27324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getRawContactView() { 2733763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getRawContactView(false); 2734763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 2735763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 2736763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getRawContactView(boolean requireRestrictedView) { 2737d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2738763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.RAW_CONTACTS_ALL : Views.RAW_CONTACTS_RESTRICTED; 27394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 27414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getContactView() { 2742763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getContactView(false); 27434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 27444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2745763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getContactView(boolean requireRestrictedView) { 2746d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2747763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.CONTACTS_ALL : Views.CONTACTS_RESTRICTED; 2748f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey } 2749f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey 275089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public String getGroupView() { 275189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov return Views.GROUPS_ALL; 275289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov } 275389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 2754d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getContactEntitiesView() { 2755d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getContactEntitiesView(false); 2756d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 2757d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 2758d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getContactEntitiesView(boolean requireRestrictedView) { 2759d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 2760d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Tables.CONTACT_ENTITIES : Tables.CONTACT_ENTITIES_RESTRICTED; 2761d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 2762d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 2763ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** 2764ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov * Test if any of the columns appear in the given projection. 2765ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov */ 2766ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov public boolean isInProjection(String[] projection, String... columns) { 276782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (projection == null) { 276882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 276982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 2770ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 277182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov // Optimized for a single-column test 277282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (columns.length == 1) { 277382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov String column = columns[0]; 277482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 277582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (column.equals(test)) { 277682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 277782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 277882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 277982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } else { 278082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 278182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String column : columns) { 2782ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (column.equals(test)) { 2783ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return true; 2784ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 2785ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 2786ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 2787ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 2788ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return false; 27894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 2790fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 2791fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 2792fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 2793fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 2794fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 2795fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(Uri uri) { 2796fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return exceptionMessage(null, uri); 2797fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2798fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 2799fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 2800fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 2801fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 2802fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 2803fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(String message, Uri uri) { 2804fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 2805fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (message != null) { 2806fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(message).append("; "); 2807fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2808fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("URI: ").append(uri); 2809fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 2810fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov int callingUid = Binder.getCallingUid(); 2811fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling user: "); 2812fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov String userName = pm.getNameForUid(callingUid); 2813fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (userName != null) { 2814fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(userName); 2815fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 2816fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callingUid); 2817fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2818fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 2819fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(callingUid); 2820fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages != null && callerPackages.length > 0) { 2821fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages.length == 1) { 2822fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package:"); 2823fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[0]); 2824fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 2825fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package is one of: ["); 2826fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov for (int i = 0; i < callerPackages.length; i++) { 2827fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (i != 0) { 2828fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", "); 2829fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2830fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[i]); 2831fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2832fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("]"); 2833fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2834fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2835fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 2836fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return sb.toString(); 2837fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 2838b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 2839