ContactsDatabaseHelper.java revision 3ea7932a47027c8629d3a301e1a16e7d2c8a298d
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 1953214b3ed12b0ff9cb589b6559311f2ac142f2e3Bjorn Bringertimport com.android.common.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; 37892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikovimport android.location.CountryDetector; 38fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikovimport android.net.Uri; 394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.os.Binder; 40a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.os.Bundle; 41c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamiltonimport android.os.SystemClock; 42b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns; 43e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikovimport android.provider.CallLog.Calls; 44a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract; 45b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 46a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 47a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 48a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 49a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 50a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 51a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 52d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 533d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikovimport android.provider.ContactsContract.Contacts.Photo; 54de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 55d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikovimport android.provider.ContactsContract.Directory; 565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources; 575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle; 58ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 59d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 60eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings; 6182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates; 6267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities; 63bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils; 6436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.text.TextUtils; 65b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Token; 66b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Tokenizer; 67b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log; 68b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 69b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap; 705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale; 71b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 72b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/** 73b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Database helper for contacts. Designed as a singleton to make sure that all 74b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * {@link android.content.ContentProvider} users get the same reference. 75b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Provides handy methods for maintaining package and mime-type lookup tables. 76b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 77b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov/* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper { 78b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static final String TAG = "ContactsDatabaseHelper"; 79b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 8097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov /** 8194c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov * Contacts DB version ranges: 8297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * <pre> 8397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 0-98 Cupcake/Donut 8497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 100-199 Eclair 8597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 200-299 Eclair-MR1 8697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 300-349 Froyo 8797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 350-399 Gingerbread 8897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 400-499 Honeycomb 8997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * </pre> 9097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov */ 91c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov static final int DATABASE_VERSION = 415; 92e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 93b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String DATABASE_NAME = "contacts2.db"; 941f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final String DATABASE_PRESENCE = "presence_db"; 95b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 96b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface Tables { 97d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONTACTS = "contacts"; 985ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACTS = "raw_contacts"; 99ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String PACKAGES = "packages"; 100ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPES = "mimetypes"; 101b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PHONE_LOOKUP = "phone_lookup"; 102a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP = "name_lookup"; 103b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; 104eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey public static final String SETTINGS = "settings"; 105b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA = "data"; 106ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS = "groups"; 1071f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String PRESENCE = "presence"; 108e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public static final String AGGREGATED_PRESENCE = "agg_presence"; 109b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NICKNAME_LOOKUP = "nickname_lookup"; 110e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov public static final String CALLS = "calls"; 111a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String STATUS_UPDATES = "status_updates"; 112b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public static final String PROPERTIES = "properties"; 113743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov public static final String ACCOUNTS = "accounts"; 1144394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov public static final String VISIBLE_CONTACTS = "visible_contacts"; 115d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov public static final String DIRECTORIES = "directories"; 116385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov public static final String DEFAULT_DIRECTORY = "default_directory"; 117b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 118ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_MIMETYPES = "data " 1191b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id)"; 120b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 12111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov public static final String DATA_JOIN_RAW_CONTACTS = "data " 1228e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 12311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 1245ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPE_RAW_CONTACTS = "data " 125c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 126c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 127bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 128e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 129e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS = "raw_contacts " 130e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN settings ON (" 131e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 132e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 133e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 134e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 135e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID 136e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + ")"; 137e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 138e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 139e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS = "settings " 140e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN raw_contacts ON (" 141e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 142e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 143e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 144e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 145e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 146e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 147d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data " 1481b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1491b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 150d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 151ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data " 1531b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1541b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 15567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 1569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "; 159ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 160ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES = "groups " 161ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)"; 162ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 163b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 164b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String ACTIVITIES = "activities"; 165b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 166ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String ACTIVITIES_JOIN_MIMETYPES = "activities " 167ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)"; 168b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 169d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS = 1705ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov "activities " 17167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) " 172ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) " 1735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " + 174fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "raw_contacts._id) " 175d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 1767e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1775ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup " 1785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "INNER JOIN raw_contacts ON (name_lookup.raw_contact_id = raw_contacts._id)"; 179b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 180b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public interface Views { 1824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_ALL = "view_data"; 1834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_RESTRICTED = "view_data_restricted"; 1844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_ALL = "view_raw_contacts"; 1864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_RESTRICTED = "view_raw_contacts_restricted"; 1874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_ALL = "view_contacts"; 1894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_RESTRICTED = "view_contacts_restricted"; 19089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 191a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String ENTITIES = "view_entities"; 192a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String ENTITIES_RESTRICTED = "view_entities_restricted"; 193a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 194a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String RAW_ENTITIES = "view_raw_entities"; 195a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String RAW_ENTITIES_RESTRICTED = "view_raw_entities_restricted"; 196a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 19789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public static final String GROUPS_ALL = "view_groups"; 1984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 1994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2001f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public interface Clauses { 201e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE + "='" 202e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + GroupMembership.CONTENT_ITEM_TYPE + "'"; 203ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 204e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "=" 205ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupsColumns.CONCRETE_ID; 206ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 20768936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String HAVING_NO_GROUPS = "COUNT(" + DataColumns.CONCRETE_GROUP_ID + ") == 0"; 2089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 20968936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String GROUP_BY_ACCOUNT_CONTACT_ID = SettingsColumns.CONCRETE_ACCOUNT_NAME + "," 21068936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "," + RawContacts.CONTACT_ID; 211e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 212e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String RAW_CONTACT_IS_LOCAL = RawContactsColumns.CONCRETE_ACCOUNT_NAME 213e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + " IS NULL AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL"; 214e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 215e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String ZERO_GROUP_MEMBERSHIPS = "COUNT(" + GroupsColumns.CONCRETE_ID + ")=0"; 216e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 2171a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS = "outer_raw_contacts"; 2181a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS_ID = OUTER_RAW_CONTACTS + "." + RawContacts._ID; 2191a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey 220b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov final String CONTACT_IS_VISIBLE = 221b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "SELECT " + 2221a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey "MAX((SELECT (CASE WHEN " + 223b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "(CASE" + 224b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + RAW_CONTACT_IS_LOCAL + 225b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN 1 " + 226b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + ZERO_GROUP_MEMBERSHIPS + 227b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN " + Settings.UNGROUPED_VISIBLE + 228b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " ELSE MAX(" + Groups.GROUP_VISIBLE + ")" + 229b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "END)=1 THEN 1 ELSE 0 END)" + 230b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS + 2311a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + OUTER_RAW_CONTACTS_ID + "))" + 2321a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " FROM " + Tables.RAW_CONTACTS + " AS " + OUTER_RAW_CONTACTS + 233b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 234b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " GROUP BY " + RawContacts.CONTACT_ID; 235e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 236e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND " 237e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?"; 2384394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 2394394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov public static final String CONTACT_VISIBLE = 2404394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "EXISTS (SELECT _id FROM " + Tables.VISIBLE_CONTACTS 2414394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + " WHERE " + Tables.CONTACTS +"." + Contacts._ID 2424394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + "=" + Tables.VISIBLE_CONTACTS +"." + Contacts._ID + ")"; 2431f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 2441f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 245d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public interface ContactsColumns { 2464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * This flag is set for a contact if it has only one constituent raw contact and 2484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * it is restricted. 2494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 25067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String SINGLE_IS_RESTRICTED = "single_is_restricted"; 251ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 252a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String LAST_STATUS_UPDATE_ID = "status_update_id"; 253a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 254d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID; 25567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 256d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "." 257d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED; 258d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "." 259d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.LAST_TIME_CONTACTED; 260d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED; 261d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "." 262d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.CUSTOM_RINGTONE; 263d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "." 264d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.SEND_TO_VOICEMAIL; 2652d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill public static final String CONCRETE_LOOKUP_KEY = Tables.CONTACTS + "." 2662d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill + Contacts.LOOKUP_KEY; 267619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 268619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2696cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov public interface RawContactsColumns { 27033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_ID = 2715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + BaseColumns._ID; 2729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_NAME = 2735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME; 2749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_TYPE = 2755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE; 27633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_SOURCE_ID = 2775ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID; 27833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_VERSION = 2795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.VERSION; 28033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DIRTY = 2815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DIRTY; 28233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DELETED = 2835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DELETED; 2847a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC1 = 2857a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC1; 2867a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC2 = 2877a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC2; 2887a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC3 = 2897a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC3; 2907a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC4 = 2917a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC4; 292c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey public static final String CONCRETE_STARRED = 293c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.STARRED; 294bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey public static final String CONCRETE_IS_RESTRICTED = 295bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.IS_RESTRICTED; 2968e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 2975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME = RawContacts.DISPLAY_NAME_PRIMARY; 2985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME_SOURCE = RawContacts.DISPLAY_NAME_SOURCE; 2998e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov public static final String AGGREGATION_NEEDED = "aggregation_needed"; 300fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 301fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_DISPLAY_NAME = 302fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + DISPLAY_NAME; 303fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_CONTACT_ID = 304fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID; 305f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov public static final String CONCRETE_NAME_VERIFIED = 306f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED; 307619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 308619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 309619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface DataColumns { 31067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 311b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 312ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 313ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID; 314226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID; 315d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "." 316d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Data.RAW_CONTACT_ID; 317ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_GROUP_ID = Tables.DATA + "." 318ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupMembership.GROUP_ROW_ID; 319e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 320e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1; 321e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2; 322e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3; 323e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4; 324e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5; 325e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6; 326e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7; 327e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8; 328e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9; 329e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10; 3300f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11; 3310f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12; 3320f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13; 3330f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14; 3340f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15; 335e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY; 336226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID; 337e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 338e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 3390f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov // Used only for legacy API support 3400f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface ExtensionsColumns { 3410f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String NAME = Data.DATA1; 3420f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String VALUE = Data.DATA2; 3430f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3440f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 3450f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface GroupMembershipColumns { 3465ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID; 3470f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID; 3480f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3490f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 350e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public interface PhoneColumns { 351e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String NORMALIZED_NUMBER = Data.DATA4; 352e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4; 353ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 354ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 355ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface GroupsColumns { 35667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 35767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 358ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID; 35967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID; 360341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.GROUPS + "." + Groups.ACCOUNT_NAME; 361341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.GROUPS + "." + Groups.ACCOUNT_TYPE; 362341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey } 363b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 364b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface ActivitiesColumns { 365b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE_ID = "package_id"; 366b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 367b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 368b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 369b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface PhoneLookupColumns { 370b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 371b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA_ID = "data_id"; 3725ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 373b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String NORMALIZED_NUMBER = "normalized_number"; 37436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public static final String MIN_MATCH = "min_match"; 375b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 376b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 377a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public interface NameLookupColumns { 3785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 37914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public static final String DATA_ID = "data_id"; 380a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NORMALIZED_NAME = "normalized_name"; 381a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_TYPE = "name_type"; 382a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 383a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 384a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public final static class NameLookupType { 3852a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_EXACT = 0; 3862a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_VARIANT = 1; 3872a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_COLLATION_KEY = 2; 3882a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NICKNAME = 3; 3892a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int EMAIL_BASED_NICKNAME = 4; 390a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka public static final int ORGANIZATION = 5; 3914cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao public static final int NAME_SHORTHAND = 6; 392f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee public static final int NAME_CONSONANTS = 7; 393a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 394a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov // This is the highest name lookup type code plus one 3955086b63bf3de5f26f495b640e85259c0ebf5ca47Dmitri Plotnikov public static final int TYPE_COUNT = 8; 396a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov 397a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static boolean isBasedOnStructuredName(int nameLookupType) { 3982a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov return nameLookupType == NameLookupType.NAME_EXACT 3992a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_VARIANT 4002a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_COLLATION_KEY; 401a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov } 402a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 403a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 404ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface PackagesColumns { 405b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 406b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE = "package"; 407226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 408226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID; 409b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 410b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 411ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface MimetypesColumns { 412b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 413b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE = "mimetype"; 414ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 415ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID; 416ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE; 417b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 418b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 419b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public interface AggregationExceptionColumns { 420b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 421b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 422b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 423b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public interface NicknameLookupColumns { 424b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NAME = "name"; 425b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String CLUSTER = "cluster"; 426b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 427b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 428e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public interface SettingsColumns { 429e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.SETTINGS + "." 430e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_NAME; 431e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.SETTINGS + "." 432e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_TYPE; 433e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 434e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 4354dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov public interface PresenceColumns { 4364dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov String RAW_CONTACT_ID = "presence_raw_contact_id"; 437bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4384dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 4394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 440e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public interface AggregatedPresenceColumns { 441e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4423296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4433296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_CONTACT_ID = Tables.AGGREGATED_PRESENCE + "." + CONTACT_ID; 444e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 445e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 446a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public interface StatusUpdatesColumns { 447a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov String DATA_ID = "status_update_data_id"; 4483296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4493296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = Tables.STATUS_UPDATES + "." + DATA_ID; 4503296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4513296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = Tables.STATUS_UPDATES + "." + StatusUpdates.PRESENCE; 4523296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS; 4533296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = Tables.STATUS_UPDATES + "." 4543296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_TIMESTAMP; 4553296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = Tables.STATUS_UPDATES + "." 4563296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_RES_PACKAGE; 4573296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_LABEL; 4583296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_ICON; 4593296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey } 4603296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4613296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey public interface ContactsStatusUpdatesColumns { 4623296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String ALIAS = "contacts_" + Tables.STATUS_UPDATES; 4633296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4643296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = ALIAS + "." + StatusUpdatesColumns.DATA_ID; 4653296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4663296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = ALIAS + "." + StatusUpdates.PRESENCE; 4673296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = ALIAS + "." + StatusUpdates.STATUS; 4683296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = ALIAS + "." + StatusUpdates.STATUS_TIMESTAMP; 4693296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = ALIAS + "." + StatusUpdates.STATUS_RES_PACKAGE; 4703296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = ALIAS + "." + StatusUpdates.STATUS_LABEL; 4713296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = ALIAS + "." + StatusUpdates.STATUS_ICON; 472a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov } 473a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 474b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public interface PropertiesColumns { 475b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_KEY = "property_key"; 476b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_VALUE = "property_value"; 477b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 478b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 479e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov public static final class DirectoryColumns { 480e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov public static final String TYPE_RESOURCE_NAME = "typeResourceName"; 481e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 482e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 4833296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey /** In-memory cache of previously found MIME-type mappings */ 484bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 485b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 486bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 487b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 488b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 489b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 490b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 491b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 492d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private SQLiteStatement mContactIdQuery; 493f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 494b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 495b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 496b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 497b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 498b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 499b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 50035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 501f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov 502f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private boolean mReopenDatabase = false; 503f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 504b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static ContactsDatabaseHelper sSingleton = null; 505b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 50636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private boolean mUseStrictPhoneNumberComparison; 5073a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa 508d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton /** 509d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton * List of package names with access to {@link RawContacts#IS_RESTRICTED} data. 510d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton */ 511d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton private String[] mUnrestrictedPackages; 512d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton 513b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov public static synchronized ContactsDatabaseHelper getInstance(Context context) { 514b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 515b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov sSingleton = new ContactsDatabaseHelper(context); 516b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 517b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 518b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 519b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 5201f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 52131b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 52235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 5231f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 524b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov ContactsDatabaseHelper(Context context) { 525b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey super(context, DATABASE_NAME, null, DATABASE_VERSION); 526d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton Resources resources = context.getResources(); 527619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 528b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 52928b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 53036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov mUseStrictPhoneNumberComparison = 531d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton resources.getBoolean( 532d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton com.android.internal.R.bool.config_use_strict_phone_number_comparation); 5330f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov int resourceId = resources.getIdentifier("unrestricted_packages", "array", 5340f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov context.getPackageName()); 5350f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov if (resourceId != 0) { 5360f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = resources.getStringArray(resourceId); 5370f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } else { 5380f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = new String[0]; 5390f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } 540b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 541b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 542b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 543b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 54435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.onDatabaseOpened(db); 54535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 546b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Create compiled statements for package and mimetype lookups 547ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM " 548ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 549ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM " 550ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?"); 551d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mContactIdQuery = db.compileStatement("SELECT " + RawContacts.CONTACT_ID + " FROM " 5525ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 5536cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov mAggregationModeQuery = db.compileStatement("SELECT " + RawContacts.AGGREGATION_MODE 5545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 555ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "(" 556ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + MimetypesColumns.MIMETYPE + ") VALUES (?)"); 557ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "(" 558ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + PackagesColumns.PACKAGE + ") VALUES (?)"); 559ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 560ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM " 561ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 562ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE 563ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "." 564b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + Activities._ID + "=?"); 5651f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 5661f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 567e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+ 56882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 56982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PROTOCOL + " INTEGER NOT NULL," + 57082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + 57182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_HANDLE + " TEXT," + 57282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_ACCOUNT + " TEXT," + 573a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 574a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 57582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE + " INTEGER," + 576aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0," + 57782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL 57882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + 5791f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 5801f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 581e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON " 5824dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");"); 58309562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex2" + " ON " 58409562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori + Tables.PRESENCE + " (" + PresenceColumns.CONTACT_ID + ");"); 585e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 586e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " 587aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+ 588e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov AggregatedPresenceColumns.CONTACT_ID 589e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," + 590632248ae0053fa99b1f5b4cfaab3e55b7453fcb1Vasu Nori StatusUpdates.PRESENCE + " INTEGER," + 591aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0" + 592e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov ");"); 593bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 594bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 595bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted" 596bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 597bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 598bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATED_PRESENCE 599bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " + 600bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.CONTACT_ID + 601bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 602bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.RAW_CONTACT_ID 603bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.RAW_CONTACT_ID + 604bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND NOT EXISTS" + 605bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.RAW_CONTACT_ID + 606bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 607bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 608bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.CONTACT_ID + 609bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND " + PresenceColumns.RAW_CONTACT_ID 610bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));" 611bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 612bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 613aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori final String replaceAggregatePresenceSql = 614aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 615093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + AggregatedPresenceColumns.CONTACT_ID + ", " 616093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.PRESENCE + ", " 617093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.CHAT_CAPABILITY + ")" 618093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " SELECT " 619093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + PresenceColumns.CONTACT_ID + "," 620093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.PRESENCE + "," 621093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.CHAT_CAPABILITY 622aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " FROM " + Tables.PRESENCE 623aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " WHERE " 624093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " (ifnull(" + StatusUpdates.PRESENCE + ",0) * 10 " 625093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))" 626093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " = (SELECT " 627093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "MAX (ifnull(" + StatusUpdates.PRESENCE + ",0) * 10 " 628093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))" 629093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " FROM " + Tables.PRESENCE 630093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " WHERE " + PresenceColumns.CONTACT_ID 631093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "=NEW." + PresenceColumns.CONTACT_ID 632093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + ")" 633093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " AND " + PresenceColumns.CONTACT_ID + "=NEW." + PresenceColumns.CONTACT_ID + ";"; 634bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 635bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted" 636bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 637bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 638bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 639bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 640bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 641bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated" 642bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 643bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 644bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 645bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 646b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 647b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 648b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 649b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 650b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 651b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 65235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 65335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 654b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 655d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 656b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 657fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 658d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 659d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 660d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 661d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 662d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 663d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 664f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + 6655870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + " TEXT," + 666a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + 6674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0" + 668b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 669b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 67054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" + 67154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov Contacts.HAS_PHONE_NUMBER + 67254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 67354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 67454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_restricted_index ON " + Tables.CONTACTS + " (" + 67554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + 67654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 67754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 678fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 679fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 680fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 681fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 682b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 6835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" + 6846cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 6856cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 6866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 6876cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 6886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID + " TEXT," + 68997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov RawContacts.RAW_CONTACT_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 6906cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 69173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 69233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + 69354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 6946cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 6956cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DEFAULT + "," + 6968e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + 6976cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + " TEXT," + 6986cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 6996cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 7006cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED + " INTEGER," + 70133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 7025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + 7035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + 7045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + 70525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.UNDEFINED + "," + 7065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + " TEXT," + 7075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + " TEXT," + 708de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " + 709de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 710de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " + 711de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 712f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + 7133cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC1 + " TEXT, " + 7143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC2 + " TEXT, " + 7153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC3 + " TEXT, " + 7163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC4 + " TEXT " + 717b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 718b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 71954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" + 72054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + 72154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 72254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 7235f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" + 7245f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.SOURCE_ID + ", " + 7255f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + ", " + 7265f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + 7275f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 7285f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 729f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // TODO readd the index and investigate a controlled use of it 730f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" + 731f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// RawContactsColumns.AGGREGATION_NEEDED + 732f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// ");"); 7338e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 734b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 735ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 736ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 737ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 738b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 739b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 740ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 741ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 742ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 743ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 744b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 745b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 74608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov // Mimetype table requires an index on mime type 74708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX mime_type ON " + Tables.MIMETYPES + " (" + 74808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov MimetypesColumns.MIMETYPE + 74908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov ");"); 75008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 751b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 752b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 753b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 75467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 755b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 75611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 75797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Data.IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 758f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 759f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 760f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 761f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 762f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 763f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 764f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 765f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 766f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 767f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 768f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 769f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 77067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 77167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 77267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 77367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 77467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 7753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.DATA15 + " TEXT," + 7763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC1 + " TEXT, " + 7773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC2 + " TEXT, " + 7783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC3 + " TEXT, " + 7793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC4 + " TEXT " + 780b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 781b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 78211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" + 78311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + 78411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 78511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 78611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov /** 78711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov * For email lookup and similar queries. 78811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov */ 789f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" + 79011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov DataColumns.MIMETYPE_ID + "," + 791f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov Data.DATA1 + 79211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 79311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 794b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 795b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 796f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.DATA_ID 797892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 7985ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 7995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 80036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 80136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 802b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 803b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 804b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 805f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 806f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 807b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 808b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 809b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 81036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 81136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 81236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 81336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 81436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 81536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 816a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 817a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 81814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.DATA_ID 81914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 8205ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID 8215ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 82211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," + 82311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," + 82414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "PRIMARY KEY (" 82514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + NameLookupColumns.DATA_ID + ", " 82611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ", " 82711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + ")" + 828a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 829a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 83014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" + 83114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + 83214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov ");"); 83314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 834b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 835b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 836b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 837b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 838b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 839b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 840b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 841b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 842b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 843b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 844ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 845ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 846ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 84767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 848035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 849035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 850ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 8519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 85273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 853ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 85467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 8550f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 8560f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 85794021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + 858eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 859ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + 860dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0," + 861dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0," + 862c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 8633cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC1 + " TEXT, " + 8643cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC2 + " TEXT, " + 8653cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC3 + " TEXT, " + 8663cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC4 + " TEXT " + 867ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 868ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 8695f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" + 8705f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.SOURCE_ID + ", " + 8715f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_TYPE + ", " + 8725f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_NAME + 8735f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 8745f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 875b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 876b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 877b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 8780c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 8795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id), " + 8800c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 8815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id)" + 882b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank ");"); 883b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 884b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 885b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8860c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + ", " + 8870c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + 888b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 889b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 890b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 891b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8920c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + ", " + 8930c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + 894b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 895b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 896eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" + 897eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_NAME + " STRING NOT NULL," + 898eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_TYPE + " STRING NOT NULL," + 899eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 900eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1, " + 901eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey "PRIMARY KEY (" + Settings.ACCOUNT_NAME + ", " + 902e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey Settings.ACCOUNT_TYPE + ") ON CONFLICT REPLACE" + 903eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey ");"); 904eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 9054394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 9064394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 9074394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 9084394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 909385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 910385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 911385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 912385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 913e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // The table for recent calls is here so we can do table joins 914e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // on people, phones, and calls all in one place. 915e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CALLS + " (" + 916e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 917e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NUMBER + " TEXT," + 918e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DATE + " INTEGER," + 919e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DURATION + " INTEGER," + 920e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.TYPE + " INTEGER," + 921e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NEW + " INTEGER," + 922e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NAME + " TEXT," + 923e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_TYPE + " INTEGER," + 9242530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.CACHED_NUMBER_LABEL + " TEXT," + 9252530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.COUNTRY_ISO + " TEXT" + ");"); 926e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov 927b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 928b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 929b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 93067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 931b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 932b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 933499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 9345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 9355ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 936b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 937499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 938b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 939b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 940adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 941b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 942b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 943b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 944a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" + 945a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 9460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS + " TEXT," + 9470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + 9480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + 9490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_LABEL + " INTEGER, " + 9500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_ICON + " INTEGER" + 951a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ");"); 952a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 953b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" + 954b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " + 955b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_VALUE + " TEXT " + 956b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 957b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 958743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" + 959743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " TEXT, " + 960743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " TEXT " + 961743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov ");"); 962743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 963743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // Allow contacts without any account to be created for now. Achieve that 964743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // by inserting a fake account with both type and name as NULL. 965743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // This "account" should be eliminated as soon as the first real writable account 966743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // is added to the phone. 967743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("INSERT INTO accounts VALUES(NULL, NULL)"); 968743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 969d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 970d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 971a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createContactsViews(db); 972a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createGroupsView(db); 973fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov createContactsTriggers(db); 974916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 9754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 976a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov loadNicknameLookupTable(db); 977a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 978a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // Add the legacy API support views, etc 979a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov LegacyApiSupport.createDatabase(db); 980a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 981a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // This will create a sqlite_stat1 table that is used for query optimization 982a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("ANALYZE;"); 983a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 984a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateSqliteStats(db); 985a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 986a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // We need to close and reopen the database connection so that the stats are 987a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // taken into account. Make a note of it and do the actual reopening in the 988a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // getWritableDatabase method. 989a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov mReopenDatabase = true; 990a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 991a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContentResolver.requestSync(null /* all accounts */, 992a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContactsContract.AUTHORITY, new Bundle()); 993a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 994a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 995d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void createDirectoriesTable(SQLiteDatabase db) { 996d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DIRECTORIES + "(" + 997d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 998d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.PACKAGE_NAME + " TEXT NOT NULL," + 999d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DIRECTORY_AUTHORITY + " TEXT NOT NULL," + 1000d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.TYPE_RESOURCE_ID + " INTEGER," + 1001e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov DirectoryColumns.TYPE_RESOURCE_NAME + " TEXT," + 1002d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_TYPE + " TEXT," + 1003d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_NAME + " TEXT," + 1004d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DISPLAY_NAME + " TEXT, " + 1005d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.EXPORT_SUPPORT + " INTEGER NOT NULL" + 100697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov " DEFAULT " + Directory.EXPORT_SUPPORT_NONE + "," + 100797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Directory.SHORTCUT_SUPPORT + " INTEGER NOT NULL" + 10083d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.SHORTCUT_SUPPORT_NONE + "," + 10093d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Directory.PHOTO_SUPPORT + " INTEGER NOT NULL" + 10103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.PHOTO_SUPPORT_NONE + 1011d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov ");"); 1012d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 10133d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov // Trigger a full scan of directories in the system 10143d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(db, ContactDirectoryManager.PROPERTY_DIRECTORY_SCAN_COMPLETE, "0"); 1015d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1016d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1017916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsTriggers(SQLiteDatabase db) { 1018fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1019fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1020fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Automatically delete Data rows when a raw contact is deleted. 1021fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1022fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;"); 1023fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted " 1024fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEFORE DELETE ON " + Tables.RAW_CONTACTS 1025fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1026fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.DATA 1027fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data.RAW_CONTACT_ID 1028fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 1029fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS 1030fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 1031fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID 1032fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " OR " + AggregationExceptions.RAW_CONTACT_ID2 1033fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 103435da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " DELETE FROM " + Tables.VISIBLE_CONTACTS 103535da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 103635da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 103735da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 103835da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " )=1;" 1039385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " DELETE FROM " + Tables.DEFAULT_DIRECTORY 1040385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1041385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1042385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1043385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " )=1;" 1044fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.CONTACTS 1045fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1046fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1047fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1048fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " )=1;" 1049fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1050fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1051fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1052fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;"); 10536c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;"); 1054fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1055fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1056fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Triggers that update {@link RawContacts#VERSION} when the contact is 1057fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * marked for deletion or any time a data row is inserted, updated or 1058fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * deleted. 1059fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1060fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;"); 1061fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted " 10627f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.RAW_CONTACTS 1063fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1064fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1065fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1066fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 " 1067fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID 1068fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";" 1069fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1070fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1071fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;"); 10727f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 1073fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1074fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.DATA 1075fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 1076fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 1077fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1078fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1079fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1080fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1081fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1082fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;"); 1083fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 1084fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1085fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1086fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1087fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1088fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.PHONE_LOOKUP 1089fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1090fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.STATUS_UPDATES 1091fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";" 1092fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.NAME_LOOKUP 1093fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1094fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1095fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1096fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1097fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;"); 1098fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 10997f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.GROUPS 1100fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1101fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.GROUPS 1102fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1103fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + Groups.VERSION + "=OLD." + Groups.VERSION + "+1" 1104fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 1105fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1106fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1107fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1108916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsIndexes(SQLiteDatabase db) { 1109916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 1110916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 1111916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + "," + 1112916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NAME_TYPE + ", " + 1113916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + ", " + 1114916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.DATA_ID + 1115916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov ");"); 111604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 111704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index"); 111804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 111904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 112004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 112104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 112204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index"); 112304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 112404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 112504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 1126916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1127916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1128a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createContactsViews(SQLiteDatabase db) { 1129a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_ALL + ";"); 1130a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_RESTRICTED + ";"); 1131a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_ALL + ";"); 1132a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_RESTRICTED + ";"); 1133a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_ALL + ";"); 1134a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_RESTRICTED + ";"); 1135a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES + ";"); 1136a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES_RESTRICTED + ";"); 1137a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES + ";"); 1138a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES_RESTRICTED + ";"); 1139a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 11404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataColumns = 11414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Data.IS_PRIMARY + ", " 11424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.IS_SUPER_PRIMARY + ", " 11434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA_VERSION + ", " 11444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 11454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", " 114697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + Data.IS_READ_ONLY + ", " 11474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA1 + ", " 11484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA2 + ", " 11494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA3 + ", " 11504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA4 + ", " 11514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA5 + ", " 11524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA6 + ", " 11534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA7 + ", " 11544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA8 + ", " 11554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA9 + ", " 11564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA10 + ", " 11574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA11 + ", " 11584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA12 + ", " 11594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA13 + ", " 11604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA14 + ", " 11614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA15 + ", " 11624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC1 + ", " 11634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC2 + ", " 11644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC3 + ", " 11654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC4; 11664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String syncColumns = 11684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 11694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 11704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 1171f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 11724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 11734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 11744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," 11754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + "," 11764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + "," 11774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4; 11784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11793d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov String baseContactColumns = 11803d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + ", " 11813d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + ", " 11823d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 11833d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.PHOTO_ID + ", " 11843d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Clauses.CONTACT_VISIBLE + " AS " + Contacts.IN_VISIBLE_GROUP + ", " 11853d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID; 11863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 11874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactOptionColumns = 11884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 11894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.CUSTOM_RINGTONE + "," 11904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 11914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.SEND_TO_VOICEMAIL + "," 11924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 11934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.LAST_TIME_CONTACTED + "," 11944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 11954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.TIMES_CONTACTED + "," 11964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 11974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.STARRED; 11984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String contactNameColumns = 12005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE 12015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", " 12025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY 12035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", " 12045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE 12055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", " 12065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME 12075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME + ", " 12085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE 12095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME_STYLE + ", " 12105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY 12115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_PRIMARY + ", " 12125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE 12134394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_ALTERNATIVE; 12145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 12154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataSelect = "SELECT " 12164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Data._ID + "," 12174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.RAW_CONTACT_ID + ", " 1218fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 12194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns + ", " 12204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + dataColumns + ", " 12214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + contactOptionColumns + ", " 12225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 12233d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 12243d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12253d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 12263d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12273d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 12284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 12294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA 1230a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.MIMETYPES + " ON (" 12314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1232a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " ON (" 12334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1234a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1235fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1236fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1237fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1238a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1239a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 12404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 12414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1242f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1243a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 12444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_ALL + " AS " + dataSelect); 12464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_RESTRICTED + " AS " + dataSelect + " WHERE " 1247fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 12484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactOptionColumns = 12504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + "," 12514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.SEND_TO_VOICEMAIL + "," 12524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "," 12534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "," 12544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.STARRED; 12554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactsSelect = "SELECT " 12574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + "," 12584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 12594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.AGGREGATION_MODE + ", " 126097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + RawContacts.RAW_CONTACT_IS_READ_ONLY + ", " 12614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.DELETED + ", " 12625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + ", " 12635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_PRIMARY + ", " 12645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_ALTERNATIVE + ", " 12655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME + ", " 12665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME_STYLE + ", " 12675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_PRIMARY + ", " 12685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_ALTERNATIVE + ", " 12694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + rawContactOptionColumns + ", " 12704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns 12714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS; 12724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_ALL + " AS " + rawContactsSelect); 12744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_RESTRICTED + " AS " + rawContactsSelect 12754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 12764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsColumns = 12784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 12794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.CUSTOM_RINGTONE + ", " 12805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 12813d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 12824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 12834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED + ", " 12844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 12854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL + ", " 12864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 12874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.STARRED + ", " 12884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 12893d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + " AS " + Contacts.TIMES_CONTACTED; 12904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsSelect = "SELECT " 12924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + "," 12933d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + contactsColumns + ", " 12943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_URI) + ", " 12953d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_THUMBNAIL_URI) 12964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.CONTACTS 1297fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1298fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"; 12994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_ALL + " AS " + contactsSelect); 1301fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_RESTRICTED + " AS " + contactsSelect 1302fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " WHERE " + ContactsColumns.SINGLE_IS_RESTRICTED + "=0"); 1303a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1304a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String rawEntitiesSelect = "SELECT " 1305a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 1306a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1307a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1308a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1309a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1310a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1311a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1312a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1313a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", " 1314a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + "," 1315a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + "," 1316a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + " AS " 1317a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.IS_RESTRICTED + "," 1318a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1319a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1320a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1321a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1322a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1323a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1324a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1325a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1326a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1327a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1328a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1329a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1330a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1331a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES + " AS " 1332a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect); 1333a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES_RESTRICTED + " AS " 1334a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 1335a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1336a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String entitiesSelect = "SELECT " 1337a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + Contacts._ID + ", " 1338a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 1339a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1340a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED 1341a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " AS " + RawContacts.IS_RESTRICTED + "," 1342a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1343a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1344a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + contactsColumns + ", " 13453d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 13463d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 13473d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 13483d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 1349a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1350a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1351a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1352a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1353a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + Contacts.Entity.RAW_CONTACT_ID + ", " 1354a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Contacts.Entity.DATA_ID + "," 1355a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1356a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1357a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1358a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1359a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1360a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1361a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1362a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1363a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1364a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1365a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1366a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1367a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1368a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES + " AS " 1373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect); 1374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES_RESTRICTED + " AS " 1375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect + " WHERE " + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 1376a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 13774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13783d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private static String buildPhotoUriAlias(String contactIdColumn, String alias) { 13792b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov return "(CASE WHEN " + Contacts.PHOTO_ID + " IS NULL" 13802b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " OR " + Contacts.PHOTO_ID + "=0" 13812b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " THEN NULL" 13822b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " ELSE " + "'" + Contacts.CONTENT_URI + "/'||" 13832b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + contactIdColumn + "|| '/" + Photo.CONTENT_DIRECTORY + "'" 13842b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " END)" 13852b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " AS " + alias; 13863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 13873d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 1388a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createGroupsView(SQLiteDatabase db) { 1389a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS_ALL + ";"); 139089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsColumns = 139189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov Groups.ACCOUNT_NAME + "," 139289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.ACCOUNT_TYPE + "," 139389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SOURCE_ID + "," 139489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.VERSION + "," 139589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DIRTY + "," 139689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE + "," 139789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE_RES + "," 139889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.NOTES + "," 139989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYSTEM_ID + "," 140089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DELETED + "," 140189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.GROUP_VISIBLE + "," 140289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SHOULD_SYNC + "," 1403dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.AUTO_ADD + "," 1404dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.FAVORITES + "," 1405c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov + Groups.GROUP_IS_READ_ONLY + "," 140689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC1 + "," 140789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC2 + "," 140889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC3 + "," 140989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC4 + "," 141089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE; 141189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 141289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsSelect = "SELECT " 141389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + "," 141489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + groupsColumns 141589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + " FROM " + Tables.GROUPS_JOIN_PACKAGES; 141689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 141789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.GROUPS_ALL + " AS " + groupsSelect); 1418b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1419b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1420b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 1421b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 142246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion < 99) { 142346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 142446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + ", data will be lost!"); 142546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 142646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 142746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";"); 142846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 142946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 143046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 143146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 143246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 143346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 143446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 143546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 143646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";"); 143746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";"); 143846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";"); 143946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 144046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // TODO: we should not be dropping agg_exceptions and contact_options. In case that 144146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // table's schema changes, we should try to preserve the data, because it was entered 144246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // by the user and has never been synched to the server. 144346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 144446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 144546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana onCreate(db); 144646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana return; 144746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1448f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 144946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion); 1450a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 145108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov boolean upgradeViewsAndTriggers = false; 145204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov boolean upgradeNameLookup = false; 145308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 145446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion == 99) { 145508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 145646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana oldVersion++; 145746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 145846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1459a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov if (oldVersion == 100) { 1460a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON " 1461a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.MIMETYPES + " (" 1462a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns.MIMETYPE + "," 1463a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns._ID + ");"); 1464a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateIndexStats(db, Tables.MIMETYPES, 1465a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov "mimetypes_mimetype_index", "50 1 1"); 1466a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 146708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1468a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov oldVersion++; 1469a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1470a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1471fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov if (oldVersion == 101) { 147208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1473fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov oldVersion++; 1474fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1475fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 147647ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov if (oldVersion == 102) { 147708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 147847ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov oldVersion++; 147947ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov } 148047ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov 148136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (oldVersion == 103) { 148208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1483bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey oldVersion++; 1484bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey } 1485bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey 148671037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 104 || oldVersion == 201) { 148771037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov LegacyApiSupport.createSettingsTable(db); 148808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 14893410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion++; 14903410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov } 14913410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov 149271037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 105) { 14935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion202(db); 149404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov upgradeNameLookup = true; 14953410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion = 202; 149636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 149736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 1498fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov if (oldVersion == 202) { 14995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion203(db); 150008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1501fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov oldVersion++; 1502fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1503fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 15049b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori if (oldVersion == 203) { 150508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15069b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori oldVersion++; 15079b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori } 15089b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori 15095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (oldVersion == 204) { 15105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion205(db); 151108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov oldVersion++; 15135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 15145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1515f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov if (oldVersion == 205) { 1516f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgrateToVersion206(db); 1517f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgradeViewsAndTriggers = true; 1518f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov oldVersion++; 1519f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1520f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 152131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (oldVersion == 206) { 1522b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeToVersion300(db); 152334469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov oldVersion = 300; 152431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 152531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 15266c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook if (oldVersion == 300) { 15276c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook upgradeViewsAndTriggers = true; 15286c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook oldVersion = 301; 15296c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook } 15306c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook 1531916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov if (oldVersion == 301) { 1532916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov upgradeViewsAndTriggers = true; 1533916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov oldVersion = 302; 1534916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1535916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1536b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (oldVersion == 302) { 1537b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeEmailToVersion303(db); 1538b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeNicknameToVersion303(db); 1539b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov oldVersion = 303; 1540b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1541b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 154208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (oldVersion == 303) { 154308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov upgradeToVersion304(db); 154408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov oldVersion = 304; 154508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 154608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 1547f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee if (oldVersion == 304) { 1548f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee upgradeNameLookup = true; 1549f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee oldVersion = 305; 1550f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee } 1551f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee 155260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (oldVersion == 305) { 155360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann upgradeToVersion306(db); 155460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann oldVersion = 306; 155560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 155660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 1557b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (oldVersion == 306) { 1558b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov upgradeToVersion307(db); 1559b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov oldVersion = 307; 1560b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 1561b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 1562743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov if (oldVersion == 307) { 1563743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov upgradeToVersion308(db); 1564743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov oldVersion = 308; 1565743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 1566743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 156794c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov // Gingerbread upgrades 156894c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion < 350) { 1569afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann upgradeViewsAndTriggers = true; 157094c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 351; 1571afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann } 1572afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann 157394c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion == 351) { 157494c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov upgradeNameLookup = true; 157594c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 352; 157680d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann } 157780d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann 15787da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov if (oldVersion == 352) { 15797da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov upgradeToVersion353(db); 15807da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov oldVersion = 353; 15817da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 15827da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 1583f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov // Honeycomb upgrades 1584f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion < 400) { 1585dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana upgradeViewsAndTriggers = true; 1586f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov upgradeToVersion400(db); 1587f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov oldVersion = 400; 1588dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 1589dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 1590f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion == 400) { 15914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeViewsAndTriggers = true; 15924394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeToVersion401(db); 15934394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov oldVersion = 401; 15944394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 15954394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 1596d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov if (oldVersion == 401) { 1597d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov upgradeToVersion402(db); 1598d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov oldVersion = 402; 1599d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1600d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 160197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov if (oldVersion == 402) { 160297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeViewsAndTriggers = true; 160397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeToVersion403(db); 160497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov oldVersion = 403; 160597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 160697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 1607a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov if (oldVersion == 403) { 1608a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov upgradeViewsAndTriggers = true; 1609a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov oldVersion = 404; 1610a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 1611a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1612892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (oldVersion == 404) { 1613892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeViewsAndTriggers = true; 1614892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeToVersion405(db); 1615892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov oldVersion = 405; 1616892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 1617892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 16182530512f639c4979fd7371c7dd25dd67e8118124Bai Tao if (oldVersion == 405) { 16192530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeViewsAndTriggers = true; 16202530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeToVersion406(db); 16212530512f639c4979fd7371c7dd25dd67e8118124Bai Tao oldVersion = 406; 16222530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 16232530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 1624cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov if (oldVersion == 406) { 1625cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov upgradeViewsAndTriggers = true; 1626cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov oldVersion = 407; 1627cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov } 1628cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov 1629385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov if (oldVersion == 407) { 1630d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Obsolete 1631385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov oldVersion = 408; 1632385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 1633385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 16343d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov if (oldVersion == 408) { 16353d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeViewsAndTriggers = true; 16363d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeToVersion409(db); 16373d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov oldVersion = 409; 16383d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 16393d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 16402b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov if (oldVersion == 409) { 16412b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov upgradeViewsAndTriggers = true; 16422b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov oldVersion = 410; 16432b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov } 16442b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov 1645d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov if (oldVersion == 410) { 1646d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov upgradeToVersion411(db); 1647d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov oldVersion = 411; 1648d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 1649d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 16507da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov if (oldVersion == 411) { 16517da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov // Same upgrade as 353, only on Honeycomb devices 16527da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov upgradeToVersion353(db); 16537da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov oldVersion = 412; 16547da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 16557da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 1656e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov if (oldVersion == 412) { 1657e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov upgradeToVersion413(db); 1658e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov oldVersion = 413; 1659e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 1660e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 166156f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee if (oldVersion == 413) { 166256f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee upgradeNameLookup = true; 166356f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee oldVersion = 414; 166456f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee } 166556f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee 1666c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov if (oldVersion == 414) { 1667c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov upgradeToVersion415(db); 1668c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov upgradeViewsAndTriggers = true; 1669c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov oldVersion = 415; 1670c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov } 1671c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov 167208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov if (upgradeViewsAndTriggers) { 167308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsViews(db); 167408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createGroupsView(db); 167508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsTriggers(db); 1676916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 167708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov LegacyApiSupport.createViews(db); 1678916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov updateSqliteStats(db); 1679916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov mReopenDatabase = true; 168008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov } 168108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 168204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (upgradeNameLookup) { 168304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rebuildNameLookup(db); 168404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 168504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 168646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion != newVersion) { 168746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana throw new IllegalStateException( 168846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana "error upgrading the database to version " + newVersion); 168946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1690b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1691b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 16925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion202(SQLiteDatabase db) { 169336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL( 169436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "ALTER TABLE " + Tables.PHONE_LOOKUP + 169536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;"); 169636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 169736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 169836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 169936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 170036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 170136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 170236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 170336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 170436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 170536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 170636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov SQLiteStatement update = db.compileStatement( 170736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "UPDATE " + Tables.PHONE_LOOKUP + 170836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " SET " + PhoneLookupColumns.MIN_MATCH + "=?" + 170936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " WHERE " + PhoneLookupColumns.DATA_ID + "=?"); 171036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 171136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov // Populate the new column 171236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA + 171336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")", 171436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null); 171536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov try { 171636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov while (c.moveToNext()) { 171736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov long dataId = c.getLong(0); 171836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String number = c.getString(1); 171936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 172036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number)); 172136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindLong(2, dataId); 172236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.execute(); 172336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 172436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 172536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } finally { 172636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov c.close(); 172736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 172836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 172936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 17305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion203(SQLiteDatabase db) { 1731758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // Garbage-collect first. A bug in Eclair was sometimes leaving 1732758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // raw_contacts in the database that no longer had contacts associated 1733758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // with them. To avoid failures during this database upgrade, drop 1734758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // the orphaned raw_contacts. 1735758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov db.execSQL( 1736758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov "DELETE FROM raw_contacts" + 1737758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " WHERE contact_id NOT NULL" + 1738758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " AND contact_id NOT IN (SELECT _id FROM contacts)"); 1739758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov 1740fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1741fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.CONTACTS + 1742fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)"); 1743fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1744fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.RAW_CONTACTS + 17454394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " ADD contact_in_visible_group INTEGER NOT NULL DEFAULT 0"); 1746fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1747fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // For each Contact, find the RawContact that contributed the display name 1748fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1749fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1750fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1751fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1752fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1753fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1754fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" + 1755fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.CONTACTS + "." + Contacts.DISPLAY_NAME + 1756fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1757fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" 1758fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1759fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1760fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 1761fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 1762fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1763fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1764fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // If for some unknown reason we missed some names, let's make sure there are 1765fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // no contacts without a name, picking a raw contact "at random". 1766fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1767fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1768fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1769fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1770fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1771fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1772fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1773fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" + 1774fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL" 1775fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1776fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1777fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use. 1778fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1779fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1780fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.DISPLAY_NAME + "=NULL" 1781fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1782fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1783fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow 1784fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // indexing on (display_name, in_visible_group) 1785fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1786fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 17874394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SET contact_in_visible_group=(" + 1788fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 1789fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.CONTACTS + 1790bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" + 1791bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " NOT NULL" 1792fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1793fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1794fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 17954394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 1796fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" + 1797fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1798fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1799fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 1800fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 1801fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 1802fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1803fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1804fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 18055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion205(SQLiteDatabase db) { 18065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;"); 18085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;"); 18105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;"); 18125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1813de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_PRIMARY 1814de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 18155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1816de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE 1817de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 18185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov final Locale locale = Locale.getDefault(); 18205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 182151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov NameSplitter splitter = createNameSplitter(); 18225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate = db.compileStatement( 18245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 18255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 18265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 18275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 18285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 18295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 18305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 18315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 18325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 18335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter); 18355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter); 18365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 18385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 18394394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 18405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 18415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 18425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 18444394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 18455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 18465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 18475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface StructName205Query { 18505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 18515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 18535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 18545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 18555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE, 18565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY, 18575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PREFIX, 18585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.GIVEN_NAME, 18595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.MIDDLE_NAME, 18605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FAMILY_NAME, 18615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.SUFFIX, 18625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_FAMILY_NAME, 18635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_MIDDLE_NAME, 18645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_GIVEN_NAME, 18655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 18665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 18685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 18695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME_SOURCE = 2; 18705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME = 3; 18715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PREFIX = 4; 18725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int GIVEN_NAME = 5; 18735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int MIDDLE_NAME = 6; 18745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int FAMILY_NAME = 7; 18755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int SUFFIX = 8; 18765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_FAMILY_NAME = 9; 18775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_MIDDLE_NAME = 10; 18785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_GIVEN_NAME = 11; 18795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeStructuredNamesToVersion205(SQLiteDatabase db, 18825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 18835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // Process structured names to detect the style of the full name and phonetic name 18855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long mMimeType; 18875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 18885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mMimeType = DatabaseUtils.longForQuery(db, 18895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 18905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 18915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 18925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null); 18935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } catch (SQLiteDoneException e) { 18945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // No structured names in the database 18955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return; 18965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate = db.compileStatement( 18995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 19005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 19015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FULL_NAME_STYLE + "=?," + 19025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.DISPLAY_NAME + "=?," + 19035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_NAME_STYLE + "=?" + 19045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 19055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 19075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 19085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(StructName205Query.TABLE, 19095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructName205Query.COLUMNS, 19105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null); 19115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 19125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 19135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(StructName205Query.ID); 19145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID); 19155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE); 19165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = cursor.getString(StructName205Query.DISPLAY_NAME); 19175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.clear(); 19195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.prefix = cursor.getString(StructName205Query.PREFIX); 19205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME); 19215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME); 19225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.familyName = cursor.getString(StructName205Query.FAMILY_NAME); 19235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.suffix = cursor.getString(StructName205Query.SUFFIX); 19245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME); 19255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME); 19265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME); 19275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name, 19295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate, rawContactUpdate, splitter, sb); 19305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 19325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 19335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource, 19375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String currentDisplayName, NameSplitter.Name name, 19385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate, 19395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter, StringBuilder sb) { 19405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov splitter.guessNameStyle(name); 1942ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao int unadjustedFullNameStyle = name.fullNameStyle; 19435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle); 19445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = splitter.join(name, true); 19455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1946ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // Don't update database with the adjusted fullNameStyle as it is locale 1947ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // related 1948ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao structuredNameUpdate.bindLong(1, unadjustedFullNameStyle); 19495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName); 19505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(3, name.phoneticNameStyle); 19515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(4, dataId); 19525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.execute(); 19535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) { 19555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayNameAlternative = splitter.join(name, false); 19565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = splitter.joinPhoneticName(name); 19575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 19585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKeyAlternative = null; 19595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName != null) { 19615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = phoneticName; 1962ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao } else if (name.fullNameStyle == FullNameStyle.CHINESE || 1963ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao name.fullNameStyle == FullNameStyle.CJK) { 1964ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = sortKeyAlternative = ContactLocaleUtils.getIntance() 1965ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(displayName, name.fullNameStyle); 19665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 19695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = displayName; 19705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative = displayNameAlternative; 19715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, displayName, 19745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey, 19755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative); 19765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface Organization205Query { 19805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 19815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 19835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 19845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 19855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.COMPANY, 19865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME, 19875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 19885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 19905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 19915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int COMPANY = 2; 19925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_NAME = 3; 19935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeOrganizationsToVersion205(SQLiteDatabase db, 19965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 1997b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 19985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement organizationUpdate = db.compileStatement( 20005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 20015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 20025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME_STYLE + "=?" + 20035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 20045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS, 2006b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mimeType + " AND " 20075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION, 20085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov null, null, null, null); 20095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 20105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 20115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(Organization205Query.ID); 20125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID); 20135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String company = cursor.getString(Organization205Query.COMPANY); 20145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME); 20155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName); 20175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(1, phoneticNameStyle); 20195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(2, dataId); 20205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.execute(); 20215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 20235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName == null && company != null) { 20245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int nameStyle = splitter.guessFullNameStyle(company); 20255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov nameStyle = splitter.getAdjustedFullNameStyle(nameStyle); 2026ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao if (nameStyle == FullNameStyle.CHINESE || 2027ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao nameStyle == FullNameStyle.CJK ) { 2028ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = ContactLocaleUtils.getIntance() 2029ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(company, nameStyle); 20305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 20345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = company; 20355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, company, 20385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov company, phoneticNameStyle, phoneticName, sortKey, sortKey); 20395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 20415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 20425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId, 20465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName, String displayNameAlternative, int phoneticNameStyle, 20475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName, String sortKeyPrimary, String sortKeyAlternative) { 20485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 1, displayName); 20495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 2, displayNameAlternative); 20505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 3, phoneticName); 20515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(4, phoneticNameStyle); 20525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 5, sortKeyPrimary); 20535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 6, sortKeyAlternative); 20545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(7, rawContactId); 20555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.execute(); 20565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2058f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov private void upgrateToVersion206(SQLiteDatabase db) { 2059f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 2060f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); 2061f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 2062f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 206331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov private interface Organization300Query { 206431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String TABLE = Tables.DATA; 206531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 206631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String SELECTION = DataColumns.MIMETYPE_ID + "=?"; 206731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 206831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String COLUMNS[] = { 206931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization._ID, 207031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.RAW_CONTACT_ID, 207131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.COMPANY, 207231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.TITLE 207331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov }; 207431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 207531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int ID = 0; 207631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int RAW_CONTACT_ID = 1; 207731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int COMPANY = 2; 207831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int TITLE = 3; 207931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 208031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 208131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov /** 208231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * Fix for the bug where name lookup records for organizations would get removed by 208331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * unrelated updates of the data rows. 208431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov */ 2085b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeToVersion300(SQLiteDatabase db) { 2086b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 2087b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeType == -1) { 208831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov return; 208931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 209031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 209131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov ContentValues values = new ContentValues(); 209231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 209331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Find all data rows with the mime type "organization" 209431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Cursor cursor = db.query(Organization300Query.TABLE, Organization300Query.COLUMNS, 2095b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Organization300Query.SELECTION, new String[] {String.valueOf(mimeType)}, 209631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov null, null, null); 209731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov try { 209831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov while (cursor.moveToNext()) { 209931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long dataId = cursor.getLong(Organization300Query.ID); 210031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long rawContactId = cursor.getLong(Organization300Query.RAW_CONTACT_ID); 210131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String company = cursor.getString(Organization300Query.COMPANY); 210231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String title = cursor.getString(Organization300Query.TITLE); 210331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 210431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // First delete name lookup if there is any (chances are there won't be) 210531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.delete(Tables.NAME_LOOKUP, NameLookupColumns.DATA_ID + "=?", 210631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov new String[]{String.valueOf(dataId)}); 210731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 210831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Now insert two name lookup records: one for company name, one for title 210931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 211031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 211131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.ORGANIZATION); 211231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 211331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(company)) { 211431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 211531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(company)); 211631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 211731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 211831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 211931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(title)) { 212031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 212131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(title)); 212231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 212331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 212431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 212531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } finally { 212631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov cursor.close(); 212731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 212831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 212931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 2130b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final class Upgrade303Query { 2131b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String TABLE = Tables.DATA; 2132b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2133b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String SELECTION = 2134b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=?" + 2135b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data._ID + " NOT IN " + 2136b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" + 2137b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data.DATA1 + " NOT NULL"; 2138b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2139b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String COLUMNS[] = { 2140b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data._ID, 2141b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.RAW_CONTACT_ID, 2142b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.DATA1, 2143b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov }; 2144b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2145b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int ID = 0; 2146b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 2147b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int DATA1 = 2; 2148b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2149b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2150b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2151b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2152b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * emails during the sync. We need to restore the lost name lookup rows. 2153b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2154b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeEmailToVersion303(SQLiteDatabase db) { 2155b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 2156b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2157b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2158b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2159b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2160b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2161b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2162b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "email" that are missing name lookup 2163b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2164b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2165b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2166b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2167b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2168b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2169b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2170b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2171b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov value = extractHandleFromEmailAddress(value); 2172b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2173b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (value != null) { 2174b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2175b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2176b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME); 2177b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2178b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2179b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2180b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2181b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2182b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2183b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2184b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2185b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2186b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2187b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2188b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * nicknames during the sync. We need to restore the lost name lookup rows. 2189b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2190b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeNicknameToVersion303(SQLiteDatabase db) { 2191b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 2192b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2193b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2194b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2195b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2196b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2197b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2198b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "nickname" that are missing name lookup 2199b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2200b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2201b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2202b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2203b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2204b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2205b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2206b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2207b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2208b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2209b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2210b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME); 2211b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2212b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2213b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2214b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2215b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2216b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2217b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2218b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 221951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void upgradeToVersion304(SQLiteDatabase db) { 222051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Mimetype table requires an index on mime type 222151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS mime_type ON " + Tables.MIMETYPES + " (" + 222251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov MimetypesColumns.MIMETYPE + 222351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov ");"); 222451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 222551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 222660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann private void upgradeToVersion306(SQLiteDatabase db) { 222760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // Fix invalid lookup that was used for Exchange contacts (it was not escaped) 222860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // It happened when a new contact was created AND synchronized 222960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final StringBuilder lookupKeyBuilder = new StringBuilder(); 223060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final SQLiteStatement updateStatement = db.compileStatement( 223160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "UPDATE contacts " + 223260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SET lookup=? " + 223360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE _id=?"); 223460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor contactIdCursor = db.rawQuery( 223560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT DISTINCT contact_id " + 223660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 223760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE deleted=0 AND account_type='com.android.exchange'", 223860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann null); 223960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 224060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (contactIdCursor.moveToNext()) { 224160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final long contactId = contactIdCursor.getLong(0); 224260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann lookupKeyBuilder.setLength(0); 224360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor c = db.rawQuery( 224460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT account_type, account_name, _id, sourceid, display_name " + 224560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 224660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE contact_id=? " + 224760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "ORDER BY _id", 224860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann new String[] { String.valueOf(contactId) }); 224960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 225060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (c.moveToNext()) { 225160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann ContactLookupKey.appendToLookupKey(lookupKeyBuilder, 225260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(0), 225360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(1), 225460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getLong(2), 225560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(3), 225660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(4)); 225760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 225860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 225960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.close(); 226060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 226160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 226260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (lookupKeyBuilder.length() == 0) { 226360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindNull(1); 226460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } else { 226560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindString(1, Uri.encode(lookupKeyBuilder.toString())); 226660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 226760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindLong(2, contactId); 226860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 226960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.execute(); 227060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 227160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 227260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.close(); 227360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann contactIdCursor.close(); 227460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 227560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 227660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 2277b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov private void upgradeToVersion307(SQLiteDatabase db) { 2278b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE properties (" + 2279b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_key TEXT PRIMARY_KEY, " + 2280b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_value TEXT" + 2281b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 2282b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2283b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2284743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov private void upgradeToVersion308(SQLiteDatabase db) { 22854394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE accounts (" + 22864394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_name TEXT, " + 22874394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_type TEXT " + 22884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 2289743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 22904394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO accounts " + 22914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "SELECT DISTINCT account_name, account_type FROM raw_contacts"); 2292743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 2293743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 2294f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov private void upgradeToVersion400(SQLiteDatabase db) { 2295dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2296dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0;"); 2297dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2298dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0;"); 2299dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 2300dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 23017da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov private void upgradeToVersion353(SQLiteDatabase db) { 23027da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov db.execSQL("DELETE FROM contacts " + 23037da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov "WHERE NOT EXISTS (SELECT 1 FROM raw_contacts WHERE contact_id=contacts._id)"); 23047da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 23057da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 230651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildNameLookup(SQLiteDatabase db) { 230751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 230851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 230951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 231051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 231151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 231204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 231351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates all locale-sensitive data: nickname_lookup, name_lookup and sort keys. 231404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 231551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov public void setLocale(ContactsProvider2 provider, Locale locale) { 231651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.i(TAG, "Switching to locale " + locale); 231704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2318c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton long start = SystemClock.uptimeMillis(); 231951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 232051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setLocale(locale); 232151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.beginTransaction(); 232251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 232351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 232451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key2_index"); 232551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 232651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 232751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov loadNicknameLookupTable(db); 232851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 232951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov rebuildSortKeys(db, provider); 233051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 233151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setTransactionSuccessful(); 233251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 233351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.endTransaction(); 233451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 233551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 2336c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton Log.i(TAG, "Locale change completed in " + (SystemClock.uptimeMillis() - start) + "ms"); 233751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 233851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 233951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov /** 234051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates sort keys for all contacts. 234151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov */ 234251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildSortKeys(SQLiteDatabase db, ContactsProvider2 provider) { 234351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Cursor cursor = db.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID}, 234451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov null, null, null, null, null); 234551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 234651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov while (cursor.moveToNext()) { 234751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov long rawContactId = cursor.getLong(0); 234851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov provider.updateRawContactDisplayName(db, rawContactId); 234951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 235051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 235151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov cursor.close(); 235251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 235351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 235451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 235551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void insertNameLookup(SQLiteDatabase db) { 235604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP); 235704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 235804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov SQLiteStatement nameLookupInsert = db.compileStatement( 235904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 236004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 236104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 236204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 236304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + 236404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ") VALUES (?,?,?,?)"); 236504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 236651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 236751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertStructuredNameLookup(db, nameLookupInsert); 236851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertOrganizationLookup(db, nameLookupInsert); 236951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertEmailLookup(db, nameLookupInsert); 237051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNicknameLookup(db, nameLookupInsert); 237151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 237251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nameLookupInsert.close(); 237351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 237404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 237504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 237604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class StructuredNameQuery { 237704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 237804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 237904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 238004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 238104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 238304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName._ID, 238404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.RAW_CONTACT_ID, 238504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.DISPLAY_NAME, 238604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 238704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 238904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 239004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int DISPLAY_NAME = 2; 239104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 239204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private class StructuredNameLookupBuilder extends NameLookupBuilder { 239404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final SQLiteStatement mNameLookupInsert; 239604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final CommonNicknameCache mCommonNicknameCache; 239704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public StructuredNameLookupBuilder(NameSplitter splitter, 239904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) { 240004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov super(splitter); 240104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mCommonNicknameCache = commonNicknameCache; 240204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mNameLookupInsert = nameLookupInsert; 240304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 240404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 240504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 240604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected void insertNameLookup(long rawContactId, long dataId, int lookupType, 240704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name) { 240804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (!TextUtils.isEmpty(name)) { 240904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert, 241004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rawContactId, dataId, lookupType, name); 241104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 241204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 241304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 241404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 241504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected String[] getCommonNicknameClusters(String normalizedName) { 241604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return mCommonNicknameCache.getCommonNicknameClusters(normalizedName); 241704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 241804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 241904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 242004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 242104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all structured names in the database. 242204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 242304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 2424d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameSplitter nameSplitter = createNameSplitter(); 2425d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(nameSplitter, 242604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov new CommonNicknameCache(db), nameLookupInsert); 242704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE); 242804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS, 242904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 243004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 243104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 243204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 243304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(StructuredNameQuery.ID); 243404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID); 243504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME); 2436d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov int fullNameStyle = nameSplitter.guessFullNameStyle(name); 243751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov fullNameStyle = nameSplitter.getAdjustedFullNameStyle(fullNameStyle); 2438d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov nameLookupBuilder.insertNameLookup(rawContactId, dataId, name, fullNameStyle); 243904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 244004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 244104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 244204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 244304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 244404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 244504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class OrganizationQuery { 244604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 244704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 244804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 244904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 245004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 245104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 245204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization._ID, 245304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.RAW_CONTACT_ID, 245404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.COMPANY, 245504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.TITLE, 245604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 245704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 245804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 245904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 246004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int COMPANY = 2; 246104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int TITLE = 3; 246204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 246304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 246404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 246504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all organizations in the database. 246604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 246704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertOrganizationLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 246804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 246904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(OrganizationQuery.TABLE, OrganizationQuery.COLUMNS, 247004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov OrganizationQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 247104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 247204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 247304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 247404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(OrganizationQuery.ID); 247504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(OrganizationQuery.RAW_CONTACT_ID); 247604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String organization = cursor.getString(OrganizationQuery.COMPANY); 247704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String title = cursor.getString(OrganizationQuery.TITLE); 247804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 247904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, organization); 248004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 248104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, title); 248204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 248304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 248404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 248504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 248604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 248704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 248804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class EmailQuery { 248904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 249004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 249104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 249204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 249304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 249404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 249504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email._ID, 249604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.RAW_CONTACT_ID, 249704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.ADDRESS, 249804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 249904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 250004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 250104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 250204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ADDRESS = 2; 250304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 250404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 250504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 250604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all email addresses in the database. 250704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 250804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 250904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 251004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS, 251104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 251204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 251304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 251404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 251504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(EmailQuery.ID); 251604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID); 251704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String address = cursor.getString(EmailQuery.ADDRESS); 251804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov address = extractHandleFromEmailAddress(address); 251904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 252004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, address); 252104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 252304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 252404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 252704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class NicknameQuery { 252804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 252904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 253104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 253204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 253404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname._ID, 253504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.RAW_CONTACT_ID, 253604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.NAME, 253704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 253804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 254004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 254104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int NAME = 2; 254204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 254404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 254504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all nicknames in the database. 254604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 254704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 254804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 254904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS, 255004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 255104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 255204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 255304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 255404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(NicknameQuery.ID); 255504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID); 255604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String nickname = cursor.getString(NicknameQuery.NAME); 255704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 255804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.NICKNAME, nickname); 255904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 256104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 256204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 256504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 256604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 256704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 256804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 256904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String name) { 257004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 257104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 257204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 257304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 257404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String normalized = NameNormalizer.normalize(name); 257504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(normalized)) { 257604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 257704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 257804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 257904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized); 258004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 258104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 258204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 258304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String normalizedName) { 258404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(1, rawContactId); 258504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(2, dataId); 258604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(3, lookupType); 258704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindString(4, normalizedName); 258804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.executeInsert(); 258904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 259004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 25914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov /** 25924394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov * Changing the VISIBLE bit from a field on both RawContacts and Contacts to a separate table. 25934394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov */ 25944394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov private void upgradeToVersion401(SQLiteDatabase db) { 25954394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 25964394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 25974394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 25984394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 25994394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 26004394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 26014394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts.IN_VISIBLE_GROUP + "!=0"); 26024394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 26034394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 26044394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 2605d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov /** 2606d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov * Introducing a new table: directories. 2607d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov */ 2608d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void upgradeToVersion402(SQLiteDatabase db) { 2609d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 2610d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 2611d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 261297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov private void upgradeToVersion403(SQLiteDatabase db) { 261397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 261497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov createDirectoriesTable(db); 261597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 261697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE raw_contacts" 261797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD raw_contact_is_read_only INTEGER NOT NULL DEFAULT 0;"); 261897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 261997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE data" 262097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD is_read_only INTEGER NOT NULL DEFAULT 0;"); 262197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 262297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 2623892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void upgradeToVersion405(SQLiteDatabase db) { 2624892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS phone_lookup;"); 2625892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov // Private phone numbers table used for lookup 2626892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 2627892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID 2628892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 2629892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 2630892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 2631892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 2632892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 2633892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2634892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2635892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 2636892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 2637892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2638892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2639892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2640892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2641892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 2642892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 2643892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2644892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2645892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2646892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2647892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Phone.CONTENT_ITEM_TYPE); 2648892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (mimeTypeId == -1) { 2649892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return; 2650892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2651892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2652892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String mCountryIso = getCountryIso(); 2653892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov Cursor cursor = db.rawQuery( 2654892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov "SELECT _id, " + Phone.RAW_CONTACT_ID + ", " + Phone.NUMBER + 2655892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " FROM " + Tables.DATA + 2656892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId 2657892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " AND " + Phone.NUMBER + " NOT NULL", null); 2658892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2659892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ContentValues phoneValues = new ContentValues(); 2660892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov try { 2661892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov while (cursor.moveToNext()) { 2662892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long dataID = cursor.getLong(0); 2663892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long rawContactID = cursor.getLong(1); 2664892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String number = cursor.getString(2); 2665892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String numberE164 = PhoneNumberUtils.formatNumberToE164(number, mCountryIso); 2666892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String normalizedNumber = PhoneNumberUtils.normalizeNumber(number); 2667892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (!TextUtils.isEmpty(normalizedNumber)) { 2668892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.clear(); 2669892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactID); 2670892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.DATA_ID, dataID); 2671892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber); 2672892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2673892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber)); 2674892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2675892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2676892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (numberE164 != null && !numberE164.equals(normalizedNumber)) { 2677892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164); 2678892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2679892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(numberE164)); 2680892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2681892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2682892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2683892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2684892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } finally { 2685892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov cursor.close(); 2686892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2687892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2688892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 26892530512f639c4979fd7371c7dd25dd67e8118124Bai Tao private void upgradeToVersion406(SQLiteDatabase db) { 26902530512f639c4979fd7371c7dd25dd67e8118124Bai Tao db.execSQL("ALTER TABLE calls ADD countryiso TEXT;"); 26912530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 26922530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 2693d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion409(SQLiteDatabase db) { 2694d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 2695d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov createDirectoriesTable(db); 2696d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 2697d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 2698385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov /** 2699d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov * Adding DEFAULT_DIRECTORY table. 2700385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov */ 2701d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion411(SQLiteDatabase db) { 2702d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.DEFAULT_DIRECTORY); 2703385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 2704385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 2705385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 2706385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2707385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process contacts without an account 2708385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2709385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2710385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2711385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 2712385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL "); 2713385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2714385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process accounts that don't have a default group (e.g. Exchange) 2715385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2716385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2717385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2718385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE NOT EXISTS" + 2719385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 2720385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 2721385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2722385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2723385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2724385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2725385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2726385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")"); 2727385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2728385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = lookupMimeTypeId(db, GroupMembership.CONTENT_ITEM_TYPE); 2729385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2730d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Process accounts that do have a default group (e.g. Google) 2731385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2732385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2733385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2734385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 2735385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" + Data.RAW_CONTACT_ID + ")" + 2736385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimetype + 2737d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND EXISTS" + 2738d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " (SELECT " + Groups._ID + 2739d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " FROM " + Tables.GROUPS + 2740d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2741d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2742d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2743d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2744d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2745d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov ")"); 27463d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 2747385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2748e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov private void upgradeToVersion413(SQLiteDatabase db) { 27493ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 27503ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov createDirectoriesTable(db); 2751e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 2752e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 2753c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov private void upgradeToVersion415(SQLiteDatabase db) { 2754c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov db.execSQL( 2755c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov "ALTER TABLE " + Tables.GROUPS + 2756c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " ADD " + Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0"); 2757c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov db.execSQL( 2758c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov "UPDATE " + Tables.GROUPS + 2759c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " SET " + Groups.GROUP_IS_READ_ONLY + "=1" + 2760c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " WHERE " + Groups.SYSTEM_ID + " NOT NULL"); 2761c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov } 2762c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov 2763b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public String extractHandleFromEmailAddress(String email) { 2764b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 2765b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (tokens.length == 0) { 2766b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2767b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2768b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2769b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String address = tokens[0].getAddress(); 2770b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov int at = address.indexOf('@'); 2771b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (at != -1) { 2772b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return address.substring(0, at); 2773b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2774b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2775b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2776b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 277708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov public String extractAddressFromEmailAddress(String email) { 277808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 277908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (tokens.length == 0) { 278008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return null; 278108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 278208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 278308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return tokens[0].getAddress(); 278408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 278508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 2786b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private long lookupMimeTypeId(SQLiteDatabase db, String mimeType) { 2787b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2788b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return DatabaseUtils.longForQuery(db, 2789b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 2790b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 2791b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 2792b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov + "='" + mimeType + "'", null); 2793b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } catch (SQLiteDoneException e) { 2794b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // No rows of this type in the database 2795b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return -1; 2796b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2797b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2798b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 27995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void bindString(SQLiteStatement stmt, int index, String value) { 28005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (value == null) { 28015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindNull(index); 28025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else { 28035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindString(index, value); 28045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 28055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 28065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2807a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 2808f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Adds index stats into the SQLite database to force it to always use the lookup indexes. 2809f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 2810f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private void updateSqliteStats(SQLiteDatabase db) { 2811f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2812f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // Specific stats strings are based on an actual large database after running ANALYZE 2813f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov try { 28148fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 28158fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_restricted_index", "10000 9000"); 28168fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 28178fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_has_phone_index", "10000 500"); 28188fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28198fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 28208fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_source_id_index", "10000 1 1 1"); 28218fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 28228fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_contact_id_index", "10000 2"); 28238fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28248fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 28258fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "name_lookup_raw_contact_id_index", "10000 3"); 28268fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 2827916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov "name_lookup_index", "10000 3 2 2 1"); 28288fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 28298fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "10000 3 2 1"); 28308fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28318fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 28328fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "phone_lookup_index", "10000 2 2 1"); 283336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 283436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 28358fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28368fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 28378fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_mimetype_data1_index", "60000 5000 2"); 28388fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 28398fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_raw_contact_id", "60000 10"); 28408fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28418fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.GROUPS, 28428fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "groups_source_id_index", "50 1 1 1"); 28438fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28448fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NICKNAME_LOOKUP, 28458fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "500 2 1"); 28468fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 2847f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } catch (SQLException e) { 2848f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov Log.e(TAG, "Could not update index stats", e); 2849f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2850f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2851f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2852f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2853f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Stores statistics for a given index. 2854f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * 2855f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * @param stats has the following structure: the first index is the expected size of 2856f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * the table. The following integer(s) are the expected number of records selected with the 2857f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * index. There should be one integer per indexed column. 2858f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 28595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateIndexStats(SQLiteDatabase db, String table, String index, 28605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String stats) { 2861f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';"); 2862f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)" 2863f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " VALUES ('" + table + "','" + index + "','" + stats + "');"); 2864f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2865f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2866f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov @Override 2867f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov public synchronized SQLiteDatabase getWritableDatabase() { 2868f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov SQLiteDatabase db = super.getWritableDatabase(); 2869f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov if (mReopenDatabase) { 2870f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov mReopenDatabase = false; 2871f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov close(); 2872f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db = super.getWritableDatabase(); 2873f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2874f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov return db; 2875f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2876f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2877f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2878a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 2879a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 2880a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 2881a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 28823d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 288333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACCOUNTS + ";"); 288469cc3a2b09e2ffb606c6e52a71b604bba526d225Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL)"); 288533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov 2886d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 28875ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";"); 2888a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 2889a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 2890a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 2891ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 2892b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 2893eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("DELETE FROM " + Tables.SETTINGS + ";"); 2894a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 28953d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CALLS + ";"); 289672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DIRECTORIES + ";"); 289772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov 2898b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 2899a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 2900b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 290104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public NameSplitter createNameSplitter() { 290204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return new NameSplitter( 290304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 290404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 290504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 290604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 290704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Locale.getDefault()); 290804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 290904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2910b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2911619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 2912619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2913619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 2914619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 2915619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 2916619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 2917619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 2918619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 2919619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2920619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2921619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2922619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2923b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 2924b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 2925b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 2926b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 2927b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 2928b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 2929b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 2930b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 2931b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 2932b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 2933b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 2934b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2935f4a3b7e523e36679b68edd2af632e26648758ff2Dmitri Plotnikov private long getCachedId(SQLiteStatement query, SQLiteStatement insert, 2936b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 2937b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 2938b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 2939b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 2940b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2941b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2942b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey long id = -1; 2943b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2944b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try searching database for mapping 2945b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(query, 1, value); 2946b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = query.simpleQueryForLong(); 2947b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2948b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Nothing found, so try inserting new mapping 2949b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(insert, 1, value); 2950b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = insert.executeInsert(); 2951b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2952b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2953b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (id != -1) { 2954b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Cache and return the new answer 2955b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey cache.put(value, id); 2956b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return id; 2957b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } else { 2958b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Otherwise throw if no mapping found or created 2959b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey throw new IllegalStateException("Couldn't find or create internal " 2960b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + "lookup table entry for value " + value); 2961b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2962b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2963b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2964b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2965ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 2966b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2967b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2968b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 2969b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2970b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2971b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 2972b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2973b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2974b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2975ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 2976b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2977b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2978b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 2979b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2980b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 29815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return getMimeTypeIdNoDbCheck(mimetype); 29825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 29835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 29845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private long getMimeTypeIdNoDbCheck(String mimetype) { 2985b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 2986b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2987b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2988b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2989ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 2990b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2991b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 2992b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2993b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2994b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2995b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2996b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 2997b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 2998b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2999b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 3000b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 3001b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 3002b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3003b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3004b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 3005b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3006b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 3007b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3008b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 3009b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 3010b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 3011b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 3012b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 3013b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 3014b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 3015b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 3016b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 3017b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 3018b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 3019b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3020b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 30216bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 30226bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 3023d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts. 3024ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 3025ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 3026385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov updateCustomContactVisibility(getWritableDatabase(), ""); 3027ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3028ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3029ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3030385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} and 3031385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * {@link Tables#DEFAULT_DIRECTORY} for a specific contact. 3032ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 3033fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public void updateContactVisible(long contactId) { 30344394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3035385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov updateCustomContactVisibility(getWritableDatabase(), 3036385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Contacts._ID + "=" + contactId); 3037385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3038385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov String contactIdAsString = String.valueOf(contactId); 3039385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 3040385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3041385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // The contact will be included in the default directory if contains 3042d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // a raw contact that is in any group or in an account that 3043385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // does not have any AUTO_ADD groups. 3044385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long visibleRawContact = DatabaseUtils.longForQuery(db, 3045385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT EXISTS (" + 3046385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 3047385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3048385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 3049385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" 3050385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + Data.RAW_CONTACT_ID + ")" + 3051385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3052385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + DataColumns.MIMETYPE_ID + "=?" + 3053385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3054385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3055385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3056385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3057385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND NOT EXISTS" + 3058385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 3059385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 3060385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 3061385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 3062385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 3063385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 3064385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 3065385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")" + 3066385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3067385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3068385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3069385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3070385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 3071385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL" + 3072385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")", 3073385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { 3074385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 30756c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov String.valueOf(mimetype), 3076385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 30776c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov contactIdAsString 3078385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov }); 3079385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3080385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov if (visibleRawContact != 0) { 3081385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + " VALUES(?)", 3082385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3083385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } else { 3084385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DEFAULT_DIRECTORY + " WHERE " + Contacts._ID + "=?", 3085385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3086385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 3087385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 30884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 3089385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov private void updateCustomContactVisibility(SQLiteDatabase db, String selection) { 3090ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 30914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)}; 30924394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 30934394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // First delete what needs to be deleted, then insert what needs to be added. 30944394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // Since flash writes are very expensive, this approach is much better than 30954394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // delete-all-insert-all. 30964394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.VISIBLE_CONTACTS + 30974394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + "_id NOT IN" + 30984394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "(SELECT " + Contacts._ID + 30994394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 31004394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE (" + Clauses.CONTACT_IS_VISIBLE + ")=1) " + selection, 31014394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3102fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 31034394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 31044394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 31054394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 31064394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts._ID + 31074394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " NOT IN " + Tables.VISIBLE_CONTACTS + 31084394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1 " + selection, 31094394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3110ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3111ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3112ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3113d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Returns contact ID for the given contact or zero if it is NULL. 31146bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 3115d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public long getContactId(long rawContactId) { 31166bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov getReadableDatabase(); 31176bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 3118d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId); 3119d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactIdQuery.simpleQueryForLong(); 31206bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 3121a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana // No valid mapping found, so return 0 31226bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 31236bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 31246bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 312561bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 31265ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int getAggregationMode(long rawContactId) { 3127f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov getReadableDatabase(); 3128f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 31295ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId); 3130f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 3131f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 31326cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // No valid row found, so return "disabled" 31336cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.AGGREGATION_MODE_DISABLED; 3134f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3135f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3136f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3137892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov public void buildPhoneLookupAndContactQuery( 3138892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov SQLiteQueryBuilder qb, String normalizedNumber, String numberE164) { 3139892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber); 3140e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 314136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, true); 3142e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setTables(sb.toString()); 3143e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3144e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb = new StringBuilder(); 3145892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, normalizedNumber, numberE164); 3146e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 3147bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 3148bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3149e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public String buildPhoneLookupAsNestedQuery(String number) { 3150e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 315136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 3152e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id" + " FROM "); 315336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, false); 3154e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(" WHERE "); 3155892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, number, null); 3156e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(")"); 3157e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov return sb.toString(); 3158e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3159e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 316036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private void appendPhoneLookupTables(StringBuilder sb, final String minMatch, 3161e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov boolean joinContacts) { 3162e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(Tables.RAW_CONTACTS); 3163e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov if (joinContacts) { 3164fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov sb.append(" JOIN " + getContactView() + " contacts_view" 3165fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " ON (contacts_view._id = raw_contacts.contact_id)"); 3166e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3167892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(", (SELECT data_id, normalized_number, length(normalized_number) as len " 3168892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " FROM phone_lookup " + " WHERE (" + Tables.PHONE_LOOKUP + "." 3169892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + PhoneLookupColumns.MIN_MATCH + " = '"); 317036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 317136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("')) AS lookup, " + Tables.DATA); 3172e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3173e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3174892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void appendPhoneLookupSelection(StringBuilder sb, String number, String numberE164) { 3175892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id"); 3176892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumberE164 = !TextUtils.isEmpty(numberE164); 3177892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumber = !TextUtils.isEmpty(number); 3178892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 || hasNumber) { 3179892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND ( "); 3180892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164) { 3181892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.normalized_number = "); 3182892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, numberE164); 3183892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3184892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 && hasNumber) { 3185892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" OR "); 3186892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3187892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumber) { 3188892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov int numberLen = number.length(); 3189892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.len <= "); 3190892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3191892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND substr("); 3192892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 3193892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(','); 3194892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3195892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" - lookup.len + 1) = lookup.normalized_number"); 3196892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3197892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(')'); 3198892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 319936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 320036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 320136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public String getUseStrictPhoneNumberComparisonParameter() { 320236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov return mUseStrictPhoneNumberComparison ? "1" : "0"; 3203fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov } 3204bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3205619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 3206b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 3207b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 3208b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 320951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP); 321051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 321128f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 321228f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 3213b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 3214b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 3215b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3216b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3217b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 3218b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 3219b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 3220b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 322151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 322251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 322351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String[] names = strings[clusterId].split(","); 322451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int j = 0; j < names.length; j++) { 322551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 322651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 322751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 322851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 322951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String.valueOf(clusterId)); 323051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.executeInsert(); 323151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } catch (SQLiteException e) { 323251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 323351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Print the exception and keep going - this is not a fatal error 323451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 323551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 3236b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3237b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 323851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 323951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.close(); 3240b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3241b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3242b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3243f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 3244f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3245f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3246f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 3247f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3248f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3249f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3250f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 3251f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3252f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3253f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 3254f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 3255f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 3256f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 3257f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 3258f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 3259f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 3260f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 32611b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov } else if (value instanceof String) { 32621b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = Long.parseLong((String)value); 3263f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 32641b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = ((Number)value).longValue(); 3265f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3266f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 3267f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3268f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3269f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 327035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 327135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 327235ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 3273c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3274c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov /** 3275c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Delete the aggregate contact if it has no constituent raw contacts other 3276c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * than the supplied one. 3277c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 3278c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov public void removeContactIfSingleton(long rawContactId) { 3279c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3280c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3281c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Obtain contact ID from the supplied raw contact ID 3282c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM " 3283c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")"; 3284c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3285c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Find other raw contacts in the same aggregate contact 3286c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM " 3287c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON (" 3288c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID 3289c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + "" 3290c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")"; 3291c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3292c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS 3293c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId 3294c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND NOT EXISTS " + otherRawContacts + ";"); 3295c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 32964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 32974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 3298b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Returns the value from the {@link Tables#PROPERTIES} table. 3299b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3300b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public String getProperty(String key, String defaultValue) { 3301b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov Cursor cursor = getReadableDatabase().query(Tables.PROPERTIES, 3302b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{PropertiesColumns.PROPERTY_VALUE}, 3303b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + "=?", 3304b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{key}, null, null, null); 3305b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String value = null; 3306b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov try { 3307b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (cursor.moveToFirst()) { 3308b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov value = cursor.getString(0); 3309b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3310b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } finally { 3311b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov cursor.close(); 3312b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3313b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3314b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov return value != null ? value : defaultValue; 3315b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3316b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3317b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 3318b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Stores a key-value pair in the {@link Tables#PROPERTIES} table. 3319b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3320b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public void setProperty(String key, String value) { 33213d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(getWritableDatabase(), key, value); 33223d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 33233d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 33243d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private void setProperty(SQLiteDatabase db, String key, String value) { 3325b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ContentValues values = new ContentValues(); 3326b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_KEY, key); 3327b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_VALUE, value); 33283d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov db.replace(Tables.PROPERTIES, null, values); 3329b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3330b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3331b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 33324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Check if {@link Binder#getCallingUid()} should be allowed access to 33334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * {@link RawContacts#IS_RESTRICTED} data. 33344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 3335d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData() { 33364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 33376ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen int caller = Binder.getCallingUid(); 33386ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen if (caller == 0) return true; // root can do anything 33396ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen final String[] callerPackages = pm.getPackagesForUid(caller); 33404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Has restricted access if caller matches any packages 33424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov for (String callerPackage : callerPackages) { 3343d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (hasAccessToRestrictedData(callerPackage)) { 3344763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return true; 3345763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3346763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3347763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return false; 3348763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3349763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3350763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar /** 3351763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * Check if requestingPackage should be allowed access to 3352763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * {@link RawContacts#IS_RESTRICTED} data. 3353763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar */ 3354d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData(String requestingPackage) { 3355d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (mUnrestrictedPackages != null) { 3356d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton for (String allowedPackage : mUnrestrictedPackages) { 3357d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (allowedPackage.equals(requestingPackage)) { 3358d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return true; 3359d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton } 33604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov return false; 33634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getDataView() { 3366d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getDataView(false); 3367d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3368d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3369d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getDataView(boolean requireRestrictedView) { 3370d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3371d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Views.DATA_ALL : Views.DATA_RESTRICTED; 33724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getRawContactView() { 3375763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getRawContactView(false); 3376763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3377763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3378763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getRawContactView(boolean requireRestrictedView) { 3379d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3380763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.RAW_CONTACTS_ALL : Views.RAW_CONTACTS_RESTRICTED; 33814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getContactView() { 3384763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getContactView(false); 33854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3387763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getContactView(boolean requireRestrictedView) { 3388d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3389763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.CONTACTS_ALL : Views.CONTACTS_RESTRICTED; 3390f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey } 3391f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey 339289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public String getGroupView() { 339389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov return Views.GROUPS_ALL; 339489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov } 339589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 3396a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView() { 3397a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getRawEntitiesView(false); 3398a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3399a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3400a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView(boolean requireRestrictedView) { 3401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3402a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.RAW_ENTITIES : Views.RAW_ENTITIES_RESTRICTED; 3403a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3404a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3405a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView() { 3406a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getEntitiesView(false); 3407d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3408d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3409a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView(boolean requireRestrictedView) { 3410d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3411a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.ENTITIES : Views.ENTITIES_RESTRICTED; 3412d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3413d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3414ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** 3415ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov * Test if any of the columns appear in the given projection. 3416ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov */ 3417ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov public boolean isInProjection(String[] projection, String... columns) { 341882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (projection == null) { 341982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 342082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 3421ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 342282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov // Optimized for a single-column test 342382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (columns.length == 1) { 342482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov String column = columns[0]; 342582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 342682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (column.equals(test)) { 342782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 342882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 342982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 343082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } else { 343182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 343282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String column : columns) { 3433ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (column.equals(test)) { 3434ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return true; 3435ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3436ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3437ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3438ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3439ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return false; 34404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 3441fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3442fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3443fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3444fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3445fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3446fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(Uri uri) { 3447fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return exceptionMessage(null, uri); 3448fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3449fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3450fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3451fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3452fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3453fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3454fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(String message, Uri uri) { 3455fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 3456fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (message != null) { 3457fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(message).append("; "); 3458fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3459fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("URI: ").append(uri); 3460fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 3461fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov int callingUid = Binder.getCallingUid(); 3462fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling user: "); 3463fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov String userName = pm.getNameForUid(callingUid); 3464fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (userName != null) { 3465fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(userName); 3466fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3467fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callingUid); 3468fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3469fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3470fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(callingUid); 3471fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages != null && callerPackages.length > 0) { 3472fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages.length == 1) { 3473fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package:"); 3474fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[0]); 3475fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3476fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package is one of: ["); 3477fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov for (int i = 0; i < callerPackages.length; i++) { 3478fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (i != 0) { 3479fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", "); 3480fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3481fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[i]); 3482fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3483fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("]"); 3484fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3485fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3486fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3487fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return sb.toString(); 3488fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3489892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 3490892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov protected String getCountryIso() { 3491892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov CountryDetector detector = 3492892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov (CountryDetector) mContext.getSystemService(Context.COUNTRY_DETECTOR); 3493892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return detector.detectCountry().getCountryIso(); 3494892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3495b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 3496