ContactsDatabaseHelper.java revision d6ef718d85724dc482dc88f8c8a87b356e63c0f6
1b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/* 2b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Copyright (C) 2009 The Android Open Source Project 3b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 4b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * you may not use this file except in compliance with the License. 6b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * You may obtain a copy of the License at 7b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 8b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 10b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * See the License for the specific language governing permissions and 14b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * limitations under the License 15b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 16b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts; 18b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport com.android.internal.content.SyncStateContentProviderHelper; 2067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 2182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.content.ContentResolver; 22619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.ContentValues; 23b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.content.Context; 24619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.ApplicationInfo; 25619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager; 26619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 27d91272b48f97243533c6580981e12a4847b5783fJeff Hamiltonimport android.content.res.Resources; 2836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.database.Cursor; 29b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.DatabaseUtils; 30f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikovimport android.database.SQLException; 31b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDatabase; 32b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDoneException; 33b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikovimport android.database.sqlite.SQLiteException; 34b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteOpenHelper; 35bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.database.sqlite.SQLiteQueryBuilder; 36b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteStatement; 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 */ 91d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov static final int DATABASE_VERSION = 411; 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 4793296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey /** In-memory cache of previously found MIME-type mappings */ 480bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 481b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 482bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 483b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 484b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 485b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 486b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 487b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 488d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private SQLiteStatement mContactIdQuery; 489f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 490b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 491b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 492b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 493b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 494b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 495b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 49635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 497f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov 498f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private boolean mReopenDatabase = false; 499f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 500b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static ContactsDatabaseHelper sSingleton = null; 501b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 50236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private boolean mUseStrictPhoneNumberComparison; 5033a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa 504d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton /** 505d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton * List of package names with access to {@link RawContacts#IS_RESTRICTED} data. 506d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton */ 507d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton private String[] mUnrestrictedPackages; 508d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton 509b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov public static synchronized ContactsDatabaseHelper getInstance(Context context) { 510b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 511b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov sSingleton = new ContactsDatabaseHelper(context); 512b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 513b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 514b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 515b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 5161f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 51731b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 51835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 5191f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 520b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov ContactsDatabaseHelper(Context context) { 521b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey super(context, DATABASE_NAME, null, DATABASE_VERSION); 522d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton Resources resources = context.getResources(); 523619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 524b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 52528b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 52636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov mUseStrictPhoneNumberComparison = 527d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton resources.getBoolean( 528d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton com.android.internal.R.bool.config_use_strict_phone_number_comparation); 5290f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov int resourceId = resources.getIdentifier("unrestricted_packages", "array", 5300f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov context.getPackageName()); 5310f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov if (resourceId != 0) { 5320f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = resources.getStringArray(resourceId); 5330f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } else { 5340f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = new String[0]; 5350f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } 536b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 537b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 538b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 539b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 54035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.onDatabaseOpened(db); 54135ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 542b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Create compiled statements for package and mimetype lookups 543ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM " 544ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 545ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM " 546ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?"); 547d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov mContactIdQuery = db.compileStatement("SELECT " + RawContacts.CONTACT_ID + " FROM " 5485ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 5496cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov mAggregationModeQuery = db.compileStatement("SELECT " + RawContacts.AGGREGATION_MODE 5505ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?"); 551ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "(" 552ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + MimetypesColumns.MIMETYPE + ") VALUES (?)"); 553ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "(" 554ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + PackagesColumns.PACKAGE + ") VALUES (?)"); 555ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 556ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM " 557ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 558ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE 559ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "." 560b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + Activities._ID + "=?"); 5611f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 5621f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 563e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+ 56482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 56582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PROTOCOL + " INTEGER NOT NULL," + 56682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + 56782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_HANDLE + " TEXT," + 56882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_ACCOUNT + " TEXT," + 569a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 570a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 57182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE + " INTEGER," + 572aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0," + 57382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL 57482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + 5751f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 5761f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 577e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON " 5784dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");"); 579e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 580e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " 581aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+ 582e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov AggregatedPresenceColumns.CONTACT_ID 583e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," + 584632248ae0053fa99b1f5b4cfaab3e55b7453fcb1Vasu Nori StatusUpdates.PRESENCE + " INTEGER," + 585aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0" + 586e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov ");"); 587bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 588bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 589bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted" 590bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 591bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 592bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATED_PRESENCE 593bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " + 594bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.CONTACT_ID + 595bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 596bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.RAW_CONTACT_ID 597bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.RAW_CONTACT_ID + 598bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND NOT EXISTS" + 599bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.RAW_CONTACT_ID + 600bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 601bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 602bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.CONTACT_ID + 603bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND " + PresenceColumns.RAW_CONTACT_ID 604bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));" 605bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 606bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 607aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori final String replaceAggregatePresenceSql = 608aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 609aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + AggregatedPresenceColumns.CONTACT_ID + ", " 610a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + StatusUpdates.PRESENCE + ", " 611aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + StatusUpdates.CHAT_CAPABILITY + ")" 612aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " SELECT " + PresenceColumns.CONTACT_ID + "," 613a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + StatusUpdates.PRESENCE + "," 614aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + StatusUpdates.CHAT_CAPABILITY 615aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " FROM " + Tables.PRESENCE 616aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " WHERE " 617a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " (" + StatusUpdates.PRESENCE 618aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " * 10 + " + StatusUpdates.CHAT_CAPABILITY + ")" 619aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " = (SELECT " 620a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "MAX (" + StatusUpdates.PRESENCE 621aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " * 10 + " + StatusUpdates.CHAT_CAPABILITY + ")" 622aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " FROM " + Tables.PRESENCE 623aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " WHERE " + PresenceColumns.CONTACT_ID 624aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + "=NEW." + PresenceColumns.CONTACT_ID + ")" 625aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " AND " + PresenceColumns.CONTACT_ID 626aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + "=NEW." + PresenceColumns.CONTACT_ID + ";"; 627bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 628bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted" 629bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 630bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 631bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 632bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 633bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 634bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated" 635bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 636bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 637bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 638bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 639b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 640b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 641b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 642b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 643b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 644b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 64535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 64635ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 647b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 648d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 649b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 650fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 651d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 652d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 653d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 654d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 655d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 656d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 657f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + 6585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + " TEXT," + 659a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + 6604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0" + 661b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 662b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 66354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" + 66454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov Contacts.HAS_PHONE_NUMBER + 66554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 66654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 66754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_restricted_index ON " + Tables.CONTACTS + " (" + 66854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + 66954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 67054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 671fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 672fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 673fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 674fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 675b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 6765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" + 6776cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 6786cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 6796cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 6806cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 6816cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID + " TEXT," + 68297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov RawContacts.RAW_CONTACT_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 6836cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 68473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 68533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + 68654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 6876cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 6886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DEFAULT + "," + 6898e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + 6906cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + " TEXT," + 6916cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 6926cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 6936cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED + " INTEGER," + 69433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 6955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + 6965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + 6975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + 69825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.UNDEFINED + "," + 6995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + " TEXT," + 7005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + " TEXT," + 701de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " + 702de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 703de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " + 704de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 705f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + 7063cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC1 + " TEXT, " + 7073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC2 + " TEXT, " + 7083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC3 + " TEXT, " + 7093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC4 + " TEXT " + 710b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 711b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 71254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" + 71354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + 71454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 71554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 7165f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" + 7175f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.SOURCE_ID + ", " + 7185f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + ", " + 7195f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + 7205f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 7215f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 722f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // TODO readd the index and investigate a controlled use of it 723f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" + 724f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// RawContactsColumns.AGGREGATION_NEEDED + 725f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// ");"); 7268e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 727b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 728ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 729ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 730ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 731b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 732b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 733ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 734ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 735ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 736ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 737b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 738b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 73908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov // Mimetype table requires an index on mime type 74008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX mime_type ON " + Tables.MIMETYPES + " (" + 74108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov MimetypesColumns.MIMETYPE + 74208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov ");"); 74308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 744b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 745b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 746b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 74767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 748b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 74911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 75097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Data.IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 751f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 752f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 753f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 754f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 755f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 756f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 757f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 758f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 759f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 760f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 761f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 762f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 76367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 76467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 76567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 76667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 76767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 7683cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.DATA15 + " TEXT," + 7693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC1 + " TEXT, " + 7703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC2 + " TEXT, " + 7713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC3 + " TEXT, " + 7723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC4 + " TEXT " + 773b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 774b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 77511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" + 77611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + 77711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 77811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 77911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov /** 78011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov * For email lookup and similar queries. 78111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov */ 782f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" + 78311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov DataColumns.MIMETYPE_ID + "," + 784f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov Data.DATA1 + 78511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 78611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 787b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 788b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 789f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.DATA_ID 790892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 7915ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 7925ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 79336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 79436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 795b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 796b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 797b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 798f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 799f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 800b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 801b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 802b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 80336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 80436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 80536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 80636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 80736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 80836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 809a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 810a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 81114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.DATA_ID 81214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 8135ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID 8145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 81511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," + 81611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," + 81714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "PRIMARY KEY (" 81814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + NameLookupColumns.DATA_ID + ", " 81911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ", " 82011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + ")" + 821a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 822a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 82314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" + 82414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + 82514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov ");"); 82614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 827b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 828b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 829b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 830b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 831b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 832b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 833b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 834b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 835b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 836b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 837ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 838ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 839ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 84067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 841035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 842035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 843ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 8449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 84573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 846ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 84767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 8480f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 8490f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 85094021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + 851eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 852ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + 853dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0," + 854dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0," + 8553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC1 + " TEXT, " + 8563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC2 + " TEXT, " + 8573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC3 + " TEXT, " + 8583cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC4 + " TEXT " + 859ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 860ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 8615f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" + 8625f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.SOURCE_ID + ", " + 8635f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_TYPE + ", " + 8645f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_NAME + 8655f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 8665f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 867b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 868b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 869b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 8700c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 8715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id), " + 8720c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 8735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id)" + 874b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank ");"); 875b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 876b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 877b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8780c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + ", " + 8790c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + 880b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 881b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 882b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 883b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 8840c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + ", " + 8850c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + 886b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 887b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 888eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" + 889eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_NAME + " STRING NOT NULL," + 890eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_TYPE + " STRING NOT NULL," + 891eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 892eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1, " + 893eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey "PRIMARY KEY (" + Settings.ACCOUNT_NAME + ", " + 894e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey Settings.ACCOUNT_TYPE + ") ON CONFLICT REPLACE" + 895eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey ");"); 896eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 8974394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 8984394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 8994394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 9004394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 901385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 902385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 903385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 904385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 905e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // The table for recent calls is here so we can do table joins 906e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // on people, phones, and calls all in one place. 907e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CALLS + " (" + 908e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 909e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NUMBER + " TEXT," + 910e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DATE + " INTEGER," + 911e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DURATION + " INTEGER," + 912e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.TYPE + " INTEGER," + 913e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NEW + " INTEGER," + 914e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NAME + " TEXT," + 915e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_TYPE + " INTEGER," + 9162530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.CACHED_NUMBER_LABEL + " TEXT," + 9172530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.COUNTRY_ISO + " TEXT" + ");"); 918e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov 919b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 920b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 921b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 92267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 923b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 924b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 925499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 9265ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 9275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 928b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 929499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 930b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 931b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 932adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 933b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 934b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 935b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 936a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" + 937a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 9380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS + " TEXT," + 9390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + 9400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + 9410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_LABEL + " INTEGER, " + 9420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_ICON + " INTEGER" + 943a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ");"); 944a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 945b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" + 946b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " + 947b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_VALUE + " TEXT " + 948b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 949b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 950743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" + 951743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " TEXT, " + 952743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " TEXT " + 953743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov ");"); 954743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 955743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // Allow contacts without any account to be created for now. Achieve that 956743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // by inserting a fake account with both type and name as NULL. 957743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // This "account" should be eliminated as soon as the first real writable account 958743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // is added to the phone. 959743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("INSERT INTO accounts VALUES(NULL, NULL)"); 960743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 961d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 962d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 963a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createContactsViews(db); 964a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createGroupsView(db); 965fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov createContactsTriggers(db); 966916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 9674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 968a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov loadNicknameLookupTable(db); 969a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 970a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // Add the legacy API support views, etc 971a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov LegacyApiSupport.createDatabase(db); 972a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 973a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // This will create a sqlite_stat1 table that is used for query optimization 974a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("ANALYZE;"); 975a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 976a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateSqliteStats(db); 977a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 978a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // We need to close and reopen the database connection so that the stats are 979a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // taken into account. Make a note of it and do the actual reopening in the 980a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // getWritableDatabase method. 981a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov mReopenDatabase = true; 982a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 983a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContentResolver.requestSync(null /* all accounts */, 984a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContactsContract.AUTHORITY, new Bundle()); 985a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 986a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 987d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void createDirectoriesTable(SQLiteDatabase db) { 988d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DIRECTORIES + "(" + 989d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 990d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.PACKAGE_NAME + " TEXT NOT NULL," + 991d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DIRECTORY_AUTHORITY + " TEXT NOT NULL," + 992d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.TYPE_RESOURCE_ID + " INTEGER," + 993d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_TYPE + " TEXT," + 994d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_NAME + " TEXT," + 995d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DISPLAY_NAME + " TEXT, " + 996d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.EXPORT_SUPPORT + " INTEGER NOT NULL" + 99797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov " DEFAULT " + Directory.EXPORT_SUPPORT_NONE + "," + 99897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Directory.SHORTCUT_SUPPORT + " INTEGER NOT NULL" + 9993d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.SHORTCUT_SUPPORT_NONE + "," + 10003d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Directory.PHOTO_SUPPORT + " INTEGER NOT NULL" + 10013d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.PHOTO_SUPPORT_NONE + 1002d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov ");"); 1003d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1004d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov insertDefaultDirectory(db); 1005d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov insertLocalInvisibleDirectory(db); 10063d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 10073d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov // Trigger a full scan of directories in the system 10083d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(db, ContactDirectoryManager.PROPERTY_DIRECTORY_SCAN_COMPLETE, "0"); 1009d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1010d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1011d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void insertDefaultDirectory(SQLiteDatabase db) { 1012d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov ContentValues values = new ContentValues(); 1013d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory._ID, Directory.DEFAULT); 1014d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.PACKAGE_NAME, mContext.getApplicationInfo().packageName); 1015d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.DIRECTORY_AUTHORITY, ContactsContract.AUTHORITY); 1016d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.TYPE_RESOURCE_ID, R.string.default_directory); 1017d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.EXPORT_SUPPORT, Directory.EXPORT_SUPPORT_NONE); 101897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov values.put(Directory.SHORTCUT_SUPPORT, Directory.SHORTCUT_SUPPORT_FULL); 10193d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov values.put(Directory.PHOTO_SUPPORT, Directory.PHOTO_SUPPORT_FULL); 1020d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov db.insert(Tables.DIRECTORIES, null, values); 1021d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1022d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1023d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void insertLocalInvisibleDirectory(SQLiteDatabase db) { 1024d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov ContentValues values = new ContentValues(); 1025d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory._ID, Directory.LOCAL_INVISIBLE); 1026d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.PACKAGE_NAME, mContext.getApplicationInfo().packageName); 1027d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.DIRECTORY_AUTHORITY, ContactsContract.AUTHORITY); 1028d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.TYPE_RESOURCE_ID, R.string.local_invisible_directory); 1029d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov values.put(Directory.EXPORT_SUPPORT, Directory.EXPORT_SUPPORT_NONE); 103097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov values.put(Directory.SHORTCUT_SUPPORT, Directory.SHORTCUT_SUPPORT_FULL); 10313d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov values.put(Directory.PHOTO_SUPPORT, Directory.PHOTO_SUPPORT_FULL); 1032d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov db.insert(Tables.DIRECTORIES, null, values); 1033d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1034d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1035916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsTriggers(SQLiteDatabase db) { 1036fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1037fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1038fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Automatically delete Data rows when a raw contact is deleted. 1039fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1040fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;"); 1041fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted " 1042fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEFORE DELETE ON " + Tables.RAW_CONTACTS 1043fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1044fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.DATA 1045fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data.RAW_CONTACT_ID 1046fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 1047fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS 1048fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 1049fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID 1050fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " OR " + AggregationExceptions.RAW_CONTACT_ID2 1051fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 105235da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " DELETE FROM " + Tables.VISIBLE_CONTACTS 105335da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 105435da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 105535da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 105635da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " )=1;" 1057385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " DELETE FROM " + Tables.DEFAULT_DIRECTORY 1058385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1059385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1060385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1061385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " )=1;" 1062fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.CONTACTS 1063fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1064fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1065fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1066fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " )=1;" 1067fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1068fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1069fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1070fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;"); 10716c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;"); 1072fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1073fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1074fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Triggers that update {@link RawContacts#VERSION} when the contact is 1075fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * marked for deletion or any time a data row is inserted, updated or 1076fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * deleted. 1077fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1078fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;"); 1079fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted " 10807f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.RAW_CONTACTS 1081fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1082fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1083fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1084fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 " 1085fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID 1086fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";" 1087fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1088fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1089fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;"); 10907f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 1091fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1092fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.DATA 1093fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 1094fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 1095fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1096fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1097fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1098fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1099fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1100fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;"); 1101fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 1102fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1103fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1104fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1105fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1106fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.PHONE_LOOKUP 1107fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1108fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.STATUS_UPDATES 1109fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";" 1110fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.NAME_LOOKUP 1111fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1112fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1113fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1114fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1115fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;"); 1116fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 11177f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.GROUPS 1118fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1119fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.GROUPS 1120fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1121fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + Groups.VERSION + "=OLD." + Groups.VERSION + "+1" 1122fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 1123fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1124fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1125fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1126916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsIndexes(SQLiteDatabase db) { 1127916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 1128916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 1129916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + "," + 1130916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NAME_TYPE + ", " + 1131916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + ", " + 1132916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.DATA_ID + 1133916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov ");"); 113404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 113504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index"); 113604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 113704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 113804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 113904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 114004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index"); 114104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 114204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 114304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 1144916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1145916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1146a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createContactsViews(SQLiteDatabase db) { 1147a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_ALL + ";"); 1148a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_RESTRICTED + ";"); 1149a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_ALL + ";"); 1150a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_RESTRICTED + ";"); 1151a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_ALL + ";"); 1152a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_RESTRICTED + ";"); 1153a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES + ";"); 1154a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES_RESTRICTED + ";"); 1155a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES + ";"); 1156a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES_RESTRICTED + ";"); 1157a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 11584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataColumns = 11594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Data.IS_PRIMARY + ", " 11604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.IS_SUPER_PRIMARY + ", " 11614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA_VERSION + ", " 11624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 11634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", " 116497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + Data.IS_READ_ONLY + ", " 11654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA1 + ", " 11664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA2 + ", " 11674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA3 + ", " 11684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA4 + ", " 11694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA5 + ", " 11704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA6 + ", " 11714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA7 + ", " 11724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA8 + ", " 11734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA9 + ", " 11744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA10 + ", " 11754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA11 + ", " 11764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA12 + ", " 11774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA13 + ", " 11784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA14 + ", " 11794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA15 + ", " 11804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC1 + ", " 11814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC2 + ", " 11824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC3 + ", " 11834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC4; 11844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String syncColumns = 11864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 11874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 11884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 1189f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 11904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 11914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 11924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," 11934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + "," 11944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + "," 11954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4; 11964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 11973d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov String baseContactColumns = 11983d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + ", " 11993d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + ", " 12003d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 12013d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.PHOTO_ID + ", " 12023d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Clauses.CONTACT_VISIBLE + " AS " + Contacts.IN_VISIBLE_GROUP + ", " 12033d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID; 12043d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 12054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactOptionColumns = 12064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 12074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.CUSTOM_RINGTONE + "," 12084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 12094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.SEND_TO_VOICEMAIL + "," 12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 12114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.LAST_TIME_CONTACTED + "," 12124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 12134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.TIMES_CONTACTED + "," 12144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 12154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.STARRED; 12164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String contactNameColumns = 12185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE 12195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", " 12205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY 12215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", " 12225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE 12235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", " 12245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME 12255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME + ", " 12265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE 12275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME_STYLE + ", " 12285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY 12295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_PRIMARY + ", " 12305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE 12314394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_ALTERNATIVE; 12325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 12334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataSelect = "SELECT " 12344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Data._ID + "," 12354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.RAW_CONTACT_ID + ", " 1236fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 12374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns + ", " 12384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + dataColumns + ", " 12394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + contactOptionColumns + ", " 12405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 12413d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 12423d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12433d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 12443d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12453d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 12464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 12474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA 1248a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.MIMETYPES + " ON (" 12494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1250a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " ON (" 12514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1252a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1253fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1254fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1255fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1256a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1257a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 12584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 12594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1260f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1261a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 12624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_ALL + " AS " + dataSelect); 12644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_RESTRICTED + " AS " + dataSelect + " WHERE " 1265fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 12664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactOptionColumns = 12684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + "," 12694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.SEND_TO_VOICEMAIL + "," 12704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "," 12714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "," 12724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.STARRED; 12734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactsSelect = "SELECT " 12754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + "," 12764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 12774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.AGGREGATION_MODE + ", " 127897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + RawContacts.RAW_CONTACT_IS_READ_ONLY + ", " 12794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.DELETED + ", " 12805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + ", " 12815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_PRIMARY + ", " 12825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_ALTERNATIVE + ", " 12835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME + ", " 12845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME_STYLE + ", " 12855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_PRIMARY + ", " 12865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_ALTERNATIVE + ", " 12874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + rawContactOptionColumns + ", " 12884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns 12894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS; 12904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_ALL + " AS " + rawContactsSelect); 12924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_RESTRICTED + " AS " + rawContactsSelect 12934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 12944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsColumns = 12964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 12974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.CUSTOM_RINGTONE + ", " 12985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 12993d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 13004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 13014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED + ", " 13024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 13034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL + ", " 13044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 13054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.STARRED + ", " 13064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 13073d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + " AS " + Contacts.TIMES_CONTACTED; 13084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsSelect = "SELECT " 13104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + "," 13113d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + contactsColumns + ", " 13123d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_URI) + ", " 13133d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_THUMBNAIL_URI) 13144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.CONTACTS 1315fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1316fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"; 13174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_ALL + " AS " + contactsSelect); 1319fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_RESTRICTED + " AS " + contactsSelect 1320fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " WHERE " + ContactsColumns.SINGLE_IS_RESTRICTED + "=0"); 1321a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1322a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String rawEntitiesSelect = "SELECT " 1323a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 1324a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1325a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1326a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1327a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1328a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1329a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1330a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1331a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", " 1332a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + "," 1333a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + "," 1334a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + " AS " 1335a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.IS_RESTRICTED + "," 1336a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1337a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1338a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1339a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1340a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1341a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1342a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1343a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1344a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1345a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1346a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1347a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1348a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1349a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES + " AS " 1350a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect); 1351a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES_RESTRICTED + " AS " 1352a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 1353a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1354a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String entitiesSelect = "SELECT " 1355a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + Contacts._ID + ", " 1356a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 1357a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1358a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED 1359a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " AS " + RawContacts.IS_RESTRICTED + "," 1360a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1361a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1362a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + contactsColumns + ", " 13633d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 13643d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 13653d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 13663d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 1367a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1368a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + Contacts.Entity.RAW_CONTACT_ID + ", " 1372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Contacts.Entity.DATA_ID + "," 1373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1380a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1381a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1383a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1385a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1386a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1387a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1388a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1389a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1390a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES + " AS " 1391a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect); 1392a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES_RESTRICTED + " AS " 1393a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect + " WHERE " + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 1394a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 13954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13963d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private static String buildPhotoUriAlias(String contactIdColumn, String alias) { 13972b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov return "(CASE WHEN " + Contacts.PHOTO_ID + " IS NULL" 13982b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " OR " + Contacts.PHOTO_ID + "=0" 13992b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " THEN NULL" 14002b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " ELSE " + "'" + Contacts.CONTENT_URI + "/'||" 14012b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + contactIdColumn + "|| '/" + Photo.CONTENT_DIRECTORY + "'" 14022b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " END)" 14032b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " AS " + alias; 14043d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 14053d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 1406a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createGroupsView(SQLiteDatabase db) { 1407a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS_ALL + ";"); 140889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsColumns = 140989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov Groups.ACCOUNT_NAME + "," 141089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.ACCOUNT_TYPE + "," 141189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SOURCE_ID + "," 141289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.VERSION + "," 141389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DIRTY + "," 141489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE + "," 141589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE_RES + "," 141689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.NOTES + "," 141789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYSTEM_ID + "," 141889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DELETED + "," 141989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.GROUP_VISIBLE + "," 142089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SHOULD_SYNC + "," 1421dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.AUTO_ADD + "," 1422dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.FAVORITES + "," 142389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC1 + "," 142489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC2 + "," 142589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC3 + "," 142689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC4 + "," 142789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE; 142889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 142989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsSelect = "SELECT " 143089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + "," 143189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + groupsColumns 143289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + " FROM " + Tables.GROUPS_JOIN_PACKAGES; 143389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 143489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.GROUPS_ALL + " AS " + groupsSelect); 1435b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1436b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1437b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 1438b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 143946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion < 99) { 144046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 144146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + ", data will be lost!"); 144246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 144346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 144446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";"); 144546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 144646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 144746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 144846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 144946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 145046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 145146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 145246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 145346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";"); 145446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";"); 145546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";"); 145646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 145746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // TODO: we should not be dropping agg_exceptions and contact_options. In case that 145846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // table's schema changes, we should try to preserve the data, because it was entered 145946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // by the user and has never been synched to the server. 146046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 146146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 146246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana onCreate(db); 146346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana return; 146446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1465f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 146646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion); 1467a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 146808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov boolean upgradeViewsAndTriggers = false; 146904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov boolean upgradeNameLookup = false; 147008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 147146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion == 99) { 147208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 147346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana oldVersion++; 147446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 147546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1476a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov if (oldVersion == 100) { 1477a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON " 1478a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.MIMETYPES + " (" 1479a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns.MIMETYPE + "," 1480a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns._ID + ");"); 1481a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateIndexStats(db, Tables.MIMETYPES, 1482a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov "mimetypes_mimetype_index", "50 1 1"); 1483a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 148408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1485a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov oldVersion++; 1486a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1487a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1488fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov if (oldVersion == 101) { 148908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1490fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov oldVersion++; 1491fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1492fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 149347ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov if (oldVersion == 102) { 149408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 149547ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov oldVersion++; 149647ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov } 149747ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov 149836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (oldVersion == 103) { 149908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1500bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey oldVersion++; 1501bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey } 1502bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey 150371037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 104 || oldVersion == 201) { 150471037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov LegacyApiSupport.createSettingsTable(db); 150508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15063410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion++; 15073410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov } 15083410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov 150971037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 105) { 15105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion202(db); 151104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov upgradeNameLookup = true; 15123410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion = 202; 151336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 151436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 1515fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov if (oldVersion == 202) { 15165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion203(db); 151708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1518fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov oldVersion++; 1519fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1520fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 15219b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori if (oldVersion == 203) { 152208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15239b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori oldVersion++; 15249b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori } 15259b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori 15265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (oldVersion == 204) { 15275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion205(db); 152808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov oldVersion++; 15305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 15315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1532f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov if (oldVersion == 205) { 1533f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgrateToVersion206(db); 1534f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgradeViewsAndTriggers = true; 1535f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov oldVersion++; 1536f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1537f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 153831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (oldVersion == 206) { 1539b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeToVersion300(db); 154034469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov oldVersion = 300; 154131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 154231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 15436c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook if (oldVersion == 300) { 15446c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook upgradeViewsAndTriggers = true; 15456c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook oldVersion = 301; 15466c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook } 15476c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook 1548916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov if (oldVersion == 301) { 1549916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov upgradeViewsAndTriggers = true; 1550916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov oldVersion = 302; 1551916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1552916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1553b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (oldVersion == 302) { 1554b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeEmailToVersion303(db); 1555b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeNicknameToVersion303(db); 1556b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov oldVersion = 303; 1557b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1558b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 155908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (oldVersion == 303) { 156008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov upgradeToVersion304(db); 156108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov oldVersion = 304; 156208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 156308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 1564f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee if (oldVersion == 304) { 1565f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee upgradeNameLookup = true; 1566f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee oldVersion = 305; 1567f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee } 1568f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee 156960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (oldVersion == 305) { 157060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann upgradeToVersion306(db); 157160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann oldVersion = 306; 157260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 157360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 1574b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (oldVersion == 306) { 1575b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov upgradeToVersion307(db); 1576b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov oldVersion = 307; 1577b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 1578b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 1579743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov if (oldVersion == 307) { 1580743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov upgradeToVersion308(db); 1581743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov oldVersion = 308; 1582743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 1583743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 158494c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov // Gingerbread upgrades 158594c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion < 350) { 1586afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann upgradeViewsAndTriggers = true; 158794c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 351; 1588afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann } 1589afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann 159094c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion == 351) { 159194c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov upgradeNameLookup = true; 159294c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 352; 159380d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann } 159480d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann 1595f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov // Honeycomb upgrades 1596f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion < 400) { 1597dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana upgradeViewsAndTriggers = true; 1598f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov upgradeToVersion400(db); 1599f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov oldVersion = 400; 1600dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 1601dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 1602f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion == 400) { 16034394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeViewsAndTriggers = true; 16044394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeToVersion401(db); 16054394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov oldVersion = 401; 16064394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 16074394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 1608d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov if (oldVersion == 401) { 1609d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov upgradeToVersion402(db); 1610d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov oldVersion = 402; 1611d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1612d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 161397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov if (oldVersion == 402) { 161497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeViewsAndTriggers = true; 161597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeToVersion403(db); 161697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov oldVersion = 403; 161797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 161897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 1619a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov if (oldVersion == 403) { 1620a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov upgradeViewsAndTriggers = true; 1621a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov oldVersion = 404; 1622a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 1623a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1624892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (oldVersion == 404) { 1625892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeViewsAndTriggers = true; 1626892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeToVersion405(db); 1627892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov oldVersion = 405; 1628892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 1629892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 16302530512f639c4979fd7371c7dd25dd67e8118124Bai Tao if (oldVersion == 405) { 16312530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeViewsAndTriggers = true; 16322530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeToVersion406(db); 16332530512f639c4979fd7371c7dd25dd67e8118124Bai Tao oldVersion = 406; 16342530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 16352530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 1636cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov if (oldVersion == 406) { 1637cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov upgradeViewsAndTriggers = true; 1638cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov oldVersion = 407; 1639cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov } 1640cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov 1641385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov if (oldVersion == 407) { 1642d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Obsolete 1643385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov oldVersion = 408; 1644385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 1645385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 16463d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov if (oldVersion == 408) { 16473d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeViewsAndTriggers = true; 16483d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeToVersion409(db); 16493d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov oldVersion = 409; 16503d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 16513d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 16522b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov if (oldVersion == 409) { 16532b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov upgradeViewsAndTriggers = true; 16542b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov oldVersion = 410; 16552b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov } 16562b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov 1657d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov if (oldVersion == 410) { 1658d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov upgradeToVersion411(db); 1659d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov oldVersion = 411; 1660d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 1661d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 166208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov if (upgradeViewsAndTriggers) { 166308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsViews(db); 166408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createGroupsView(db); 166508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsTriggers(db); 1666916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 166708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov LegacyApiSupport.createViews(db); 1668916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov updateSqliteStats(db); 1669916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov mReopenDatabase = true; 167008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov } 167108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 167204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (upgradeNameLookup) { 167304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rebuildNameLookup(db); 167404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 167504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 167646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion != newVersion) { 167746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana throw new IllegalStateException( 167846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana "error upgrading the database to version " + newVersion); 167946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1680b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1681b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 16825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion202(SQLiteDatabase db) { 168336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL( 168436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "ALTER TABLE " + Tables.PHONE_LOOKUP + 168536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;"); 168636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 168736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 168836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 168936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 169036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 169136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 169236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 169336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 169436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 169536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 169636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov SQLiteStatement update = db.compileStatement( 169736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "UPDATE " + Tables.PHONE_LOOKUP + 169836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " SET " + PhoneLookupColumns.MIN_MATCH + "=?" + 169936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " WHERE " + PhoneLookupColumns.DATA_ID + "=?"); 170036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 170136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov // Populate the new column 170236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA + 170336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")", 170436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null); 170536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov try { 170636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov while (c.moveToNext()) { 170736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov long dataId = c.getLong(0); 170836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String number = c.getString(1); 170936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 171036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number)); 171136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindLong(2, dataId); 171236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.execute(); 171336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 171436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 171536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } finally { 171636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov c.close(); 171736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 171836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 171936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 17205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion203(SQLiteDatabase db) { 1721758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // Garbage-collect first. A bug in Eclair was sometimes leaving 1722758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // raw_contacts in the database that no longer had contacts associated 1723758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // with them. To avoid failures during this database upgrade, drop 1724758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // the orphaned raw_contacts. 1725758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov db.execSQL( 1726758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov "DELETE FROM raw_contacts" + 1727758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " WHERE contact_id NOT NULL" + 1728758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " AND contact_id NOT IN (SELECT _id FROM contacts)"); 1729758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov 1730fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1731fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.CONTACTS + 1732fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)"); 1733fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1734fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.RAW_CONTACTS + 17354394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " ADD contact_in_visible_group INTEGER NOT NULL DEFAULT 0"); 1736fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1737fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // For each Contact, find the RawContact that contributed the display name 1738fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1739fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1740fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1741fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1742fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1743fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1744fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" + 1745fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.CONTACTS + "." + Contacts.DISPLAY_NAME + 1746fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1747fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" 1748fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1749fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1750fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 1751fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 1752fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1753fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1754fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // If for some unknown reason we missed some names, let's make sure there are 1755fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // no contacts without a name, picking a raw contact "at random". 1756fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1757fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1758fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1759fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1760fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1761fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1762fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1763fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" + 1764fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL" 1765fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1766fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1767fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use. 1768fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1769fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1770fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.DISPLAY_NAME + "=NULL" 1771fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1772fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1773fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow 1774fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // indexing on (display_name, in_visible_group) 1775fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1776fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 17774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SET contact_in_visible_group=(" + 1778fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 1779fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.CONTACTS + 1780bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" + 1781bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " NOT NULL" 1782fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1783fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1784fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 17854394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 1786fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" + 1787fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1788fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1789fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 1790fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 1791fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 1792fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1793fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1794fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 17955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion205(SQLiteDatabase db) { 17965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 17975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;"); 17985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 17995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;"); 18005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;"); 18025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1803de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_PRIMARY 1804de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 18055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1806de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE 1807de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 18085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov final Locale locale = Locale.getDefault(); 18105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 181151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov NameSplitter splitter = createNameSplitter(); 18125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate = db.compileStatement( 18145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 18155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 18165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 18175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 18185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 18195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 18205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 18215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 18225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 18235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter); 18255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter); 18265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 18285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 18294394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 18305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 18315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 18325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 18344394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 18355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 18365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 18375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface StructName205Query { 18405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 18415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 18435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 18445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 18455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE, 18465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY, 18475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PREFIX, 18485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.GIVEN_NAME, 18495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.MIDDLE_NAME, 18505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FAMILY_NAME, 18515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.SUFFIX, 18525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_FAMILY_NAME, 18535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_MIDDLE_NAME, 18545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_GIVEN_NAME, 18555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 18565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 18585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 18595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME_SOURCE = 2; 18605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME = 3; 18615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PREFIX = 4; 18625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int GIVEN_NAME = 5; 18635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int MIDDLE_NAME = 6; 18645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int FAMILY_NAME = 7; 18655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int SUFFIX = 8; 18665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_FAMILY_NAME = 9; 18675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_MIDDLE_NAME = 10; 18685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_GIVEN_NAME = 11; 18695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeStructuredNamesToVersion205(SQLiteDatabase db, 18725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 18735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // Process structured names to detect the style of the full name and phonetic name 18755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long mMimeType; 18775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 18785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mMimeType = DatabaseUtils.longForQuery(db, 18795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 18805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 18815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 18825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null); 18835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } catch (SQLiteDoneException e) { 18845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // No structured names in the database 18855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return; 18865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 18875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate = db.compileStatement( 18895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 18905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 18915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FULL_NAME_STYLE + "=?," + 18925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.DISPLAY_NAME + "=?," + 18935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_NAME_STYLE + "=?" + 18945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 18955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 18965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 18975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 18985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(StructName205Query.TABLE, 18995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructName205Query.COLUMNS, 19005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null); 19015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 19025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 19035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(StructName205Query.ID); 19045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID); 19055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE); 19065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = cursor.getString(StructName205Query.DISPLAY_NAME); 19075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.clear(); 19095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.prefix = cursor.getString(StructName205Query.PREFIX); 19105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME); 19115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME); 19125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.familyName = cursor.getString(StructName205Query.FAMILY_NAME); 19135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.suffix = cursor.getString(StructName205Query.SUFFIX); 19145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME); 19155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME); 19165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME); 19175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name, 19195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate, rawContactUpdate, splitter, sb); 19205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 19225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 19235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource, 19275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String currentDisplayName, NameSplitter.Name name, 19285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate, 19295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter, StringBuilder sb) { 19305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov splitter.guessNameStyle(name); 1932ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao int unadjustedFullNameStyle = name.fullNameStyle; 19335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle); 19345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = splitter.join(name, true); 19355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1936ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // Don't update database with the adjusted fullNameStyle as it is locale 1937ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // related 1938ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao structuredNameUpdate.bindLong(1, unadjustedFullNameStyle); 19395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName); 19405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(3, name.phoneticNameStyle); 19415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(4, dataId); 19425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.execute(); 19435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) { 19455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayNameAlternative = splitter.join(name, false); 19465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = splitter.joinPhoneticName(name); 19475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 19485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKeyAlternative = null; 19495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName != null) { 19515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = phoneticName; 1952ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao } else if (name.fullNameStyle == FullNameStyle.CHINESE || 1953ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao name.fullNameStyle == FullNameStyle.CJK) { 1954ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = sortKeyAlternative = ContactLocaleUtils.getIntance() 1955ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(displayName, name.fullNameStyle); 19565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 19595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = displayName; 19605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative = displayNameAlternative; 19615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, displayName, 19645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey, 19655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative); 19665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface Organization205Query { 19705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 19715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 19735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 19745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 19755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.COMPANY, 19765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME, 19775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 19785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 19805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 19815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int COMPANY = 2; 19825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_NAME = 3; 19835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeOrganizationsToVersion205(SQLiteDatabase db, 19865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 1987b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 19885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement organizationUpdate = db.compileStatement( 19905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 19915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 19925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME_STYLE + "=?" + 19935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 19945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS, 1996b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mimeType + " AND " 19975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION, 19985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov null, null, null, null); 19995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 20005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 20015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(Organization205Query.ID); 20025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID); 20035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String company = cursor.getString(Organization205Query.COMPANY); 20045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME); 20055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName); 20075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(1, phoneticNameStyle); 20095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(2, dataId); 20105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.execute(); 20115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 20135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName == null && company != null) { 20145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int nameStyle = splitter.guessFullNameStyle(company); 20155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov nameStyle = splitter.getAdjustedFullNameStyle(nameStyle); 2016ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao if (nameStyle == FullNameStyle.CHINESE || 2017ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao nameStyle == FullNameStyle.CJK ) { 2018ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = ContactLocaleUtils.getIntance() 2019ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(company, nameStyle); 20205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 20245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = company; 20255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, company, 20285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov company, phoneticNameStyle, phoneticName, sortKey, sortKey); 20295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 20315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 20325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId, 20365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName, String displayNameAlternative, int phoneticNameStyle, 20375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName, String sortKeyPrimary, String sortKeyAlternative) { 20385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 1, displayName); 20395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 2, displayNameAlternative); 20405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 3, phoneticName); 20415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(4, phoneticNameStyle); 20425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 5, sortKeyPrimary); 20435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 6, sortKeyAlternative); 20445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(7, rawContactId); 20455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.execute(); 20465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2048f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov private void upgrateToVersion206(SQLiteDatabase db) { 2049f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 2050f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); 2051f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 2052f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 205331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov private interface Organization300Query { 205431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String TABLE = Tables.DATA; 205531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 205631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String SELECTION = DataColumns.MIMETYPE_ID + "=?"; 205731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 205831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String COLUMNS[] = { 205931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization._ID, 206031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.RAW_CONTACT_ID, 206131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.COMPANY, 206231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.TITLE 206331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov }; 206431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 206531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int ID = 0; 206631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int RAW_CONTACT_ID = 1; 206731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int COMPANY = 2; 206831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int TITLE = 3; 206931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 207031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 207131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov /** 207231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * Fix for the bug where name lookup records for organizations would get removed by 207331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * unrelated updates of the data rows. 207431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov */ 2075b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeToVersion300(SQLiteDatabase db) { 2076b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 2077b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeType == -1) { 207831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov return; 207931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 208031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 208131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov ContentValues values = new ContentValues(); 208231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 208331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Find all data rows with the mime type "organization" 208431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Cursor cursor = db.query(Organization300Query.TABLE, Organization300Query.COLUMNS, 2085b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Organization300Query.SELECTION, new String[] {String.valueOf(mimeType)}, 208631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov null, null, null); 208731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov try { 208831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov while (cursor.moveToNext()) { 208931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long dataId = cursor.getLong(Organization300Query.ID); 209031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long rawContactId = cursor.getLong(Organization300Query.RAW_CONTACT_ID); 209131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String company = cursor.getString(Organization300Query.COMPANY); 209231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String title = cursor.getString(Organization300Query.TITLE); 209331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 209431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // First delete name lookup if there is any (chances are there won't be) 209531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.delete(Tables.NAME_LOOKUP, NameLookupColumns.DATA_ID + "=?", 209631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov new String[]{String.valueOf(dataId)}); 209731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 209831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Now insert two name lookup records: one for company name, one for title 209931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 210031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 210131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.ORGANIZATION); 210231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 210331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(company)) { 210431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 210531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(company)); 210631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 210731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 210831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 210931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(title)) { 211031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 211131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(title)); 211231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 211331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 211431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 211531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } finally { 211631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov cursor.close(); 211731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 211831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 211931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 2120b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final class Upgrade303Query { 2121b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String TABLE = Tables.DATA; 2122b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2123b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String SELECTION = 2124b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=?" + 2125b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data._ID + " NOT IN " + 2126b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" + 2127b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data.DATA1 + " NOT NULL"; 2128b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2129b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String COLUMNS[] = { 2130b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data._ID, 2131b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.RAW_CONTACT_ID, 2132b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.DATA1, 2133b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov }; 2134b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2135b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int ID = 0; 2136b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 2137b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int DATA1 = 2; 2138b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2139b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2140b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2141b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2142b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * emails during the sync. We need to restore the lost name lookup rows. 2143b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2144b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeEmailToVersion303(SQLiteDatabase db) { 2145b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 2146b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2147b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2148b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2149b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2150b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2151b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2152b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "email" that are missing name lookup 2153b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2154b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2155b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2156b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2157b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2158b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2159b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2160b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2161b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov value = extractHandleFromEmailAddress(value); 2162b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2163b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (value != null) { 2164b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2165b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2166b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME); 2167b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2168b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2169b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2170b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2171b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2172b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2173b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2174b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2175b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2176b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2177b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2178b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * nicknames during the sync. We need to restore the lost name lookup rows. 2179b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2180b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeNicknameToVersion303(SQLiteDatabase db) { 2181b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 2182b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2183b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2184b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2185b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2186b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2187b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2188b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "nickname" that are missing name lookup 2189b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2190b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2191b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2192b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2193b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2194b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2195b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2196b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2197b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2198b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2199b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2200b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME); 2201b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2202b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2203b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2204b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2205b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2206b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2207b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2208b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 220951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void upgradeToVersion304(SQLiteDatabase db) { 221051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Mimetype table requires an index on mime type 221151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS mime_type ON " + Tables.MIMETYPES + " (" + 221251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov MimetypesColumns.MIMETYPE + 221351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov ");"); 221451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 221551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 221660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann private void upgradeToVersion306(SQLiteDatabase db) { 221760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // Fix invalid lookup that was used for Exchange contacts (it was not escaped) 221860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // It happened when a new contact was created AND synchronized 221960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final StringBuilder lookupKeyBuilder = new StringBuilder(); 222060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final SQLiteStatement updateStatement = db.compileStatement( 222160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "UPDATE contacts " + 222260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SET lookup=? " + 222360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE _id=?"); 222460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor contactIdCursor = db.rawQuery( 222560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT DISTINCT contact_id " + 222660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 222760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE deleted=0 AND account_type='com.android.exchange'", 222860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann null); 222960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 223060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (contactIdCursor.moveToNext()) { 223160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final long contactId = contactIdCursor.getLong(0); 223260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann lookupKeyBuilder.setLength(0); 223360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor c = db.rawQuery( 223460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT account_type, account_name, _id, sourceid, display_name " + 223560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 223660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE contact_id=? " + 223760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "ORDER BY _id", 223860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann new String[] { String.valueOf(contactId) }); 223960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 224060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (c.moveToNext()) { 224160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann ContactLookupKey.appendToLookupKey(lookupKeyBuilder, 224260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(0), 224360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(1), 224460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getLong(2), 224560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(3), 224660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(4)); 224760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 224860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 224960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.close(); 225060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 225160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 225260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (lookupKeyBuilder.length() == 0) { 225360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindNull(1); 225460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } else { 225560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindString(1, Uri.encode(lookupKeyBuilder.toString())); 225660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 225760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindLong(2, contactId); 225860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 225960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.execute(); 226060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 226160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 226260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.close(); 226360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann contactIdCursor.close(); 226460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 226560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 226660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 2267b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov private void upgradeToVersion307(SQLiteDatabase db) { 2268b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE properties (" + 2269b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_key TEXT PRIMARY_KEY, " + 2270b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_value TEXT" + 2271b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 2272b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2273b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2274743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov private void upgradeToVersion308(SQLiteDatabase db) { 22754394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE accounts (" + 22764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_name TEXT, " + 22774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_type TEXT " + 22784394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 2279743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 22804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO accounts " + 22814394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "SELECT DISTINCT account_name, account_type FROM raw_contacts"); 2282743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 2283743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 2284f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov private void upgradeToVersion400(SQLiteDatabase db) { 2285dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2286dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0;"); 2287dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2288dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0;"); 2289dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 2290dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 229151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildNameLookup(SQLiteDatabase db) { 229251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 229351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 229451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 229551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 229651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 229704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 229851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates all locale-sensitive data: nickname_lookup, name_lookup and sort keys. 229904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 230051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov public void setLocale(ContactsProvider2 provider, Locale locale) { 230151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.i(TAG, "Switching to locale " + locale); 230204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2303c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton long start = SystemClock.uptimeMillis(); 230451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 230551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setLocale(locale); 230651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.beginTransaction(); 230751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 230851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 230951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key2_index"); 231051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 231151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 231251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov loadNicknameLookupTable(db); 231351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 231451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov rebuildSortKeys(db, provider); 231551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 231651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setTransactionSuccessful(); 231751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 231851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.endTransaction(); 231951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 232051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 2321c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton Log.i(TAG, "Locale change completed in " + (SystemClock.uptimeMillis() - start) + "ms"); 232251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 232351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 232451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov /** 232551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates sort keys for all contacts. 232651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov */ 232751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildSortKeys(SQLiteDatabase db, ContactsProvider2 provider) { 232851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Cursor cursor = db.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID}, 232951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov null, null, null, null, null); 233051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 233151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov while (cursor.moveToNext()) { 233251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov long rawContactId = cursor.getLong(0); 233351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov provider.updateRawContactDisplayName(db, rawContactId); 233451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 233551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 233651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov cursor.close(); 233751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 233851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 233951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 234051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void insertNameLookup(SQLiteDatabase db) { 234104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP); 234204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 234304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov SQLiteStatement nameLookupInsert = db.compileStatement( 234404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 234504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 234604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 234704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 234804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + 234904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ") VALUES (?,?,?,?)"); 235004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 235151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 235251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertStructuredNameLookup(db, nameLookupInsert); 235351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertOrganizationLookup(db, nameLookupInsert); 235451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertEmailLookup(db, nameLookupInsert); 235551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNicknameLookup(db, nameLookupInsert); 235651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 235751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nameLookupInsert.close(); 235851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 235904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 236004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 236104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class StructuredNameQuery { 236204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 236304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 236404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 236504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 236604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 236704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 236804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName._ID, 236904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.RAW_CONTACT_ID, 237004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.DISPLAY_NAME, 237104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 237204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 237304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 237404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 237504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int DISPLAY_NAME = 2; 237604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 237704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 237804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private class StructuredNameLookupBuilder extends NameLookupBuilder { 237904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final SQLiteStatement mNameLookupInsert; 238104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final CommonNicknameCache mCommonNicknameCache; 238204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 238304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public StructuredNameLookupBuilder(NameSplitter splitter, 238404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) { 238504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov super(splitter); 238604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mCommonNicknameCache = commonNicknameCache; 238704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mNameLookupInsert = nameLookupInsert; 238804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 238904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 239104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected void insertNameLookup(long rawContactId, long dataId, int lookupType, 239204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name) { 239304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (!TextUtils.isEmpty(name)) { 239404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert, 239504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rawContactId, dataId, lookupType, name); 239604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 239704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 239804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 239904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 240004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected String[] getCommonNicknameClusters(String normalizedName) { 240104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return mCommonNicknameCache.getCommonNicknameClusters(normalizedName); 240204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 240304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 240404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 240504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 240604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all structured names in the database. 240704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 240804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 2409d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameSplitter nameSplitter = createNameSplitter(); 2410d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(nameSplitter, 241104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov new CommonNicknameCache(db), nameLookupInsert); 241204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE); 241304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS, 241404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 241504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 241604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 241704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 241804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(StructuredNameQuery.ID); 241904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID); 242004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME); 2421d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov int fullNameStyle = nameSplitter.guessFullNameStyle(name); 242251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov fullNameStyle = nameSplitter.getAdjustedFullNameStyle(fullNameStyle); 2423d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov nameLookupBuilder.insertNameLookup(rawContactId, dataId, name, fullNameStyle); 242404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 242504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 242604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 242704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 242804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 242904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 243004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class OrganizationQuery { 243104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 243204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 243304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 243404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 243504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 243604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 243704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization._ID, 243804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.RAW_CONTACT_ID, 243904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.COMPANY, 244004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.TITLE, 244104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 244204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 244304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 244404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 244504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int COMPANY = 2; 244604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int TITLE = 3; 244704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 244804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 244904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 245004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all organizations in the database. 245104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 245204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertOrganizationLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 245304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 245404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(OrganizationQuery.TABLE, OrganizationQuery.COLUMNS, 245504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov OrganizationQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 245604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 245704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 245804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 245904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(OrganizationQuery.ID); 246004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(OrganizationQuery.RAW_CONTACT_ID); 246104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String organization = cursor.getString(OrganizationQuery.COMPANY); 246204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String title = cursor.getString(OrganizationQuery.TITLE); 246304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 246404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, organization); 246504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 246604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, title); 246704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 246804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 246904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 247004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 247104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 247204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 247304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class EmailQuery { 247404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 247504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 247604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 247704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 247804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 247904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 248004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email._ID, 248104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.RAW_CONTACT_ID, 248204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.ADDRESS, 248304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 248404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 248504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 248604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 248704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ADDRESS = 2; 248804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 248904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 249004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 249104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all email addresses in the database. 249204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 249304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 249404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 249504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS, 249604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 249704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 249804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 249904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 250004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(EmailQuery.ID); 250104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID); 250204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String address = cursor.getString(EmailQuery.ADDRESS); 250304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov address = extractHandleFromEmailAddress(address); 250404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 250504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, address); 250604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 250704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 250804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 250904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 251004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 251104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 251204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class NicknameQuery { 251304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 251404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 251504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 251604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 251704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 251804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 251904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname._ID, 252004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.RAW_CONTACT_ID, 252104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.NAME, 252204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 252304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 252404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 252504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 252604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int NAME = 2; 252704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 252904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 253004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all nicknames in the database. 253104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 253204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 253304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 253404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS, 253504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 253604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 253704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 253804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 253904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(NicknameQuery.ID); 254004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID); 254104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String nickname = cursor.getString(NicknameQuery.NAME); 254204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 254304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.NICKNAME, nickname); 254404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 254604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 254704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 255004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 255104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 255204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 255304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 255404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String name) { 255504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 255604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 255704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 255804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 255904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String normalized = NameNormalizer.normalize(name); 256004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(normalized)) { 256104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 256204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 256404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized); 256504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 256704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 256804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String normalizedName) { 256904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(1, rawContactId); 257004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(2, dataId); 257104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(3, lookupType); 257204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindString(4, normalizedName); 257304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.executeInsert(); 257404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 257504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 25764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov /** 25774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov * Changing the VISIBLE bit from a field on both RawContacts and Contacts to a separate table. 25784394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov */ 25794394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov private void upgradeToVersion401(SQLiteDatabase db) { 25804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 25814394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 25824394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 25834394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 25844394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 25854394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 25864394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts.IN_VISIBLE_GROUP + "!=0"); 25874394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 25884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 25894394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 2590d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov /** 2591d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov * Introducing a new table: directories. 2592d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov */ 2593d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void upgradeToVersion402(SQLiteDatabase db) { 2594d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 2595d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 2596d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 259797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov private void upgradeToVersion403(SQLiteDatabase db) { 259897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 259997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov createDirectoriesTable(db); 260097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 260197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE raw_contacts" 260297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD raw_contact_is_read_only INTEGER NOT NULL DEFAULT 0;"); 260397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 260497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE data" 260597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD is_read_only INTEGER NOT NULL DEFAULT 0;"); 260697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 260797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 2608892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void upgradeToVersion405(SQLiteDatabase db) { 2609892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS phone_lookup;"); 2610892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov // Private phone numbers table used for lookup 2611892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 2612892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID 2613892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 2614892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 2615892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 2616892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 2617892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 2618892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2619892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2620892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 2621892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 2622892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2623892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2624892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2625892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2626892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 2627892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 2628892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2629892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2630892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2631892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2632892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Phone.CONTENT_ITEM_TYPE); 2633892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (mimeTypeId == -1) { 2634892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return; 2635892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2636892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2637892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String mCountryIso = getCountryIso(); 2638892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov Cursor cursor = db.rawQuery( 2639892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov "SELECT _id, " + Phone.RAW_CONTACT_ID + ", " + Phone.NUMBER + 2640892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " FROM " + Tables.DATA + 2641892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId 2642892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " AND " + Phone.NUMBER + " NOT NULL", null); 2643892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2644892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ContentValues phoneValues = new ContentValues(); 2645892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov try { 2646892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov while (cursor.moveToNext()) { 2647892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long dataID = cursor.getLong(0); 2648892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long rawContactID = cursor.getLong(1); 2649892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String number = cursor.getString(2); 2650892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String numberE164 = PhoneNumberUtils.formatNumberToE164(number, mCountryIso); 2651892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String normalizedNumber = PhoneNumberUtils.normalizeNumber(number); 2652892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (!TextUtils.isEmpty(normalizedNumber)) { 2653892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.clear(); 2654892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactID); 2655892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.DATA_ID, dataID); 2656892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber); 2657892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2658892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber)); 2659892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2660892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2661892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (numberE164 != null && !numberE164.equals(normalizedNumber)) { 2662892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164); 2663892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2664892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(numberE164)); 2665892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2666892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2667892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2668892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2669892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } finally { 2670892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov cursor.close(); 2671892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2672892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2673892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 26742530512f639c4979fd7371c7dd25dd67e8118124Bai Tao private void upgradeToVersion406(SQLiteDatabase db) { 26752530512f639c4979fd7371c7dd25dd67e8118124Bai Tao db.execSQL("ALTER TABLE calls ADD countryiso TEXT;"); 26762530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 26772530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 2678d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion409(SQLiteDatabase db) { 2679d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 2680d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov createDirectoriesTable(db); 2681d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 2682d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 2683385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov /** 2684d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov * Adding DEFAULT_DIRECTORY table. 2685385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov */ 2686d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion411(SQLiteDatabase db) { 2687d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.DEFAULT_DIRECTORY); 2688385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 2689385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 2690385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 2691385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2692385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process contacts without an account 2693385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2694385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2695385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2696385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 2697385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL "); 2698385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2699385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process accounts that don't have a default group (e.g. Exchange) 2700385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2701385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2702385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2703385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE NOT EXISTS" + 2704385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 2705385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 2706385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2707385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2708385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2709385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2710385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2711385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")"); 2712385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2713385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = lookupMimeTypeId(db, GroupMembership.CONTENT_ITEM_TYPE); 2714385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2715d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Process accounts that do have a default group (e.g. Google) 2716385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2717385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2718385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2719385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 2720385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" + Data.RAW_CONTACT_ID + ")" + 2721385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimetype + 2722d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND EXISTS" + 2723d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " (SELECT " + Groups._ID + 2724d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " FROM " + Tables.GROUPS + 2725d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2726d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2727d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2728d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2729d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2730d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov ")"); 27313d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 2732385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2733b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public String extractHandleFromEmailAddress(String email) { 2734b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 2735b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (tokens.length == 0) { 2736b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2737b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2738b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2739b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String address = tokens[0].getAddress(); 2740b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov int at = address.indexOf('@'); 2741b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (at != -1) { 2742b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return address.substring(0, at); 2743b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2744b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2745b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2746b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 274708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov public String extractAddressFromEmailAddress(String email) { 274808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 274908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (tokens.length == 0) { 275008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return null; 275108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 275208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 275308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return tokens[0].getAddress(); 275408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 275508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 2756b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private long lookupMimeTypeId(SQLiteDatabase db, String mimeType) { 2757b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2758b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return DatabaseUtils.longForQuery(db, 2759b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 2760b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 2761b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 2762b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov + "='" + mimeType + "'", null); 2763b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } catch (SQLiteDoneException e) { 2764b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // No rows of this type in the database 2765b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return -1; 2766b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2767b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2768b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 27695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void bindString(SQLiteStatement stmt, int index, String value) { 27705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (value == null) { 27715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindNull(index); 27725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else { 27735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindString(index, value); 27745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 27755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 27765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2777a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 2778f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Adds index stats into the SQLite database to force it to always use the lookup indexes. 2779f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 2780f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private void updateSqliteStats(SQLiteDatabase db) { 2781f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2782f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // Specific stats strings are based on an actual large database after running ANALYZE 2783f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov try { 27848fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 27858fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_restricted_index", "10000 9000"); 27868fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 27878fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_has_phone_index", "10000 500"); 27888fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 27898fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 27908fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_source_id_index", "10000 1 1 1"); 27918fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 27928fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_contact_id_index", "10000 2"); 27938fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 27948fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 27958fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "name_lookup_raw_contact_id_index", "10000 3"); 27968fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 2797916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov "name_lookup_index", "10000 3 2 2 1"); 27988fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 27998fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "10000 3 2 1"); 28008fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28018fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 28028fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "phone_lookup_index", "10000 2 2 1"); 280336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 280436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 28058fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28068fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 28078fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_mimetype_data1_index", "60000 5000 2"); 28088fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 28098fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_raw_contact_id", "60000 10"); 28108fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28118fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.GROUPS, 28128fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "groups_source_id_index", "50 1 1 1"); 28138fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 28148fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NICKNAME_LOOKUP, 28158fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "500 2 1"); 28168fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 2817f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } catch (SQLException e) { 2818f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov Log.e(TAG, "Could not update index stats", e); 2819f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2820f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2821f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2822f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2823f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Stores statistics for a given index. 2824f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * 2825f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * @param stats has the following structure: the first index is the expected size of 2826f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * the table. The following integer(s) are the expected number of records selected with the 2827f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * index. There should be one integer per indexed column. 2828f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 28295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateIndexStats(SQLiteDatabase db, String table, String index, 28305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String stats) { 2831f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';"); 2832f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)" 2833f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " VALUES ('" + table + "','" + index + "','" + stats + "');"); 2834f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2835f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2836f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov @Override 2837f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov public synchronized SQLiteDatabase getWritableDatabase() { 2838f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov SQLiteDatabase db = super.getWritableDatabase(); 2839f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov if (mReopenDatabase) { 2840f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov mReopenDatabase = false; 2841f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov close(); 2842f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db = super.getWritableDatabase(); 2843f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2844f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov return db; 2845f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2846f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2847f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2848a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 2849a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 2850a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 2851a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 28523d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 285333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACCOUNTS + ";"); 285469cc3a2b09e2ffb606c6e52a71b604bba526d225Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL)"); 285533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov 2856d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 28575ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";"); 2858a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 2859a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 2860a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 2861ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 2862b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 2863eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("DELETE FROM " + Tables.SETTINGS + ";"); 2864a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 28653d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CALLS + ";"); 286672e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DIRECTORIES + ";"); 286772e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov 286872e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov insertDefaultDirectory(db); 286972e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov insertLocalInvisibleDirectory(db); 2870b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 2871b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 2872a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 2873b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 287404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public NameSplitter createNameSplitter() { 287504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return new NameSplitter( 287604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 287704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 287804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 287904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 288004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Locale.getDefault()); 288104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 288204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2883b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2884619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 2885619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 2886619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 2887619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 2888619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 2889619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 2890619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 2891619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 2892619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2893619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 2894619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2895619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 2896b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 2897b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 2898b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 2899b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 2900b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 2901b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 2902b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 2903b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 2904b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 2905b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 2906b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 2907b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2908f4a3b7e523e36679b68edd2af632e26648758ff2Dmitri Plotnikov private long getCachedId(SQLiteStatement query, SQLiteStatement insert, 2909b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 2910b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 2911b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 2912b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 2913b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2914b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2915b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey long id = -1; 2916b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2917b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try searching database for mapping 2918b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(query, 1, value); 2919b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = query.simpleQueryForLong(); 2920b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2921b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Nothing found, so try inserting new mapping 2922b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(insert, 1, value); 2923b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey id = insert.executeInsert(); 2924b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2925b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2926b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (id != -1) { 2927b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Cache and return the new answer 2928b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey cache.put(value, id); 2929b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return id; 2930b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } else { 2931b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Otherwise throw if no mapping found or created 2932b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey throw new IllegalStateException("Couldn't find or create internal " 2933b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey + "lookup table entry for value " + value); 2934b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2935b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2936b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2937b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2938ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 2939b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2940b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2941b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 2942b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2943b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2944b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 2945b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2946b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2947b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2948ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 2949b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 2950b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2951b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 2952b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2953b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 29545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return getMimeTypeIdNoDbCheck(mimetype); 29555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 29565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 29575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private long getMimeTypeIdNoDbCheck(String mimetype) { 2958b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 2959b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2960b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2961b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2962ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 2963b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2964b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 2965b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2966b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2967b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2968b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2969b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 2970b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 2971b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2972b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2973b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2974b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2975b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2976b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2977b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 2978b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 2979b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 2980b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 2981b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 2982b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Make sure compiled statements are ready by opening database 2983b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey getReadableDatabase(); 2984b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 2985b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 2986b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 2987b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 2988b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 2989b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 2990b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 2991b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 2992b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 2993b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 29946bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 29956bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 2996d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts. 2997ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 2998ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 2999385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov updateCustomContactVisibility(getWritableDatabase(), ""); 3000ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3001ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3002ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3003385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} and 3004385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * {@link Tables#DEFAULT_DIRECTORY} for a specific contact. 3005ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 3006fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public void updateContactVisible(long contactId) { 30074394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3008385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov updateCustomContactVisibility(getWritableDatabase(), 3009385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Contacts._ID + "=" + contactId); 3010385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3011385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov String contactIdAsString = String.valueOf(contactId); 3012385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 3013385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3014385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // The contact will be included in the default directory if contains 3015d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // a raw contact that is in any group or in an account that 3016385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // does not have any AUTO_ADD groups. 3017385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long visibleRawContact = DatabaseUtils.longForQuery(db, 3018385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT EXISTS (" + 3019385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 3020385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3021385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 3022385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" 3023385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + Data.RAW_CONTACT_ID + ")" + 3024385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3025385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + DataColumns.MIMETYPE_ID + "=?" + 3026385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3027385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3028385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3029385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3030385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND NOT EXISTS" + 3031385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 3032385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 3033385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 3034385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 3035385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 3036385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 3037385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 3038385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")" + 3039385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3040385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3041385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3042385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3043385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 3044385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL" + 3045385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")", 3046385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { 3047385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 30486c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov String.valueOf(mimetype), 3049385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 30506c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov contactIdAsString 3051385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov }); 3052385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3053385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov if (visibleRawContact != 0) { 3054385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + " VALUES(?)", 3055385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3056385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } else { 3057385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DEFAULT_DIRECTORY + " WHERE " + Contacts._ID + "=?", 3058385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3059385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 3060385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 30614394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 3062385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov private void updateCustomContactVisibility(SQLiteDatabase db, String selection) { 3063ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 30644394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)}; 30654394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 30664394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // First delete what needs to be deleted, then insert what needs to be added. 30674394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // Since flash writes are very expensive, this approach is much better than 30684394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // delete-all-insert-all. 30694394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.VISIBLE_CONTACTS + 30704394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + "_id NOT IN" + 30714394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "(SELECT " + Contacts._ID + 30724394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 30734394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE (" + Clauses.CONTACT_IS_VISIBLE + ")=1) " + selection, 30744394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3075fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 30764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 30774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 30784394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 30794394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts._ID + 30804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " NOT IN " + Tables.VISIBLE_CONTACTS + 30814394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1 " + selection, 30824394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3083ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3084ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3085ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3086d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Returns contact ID for the given contact or zero if it is NULL. 30876bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 3088d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public long getContactId(long rawContactId) { 30896bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov getReadableDatabase(); 30906bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 3091d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId); 3092d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactIdQuery.simpleQueryForLong(); 30936bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 3094a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana // No valid mapping found, so return 0 30956bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 30966bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 30976bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 309861bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 30995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int getAggregationMode(long rawContactId) { 3100f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov getReadableDatabase(); 3101f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 31025ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId); 3103f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 3104f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 31056cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // No valid row found, so return "disabled" 31066cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.AGGREGATION_MODE_DISABLED; 3107f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3108f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3109f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3110892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov public void buildPhoneLookupAndContactQuery( 3111892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov SQLiteQueryBuilder qb, String normalizedNumber, String numberE164) { 3112892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber); 3113e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 311436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, true); 3115e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setTables(sb.toString()); 3116e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3117e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb = new StringBuilder(); 3118892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, normalizedNumber, numberE164); 3119e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 3120bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 3121bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3122e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public String buildPhoneLookupAsNestedQuery(String number) { 3123e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 312436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 3125e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id" + " FROM "); 312636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, false); 3127e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(" WHERE "); 3128892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, number, null); 3129e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(")"); 3130e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov return sb.toString(); 3131e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3132e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 313336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private void appendPhoneLookupTables(StringBuilder sb, final String minMatch, 3134e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov boolean joinContacts) { 3135e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(Tables.RAW_CONTACTS); 3136e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov if (joinContacts) { 3137fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov sb.append(" JOIN " + getContactView() + " contacts_view" 3138fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " ON (contacts_view._id = raw_contacts.contact_id)"); 3139e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3140892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(", (SELECT data_id, normalized_number, length(normalized_number) as len " 3141892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " FROM phone_lookup " + " WHERE (" + Tables.PHONE_LOOKUP + "." 3142892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + PhoneLookupColumns.MIN_MATCH + " = '"); 314336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 314436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("')) AS lookup, " + Tables.DATA); 3145e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3146e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3147892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void appendPhoneLookupSelection(StringBuilder sb, String number, String numberE164) { 3148892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id"); 3149892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumberE164 = !TextUtils.isEmpty(numberE164); 3150892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumber = !TextUtils.isEmpty(number); 3151892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 || hasNumber) { 3152892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND ( "); 3153892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164) { 3154892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.normalized_number = "); 3155892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, numberE164); 3156892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3157892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 && hasNumber) { 3158892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" OR "); 3159892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3160892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumber) { 3161892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov int numberLen = number.length(); 3162892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.len <= "); 3163892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3164892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND substr("); 3165892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 3166892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(','); 3167892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3168892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" - lookup.len + 1) = lookup.normalized_number"); 3169892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3170892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(')'); 3171892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 317236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 317336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 317436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public String getUseStrictPhoneNumberComparisonParameter() { 317536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov return mUseStrictPhoneNumberComparison ? "1" : "0"; 3176fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov } 3177bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3178619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 3179b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 3180b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 3181b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 318251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP); 318351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 318428f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 318528f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 3186b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 3187b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 3188b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3189b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3190b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 3191b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 3192b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 3193b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 319451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 319551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 319651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String[] names = strings[clusterId].split(","); 319751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int j = 0; j < names.length; j++) { 319851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 319951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 320051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 320151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 320251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String.valueOf(clusterId)); 320351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.executeInsert(); 320451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } catch (SQLiteException e) { 320551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 320651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Print the exception and keep going - this is not a fatal error 320751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 320851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 3209b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3210b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 321151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 321251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.close(); 3213b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3214b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3215b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3216f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 3217f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3218f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3219f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 3220f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3221f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3222f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3223f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 3224f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3225f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3226f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 3227f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 3228f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 3229f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 3230f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 3231f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 3232f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 3233f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 32341b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov } else if (value instanceof String) { 32351b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = Long.parseLong((String)value); 3236f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 32371b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = ((Number)value).longValue(); 3238f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3239f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 3240f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3241f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3242f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 324335ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 324435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 324535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 3246c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3247c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov /** 3248c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Delete the aggregate contact if it has no constituent raw contacts other 3249c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * than the supplied one. 3250c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 3251c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov public void removeContactIfSingleton(long rawContactId) { 3252c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3253c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3254c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Obtain contact ID from the supplied raw contact ID 3255c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM " 3256c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")"; 3257c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3258c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Find other raw contacts in the same aggregate contact 3259c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM " 3260c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON (" 3261c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID 3262c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + "" 3263c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")"; 3264c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3265c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS 3266c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId 3267c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND NOT EXISTS " + otherRawContacts + ";"); 3268c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 32694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 32704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 3271b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Returns the value from the {@link Tables#PROPERTIES} table. 3272b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3273b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public String getProperty(String key, String defaultValue) { 3274b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov Cursor cursor = getReadableDatabase().query(Tables.PROPERTIES, 3275b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{PropertiesColumns.PROPERTY_VALUE}, 3276b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + "=?", 3277b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{key}, null, null, null); 3278b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String value = null; 3279b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov try { 3280b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (cursor.moveToFirst()) { 3281b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov value = cursor.getString(0); 3282b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3283b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } finally { 3284b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov cursor.close(); 3285b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3286b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3287b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov return value != null ? value : defaultValue; 3288b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3289b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3290b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 3291b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Stores a key-value pair in the {@link Tables#PROPERTIES} table. 3292b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3293b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public void setProperty(String key, String value) { 32943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(getWritableDatabase(), key, value); 32953d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 32963d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 32973d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private void setProperty(SQLiteDatabase db, String key, String value) { 3298b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ContentValues values = new ContentValues(); 3299b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_KEY, key); 3300b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_VALUE, value); 33013d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov db.replace(Tables.PROPERTIES, null, values); 3302b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3303b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3304b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 33054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Check if {@link Binder#getCallingUid()} should be allowed access to 33064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * {@link RawContacts#IS_RESTRICTED} data. 33074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 3308d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData() { 33094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 33106ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen int caller = Binder.getCallingUid(); 33116ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen if (caller == 0) return true; // root can do anything 33126ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen final String[] callerPackages = pm.getPackagesForUid(caller); 33134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Has restricted access if caller matches any packages 33154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov for (String callerPackage : callerPackages) { 3316d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (hasAccessToRestrictedData(callerPackage)) { 3317763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return true; 3318763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3319763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3320763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return false; 3321763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3322763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3323763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar /** 3324763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * Check if requestingPackage should be allowed access to 3325763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * {@link RawContacts#IS_RESTRICTED} data. 3326763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar */ 3327d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData(String requestingPackage) { 3328d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (mUnrestrictedPackages != null) { 3329d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton for (String allowedPackage : mUnrestrictedPackages) { 3330d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (allowedPackage.equals(requestingPackage)) { 3331d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return true; 3332d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton } 33334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov return false; 33364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getDataView() { 3339d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getDataView(false); 3340d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3341d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3342d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getDataView(boolean requireRestrictedView) { 3343d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3344d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Views.DATA_ALL : Views.DATA_RESTRICTED; 33454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getRawContactView() { 3348763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getRawContactView(false); 3349763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3350763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3351763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getRawContactView(boolean requireRestrictedView) { 3352d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3353763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.RAW_CONTACTS_ALL : Views.RAW_CONTACTS_RESTRICTED; 33544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 33564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getContactView() { 3357763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getContactView(false); 33584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 33594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3360763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getContactView(boolean requireRestrictedView) { 3361d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3362763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.CONTACTS_ALL : Views.CONTACTS_RESTRICTED; 3363f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey } 3364f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey 336589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public String getGroupView() { 336689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov return Views.GROUPS_ALL; 336789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov } 336889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 3369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView() { 3370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getRawEntitiesView(false); 3371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView(boolean requireRestrictedView) { 3374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.RAW_ENTITIES : Views.RAW_ENTITIES_RESTRICTED; 3376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView() { 3379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getEntitiesView(false); 3380d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3381d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView(boolean requireRestrictedView) { 3383d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.ENTITIES : Views.ENTITIES_RESTRICTED; 3385d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3386d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3387ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** 3388ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov * Test if any of the columns appear in the given projection. 3389ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov */ 3390ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov public boolean isInProjection(String[] projection, String... columns) { 339182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (projection == null) { 339282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 339382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 3394ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 339582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov // Optimized for a single-column test 339682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (columns.length == 1) { 339782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov String column = columns[0]; 339882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 339982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (column.equals(test)) { 340082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 340182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 340282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 340382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } else { 340482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 340582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String column : columns) { 3406ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (column.equals(test)) { 3407ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return true; 3408ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3409ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3410ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3411ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3412ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return false; 34134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 3414fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3415fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3416fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3417fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3418fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3419fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(Uri uri) { 3420fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return exceptionMessage(null, uri); 3421fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3422fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3423fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3424fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3425fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3426fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3427fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(String message, Uri uri) { 3428fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 3429fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (message != null) { 3430fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(message).append("; "); 3431fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3432fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("URI: ").append(uri); 3433fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 3434fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov int callingUid = Binder.getCallingUid(); 3435fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling user: "); 3436fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov String userName = pm.getNameForUid(callingUid); 3437fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (userName != null) { 3438fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(userName); 3439fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3440fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callingUid); 3441fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3442fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3443fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(callingUid); 3444fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages != null && callerPackages.length > 0) { 3445fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages.length == 1) { 3446fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package:"); 3447fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[0]); 3448fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3449fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package is one of: ["); 3450fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov for (int i = 0; i < callerPackages.length; i++) { 3451fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (i != 0) { 3452fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", "); 3453fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3454fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[i]); 3455fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3456fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("]"); 3457fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3458fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3459fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3460fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return sb.toString(); 3461fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3462892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 3463892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov protected String getCountryIso() { 3464892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov CountryDetector detector = 3465892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov (CountryDetector) mContext.getSystemService(Context.COUNTRY_DETECTOR); 3466892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return detector.detectCountry().getCountryIso(); 3467892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3468b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 3469