ContactsDatabaseHelper.java revision 50a7c86b4b49870bd19d5270722be3f1fccaf226
1b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/* 2b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Copyright (C) 2009 The Android Open Source Project 3b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 4b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * you may not use this file except in compliance with the License. 6b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * You may obtain a copy of the License at 7b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 8b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 10b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * See the License for the specific language governing permissions and 14b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * limitations under the License 15b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 16b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts; 18b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1953214b3ed12b0ff9cb589b6559311f2ac142f2e3Bjorn Bringertimport com.android.common.content.SyncStateContentProviderHelper; 2067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 2182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.content.ContentResolver; 22619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.ContentValues; 23b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.content.Context; 24619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.ApplicationInfo; 25619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager; 26619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 27d91272b48f97243533c6580981e12a4847b5783fJeff Hamiltonimport android.content.res.Resources; 2836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.database.Cursor; 29b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.DatabaseUtils; 30f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikovimport android.database.SQLException; 3178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikovimport android.database.sqlite.SQLiteConstraintException; 32b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDatabase; 33b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDoneException; 34b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikovimport android.database.sqlite.SQLiteException; 35b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteOpenHelper; 36bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.database.sqlite.SQLiteQueryBuilder; 37b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteStatement; 38892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikovimport android.location.CountryDetector; 39fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikovimport android.net.Uri; 404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.os.Binder; 41a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.os.Bundle; 42c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamiltonimport android.os.SystemClock; 43b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns; 44e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikovimport android.provider.CallLog.Calls; 45a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract; 46b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions; 47a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 48a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 492a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im; 50a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 51a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 52a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 53a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.SipAddress; 54a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 55d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 563d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikovimport android.provider.ContactsContract.Contacts.Photo; 57de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data; 58d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikovimport android.provider.ContactsContract.Directory; 595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources; 605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle; 61ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups; 62d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 63eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings; 6482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates; 6567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities; 66bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils; 6736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.text.TextUtils; 68b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Token; 69b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Tokenizer; 70b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log; 71b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 72b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap; 735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale; 74b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 75b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/** 76b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Database helper for contacts. Designed as a singleton to make sure that all 77b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * {@link android.content.ContentProvider} users get the same reference. 78b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Provides handy methods for maintaining package and mime-type lookup tables. 79b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 80b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov/* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper { 81b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static final String TAG = "ContactsDatabaseHelper"; 82b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 8397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov /** 8494c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov * Contacts DB version ranges: 8597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * <pre> 8697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 0-98 Cupcake/Donut 8797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 100-199 Eclair 8897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 200-299 Eclair-MR1 8997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 300-349 Froyo 9097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 350-399 Gingerbread 9197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * 400-499 Honeycomb 9297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov * </pre> 9397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov */ 948d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov static final int DATABASE_VERSION = 417; 95e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 96b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private static final String DATABASE_NAME = "contacts2.db"; 971f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey private static final String DATABASE_PRESENCE = "presence_db"; 98b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 99b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface Tables { 100d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONTACTS = "contacts"; 1015ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACTS = "raw_contacts"; 102ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String PACKAGES = "packages"; 103ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String MIMETYPES = "mimetypes"; 104b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PHONE_LOOKUP = "phone_lookup"; 105a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_LOOKUP = "name_lookup"; 106b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions"; 107eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey public static final String SETTINGS = "settings"; 108b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA = "data"; 109ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS = "groups"; 1101f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public static final String PRESENCE = "presence"; 111e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public static final String AGGREGATED_PRESENCE = "agg_presence"; 112b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NICKNAME_LOOKUP = "nickname_lookup"; 113e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov public static final String CALLS = "calls"; 114a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String STATUS_UPDATES = "status_updates"; 115b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public static final String PROPERTIES = "properties"; 116743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov public static final String ACCOUNTS = "accounts"; 1174394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov public static final String VISIBLE_CONTACTS = "visible_contacts"; 118d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov public static final String DIRECTORIES = "directories"; 119385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov public static final String DEFAULT_DIRECTORY = "default_directory"; 120b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 121ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String DATA_JOIN_MIMETYPES = "data " 1221b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id)"; 123b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 12411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov public static final String DATA_JOIN_RAW_CONTACTS = "data " 1258e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 12611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 1275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPE_RAW_CONTACTS = "data " 128c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 129c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"; 130bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 131e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 132e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS = "raw_contacts " 133e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN settings ON (" 134e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 135e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 136e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 137e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 138e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID 139e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + ")"; 140e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 141e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey // NOTE: This requires late binding of GroupMembership MIME-type 142e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS = "settings " 143e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN raw_contacts ON (" 144e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_name = settings.account_name AND " 145e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "raw_contacts.account_type = settings.account_type) " 146e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND " 147e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "data.raw_contact_id = raw_contacts._id) " 148e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 149e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 150d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data " 1511b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1521b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 153d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 154ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 1555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data " 1561b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) " 1571b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) " 15867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) " 1599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + "LEFT OUTER JOIN groups " 1609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' " 1619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana + " AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "; 162ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 163ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String GROUPS_JOIN_PACKAGES = "groups " 164ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)"; 165ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 166b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 167b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String ACTIVITIES = "activities"; 168b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 169ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String ACTIVITIES_JOIN_MIMETYPES = "activities " 170ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)"; 171b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 172d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS = 1735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov "activities " 17467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) " 175ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) " 1765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " + 177fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "raw_contacts._id) " 178d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)"; 1797e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana 1805ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup " 1815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + "INNER JOIN raw_contacts ON (name_lookup.raw_contact_id = raw_contacts._id)"; 182b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 183b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public interface Views { 1854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_ALL = "view_data"; 1864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String DATA_RESTRICTED = "view_data_restricted"; 1874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_ALL = "view_raw_contacts"; 1894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String RAW_CONTACTS_RESTRICTED = "view_raw_contacts_restricted"; 1904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_ALL = "view_contacts"; 1924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public static final String CONTACTS_RESTRICTED = "view_contacts_restricted"; 19389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 194a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String ENTITIES = "view_entities"; 195a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String ENTITIES_RESTRICTED = "view_entities_restricted"; 196a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 197a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String RAW_ENTITIES = "view_raw_entities"; 198a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public static final String RAW_ENTITIES_RESTRICTED = "view_raw_entities_restricted"; 199a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 20089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public static final String GROUPS_ALL = "view_groups"; 2014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 2024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 2031f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey public interface Clauses { 204e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE + "='" 205e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + GroupMembership.CONTENT_ITEM_TYPE + "'"; 206ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 207e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "=" 208ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupsColumns.CONCRETE_ID; 209ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 21068936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String HAVING_NO_GROUPS = "COUNT(" + DataColumns.CONCRETE_GROUP_ID + ") == 0"; 2119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana 21268936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey final String GROUP_BY_ACCOUNT_CONTACT_ID = SettingsColumns.CONCRETE_ACCOUNT_NAME + "," 21368936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "," + RawContacts.CONTACT_ID; 214e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 215e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String RAW_CONTACT_IS_LOCAL = RawContactsColumns.CONCRETE_ACCOUNT_NAME 216e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + " IS NULL AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL"; 217e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 218e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String ZERO_GROUP_MEMBERSHIPS = "COUNT(" + GroupsColumns.CONCRETE_ID + ")=0"; 219e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 2201a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS = "outer_raw_contacts"; 2211a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey final String OUTER_RAW_CONTACTS_ID = OUTER_RAW_CONTACTS + "." + RawContacts._ID; 2221a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey 223b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov final String CONTACT_IS_VISIBLE = 224b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "SELECT " + 2251a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey "MAX((SELECT (CASE WHEN " + 226b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "(CASE" + 227b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + RAW_CONTACT_IS_LOCAL + 228b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN 1 " + 229b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHEN " + ZERO_GROUP_MEMBERSHIPS + 230b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " THEN " + Settings.UNGROUPED_VISIBLE + 231b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " ELSE MAX(" + Groups.GROUP_VISIBLE + ")" + 232b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov "END)=1 THEN 1 ELSE 0 END)" + 233b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS + 2341a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + OUTER_RAW_CONTACTS_ID + "))" + 2351a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey " FROM " + Tables.RAW_CONTACTS + " AS " + OUTER_RAW_CONTACTS + 236b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 237b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov " GROUP BY " + RawContacts.CONTACT_ID; 238e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 239e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND " 240e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?"; 2414394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 2424394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov public static final String CONTACT_VISIBLE = 2434394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "EXISTS (SELECT _id FROM " + Tables.VISIBLE_CONTACTS 2444394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + " WHERE " + Tables.CONTACTS +"." + Contacts._ID 2454394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + "=" + Tables.VISIBLE_CONTACTS +"." + Contacts._ID + ")"; 2461f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey } 2471f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 248d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public interface ContactsColumns { 2494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 2504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * This flag is set for a contact if it has only one constituent raw contact and 2514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * it is restricted. 2524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 25367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String SINGLE_IS_RESTRICTED = "single_is_restricted"; 254ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 255a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public static final String LAST_STATUS_UPDATE_ID = "status_update_id"; 256a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 257d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID; 25867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 259d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "." 260d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.TIMES_CONTACTED; 261d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "." 262d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.LAST_TIME_CONTACTED; 263d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED; 264d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "." 265d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.CUSTOM_RINGTONE; 266d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "." 267d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Contacts.SEND_TO_VOICEMAIL; 2682d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill public static final String CONCRETE_LOOKUP_KEY = Tables.CONTACTS + "." 2692d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill + Contacts.LOOKUP_KEY; 270619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 271619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 2726cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov public interface RawContactsColumns { 27333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_ID = 2745ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + BaseColumns._ID; 2759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_NAME = 2765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME; 2779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana public static final String CONCRETE_ACCOUNT_TYPE = 2785ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE; 27933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_SOURCE_ID = 2805ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID; 28133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_VERSION = 2825ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.VERSION; 28333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DIRTY = 2845ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DIRTY; 28533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov public static final String CONCRETE_DELETED = 2865ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.DELETED; 2877a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC1 = 2887a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC1; 2897a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC2 = 2907a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC2; 2917a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC3 = 2927a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC3; 2937a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana public static final String CONCRETE_SYNC4 = 2947a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana Tables.RAW_CONTACTS + "." + RawContacts.SYNC4; 295c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey public static final String CONCRETE_STARRED = 296c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.STARRED; 297bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey public static final String CONCRETE_IS_RESTRICTED = 298bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey Tables.RAW_CONTACTS + "." + RawContacts.IS_RESTRICTED; 2998e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 3005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME = RawContacts.DISPLAY_NAME_PRIMARY; 3015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov public static final String DISPLAY_NAME_SOURCE = RawContacts.DISPLAY_NAME_SOURCE; 3028e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov public static final String AGGREGATION_NEEDED = "aggregation_needed"; 303fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 304fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_DISPLAY_NAME = 305fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + DISPLAY_NAME; 306fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public static final String CONCRETE_CONTACT_ID = 307fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID; 308f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov public static final String CONCRETE_NAME_VERIFIED = 309f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED; 310619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 311619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 312619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public interface DataColumns { 31367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 314b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 315ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 316ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID; 317226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID; 318d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "." 319d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov + Data.RAW_CONTACT_ID; 320ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_GROUP_ID = Tables.DATA + "." 321ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey + GroupMembership.GROUP_ROW_ID; 322e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 323e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1; 324e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2; 325e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3; 326e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4; 327e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5; 328e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6; 329e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7; 330e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8; 331e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9; 332e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10; 3330f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11; 3340f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12; 3350f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13; 3360f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14; 3370f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15; 338e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY; 339226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID; 340e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov } 341e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov 3420f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov // Used only for legacy API support 3430f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface ExtensionsColumns { 3440f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String NAME = Data.DATA1; 3450f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String VALUE = Data.DATA2; 3460f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3470f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 3480f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public interface GroupMembershipColumns { 3495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID; 3500f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID; 3510f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov } 3520f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov 353e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public interface PhoneColumns { 354e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String NORMALIZED_NUMBER = Data.DATA4; 355e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4; 356ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 357ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 358ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface GroupsColumns { 35967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String PACKAGE_ID = "package_id"; 36067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey 361ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID; 36267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID; 363341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.GROUPS + "." + Groups.ACCOUNT_NAME; 364341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.GROUPS + "." + Groups.ACCOUNT_TYPE; 365341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey } 366b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 367b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface ActivitiesColumns { 368b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE_ID = "package_id"; 369b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE_ID = "mimetype_id"; 370b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 371b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 372b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public interface PhoneLookupColumns { 373b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 374b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String DATA_ID = "data_id"; 3755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 376b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String NORMALIZED_NUMBER = "normalized_number"; 37736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public static final String MIN_MATCH = "min_match"; 378b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 379b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 380a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public interface NameLookupColumns { 3815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public static final String RAW_CONTACT_ID = "raw_contact_id"; 38214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov public static final String DATA_ID = "data_id"; 383a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NORMALIZED_NAME = "normalized_name"; 384a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public static final String NAME_TYPE = "name_type"; 385a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 386a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 387a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public final static class NameLookupType { 3882a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_EXACT = 0; 3892a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_VARIANT = 1; 3902a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NAME_COLLATION_KEY = 2; 3912a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int NICKNAME = 3; 3922a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov public static final int EMAIL_BASED_NICKNAME = 4; 393a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka public static final int ORGANIZATION = 5; 3944cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao public static final int NAME_SHORTHAND = 6; 395f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee public static final int NAME_CONSONANTS = 7; 396a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 397a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov // This is the highest name lookup type code plus one 3985086b63bf3de5f26f495b640e85259c0ebf5ca47Dmitri Plotnikov public static final int TYPE_COUNT = 8; 399a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov 400a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov public static boolean isBasedOnStructuredName(int nameLookupType) { 4012a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov return nameLookupType == NameLookupType.NAME_EXACT 4022a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_VARIANT 4032a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov || nameLookupType == NameLookupType.NAME_COLLATION_KEY; 404a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov } 405a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 406a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 407ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface PackagesColumns { 408b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 409b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String PACKAGE = "package"; 410226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana 411226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana public static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID; 412b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 413b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 414ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public interface MimetypesColumns { 415b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String _ID = BaseColumns._ID; 416b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public static final String MIMETYPE = "mimetype"; 417ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 418ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID; 419ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE; 420b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 421b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 422b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public interface AggregationExceptionColumns { 423b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov public static final String _ID = BaseColumns._ID; 424b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov } 425b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 426b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public interface NicknameLookupColumns { 427b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String NAME = "name"; 428b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov public static final String CLUSTER = "cluster"; 429b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 430b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 431e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public interface SettingsColumns { 432e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_NAME = Tables.SETTINGS + "." 433e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_NAME; 434e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey public static final String CONCRETE_ACCOUNT_TYPE = Tables.SETTINGS + "." 435e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey + Settings.ACCOUNT_TYPE; 436e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey } 437e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey 4384dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov public interface PresenceColumns { 4394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov String RAW_CONTACT_ID = "presence_raw_contact_id"; 440bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4414dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov } 4424dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov 443e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov public interface AggregatedPresenceColumns { 444e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov String CONTACT_ID = "presence_contact_id"; 4453296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4463296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_CONTACT_ID = Tables.AGGREGATED_PRESENCE + "." + CONTACT_ID; 447e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov } 448e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 449a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov public interface StatusUpdatesColumns { 450a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov String DATA_ID = "status_update_data_id"; 4513296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4523296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = Tables.STATUS_UPDATES + "." + DATA_ID; 4533296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4543296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = Tables.STATUS_UPDATES + "." + StatusUpdates.PRESENCE; 4553296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS; 4563296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = Tables.STATUS_UPDATES + "." 4573296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_TIMESTAMP; 4583296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = Tables.STATUS_UPDATES + "." 4593296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey + StatusUpdates.STATUS_RES_PACKAGE; 4603296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_LABEL; 4613296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_ICON; 4623296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey } 4633296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4643296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey public interface ContactsStatusUpdatesColumns { 4653296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String ALIAS = "contacts_" + Tables.STATUS_UPDATES; 4663296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4673296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_DATA_ID = ALIAS + "." + StatusUpdatesColumns.DATA_ID; 4683296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey 4693296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_PRESENCE = ALIAS + "." + StatusUpdates.PRESENCE; 4703296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS = ALIAS + "." + StatusUpdates.STATUS; 4713296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_TIMESTAMP = ALIAS + "." + StatusUpdates.STATUS_TIMESTAMP; 4723296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_RES_PACKAGE = ALIAS + "." + StatusUpdates.STATUS_RES_PACKAGE; 4733296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_LABEL = ALIAS + "." + StatusUpdates.STATUS_LABEL; 4743296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey String CONCRETE_STATUS_ICON = ALIAS + "." + StatusUpdates.STATUS_ICON; 475a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov } 476a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 477b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public interface PropertiesColumns { 478b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_KEY = "property_key"; 479b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String PROPERTY_VALUE = "property_value"; 480b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 481b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 482e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov public static final class DirectoryColumns { 483e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov public static final String TYPE_RESOURCE_NAME = "typeResourceName"; 484e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 485e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 4863296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey /** In-memory cache of previously found MIME-type mappings */ 487bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>(); 488b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** In-memory cache of previously found package name mappings */ 489bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>(); 490b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 4912a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdEmail; 4922a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdIm; 493a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov private long mMimeTypeIdSip; 4942a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdStructuredName; 4952a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdOrganization; 4962a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdNickname; 4972a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private long mMimeTypeIdPhone; 498b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 499b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** Compiled statements for querying and inserting mappings */ 500b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeQuery; 501b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageQuery; 502d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov private SQLiteStatement mContactIdQuery; 503f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov private SQLiteStatement mAggregationModeQuery; 504b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mMimetypeInsert; 505b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mPackageInsert; 506b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mDataMimetypeQuery; 507b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey private SQLiteStatement mActivitiesMimetypeQuery; 508b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 50978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** Precompiled sql statement for setting a data record to the primary. */ 51078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mSetPrimaryStatement; 51178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** Precompiled sql statement for setting a data record to the super primary. */ 51278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mSetSuperPrimaryStatement; 51378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** Precompiled sql statement for clearing super primary of a single record. */ 51478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mClearSuperPrimaryStatement; 51578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** Precompiled sql statement for updating a contact display name */ 51678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mRawContactDisplayNameUpdate; 51778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 51878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mNameLookupInsert; 51978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mNameLookupDelete; 52078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mStatusUpdateAutoTimestamp; 52178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mStatusUpdateInsert; 52278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mStatusUpdateReplace; 52378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mStatusAttributionUpdate; 52478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mStatusUpdateDelete; 52578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private SQLiteStatement mResetNameVerifiedForOtherRawContacts; 526f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov private SQLiteStatement mContactInDefaultDirectoryQuery; 52778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 528b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private final Context mContext; 5292a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private final boolean mDatabaseOptimizationEnabled; 53035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana private final SyncStateContentProviderHelper mSyncState; 531e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov private final CountryMonitor mCountryMonitor; 5325df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov private StringBuilder mSb = new StringBuilder(); 533f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov 534f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private boolean mReopenDatabase = false; 535f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 536b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov private static ContactsDatabaseHelper sSingleton = null; 537b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 53836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private boolean mUseStrictPhoneNumberComparison; 5393a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa 540d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton /** 541d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton * List of package names with access to {@link RawContacts#IS_RESTRICTED} data. 542d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton */ 543d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton private String[] mUnrestrictedPackages; 544d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton 545f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 546b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov public static synchronized ContactsDatabaseHelper getInstance(Context context) { 547b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (sSingleton == null) { 5482a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov sSingleton = new ContactsDatabaseHelper(context, DATABASE_NAME, true); 549b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 550b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return sSingleton; 551b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 552b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 5531f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey /** 55431b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov * Private constructor, callers except unit tests should obtain an instance through 55535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana * {@link #getInstance(android.content.Context)} instead. 5561f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey */ 557b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov ContactsDatabaseHelper(Context context) { 5582a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov this(context, null, false); 5592a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 5602a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 5612a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private ContactsDatabaseHelper( 5622a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov Context context, String databaseName, boolean optimizationEnabled) { 5632a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov super(context, databaseName, null, DATABASE_VERSION); 5642a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mDatabaseOptimizationEnabled = optimizationEnabled; 565d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton Resources resources = context.getResources(); 566619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 567b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov mContext = context; 56828b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana mSyncState = new SyncStateContentProviderHelper(); 569e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov mCountryMonitor = new CountryMonitor(context); 57036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov mUseStrictPhoneNumberComparison = 571d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton resources.getBoolean( 572d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton com.android.internal.R.bool.config_use_strict_phone_number_comparation); 5730f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov int resourceId = resources.getIdentifier("unrestricted_packages", "array", 5740f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov context.getPackageName()); 5750f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov if (resourceId != 0) { 5760f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = resources.getStringArray(resourceId); 5770f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } else { 5780f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov mUnrestrictedPackages = new String[0]; 5790f5116227592cb8e724542c598daffa383964679Dmitri Plotnikov } 580b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 581b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 5822a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov private void refreshDatabaseCaches(SQLiteDatabase db) { 58378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateDelete = null; 58478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateReplace = null; 58578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateInsert = null; 58678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateAutoTimestamp = null; 58778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusAttributionUpdate = null; 58878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mResetNameVerifiedForOtherRawContacts = null; 58978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate = null; 59078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement = null; 59178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mClearSuperPrimaryStatement = null; 59278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement = null; 59378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert = null; 59478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupDelete = null; 59578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mPackageQuery = null; 59678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mPackageInsert = null; 59778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mDataMimetypeQuery = null; 59878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mActivitiesMimetypeQuery = null; 59978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mContactIdQuery = null; 60078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mAggregationModeQuery = null; 601f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov mContactInDefaultDirectoryQuery = null; 6022a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 6032a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimetypeCache.clear(); 6042a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mPackageCache.clear(); 6052a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 6062a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimetypeQuery = db.compileStatement( 6072a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 6082a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 6092a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE + "=?"); 6102a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 6112a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimetypeInsert = db.compileStatement( 6122a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov "INSERT INTO " + Tables.MIMETYPES + "(" 6132a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov + MimetypesColumns.MIMETYPE + 6142a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov ") VALUES (?)"); 6152a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 6162a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdEmail = getMimeTypeId(Email.CONTENT_ITEM_TYPE); 6172a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdIm = getMimeTypeId(Im.CONTENT_ITEM_TYPE); 618a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov mMimeTypeIdSip = getMimeTypeId(SipAddress.CONTENT_ITEM_TYPE); 6192a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdStructuredName = getMimeTypeId(StructuredName.CONTENT_ITEM_TYPE); 6202a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdOrganization = getMimeTypeId(Organization.CONTENT_ITEM_TYPE); 6212a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdNickname = getMimeTypeId(Nickname.CONTENT_ITEM_TYPE); 6222a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mMimeTypeIdPhone = getMimeTypeId(Phone.CONTENT_ITEM_TYPE); 62378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 62478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 625b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 626b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onOpen(SQLiteDatabase db) { 6272a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov refreshDatabaseCaches(db); 62835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 62978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSyncState.onDatabaseOpened(db); 6301f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 6311f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";"); 632e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+ 63382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 63482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PROTOCOL + " INTEGER NOT NULL," + 63582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.CUSTOM_PROTOCOL + " TEXT," + 63682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_HANDLE + " TEXT," + 63782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.IM_ACCOUNT + " TEXT," + 638a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 639a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 64082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov StatusUpdates.PRESENCE + " INTEGER," + 641aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0," + 64282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL 64382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" + 6441f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey ");"); 6451f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey 646e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON " 6474dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");"); 64809562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex2" + " ON " 64909562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori + Tables.PRESENCE + " (" + PresenceColumns.CONTACT_ID + ");"); 650e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov 651e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " 652aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+ 653e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov AggregatedPresenceColumns.CONTACT_ID 654e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," + 655632248ae0053fa99b1f5b4cfaab3e55b7453fcb1Vasu Nori StatusUpdates.PRESENCE + " INTEGER," + 656aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0" + 657e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov ");"); 658bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 659bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 660bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted" 661bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 662bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 663bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATED_PRESENCE 664bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " + 665bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.CONTACT_ID + 666bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 667bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.RAW_CONTACT_ID 668bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.RAW_CONTACT_ID + 669bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND NOT EXISTS" + 670bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov "(SELECT " + PresenceColumns.RAW_CONTACT_ID + 671bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " FROM " + Tables.PRESENCE + 672bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " WHERE " + PresenceColumns.CONTACT_ID 673bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "=OLD." + PresenceColumns.CONTACT_ID + 674bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov " AND " + PresenceColumns.RAW_CONTACT_ID 675bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));" 676bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 677bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 678aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori final String replaceAggregatePresenceSql = 679aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "(" 680093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + AggregatedPresenceColumns.CONTACT_ID + ", " 681093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.PRESENCE + ", " 682093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.CHAT_CAPABILITY + ")" 683093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " SELECT " 684093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + PresenceColumns.CONTACT_ID + "," 685093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.PRESENCE + "," 686093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + StatusUpdates.CHAT_CAPABILITY 687aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " FROM " + Tables.PRESENCE 688aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori + " WHERE " 689093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " (ifnull(" + StatusUpdates.PRESENCE + ",0) * 10 " 690093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))" 691093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " = (SELECT " 692093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "MAX (ifnull(" + StatusUpdates.PRESENCE + ",0) * 10 " 693093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))" 694093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " FROM " + Tables.PRESENCE 695093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " WHERE " + PresenceColumns.CONTACT_ID 696093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + "=NEW." + PresenceColumns.CONTACT_ID 697093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + ")" 698093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov + " AND " + PresenceColumns.CONTACT_ID + "=NEW." + PresenceColumns.CONTACT_ID + ";"; 699bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 700bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted" 701bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 702bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 703bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 704bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 705bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov 706bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated" 707bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE 708bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " BEGIN " 709bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + replaceAggregatePresenceSql 710bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov + " END"); 711b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 712b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 713b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 714b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onCreate(SQLiteDatabase db) { 715b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Log.i(TAG, "Bootstrapping database"); 716b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 71735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana mSyncState.createDatabase(db); 71835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana 719b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // One row per group of contacts corresponding to the same person 720d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" + 721b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 722fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 723d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," + 724d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.CUSTOM_RINGTONE + " TEXT," + 725d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 726d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 727d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.LAST_TIME_CONTACTED + " INTEGER," + 728d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 729f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," + 7305870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov Contacts.LOOKUP_KEY + " TEXT," + 731a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)," + 7324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0" + 733b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 734b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 73554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" + 73654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov Contacts.HAS_PHONE_NUMBER + 73754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 73854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 73954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX contacts_restricted_index ON " + Tables.CONTACTS + " (" + 74054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ContactsColumns.SINGLE_IS_RESTRICTED + 74154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 74254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 743fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 744fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 745fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 746fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 747b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Contacts table 7485ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" + 7496cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 7506cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," + 7516cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 7526cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 7536cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SOURCE_ID + " TEXT," + 75497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov RawContacts.RAW_CONTACT_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 7556cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," + 75673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 75733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," + 75854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," + 7596cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " + 7606cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.AGGREGATION_MODE_DEFAULT + "," + 7618e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," + 7626cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + " TEXT," + 7636cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," + 7646cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," + 7656cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov RawContacts.LAST_TIME_CONTACTED + " INTEGER," + 76633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," + 7675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," + 7685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," + 7695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " + 77025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov DisplayNameSources.UNDEFINED + "," + 7715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + " TEXT," + 7725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + " TEXT," + 773de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " + 774de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 775de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " + 776de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," + 777f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," + 7783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC1 + " TEXT, " + 7793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC2 + " TEXT, " + 7803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC3 + " TEXT, " + 7813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov RawContacts.SYNC4 + " TEXT " + 782b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 783b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 78454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" + 78554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov RawContacts.CONTACT_ID + 78654d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov ");"); 78754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov 7885f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" + 7895f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.SOURCE_ID + ", " + 7905f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + ", " + 7915f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + 7925f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 7935f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 794f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // TODO readd the index and investigate a controlled use of it 795f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" + 796f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// RawContactsColumns.AGGREGATION_NEEDED + 797f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov// ");"); 7988e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov 799b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Package name mapping table 800ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" + 801ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 802ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey PackagesColumns.PACKAGE + " TEXT NOT NULL" + 803b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 804b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 805ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Mimetype mapping table 806ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" + 807ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 808ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey MimetypesColumns.MIMETYPE + " TEXT NOT NULL" + 809b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 810b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 81108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov // Mimetype table requires an index on mime type 81208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX mime_type ON " + Tables.MIMETYPES + " (" + 81308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov MimetypesColumns.MIMETYPE + 81408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov ");"); 81508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 816b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Public generic data table 817b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.DATA + " (" + 818b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 81967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 820b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 82111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 82297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Data.IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 823f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 824f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," + 825f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," + 826f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA1 + " TEXT," + 827f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA2 + " TEXT," + 828f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA3 + " TEXT," + 829f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA4 + " TEXT," + 830f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA5 + " TEXT," + 831f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA6 + " TEXT," + 832f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA7 + " TEXT," + 833f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA8 + " TEXT," + 834f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana Data.DATA9 + " TEXT," + 83567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA10 + " TEXT," + 83667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA11 + " TEXT," + 83767dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA12 + " TEXT," + 83867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA13 + " TEXT," + 83967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Data.DATA14 + " TEXT," + 8403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.DATA15 + " TEXT," + 8413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC1 + " TEXT, " + 8423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC2 + " TEXT, " + 8433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC3 + " TEXT, " + 8443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Data.SYNC4 + " TEXT " + 845b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 846b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 84711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" + 84811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov Data.RAW_CONTACT_ID + 84911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 85011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 85111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov /** 85211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov * For email lookup and similar queries. 85311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov */ 854f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" + 85511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov DataColumns.MIMETYPE_ID + "," + 856f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov Data.DATA1 + 85711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov ");"); 85811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov 859b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Private phone numbers table used for lookup 860b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 861f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.DATA_ID 862892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 8635ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 8645ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 86536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 86636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 867b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 868b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 869b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 870f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 871f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 872b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey PhoneLookupColumns.DATA_ID + 873b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 874b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 87536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 87636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 87736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 87836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 87936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 88036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 881d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_data_id_min_match_index ON " + Tables.PHONE_LOOKUP + 882d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov " (" + PhoneLookupColumns.DATA_ID + ", " + PhoneLookupColumns.MIN_MATCH + ");"); 883d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov 884a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov // Private name/nickname table used for lookup 885a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" + 88614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.DATA_ID 88714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 8885ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID 8895ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 89011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," + 89111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," + 89214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov "PRIMARY KEY (" 89314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov + NameLookupColumns.DATA_ID + ", " 89411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + ", " 89511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + ")" + 896a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov ");"); 897a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov 89814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" + 89914bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + 90014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov ");"); 90114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov 902b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" + 903b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + " TEXT," + 904b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + " TEXT" + 905b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 906b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 907b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" + 908b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.NAME + ", " + 909b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov NicknameLookupColumns.CLUSTER + 910b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov ");"); 911b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 912ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey // Groups table 913ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" + 914ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 91567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 916035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " + 917035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " + 918ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.SOURCE_ID + " TEXT," + 9199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," + 92073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," + 921ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey Groups.TITLE + " TEXT," + 92267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey Groups.TITLE_RES + " INTEGER," + 9230f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.NOTES + " TEXT," + 9240f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov Groups.SYSTEM_ID + " TEXT," + 92594021b213e4db367f60b30fcbfe9019e28571784Fred Quintana Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," + 926eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 927ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," + 928dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0," + 929dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0," + 930c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," + 9313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC1 + " TEXT, " + 9323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC2 + " TEXT, " + 9333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC3 + " TEXT, " + 9343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov Groups.SYNC4 + " TEXT " + 935ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey ");"); 936ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 9375f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" + 9385f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.SOURCE_ID + ", " + 9395f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_TYPE + ", " + 9405f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov Groups.ACCOUNT_NAME + 9415f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov ");"); 9425f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov 943b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" + 944b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 945b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov AggregationExceptions.TYPE + " INTEGER NOT NULL, " + 9460c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 9475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id), " + 9480c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 9495ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id)" + 950b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank ");"); 951b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 952b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " + 953b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 9540c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + ", " + 9550c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + 956b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 957b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 958b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " + 959b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov Tables.AGGREGATION_EXCEPTIONS + " (" + 9600c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID2 + ", " + 9610c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov AggregationExceptions.RAW_CONTACT_ID1 + 962b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov ");"); 963b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov 964eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" + 965eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_NAME + " STRING NOT NULL," + 966eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.ACCOUNT_TYPE + " STRING NOT NULL," + 967eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," + 968eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1, " + 969eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey "PRIMARY KEY (" + Settings.ACCOUNT_NAME + ", " + 970e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey Settings.ACCOUNT_TYPE + ") ON CONFLICT REPLACE" + 971eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey ");"); 972eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey 9734394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 9744394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 9754394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 9764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 977385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 978385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 979385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 980385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 981e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // The table for recent calls is here so we can do table joins 982e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov // on people, phones, and calls all in one place. 983e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.CALLS + " (" + 984e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 985e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NUMBER + " TEXT," + 986e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DATE + " INTEGER," + 987e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.DURATION + " INTEGER," + 988e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.TYPE + " INTEGER," + 989e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.NEW + " INTEGER," + 990e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NAME + " TEXT," + 991e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov Calls.CACHED_NUMBER_TYPE + " INTEGER," + 9922530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.CACHED_NUMBER_LABEL + " TEXT," + 9932530512f639c4979fd7371c7dd25dd67e8118124Bai Tao Calls.COUNTRY_ISO + " TEXT" + ");"); 994e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov 995b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Activities table 996b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" + 997b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 99867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," + 999b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," + 1000b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.RAW_ID + " TEXT," + 1001499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.IN_REPLY_TO + " TEXT," + 10025ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.AUTHOR_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 10035ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," + 1004b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.PUBLISHED + " INTEGER NOT NULL," + 1005499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," + 1006b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.TITLE + " TEXT NOT NULL," + 1007b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.SUMMARY + " TEXT," + 1008adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov Activities.LINK + " TEXT, " + 1009b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey Activities.THUMBNAIL + " BLOB" + 1010b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey ");"); 1011b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1012a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" + 1013a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," + 10140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS + " TEXT," + 10150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_TIMESTAMP + " INTEGER," + 10160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " + 10170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_LABEL + " INTEGER, " + 10180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov StatusUpdates.STATUS_ICON + " INTEGER" + 1019a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov ");"); 1020a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov 1021b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" + 1022b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " + 1023b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_VALUE + " TEXT " + 1024b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 1025b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 1026743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" + 1027743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_NAME + " TEXT, " + 1028743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov RawContacts.ACCOUNT_TYPE + " TEXT " + 1029743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov ");"); 1030743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 1031743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // Allow contacts without any account to be created for now. Achieve that 1032743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // by inserting a fake account with both type and name as NULL. 1033743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // This "account" should be eliminated as soon as the first real writable account 1034743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov // is added to the phone. 1035743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov db.execSQL("INSERT INTO accounts VALUES(NULL, NULL)"); 1036743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 1037d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 1038d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1039a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createContactsViews(db); 1040a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov createGroupsView(db); 1041fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov createContactsTriggers(db); 1042916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 10434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 1044a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov loadNicknameLookupTable(db); 1045a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1046a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov // Add the legacy API support views, etc 1047a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov LegacyApiSupport.createDatabase(db); 1048a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 10492a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov if (mDatabaseOptimizationEnabled) { 10502a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov // This will create a sqlite_stat1 table that is used for query optimization 10512a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov db.execSQL("ANALYZE;"); 1052a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 10532a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov updateSqliteStats(db); 1054a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 10552a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov // We need to close and reopen the database connection so that the stats are 10562a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov // taken into account. Make a note of it and do the actual reopening in the 10572a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov // getWritableDatabase method. 10582a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov mReopenDatabase = true; 10592a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 1060a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1061a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContentResolver.requestSync(null /* all accounts */, 1062a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov ContactsContract.AUTHORITY, new Bundle()); 1063a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1064a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1065d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void createDirectoriesTable(SQLiteDatabase db) { 1066d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DIRECTORIES + "(" + 1067d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 1068d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.PACKAGE_NAME + " TEXT NOT NULL," + 1069d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DIRECTORY_AUTHORITY + " TEXT NOT NULL," + 1070d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.TYPE_RESOURCE_ID + " INTEGER," + 1071e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov DirectoryColumns.TYPE_RESOURCE_NAME + " TEXT," + 1072d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_TYPE + " TEXT," + 1073d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.ACCOUNT_NAME + " TEXT," + 1074d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.DISPLAY_NAME + " TEXT, " + 1075d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov Directory.EXPORT_SUPPORT + " INTEGER NOT NULL" + 107697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov " DEFAULT " + Directory.EXPORT_SUPPORT_NONE + "," + 107797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov Directory.SHORTCUT_SUPPORT + " INTEGER NOT NULL" + 10783d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.SHORTCUT_SUPPORT_NONE + "," + 10793d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Directory.PHOTO_SUPPORT + " INTEGER NOT NULL" + 10803d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov " DEFAULT " + Directory.PHOTO_SUPPORT_NONE + 1081d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov ");"); 1082d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 10833d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov // Trigger a full scan of directories in the system 10843d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(db, ContactDirectoryManager.PROPERTY_DIRECTORY_SCAN_COMPLETE, "0"); 1085d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1086d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 1087916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsTriggers(SQLiteDatabase db) { 1088fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1089fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1090fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Automatically delete Data rows when a raw contact is deleted. 1091fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1092fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;"); 1093fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted " 1094fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEFORE DELETE ON " + Tables.RAW_CONTACTS 1095fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1096fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.DATA 1097fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data.RAW_CONTACT_ID 1098fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 1099fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS 1100fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 1101fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID 1102fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " OR " + AggregationExceptions.RAW_CONTACT_ID2 1103fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + "=OLD." + RawContacts._ID + ";" 110435da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " DELETE FROM " + Tables.VISIBLE_CONTACTS 110535da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 110635da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 110735da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 110835da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov + " )=1;" 1109385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " DELETE FROM " + Tables.DEFAULT_DIRECTORY 1110385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1111385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1112385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1113385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + " )=1;" 1114fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.CONTACTS 1115fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID 1116fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS 1117fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID 1118fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " )=1;" 1119fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1120fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1121fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1122fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;"); 11236c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;"); 1124fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1125fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov /* 1126fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * Triggers that update {@link RawContacts#VERSION} when the contact is 1127fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * marked for deletion or any time a data row is inserted, updated or 1128fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov * deleted. 1129fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov */ 1130fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;"); 1131fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted " 11327f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.RAW_CONTACTS 1133fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1134fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1135fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1136fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 " 1137fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID 1138fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";" 1139fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1140fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1141fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;"); 11427f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA 1143fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1144fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.DATA 1145fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 " 1146fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Data._ID + "=OLD." + Data._ID + ";" 1147fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1148fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1149fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1150fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1151fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1152fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;"); 1153fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA 1154fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1155fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.RAW_CONTACTS 1156fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 " 1157fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";" 1158fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.PHONE_LOOKUP 1159fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1160fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.STATUS_UPDATES 1161fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";" 1162fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " DELETE FROM " + Tables.NAME_LOOKUP 1163fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";" 1164fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1165fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1166fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1167fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;"); 1168fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 " 11697f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori + " AFTER UPDATE ON " + Tables.GROUPS 1170fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " BEGIN " 1171fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " UPDATE " + Tables.GROUPS 1172fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " SET " 1173fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + Groups.VERSION + "=OLD." + Groups.VERSION + "+1" 1174fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " WHERE " + Groups._ID + "=OLD." + Groups._ID + ";" 1175fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov + " END"); 1176fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1177fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 1178916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov private static void createContactsIndexes(SQLiteDatabase db) { 1179916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 1180916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" + 1181916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NORMALIZED_NAME + "," + 1182916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.NAME_TYPE + ", " + 1183916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.RAW_CONTACT_ID + ", " + 1184916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov NameLookupColumns.DATA_ID + 1185916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov ");"); 118604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 118704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index"); 118804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 118904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 119004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 119104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 119204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index"); 119304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 119404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 119504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ");"); 1196916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1197916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1198a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createContactsViews(SQLiteDatabase db) { 1199a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_ALL + ";"); 1200a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS_RESTRICTED + ";"); 1201a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_ALL + ";"); 1202a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_RESTRICTED + ";"); 1203a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_ALL + ";"); 1204a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS_RESTRICTED + ";"); 1205a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES + ";"); 1206a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES_RESTRICTED + ";"); 1207a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES + ";"); 1208a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES_RESTRICTED + ";"); 1209a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataColumns = 12114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov Data.IS_PRIMARY + ", " 12124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.IS_SUPER_PRIMARY + ", " 12134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA_VERSION + ", " 12144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + "," 12154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", " 121697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + Data.IS_READ_ONLY + ", " 12174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA1 + ", " 12184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA2 + ", " 12194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA3 + ", " 12204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA4 + ", " 12214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA5 + ", " 12224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA6 + ", " 12234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA7 + ", " 12244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA8 + ", " 12254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA9 + ", " 12264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA10 + ", " 12274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA11 + ", " 12284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA12 + ", " 12294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA13 + ", " 12304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA14 + ", " 12314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.DATA15 + ", " 12324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC1 + ", " 12334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC2 + ", " 12344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC3 + ", " 12354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.SYNC4; 12364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String syncColumns = 12384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + "," 12394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + "," 12404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + "," 1241f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS " + RawContacts.NAME_VERIFIED + "," 12424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + "," 12434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + "," 12444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + "," 12454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + "," 12464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + "," 12474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4; 12484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12493d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov String baseContactColumns = 12503d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.HAS_PHONE_NUMBER + ", " 12513d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + ", " 12523d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.LOOKUP_KEY + ", " 12533d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Contacts.PHOTO_ID + ", " 12543d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + Clauses.CONTACT_VISIBLE + " AS " + Contacts.IN_VISIBLE_GROUP + ", " 12553d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + ContactsColumns.LAST_STATUS_UPDATE_ID; 12563d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 12574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactOptionColumns = 12584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 12594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.CUSTOM_RINGTONE + "," 12604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 12614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.SEND_TO_VOICEMAIL + "," 12624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 12634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.LAST_TIME_CONTACTED + "," 12644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 12654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.TIMES_CONTACTED + "," 12664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 12674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + RawContacts.STARRED; 12684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 12695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String contactNameColumns = 12705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE 12715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", " 12725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY 12735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", " 12745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE 12755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", " 12765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME 12775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME + ", " 12785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE 12795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.PHONETIC_NAME_STYLE + ", " 12805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY 12815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_PRIMARY + ", " 12825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE 12834394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov + " AS " + Contacts.SORT_KEY_ALTERNATIVE; 12845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 12854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String dataSelect = "SELECT " 12864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Data._ID + "," 12874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Data.RAW_CONTACT_ID + ", " 1288fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 12894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns + ", " 12904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + dataColumns + ", " 12914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + contactOptionColumns + ", " 12925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 12933d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 12943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12953d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 12963d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 12973d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 12984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 12994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.DATA 1300a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.MIMETYPES + " ON (" 13014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1302a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " ON (" 13034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1304a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1305fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1306fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1307fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1308a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1309a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 13104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 13114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1312f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1313a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 13144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_ALL + " AS " + dataSelect); 13164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.DATA_RESTRICTED + " AS " + dataSelect + " WHERE " 1317fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 13184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactOptionColumns = 13204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov RawContacts.CUSTOM_RINGTONE + "," 13214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.SEND_TO_VOICEMAIL + "," 13224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.LAST_TIME_CONTACTED + "," 13234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.TIMES_CONTACTED + "," 13244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.STARRED; 13254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String rawContactsSelect = "SELECT " 13274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + "," 13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.AGGREGATION_MODE + ", " 133097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + RawContacts.RAW_CONTACT_IS_READ_ONLY + ", " 13314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + RawContacts.DELETED + ", " 13325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + ", " 13335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_PRIMARY + ", " 13345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_ALTERNATIVE + ", " 13355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME + ", " 13365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.PHONETIC_NAME_STYLE + ", " 13375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_PRIMARY + ", " 13385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.SORT_KEY_ALTERNATIVE + ", " 13394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + rawContactOptionColumns + ", " 13404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + syncColumns 13414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS; 13424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_ALL + " AS " + rawContactsSelect); 13444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS_RESTRICTED + " AS " + rawContactsSelect 13454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 13464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsColumns = 13484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov ContactsColumns.CONCRETE_CUSTOM_RINGTONE 13494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.CUSTOM_RINGTONE + ", " 13505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + contactNameColumns + ", " 13513d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + baseContactColumns + ", " 13524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED 13534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.LAST_TIME_CONTACTED + ", " 13544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL 13554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.SEND_TO_VOICEMAIL + ", " 13564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_STARRED 13574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " AS " + Contacts.STARRED + ", " 13584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_TIMES_CONTACTED 13593d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + " AS " + Contacts.TIMES_CONTACTED; 13604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov String contactsSelect = "SELECT " 13624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + "," 13633d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + contactsColumns + ", " 13643d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_URI) + ", " 13653d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_THUMBNAIL_URI) 13664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov + " FROM " + Tables.CONTACTS 1367fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1368fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"; 13694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 13704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_ALL + " AS " + contactsSelect); 1371fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE VIEW " + Views.CONTACTS_RESTRICTED + " AS " + contactsSelect 1372fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " WHERE " + ContactsColumns.SINGLE_IS_RESTRICTED + "=0"); 1373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String rawEntitiesSelect = "SELECT " 1375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.CONTACT_ID + ", " 1376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1380a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1381a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1383a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", " 1384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + "," 1385a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + "," 1386a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED + " AS " 1387a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContacts.IS_RESTRICTED + "," 1388a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1389a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1390a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1391a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1392a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1393a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1394a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1395a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1396a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1397a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1398a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1399a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1400a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES + " AS " 1402a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect); 1403a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES_RESTRICTED + " AS " 1404a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + rawEntitiesSelect + " WHERE " + RawContacts.IS_RESTRICTED + "=0"); 1405a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1406a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov String entitiesSelect = "SELECT " 1407a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + Contacts._ID + ", " 1408a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", " 1409a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + "," 1410a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_IS_RESTRICTED 1411a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " AS " + RawContacts.IS_RESTRICTED + "," 1412a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + dataColumns + ", " 1413a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + syncColumns + ", " 1414a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + contactsColumns + ", " 14153d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 14163d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_URI) + ", " 14173d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov + buildPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID, 14183d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov Contacts.PHOTO_THUMBNAIL_URI) + ", " 1419a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC1 + ", " 1420a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC2 + ", " 1421a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC3 + ", " 1422a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Data.SYNC4 + ", " 1423a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_ID + " AS " + Contacts.Entity.RAW_CONTACT_ID + ", " 1424a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_ID + " AS " + Contacts.Entity.DATA_ID + "," 1425a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID 1426a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " FROM " + Tables.RAW_CONTACTS 1427a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.CONTACTS + " ON (" 1428a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")" 1429a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON(" 1430a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")" 1431a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.DATA + " ON (" 1432a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")" 1433a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON (" 1434a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")" 1435a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON (" 1436a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")" 1437a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + " LEFT OUTER JOIN " + Tables.GROUPS + " ON (" 1438a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE 1439a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + "' AND " + GroupsColumns.CONCRETE_ID + "=" 1440a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")"; 1441a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1442a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES + " AS " 1443a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect); 1444a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.ENTITIES_RESTRICTED + " AS " 1445a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov + entitiesSelect + " WHERE " + RawContactsColumns.CONCRETE_IS_RESTRICTED + "=0"); 1446a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 14474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 14483d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private static String buildPhotoUriAlias(String contactIdColumn, String alias) { 14492b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov return "(CASE WHEN " + Contacts.PHOTO_ID + " IS NULL" 14502b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " OR " + Contacts.PHOTO_ID + "=0" 14512b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " THEN NULL" 14522b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " ELSE " + "'" + Contacts.CONTENT_URI + "/'||" 14532b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + contactIdColumn + "|| '/" + Photo.CONTENT_DIRECTORY + "'" 14542b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " END)" 14552b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov + " AS " + alias; 14563d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 14573d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 1458a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov private static void createGroupsView(SQLiteDatabase db) { 1459a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS_ALL + ";"); 146089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsColumns = 146189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov Groups.ACCOUNT_NAME + "," 146289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.ACCOUNT_TYPE + "," 146389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SOURCE_ID + "," 146489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.VERSION + "," 146589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DIRTY + "," 146689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE + "," 146789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.TITLE_RES + "," 146889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.NOTES + "," 146989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYSTEM_ID + "," 147089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.DELETED + "," 147189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.GROUP_VISIBLE + "," 147289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SHOULD_SYNC + "," 1473dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.AUTO_ADD + "," 1474dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + Groups.FAVORITES + "," 1475c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov + Groups.GROUP_IS_READ_ONLY + "," 147689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC1 + "," 147789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC2 + "," 147889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC3 + "," 147989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + Groups.SYNC4 + "," 148089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE; 148189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 148289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov String groupsSelect = "SELECT " 148389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + "," 148489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + groupsColumns 148589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov + " FROM " + Tables.GROUPS_JOIN_PACKAGES; 148689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 148789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov db.execSQL("CREATE VIEW " + Views.GROUPS_ALL + " AS " + groupsSelect); 1488b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1489b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 1490b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey @Override 1491b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 149246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion < 99) { 149346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion 149446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana + ", data will be lost!"); 149546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 149646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";"); 149746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";"); 149846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";"); 149946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";"); 150046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";"); 150146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";"); 150246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";"); 150346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";"); 150446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";"); 150546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";"); 150646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";"); 150746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";"); 150846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";"); 150946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 151046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // TODO: we should not be dropping agg_exceptions and contact_options. In case that 151146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // table's schema changes, we should try to preserve the data, because it was entered 151246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana // by the user and has never been synched to the server. 151346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";"); 151446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 151546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana onCreate(db); 151646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana return; 151746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1518f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 151946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion); 1520a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 152108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov boolean upgradeViewsAndTriggers = false; 152204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov boolean upgradeNameLookup = false; 15238d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov boolean upgradeLegacyApiSupport = false; 152408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 152546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion == 99) { 152608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 152746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana oldVersion++; 152846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 152946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana 1530a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov if (oldVersion == 100) { 1531a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON " 1532a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + Tables.MIMETYPES + " (" 1533a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns.MIMETYPE + "," 1534a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov + MimetypesColumns._ID + ");"); 1535a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov updateIndexStats(db, Tables.MIMETYPES, 1536a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov "mimetypes_mimetype_index", "50 1 1"); 1537a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 153808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1539a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov oldVersion++; 1540a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov } 1541a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov 1542fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov if (oldVersion == 101) { 154308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1544fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov oldVersion++; 1545fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov } 1546fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov 154747ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov if (oldVersion == 102) { 154808e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 154947ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov oldVersion++; 155047ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov } 155147ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov 155236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (oldVersion == 103) { 155308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1554bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey oldVersion++; 1555bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey } 1556bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey 155771037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 104 || oldVersion == 201) { 155871037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov LegacyApiSupport.createSettingsTable(db); 155908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15603410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion++; 15613410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov } 15623410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov 156371037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov if (oldVersion == 105) { 15645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion202(db); 156504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov upgradeNameLookup = true; 15663410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov oldVersion = 202; 156736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 156836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 1569fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov if (oldVersion == 202) { 15705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion203(db); 157108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 1572fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov oldVersion++; 1573fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1574fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 15759b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori if (oldVersion == 203) { 157608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15779b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori oldVersion++; 15789b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori } 15799b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori 15805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (oldVersion == 204) { 15815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeToVersion205(db); 158208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov upgradeViewsAndTriggers = true; 15835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov oldVersion++; 15845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 15855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 1586f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov if (oldVersion == 205) { 1587f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgrateToVersion206(db); 1588f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov upgradeViewsAndTriggers = true; 1589f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov oldVersion++; 1590f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 1591f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 159231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (oldVersion == 206) { 1593b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeToVersion300(db); 159434469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov oldVersion = 300; 159531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 159631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 15976c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook if (oldVersion == 300) { 15986c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook upgradeViewsAndTriggers = true; 15996c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook oldVersion = 301; 16006c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook } 16016c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook 1602916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov if (oldVersion == 301) { 1603916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov upgradeViewsAndTriggers = true; 1604916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov oldVersion = 302; 1605916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov } 1606916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov 1607b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (oldVersion == 302) { 1608b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeEmailToVersion303(db); 1609b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov upgradeNicknameToVersion303(db); 1610b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov oldVersion = 303; 1611b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 1612b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 161308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (oldVersion == 303) { 161408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov upgradeToVersion304(db); 161508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov oldVersion = 304; 161608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 161708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 1618f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee if (oldVersion == 304) { 1619f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee upgradeNameLookup = true; 1620f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee oldVersion = 305; 1621f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee } 1622f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee 162360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (oldVersion == 305) { 162460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann upgradeToVersion306(db); 162560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann oldVersion = 306; 162660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 162760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 1628b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (oldVersion == 306) { 1629b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov upgradeToVersion307(db); 1630b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov oldVersion = 307; 1631b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 1632b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 1633743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov if (oldVersion == 307) { 1634743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov upgradeToVersion308(db); 1635743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov oldVersion = 308; 1636743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 1637743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 163894c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov // Gingerbread upgrades 163994c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion < 350) { 1640afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann upgradeViewsAndTriggers = true; 164194c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 351; 1642afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann } 1643afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann 164494c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov if (oldVersion == 351) { 164594c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov upgradeNameLookup = true; 164694c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov oldVersion = 352; 164780d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann } 164880d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann 16497da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov if (oldVersion == 352) { 16507da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov upgradeToVersion353(db); 16517da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov oldVersion = 353; 16527da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 16537da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 1654f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov // Honeycomb upgrades 1655f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion < 400) { 1656dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana upgradeViewsAndTriggers = true; 1657f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov upgradeToVersion400(db); 1658f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov oldVersion = 400; 1659dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 1660dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 1661f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov if (oldVersion == 400) { 16624394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeViewsAndTriggers = true; 16634394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov upgradeToVersion401(db); 16644394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov oldVersion = 401; 16654394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 16664394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 1667d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov if (oldVersion == 401) { 1668d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov upgradeToVersion402(db); 1669d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov oldVersion = 402; 1670d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 1671d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 167297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov if (oldVersion == 402) { 167397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeViewsAndTriggers = true; 167497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov upgradeToVersion403(db); 167597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov oldVersion = 403; 167697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 167797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 1678a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov if (oldVersion == 403) { 1679a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov upgradeViewsAndTriggers = true; 1680a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov oldVersion = 404; 1681a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 1682a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 1683892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (oldVersion == 404) { 1684892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeViewsAndTriggers = true; 1685892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov upgradeToVersion405(db); 1686892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov oldVersion = 405; 1687892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 1688892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 16892530512f639c4979fd7371c7dd25dd67e8118124Bai Tao if (oldVersion == 405) { 16902530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeViewsAndTriggers = true; 16912530512f639c4979fd7371c7dd25dd67e8118124Bai Tao upgradeToVersion406(db); 16922530512f639c4979fd7371c7dd25dd67e8118124Bai Tao oldVersion = 406; 16932530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 16942530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 1695cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov if (oldVersion == 406) { 1696cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov upgradeViewsAndTriggers = true; 1697cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov oldVersion = 407; 1698cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov } 1699cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov 1700385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov if (oldVersion == 407) { 1701d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Obsolete 1702385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov oldVersion = 408; 1703385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 1704385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 17053d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov if (oldVersion == 408) { 17063d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeViewsAndTriggers = true; 17073d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov upgradeToVersion409(db); 17083d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov oldVersion = 409; 17093d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 17103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 17112b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov if (oldVersion == 409) { 17122b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov upgradeViewsAndTriggers = true; 17132b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov oldVersion = 410; 17142b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov } 17152b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov 1716d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov if (oldVersion == 410) { 1717d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov upgradeToVersion411(db); 1718d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov oldVersion = 411; 1719d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 1720d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 17217da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov if (oldVersion == 411) { 17227da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov // Same upgrade as 353, only on Honeycomb devices 17237da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov upgradeToVersion353(db); 17247da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov oldVersion = 412; 17257da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 17267da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 1727e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov if (oldVersion == 412) { 1728e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov upgradeToVersion413(db); 1729e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov oldVersion = 413; 1730e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 1731e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 173256f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee if (oldVersion == 413) { 173356f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee upgradeNameLookup = true; 173456f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee oldVersion = 414; 173556f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee } 173656f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee 1737c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov if (oldVersion == 414) { 1738c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov upgradeToVersion415(db); 1739c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov upgradeViewsAndTriggers = true; 1740c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov oldVersion = 415; 1741c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov } 1742c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov 1743d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov if (oldVersion == 415) { 1744d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov upgradeToVersion416(db); 1745d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov oldVersion = 416; 1746d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov } 1747d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov 17488d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov if (oldVersion == 416) { 17498d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov upgradeLegacyApiSupport = true; 17508d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov oldVersion = 417; 17518d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov } 17528d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov 175308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov if (upgradeViewsAndTriggers) { 175408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsViews(db); 175508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createGroupsView(db); 175608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov createContactsTriggers(db); 1757916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov createContactsIndexes(db); 1758916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov updateSqliteStats(db); 17598d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov upgradeLegacyApiSupport = true; 1760916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov mReopenDatabase = true; 176108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov } 176208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov 17638d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov if (upgradeLegacyApiSupport) { 17648d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov LegacyApiSupport.createViews(db); 17658d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov } 17668d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov 176704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (upgradeNameLookup) { 176804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rebuildNameLookup(db); 176904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 177004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 177146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana if (oldVersion != newVersion) { 177246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana throw new IllegalStateException( 177346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana "error upgrading the database to version " + newVersion); 177446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana } 1775b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 1776b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 17775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion202(SQLiteDatabase db) { 177836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL( 177936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "ALTER TABLE " + Tables.PHONE_LOOKUP + 178036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;"); 178136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 178236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 178336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 178436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 178536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 178636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov ");"); 178736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 178836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 178936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 179036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 179136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov SQLiteStatement update = db.compileStatement( 179236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "UPDATE " + Tables.PHONE_LOOKUP + 179336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " SET " + PhoneLookupColumns.MIN_MATCH + "=?" + 179436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " WHERE " + PhoneLookupColumns.DATA_ID + "=?"); 179536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 179636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov // Populate the new column 179736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA + 179836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")", 179936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null); 180036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov try { 180136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov while (c.moveToNext()) { 180236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov long dataId = c.getLong(0); 180336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov String number = c.getString(1); 180436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov if (!TextUtils.isEmpty(number)) { 180536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number)); 180636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.bindLong(2, dataId); 180736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov update.execute(); 180836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 180936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 181036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } finally { 181136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov c.close(); 181236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 181336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 181436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 18155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion203(SQLiteDatabase db) { 1816758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // Garbage-collect first. A bug in Eclair was sometimes leaving 1817758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // raw_contacts in the database that no longer had contacts associated 1818758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // with them. To avoid failures during this database upgrade, drop 1819758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov // the orphaned raw_contacts. 1820758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov db.execSQL( 1821758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov "DELETE FROM raw_contacts" + 1822758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " WHERE contact_id NOT NULL" + 1823758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov " AND contact_id NOT IN (SELECT _id FROM contacts)"); 1824758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov 1825fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1826fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.CONTACTS + 1827fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)"); 1828fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1829fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "ALTER TABLE " + Tables.RAW_CONTACTS + 18304394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " ADD contact_in_visible_group INTEGER NOT NULL DEFAULT 0"); 1831fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1832fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // For each Contact, find the RawContact that contributed the display name 1833fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1834fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1835fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1836fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1837fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1838fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1839fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" + 1840fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Tables.CONTACTS + "." + Contacts.DISPLAY_NAME + 1841fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1842fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" 1843fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1844fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1845fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" + 1846fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.NAME_RAW_CONTACT_ID + 1847fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1848fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1849fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // If for some unknown reason we missed some names, let's make sure there are 1850fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // no contacts without a name, picking a raw contact "at random". 1851fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1852fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1853fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" + 1854fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SELECT " + RawContacts._ID + 1855fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 1856fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + 1857fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " ORDER BY " + RawContacts._ID + 1858fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " LIMIT 1)" + 1859fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL" 1860fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1861fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1862fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use. 1863fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1864fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.CONTACTS + 1865fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " SET " + Contacts.DISPLAY_NAME + "=NULL" 1866fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1867fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1868fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow 1869fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov // indexing on (display_name, in_visible_group) 1870fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL( 1871fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 18724394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SET contact_in_visible_group=(" + 1873fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov "SELECT " + Contacts.IN_VISIBLE_GROUP + 1874fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov " FROM " + Tables.CONTACTS + 1875bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" + 1876bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " NOT NULL" 1877fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ); 1878fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1879fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 18804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 1881fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" + 1882fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1883fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 1884fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 1885fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" + 1886fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov Contacts.IN_VISIBLE_GROUP + 1887fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov ");"); 1888fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov } 1889fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 18905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeToVersion205(SQLiteDatabase db) { 18915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;"); 18935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;"); 18955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 18965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;"); 18975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1898de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_PRIMARY 1899de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 19005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 1901de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE 1902de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";"); 19035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov final Locale locale = Locale.getDefault(); 19055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 190651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov NameSplitter splitter = createNameSplitter(); 19075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate = db.compileStatement( 19095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 19105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 19115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 19125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 19135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 19145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 19155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 19165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 19175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 19185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter); 19205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter); 19215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 19235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" + 19244394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 19255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + 19265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 19275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" + 19294394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "contact_in_visible_group" + "," + 19305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + 19315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov ");"); 19325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface StructName205Query { 19355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 19365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 19385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 19395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 19405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE, 19415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY, 19425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PREFIX, 19435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.GIVEN_NAME, 19445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.MIDDLE_NAME, 19455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FAMILY_NAME, 19465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.SUFFIX, 19475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_FAMILY_NAME, 19485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_MIDDLE_NAME, 19495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_GIVEN_NAME, 19505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 19515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 19535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 19545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME_SOURCE = 2; 19555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int DISPLAY_NAME = 3; 19565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PREFIX = 4; 19575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int GIVEN_NAME = 5; 19585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int MIDDLE_NAME = 6; 19595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int FAMILY_NAME = 7; 19605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int SUFFIX = 8; 19615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_FAMILY_NAME = 9; 19625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_MIDDLE_NAME = 10; 19635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_GIVEN_NAME = 11; 19645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeStructuredNamesToVersion205(SQLiteDatabase db, 19675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 19685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // Process structured names to detect the style of the full name and phonetic name 19705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long mMimeType; 19725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 19735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov mMimeType = DatabaseUtils.longForQuery(db, 19745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 19755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 19765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 19775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null); 19785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } catch (SQLiteDoneException e) { 19795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov // No structured names in the database 19805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov return; 19815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 19825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate = db.compileStatement( 19845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 19855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 19865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.FULL_NAME_STYLE + "=?," + 19875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.DISPLAY_NAME + "=?," + 19885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructuredName.PHONETIC_NAME_STYLE + "=?" + 19895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 19905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 19915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter.Name name = new NameSplitter.Name(); 19925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 19935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(StructName205Query.TABLE, 19945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov StructName205Query.COLUMNS, 19955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null); 19965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 19975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 19985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(StructName205Query.ID); 19995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID); 20005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE); 20015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = cursor.getString(StructName205Query.DISPLAY_NAME); 20025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.clear(); 20045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.prefix = cursor.getString(StructName205Query.PREFIX); 20055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME); 20065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME); 20075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.familyName = cursor.getString(StructName205Query.FAMILY_NAME); 20085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.suffix = cursor.getString(StructName205Query.SUFFIX); 20095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME); 20105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME); 20115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME); 20125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name, 20145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate, rawContactUpdate, splitter, sb); 20155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 20175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 20185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource, 20225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String currentDisplayName, NameSplitter.Name name, 20235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate, 20245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov NameSplitter splitter, StringBuilder sb) { 20255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov splitter.guessNameStyle(name); 2027ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao int unadjustedFullNameStyle = name.fullNameStyle; 20285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle); 20295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName = splitter.join(name, true); 20305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2031ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // Don't update database with the adjusted fullNameStyle as it is locale 2032ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao // related 2033ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao structuredNameUpdate.bindLong(1, unadjustedFullNameStyle); 20345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName); 20355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(3, name.phoneticNameStyle); 20365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.bindLong(4, dataId); 20375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov structuredNameUpdate.execute(); 20385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) { 20405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayNameAlternative = splitter.join(name, false); 20415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = splitter.joinPhoneticName(name); 20425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 20435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKeyAlternative = null; 20445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName != null) { 20465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = sortKeyAlternative = phoneticName; 2047ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao } else if (name.fullNameStyle == FullNameStyle.CHINESE || 2048ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao name.fullNameStyle == FullNameStyle.CJK) { 2049ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = sortKeyAlternative = ContactLocaleUtils.getIntance() 2050ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(displayName, name.fullNameStyle); 20515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 20545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = displayName; 20555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative = displayNameAlternative; 20565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, displayName, 20595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey, 20605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKeyAlternative); 20615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private interface Organization205Query { 20655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String TABLE = Tables.DATA_JOIN_RAW_CONTACTS; 20665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String COLUMNS[] = { 20685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov DataColumns.CONCRETE_ID, 20695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Data.RAW_CONTACT_ID, 20705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.COMPANY, 20715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME, 20725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov }; 20735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int ID = 0; 20755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int RAW_CONTACT_ID = 1; 20765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int COMPANY = 2; 20775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int PHONETIC_NAME = 3; 20785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 20795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void upgradeOrganizationsToVersion205(SQLiteDatabase db, 20815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement rawContactUpdate, NameSplitter splitter) { 2082b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 20835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov SQLiteStatement organizationUpdate = db.compileStatement( 20855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov "UPDATE " + Tables.DATA + 20865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " SET " + 20875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Organization.PHONETIC_NAME_STYLE + "=?" + 20885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov " WHERE " + Data._ID + "=?"); 20895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 20905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS, 2091b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=" + mimeType + " AND " 20925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION, 20935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov null, null, null, null); 20945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov try { 20955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov while (cursor.moveToNext()) { 20965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long dataId = cursor.getLong(Organization205Query.ID); 20975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID); 20985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String company = cursor.getString(Organization205Query.COMPANY); 20995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME); 21005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName); 21025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(1, phoneticNameStyle); 21045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.bindLong(2, dataId); 21055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov organizationUpdate.execute(); 21065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String sortKey = null; 21085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (phoneticName == null && company != null) { 21095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov int nameStyle = splitter.guessFullNameStyle(company); 21105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov nameStyle = splitter.getAdjustedFullNameStyle(nameStyle); 2111ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao if (nameStyle == FullNameStyle.CHINESE || 2112ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao nameStyle == FullNameStyle.CJK ) { 2113ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao sortKey = ContactLocaleUtils.getIntance() 2114ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao .getSortKey(company, nameStyle); 21155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (sortKey == null) { 21195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov sortKey = company; 21205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov updateRawContact205(rawContactUpdate, rawContactId, company, 21235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov company, phoneticNameStyle, phoneticName, sortKey, sortKey); 21245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } finally { 21265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov cursor.close(); 21275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 21305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId, 21315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String displayName, String displayNameAlternative, int phoneticNameStyle, 21325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String phoneticName, String sortKeyPrimary, String sortKeyAlternative) { 21335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 1, displayName); 21345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 2, displayNameAlternative); 21355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 3, phoneticName); 21365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(4, phoneticNameStyle); 21375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 5, sortKeyPrimary); 21385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov bindString(rawContactUpdate, 6, sortKeyAlternative); 21395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.bindLong(7, rawContactId); 21405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov rawContactUpdate.execute(); 21415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 21425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 2143f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov private void upgrateToVersion206(SQLiteDatabase db) { 2144f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS 2145f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;"); 2146f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov } 2147f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov 214831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov private interface Organization300Query { 214931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String TABLE = Tables.DATA; 215031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 215131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String SELECTION = DataColumns.MIMETYPE_ID + "=?"; 215231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 215331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String COLUMNS[] = { 215431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization._ID, 215531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.RAW_CONTACT_ID, 215631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.COMPANY, 215731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Organization.TITLE 215831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov }; 215931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 216031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int ID = 0; 216131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int RAW_CONTACT_ID = 1; 216231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int COMPANY = 2; 216331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov int TITLE = 3; 216431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 216531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 216631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov /** 216731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * Fix for the bug where name lookup records for organizations would get removed by 216831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov * unrelated updates of the data rows. 216931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov */ 2170b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeToVersion300(SQLiteDatabase db) { 2171b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 2172b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeType == -1) { 217331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov return; 217431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 217531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 217631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov ContentValues values = new ContentValues(); 217731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 217831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Find all data rows with the mime type "organization" 217931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov Cursor cursor = db.query(Organization300Query.TABLE, Organization300Query.COLUMNS, 2180b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Organization300Query.SELECTION, new String[] {String.valueOf(mimeType)}, 218131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov null, null, null); 218231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov try { 218331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov while (cursor.moveToNext()) { 218431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long dataId = cursor.getLong(Organization300Query.ID); 218531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov long rawContactId = cursor.getLong(Organization300Query.RAW_CONTACT_ID); 218631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String company = cursor.getString(Organization300Query.COMPANY); 218731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov String title = cursor.getString(Organization300Query.TITLE); 218831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 218931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // First delete name lookup if there is any (chances are there won't be) 219031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.delete(Tables.NAME_LOOKUP, NameLookupColumns.DATA_ID + "=?", 219131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov new String[]{String.valueOf(dataId)}); 219231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 219331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov // Now insert two name lookup records: one for company name, one for title 219431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 219531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 219631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.ORGANIZATION); 219731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 219831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(company)) { 219931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 220031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(company)); 220131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 220231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 220331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 220431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov if (!TextUtils.isEmpty(title)) { 220531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, 220631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov NameNormalizer.normalize(title)); 220731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 220831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 220931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 221031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } finally { 221131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov cursor.close(); 221231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 221331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov } 221431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov 2215b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private static final class Upgrade303Query { 2216b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String TABLE = Tables.DATA; 2217b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2218b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String SELECTION = 2219b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=?" + 2220b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data._ID + " NOT IN " + 2221b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" + 2222b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov " AND " + Data.DATA1 + " NOT NULL"; 2223b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2224b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final String COLUMNS[] = { 2225b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data._ID, 2226b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.RAW_CONTACT_ID, 2227b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Data.DATA1, 2228b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov }; 2229b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2230b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int ID = 0; 2231b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 2232b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public static final int DATA1 = 2; 2233b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2234b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2235b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2236b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2237b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * emails during the sync. We need to restore the lost name lookup rows. 2238b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2239b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeEmailToVersion303(SQLiteDatabase db) { 2240b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 2241b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2242b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2243b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2244b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2245b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2246b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2247b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "email" that are missing name lookup 2248b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2249b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2250b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2251b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2252b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2253b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2254b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2255b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2256b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov value = extractHandleFromEmailAddress(value); 2257b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2258b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (value != null) { 2259b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2260b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2261b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME); 2262b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2263b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2264b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2265b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2266b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2267b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2268b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2269b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2270b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2271b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov /** 2272b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * The {@link ContactsProvider2#update} method was deleting name lookup for new 2273b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov * nicknames during the sync. We need to restore the lost name lookup rows. 2274b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov */ 2275b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private void upgradeNicknameToVersion303(SQLiteDatabase db) { 2276b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 2277b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (mimeTypeId == -1) { 2278b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return; 2279b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2280b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2281b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov ContentValues values = new ContentValues(); 2282b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2283b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // Find all data rows with the mime type "nickname" that are missing name lookup 2284b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS, 2285b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 2286b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov null, null, null); 2287b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2288b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov while (cursor.moveToNext()) { 2289b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long dataId = cursor.getLong(Upgrade303Query.ID); 2290b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID); 2291b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String value = cursor.getString(Upgrade303Query.DATA1); 2292b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2293b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.DATA_ID, dataId); 2294b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId); 2295b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME); 2296b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value)); 2297b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov db.insert(Tables.NAME_LOOKUP, null, values); 2298b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2299b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } finally { 2300b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov cursor.close(); 2301b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2302b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2303b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 230451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void upgradeToVersion304(SQLiteDatabase db) { 230551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Mimetype table requires an index on mime type 230651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS mime_type ON " + Tables.MIMETYPES + " (" + 230751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov MimetypesColumns.MIMETYPE + 230851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov ");"); 230951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 231051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 231160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann private void upgradeToVersion306(SQLiteDatabase db) { 231260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // Fix invalid lookup that was used for Exchange contacts (it was not escaped) 231360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann // It happened when a new contact was created AND synchronized 231460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final StringBuilder lookupKeyBuilder = new StringBuilder(); 231560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final SQLiteStatement updateStatement = db.compileStatement( 231660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "UPDATE contacts " + 231760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SET lookup=? " + 231860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE _id=?"); 231960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor contactIdCursor = db.rawQuery( 232060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT DISTINCT contact_id " + 232160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 232260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE deleted=0 AND account_type='com.android.exchange'", 232360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann null); 232460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 232560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (contactIdCursor.moveToNext()) { 232660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final long contactId = contactIdCursor.getLong(0); 232760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann lookupKeyBuilder.setLength(0); 232860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann final Cursor c = db.rawQuery( 232960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "SELECT account_type, account_name, _id, sourceid, display_name " + 233060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "FROM raw_contacts " + 233160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "WHERE contact_id=? " + 233260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann "ORDER BY _id", 233360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann new String[] { String.valueOf(contactId) }); 233460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann try { 233560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann while (c.moveToNext()) { 233660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann ContactLookupKey.appendToLookupKey(lookupKeyBuilder, 233760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(0), 233860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(1), 233960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getLong(2), 234060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(3), 234160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.getString(4)); 234260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 234360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 234460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann c.close(); 234560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 234660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 234760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann if (lookupKeyBuilder.length() == 0) { 234860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindNull(1); 234960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } else { 235060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindString(1, Uri.encode(lookupKeyBuilder.toString())); 235160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 235260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.bindLong(2, contactId); 235360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 235460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.execute(); 235560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 235660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } finally { 235760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann updateStatement.close(); 235860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann contactIdCursor.close(); 235960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 236060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann } 236160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann 2362b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov private void upgradeToVersion307(SQLiteDatabase db) { 2363b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov db.execSQL("CREATE TABLE properties (" + 2364b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_key TEXT PRIMARY_KEY, " + 2365b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov "property_value TEXT" + 2366b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ");"); 2367b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 2368b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 2369743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov private void upgradeToVersion308(SQLiteDatabase db) { 23704394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE accounts (" + 23714394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_name TEXT, " + 23724394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "account_type TEXT " + 23734394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 2374743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 23754394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO accounts " + 23764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "SELECT DISTINCT account_name, account_type FROM raw_contacts"); 2377743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov } 2378743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov 2379f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov private void upgradeToVersion400(SQLiteDatabase db) { 2380dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2381dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0;"); 2382dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana db.execSQL("ALTER TABLE " + Tables.GROUPS 2383dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana + " ADD " + Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0;"); 2384dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana } 2385dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana 23867da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov private void upgradeToVersion353(SQLiteDatabase db) { 23877da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov db.execSQL("DELETE FROM contacts " + 23887da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov "WHERE NOT EXISTS (SELECT 1 FROM raw_contacts WHERE contact_id=contacts._id)"); 23897da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov } 23907da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov 239151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildNameLookup(SQLiteDatabase db) { 239251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 239351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 239451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 239551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 239651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 239704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 239851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates all locale-sensitive data: nickname_lookup, name_lookup and sort keys. 239904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 240051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov public void setLocale(ContactsProvider2 provider, Locale locale) { 240151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.i(TAG, "Switching to locale " + locale); 240204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 2403c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton long start = SystemClock.uptimeMillis(); 240451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 240551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setLocale(locale); 240651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.beginTransaction(); 240751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 240851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key1_index"); 240951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX raw_contact_sort_key2_index"); 241051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DROP INDEX IF EXISTS name_lookup_index"); 241151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 241251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov loadNicknameLookupTable(db); 241351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNameLookup(db); 241451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov rebuildSortKeys(db, provider); 241551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov createContactsIndexes(db); 241651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.setTransactionSuccessful(); 241751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 241851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.endTransaction(); 241951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 242051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 2421c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton Log.i(TAG, "Locale change completed in " + (SystemClock.uptimeMillis() - start) + "ms"); 242251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 242351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 242451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov /** 242551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov * Regenerates sort keys for all contacts. 242651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov */ 242751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void rebuildSortKeys(SQLiteDatabase db, ContactsProvider2 provider) { 242851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Cursor cursor = db.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID}, 242951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov null, null, null, null, null); 243051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 243151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov while (cursor.moveToNext()) { 243251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov long rawContactId = cursor.getLong(0); 243351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov provider.updateRawContactDisplayName(db, rawContactId); 243451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 243551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 243651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov cursor.close(); 243751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 243851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 243951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 244051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov private void insertNameLookup(SQLiteDatabase db) { 244104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP); 244204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 244304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov SQLiteStatement nameLookupInsert = db.compileStatement( 244404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 244504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 244604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 244704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 244804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME + 244904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ") VALUES (?,?,?,?)"); 245004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 245151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 245251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertStructuredNameLookup(db, nameLookupInsert); 245351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertOrganizationLookup(db, nameLookupInsert); 245451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertEmailLookup(db, nameLookupInsert); 245551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov insertNicknameLookup(db, nameLookupInsert); 245651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 245751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nameLookupInsert.close(); 245851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 245904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 246004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 246104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class StructuredNameQuery { 246204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 246304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 246404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 246504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 246604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 246704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 246804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName._ID, 246904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.RAW_CONTACT_ID, 247004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredName.DISPLAY_NAME, 247104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 247204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 247304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 247404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 247504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int DISPLAY_NAME = 2; 247604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 247704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 247804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private class StructuredNameLookupBuilder extends NameLookupBuilder { 247904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 248004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final SQLiteStatement mNameLookupInsert; 248104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private final CommonNicknameCache mCommonNicknameCache; 248204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 248304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public StructuredNameLookupBuilder(NameSplitter splitter, 248404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) { 248504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov super(splitter); 248604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mCommonNicknameCache = commonNicknameCache; 248704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov this.mNameLookupInsert = nameLookupInsert; 248804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 248904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 249004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 249104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected void insertNameLookup(long rawContactId, long dataId, int lookupType, 249204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name) { 249304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (!TextUtils.isEmpty(name)) { 249404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert, 249504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov rawContactId, dataId, lookupType, name); 249604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 249704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 249804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 249904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov @Override 250004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov protected String[] getCommonNicknameClusters(String normalizedName) { 250104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return mCommonNicknameCache.getCommonNicknameClusters(normalizedName); 250204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 250304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 250404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 250504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 250604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all structured names in the database. 250704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 250804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 2509d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameSplitter nameSplitter = createNameSplitter(); 2510d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(nameSplitter, 251104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov new CommonNicknameCache(db), nameLookupInsert); 251204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE); 251304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS, 251404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 251504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 251604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 251704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 251804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(StructuredNameQuery.ID); 251904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID); 252004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME); 2521d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov int fullNameStyle = nameSplitter.guessFullNameStyle(name); 252251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov fullNameStyle = nameSplitter.getAdjustedFullNameStyle(fullNameStyle); 2523d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov nameLookupBuilder.insertNameLookup(rawContactId, dataId, name, fullNameStyle); 252404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 252604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 252704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 252904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class OrganizationQuery { 253104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 253204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 253404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 253504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 253604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 253704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization._ID, 253804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.RAW_CONTACT_ID, 253904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.COMPANY, 254004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Organization.TITLE, 254104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 254204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 254304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 254404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 254504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int COMPANY = 2; 254604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int TITLE = 3; 254704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 254804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 254904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 255004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all organizations in the database. 255104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 255204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertOrganizationLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 255304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE); 255404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(OrganizationQuery.TABLE, OrganizationQuery.COLUMNS, 255504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov OrganizationQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 255604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 255704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 255804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 255904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(OrganizationQuery.ID); 256004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(OrganizationQuery.RAW_CONTACT_ID); 256104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String organization = cursor.getString(OrganizationQuery.COMPANY); 256204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String title = cursor.getString(OrganizationQuery.TITLE); 256304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 256404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, organization); 256504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 256604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.ORGANIZATION, title); 256704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 256804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 256904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 257004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 257104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 257204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 257304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class EmailQuery { 257404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 257504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 257604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 257704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 257804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 257904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 258004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email._ID, 258104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.RAW_CONTACT_ID, 258204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Email.ADDRESS, 258304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 258404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 258504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 258604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 258704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ADDRESS = 2; 258804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 258904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 259004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 259104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all email addresses in the database. 259204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 259304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 259404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE); 259504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS, 259604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 259704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 259804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 259904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 260004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(EmailQuery.ID); 260104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID); 260204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String address = cursor.getString(EmailQuery.ADDRESS); 260304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov address = extractHandleFromEmailAddress(address); 260404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 260504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, address); 260604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 260704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 260804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 260904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 261004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 261104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 261204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private static final class NicknameQuery { 261304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String TABLE = Tables.DATA; 261404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 261504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String SELECTION = 261604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL"; 261704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 261804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final String COLUMNS[] = { 261904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname._ID, 262004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.RAW_CONTACT_ID, 262104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Nickname.NAME, 262204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov }; 262304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 262404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int ID = 0; 262504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int RAW_CONTACT_ID = 1; 262604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public static final int NAME = 2; 262704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 262804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 262904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 263004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts name lookup rows for all nicknames in the database. 263104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 263204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) { 263304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE); 263404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS, 263504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)}, 263604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov null, null, null); 263704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov try { 263804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov while (cursor.moveToNext()) { 263904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long dataId = cursor.getLong(NicknameQuery.ID); 264004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID); 264104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String nickname = cursor.getString(NicknameQuery.NAME); 264204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNameLookup(nameLookupInsert, rawContactId, dataId, 264304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov NameLookupType.NICKNAME, nickname); 264404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 264504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } finally { 264604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov cursor.close(); 264704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 264804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 264904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 265004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov /** 265104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 265204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov */ 265304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 265404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String name) { 265504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 265604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 265704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 265804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 265904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov String normalized = NameNormalizer.normalize(name); 266004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov if (TextUtils.isEmpty(normalized)) { 266104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return; 266204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 266304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 266404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized); 266504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 266604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 266704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId, 266804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov int lookupType, String normalizedName) { 266904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(1, rawContactId); 267004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(2, dataId); 267104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindLong(3, lookupType); 267204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.bindString(4, normalizedName); 267304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov stmt.executeInsert(); 267404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 267504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 26764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov /** 26774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov * Changing the VISIBLE bit from a field on both RawContacts and Contacts to a separate table. 26784394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov */ 26794394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov private void upgradeToVersion401(SQLiteDatabase db) { 26804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" + 26814394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 26824394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov ");"); 26834394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 26844394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 26854394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 26864394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts.IN_VISIBLE_GROUP + "!=0"); 26874394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DROP INDEX contacts_visible_index"); 26884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov } 26894394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 2690d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov /** 2691d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov * Introducing a new table: directories. 2692d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov */ 2693d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov private void upgradeToVersion402(SQLiteDatabase db) { 2694d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov createDirectoriesTable(db); 2695d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov } 2696d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov 269797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov private void upgradeToVersion403(SQLiteDatabase db) { 269897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 269997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov createDirectoriesTable(db); 270097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 270197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE raw_contacts" 270297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD raw_contact_is_read_only INTEGER NOT NULL DEFAULT 0;"); 270397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 270497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov db.execSQL("ALTER TABLE data" 270597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov + " ADD is_read_only INTEGER NOT NULL DEFAULT 0;"); 270697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov } 270797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov 2708892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void upgradeToVersion405(SQLiteDatabase db) { 2709892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS phone_lookup;"); 2710892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov // Private phone numbers table used for lookup 2711892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" + 2712892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID 2713892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES data(_id) NOT NULL," + 2714892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID 2715892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," + 2716892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," + 2717892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" + 2718892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2719892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2720892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" + 2721892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.NORMALIZED_NUMBER + "," + 2722892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2723892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2724892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2725892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2726892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" + 2727892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.MIN_MATCH + "," + 2728892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.RAW_CONTACT_ID + "," + 2729892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneLookupColumns.DATA_ID + 2730892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ");"); 2731892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2732892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov final long mimeTypeId = lookupMimeTypeId(db, Phone.CONTENT_ITEM_TYPE); 2733892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (mimeTypeId == -1) { 2734892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return; 2735892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2736892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2737892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String mCountryIso = getCountryIso(); 2738892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov Cursor cursor = db.rawQuery( 2739892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov "SELECT _id, " + Phone.RAW_CONTACT_ID + ", " + Phone.NUMBER + 2740892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " FROM " + Tables.DATA + 2741892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId 2742892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " AND " + Phone.NUMBER + " NOT NULL", null); 2743892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2744892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov ContentValues phoneValues = new ContentValues(); 2745892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov try { 2746892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov while (cursor.moveToNext()) { 2747892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long dataID = cursor.getLong(0); 2748892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov long rawContactID = cursor.getLong(1); 2749892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String number = cursor.getString(2); 2750892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String numberE164 = PhoneNumberUtils.formatNumberToE164(number, mCountryIso); 2751892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String normalizedNumber = PhoneNumberUtils.normalizeNumber(number); 2752892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (!TextUtils.isEmpty(normalizedNumber)) { 2753892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.clear(); 2754892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactID); 2755892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.DATA_ID, dataID); 2756892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber); 2757892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2758892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber)); 2759892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2760892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 2761892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (numberE164 != null && !numberE164.equals(normalizedNumber)) { 2762892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, numberE164); 2763892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov phoneValues.put(PhoneLookupColumns.MIN_MATCH, 2764892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov PhoneNumberUtils.toCallerIDMinMatch(numberE164)); 2765892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov db.insert(Tables.PHONE_LOOKUP, null, phoneValues); 2766892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2767892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2768892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2769892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } finally { 2770892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov cursor.close(); 2771892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2772892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 2773892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 27742530512f639c4979fd7371c7dd25dd67e8118124Bai Tao private void upgradeToVersion406(SQLiteDatabase db) { 27752530512f639c4979fd7371c7dd25dd67e8118124Bai Tao db.execSQL("ALTER TABLE calls ADD countryiso TEXT;"); 27762530512f639c4979fd7371c7dd25dd67e8118124Bai Tao } 27772530512f639c4979fd7371c7dd25dd67e8118124Bai Tao 2778d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion409(SQLiteDatabase db) { 2779d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 2780d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov createDirectoriesTable(db); 2781d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov } 2782d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov 2783385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov /** 2784d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov * Adding DEFAULT_DIRECTORY table. 2785385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov */ 2786d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov private void upgradeToVersion411(SQLiteDatabase db) { 2787d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS " + Tables.DEFAULT_DIRECTORY); 2788385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" + 2789385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov Contacts._ID + " INTEGER PRIMARY KEY" + 2790385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ");"); 2791385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2792385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process contacts without an account 2793385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2794385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2795385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2796385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 2797385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL "); 2798385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2799385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // Process accounts that don't have a default group (e.g. Exchange) 2800385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2801385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2802385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2803385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE NOT EXISTS" + 2804385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 2805385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 2806385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2807385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2808385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2809385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2810385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2811385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")"); 2812385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2813385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = lookupMimeTypeId(db, GroupMembership.CONTENT_ITEM_TYPE); 2814385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2815d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // Process accounts that do have a default group (e.g. Google) 2816385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + 2817385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " SELECT " + RawContacts.CONTACT_ID + 2818385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 2819385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 2820385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" + Data.RAW_CONTACT_ID + ")" + 2821385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimetype + 2822d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND EXISTS" + 2823d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " (SELECT " + Groups._ID + 2824d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " FROM " + Tables.GROUPS + 2825d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 2826d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 2827d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 2828d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 2829d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 2830d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov ")"); 28313d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 2832385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 2833e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov private void upgradeToVersion413(SQLiteDatabase db) { 28343ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov db.execSQL("DROP TABLE IF EXISTS directories;"); 28353ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov createDirectoriesTable(db); 2836e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov } 2837e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov 2838c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov private void upgradeToVersion415(SQLiteDatabase db) { 2839c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov db.execSQL( 2840c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov "ALTER TABLE " + Tables.GROUPS + 2841c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " ADD " + Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0"); 2842c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov db.execSQL( 2843c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov "UPDATE " + Tables.GROUPS + 2844c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " SET " + Groups.GROUP_IS_READ_ONLY + "=1" + 2845c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov " WHERE " + Groups.SYSTEM_ID + " NOT NULL"); 2846c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov } 2847c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov 2848d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov private void upgradeToVersion416(SQLiteDatabase db) { 2849d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov db.execSQL("CREATE INDEX phone_lookup_data_id_min_match_index ON " + Tables.PHONE_LOOKUP + 2850d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov " (" + PhoneLookupColumns.DATA_ID + ", " + PhoneLookupColumns.MIN_MATCH + ");"); 2851d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov } 2852d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov 2853b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov public String extractHandleFromEmailAddress(String email) { 2854b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 2855b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (tokens.length == 0) { 2856b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2857b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2858b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 2859b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov String address = tokens[0].getAddress(); 2860b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov int at = address.indexOf('@'); 2861b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov if (at != -1) { 2862b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return address.substring(0, at); 2863b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2864b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return null; 2865b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2866b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 286708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov public String extractAddressFromEmailAddress(String email) { 286808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email); 286908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov if (tokens.length == 0) { 287008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov return null; 287108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 287208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 287350a7c86b4b49870bd19d5270722be3f1fccaf226Dmitri Plotnikov return tokens[0].getAddress().trim(); 287408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov } 287508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov 2876b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov private long lookupMimeTypeId(SQLiteDatabase db, String mimeType) { 2877b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov try { 2878b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return DatabaseUtils.longForQuery(db, 2879b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov "SELECT " + MimetypesColumns._ID + 2880b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " FROM " + Tables.MIMETYPES + 2881b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov " WHERE " + MimetypesColumns.MIMETYPE 2882b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov + "='" + mimeType + "'", null); 2883b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } catch (SQLiteDoneException e) { 2884b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov // No rows of this type in the database 2885b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov return -1; 2886b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2887b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov } 2888b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov 28895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void bindString(SQLiteStatement stmt, int index, String value) { 28905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov if (value == null) { 28915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindNull(index); 28925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } else { 28935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov stmt.bindString(index, value); 28945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 28955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov } 28965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov 289778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov private void bindLong(SQLiteStatement stmt, int index, Number value) { 289878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (value == null) { 289978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov stmt.bindNull(index); 290078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } else { 290178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov stmt.bindLong(index, value.longValue()); 290278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 290378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 290478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 2905a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov /** 2906f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Adds index stats into the SQLite database to force it to always use the lookup indexes. 2907f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 2908f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov private void updateSqliteStats(SQLiteDatabase db) { 2909f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2910f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov // Specific stats strings are based on an actual large database after running ANALYZE 2911f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov try { 29128fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 29138fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_restricted_index", "10000 9000"); 29148fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.CONTACTS, 29158fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "contacts_has_phone_index", "10000 500"); 29168fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29178fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 29188fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_source_id_index", "10000 1 1 1"); 29198fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.RAW_CONTACTS, 29208fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "raw_contacts_contact_id_index", "10000 2"); 29218fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29228fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 29238fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "name_lookup_raw_contact_id_index", "10000 3"); 29248fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 2925916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov "name_lookup_index", "10000 3 2 2 1"); 29268fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NAME_LOOKUP, 29278fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "10000 3 2 1"); 29288fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29298fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 29308fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "phone_lookup_index", "10000 2 2 1"); 293136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov updateIndexStats(db, Tables.PHONE_LOOKUP, 293236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov "phone_lookup_min_match_index", "10000 2 2 1"); 29338fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29348fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 29358fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_mimetype_data1_index", "60000 5000 2"); 29368fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.DATA, 29378fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "data_raw_contact_id", "60000 10"); 29388fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29398fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.GROUPS, 29408fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "groups_source_id_index", "50 1 1 1"); 29418fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 29428fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov updateIndexStats(db, Tables.NICKNAME_LOOKUP, 29438fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov "sqlite_autoindex_name_lookup_1", "500 2 1"); 29448fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov 2945f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } catch (SQLException e) { 2946f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov Log.e(TAG, "Could not update index stats", e); 2947f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2948f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2949f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2950f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2951f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * Stores statistics for a given index. 2952f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * 2953f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * @param stats has the following structure: the first index is the expected size of 2954f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * the table. The following integer(s) are the expected number of records selected with the 2955f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov * index. There should be one integer per indexed column. 2956f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov */ 29575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov private void updateIndexStats(SQLiteDatabase db, String table, String index, 29585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov String stats) { 2959f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';"); 2960f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)" 2961f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov + " VALUES ('" + table + "','" + index + "','" + stats + "');"); 2962f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2963f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2964f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov @Override 2965f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov public synchronized SQLiteDatabase getWritableDatabase() { 2966f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov SQLiteDatabase db = super.getWritableDatabase(); 2967f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov if (mReopenDatabase) { 2968f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov mReopenDatabase = false; 2969f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov close(); 2970f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov db = super.getWritableDatabase(); 2971f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2972f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov return db; 2973f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov } 2974f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov 2975f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov /** 2976a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov * Wipes all data except mime type and package lookup tables. 2977a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov */ 2978a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov public void wipeData() { 2979a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 29803d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov 298133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACCOUNTS + ";"); 298269cc3a2b09e2ffb606c6e52a71b604bba526d225Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL)"); 298333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov 2984d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS + ";"); 29855ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";"); 2986a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DATA + ";"); 2987a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";"); 2988a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";"); 2989ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey db.execSQL("DELETE FROM " + Tables.GROUPS + ";"); 2990b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";"); 2991eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey db.execSQL("DELETE FROM " + Tables.SETTINGS + ";"); 2992a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";"); 29933d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CALLS + ";"); 299472e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DIRECTORIES + ";"); 299572e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov 2996b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP 2997a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov } 2998b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 299904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov public NameSplitter createNameSplitter() { 300004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov return new NameSplitter( 300104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_prefixes), 300204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_last_name_prefixes), 300304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_suffixes), 300404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov mContext.getString(com.android.internal.R.string.common_name_conjunctions), 300504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov Locale.getDefault()); 300604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov } 300704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov 3008b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3009619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey * Return the {@link ApplicationInfo#uid} for the given package name. 3010619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey */ 3011619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey public static int getUidForPackageName(PackageManager pm, String packageName) { 3012619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey try { 3013619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */); 3014619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey return clientInfo.uid; 3015619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } catch (NameNotFoundException e) { 3016619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey throw new RuntimeException(e); 3017619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 3018619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey } 3019619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey 3020619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 3021b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Perform an internal string-to-integer lookup using the compiled 3022b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * {@link SQLiteStatement} provided, using the in-memory cache to speed up 3023b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups. If a mapping isn't found in cache or database, it will be 3024b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * created. All new, uncached answers are added to the cache automatically. 3025b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * 3026b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param query Compiled statement used to query for the mapping. 3027b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param insert Compiled statement used to insert a new mapping when no 3028b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * existing one is found in cache or from query. 3029b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param value Value to find mapping for. 3030b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @param cache In-memory cache of previous answers. 3031b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * @return An unique integer mapping for the given value. 3032b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3033f4a3b7e523e36679b68edd2af632e26648758ff2Dmitri Plotnikov private long getCachedId(SQLiteStatement query, SQLiteStatement insert, 3034b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String value, HashMap<String, Long> cache) { 3035b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try an in-memory cache lookup 3036b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey if (cache.containsKey(value)) { 3037b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return cache.get(value); 3038b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3039b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 304036d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov synchronized (this) { 304136d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov long id = -1; 304236d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov try { 304336d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov // Try searching database for mapping 304436d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(query, 1, value); 304536d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov id = query.simpleQueryForLong(); 304636d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov } catch (SQLiteDoneException e) { 304736d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov // Nothing found, so try inserting new mapping 304836d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(insert, 1, value); 304936d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov id = insert.executeInsert(); 305036d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov } 305136d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov if (id != -1) { 305236d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov // Cache and return the new answer 305336d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov cache.put(value, id); 305436d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov return id; 305536d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov } else { 305636d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov // Otherwise throw if no mapping found or created 305736d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov throw new IllegalStateException("Couldn't find or create internal " 305836d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov + "lookup table entry for value " + value); 305936d7a981711dc856da815fbc8739ee88c0236a15Dmitri Plotnikov } 3060b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3061b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3062b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 3063b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3064ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a package name into an integer, using {@link Tables#PACKAGES} for 3065b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 3066b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3067b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getPackageId(String packageName) { 306878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mPackageQuery == null) { 306978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mPackageQuery = getWritableDatabase().compileStatement( 307078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + PackagesColumns._ID + 307178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.PACKAGES + 307278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + PackagesColumns.PACKAGE + "=?"); 307378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 307478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 307578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mPackageInsert == null) { 307678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mPackageInsert = getWritableDatabase().compileStatement( 307778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "INSERT INTO " + Tables.PACKAGES + "(" 307878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + PackagesColumns.PACKAGE + 307978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov ") VALUES (?)"); 308078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 3081b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache); 3082b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3083b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 3084b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3085ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for 3086b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * lookups and possible allocation of new IDs as needed. 3087b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3088b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public long getMimeTypeId(String mimetype) { 3089b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache); 3090b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3091b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 30922a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov public long getMimeTypeIdForStructuredName() { 30932a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return mMimeTypeIdStructuredName; 30942a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 30952a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 30962a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov public long getMimeTypeIdForOrganization() { 30972a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return mMimeTypeIdOrganization; 30982a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 30992a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 31002a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov public long getMimeTypeIdForIm() { 31012a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return mMimeTypeIdIm; 31022a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 31032a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 31042a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov public long getMimeTypeIdForEmail() { 31052a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return mMimeTypeIdEmail; 31062a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 31072a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 3108a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov public long getMimeTypeIdForSip() { 3109a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov return mMimeTypeIdSip; 3110a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov } 3111a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov 31122a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov public int getDisplayNameSourceForMimeTypeId(int mimeTypeId) { 31132a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov if (mimeTypeId == mMimeTypeIdStructuredName) { 31142a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.STRUCTURED_NAME; 31152a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } else if (mimeTypeId == mMimeTypeIdEmail) { 31162a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.EMAIL; 31172a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } else if (mimeTypeId == mMimeTypeIdPhone) { 31182a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.PHONE; 31192a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } else if (mimeTypeId == mMimeTypeIdOrganization) { 31202a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.ORGANIZATION; 31212a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } else if (mimeTypeId == mMimeTypeIdNickname) { 31222a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.NICKNAME; 31232a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } else { 31242a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov return DisplayNameSources.UNDEFINED; 31252a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 31262a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov } 31272a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov 3128b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3129ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey * Find the mimetype for the given {@link Data#_ID}. 3130b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3131b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getDataMimeType(long dataId) { 313278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mDataMimetypeQuery == null) { 313378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mDataMimetypeQuery = getWritableDatabase().compileStatement( 313478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + MimetypesColumns.MIMETYPE + 313578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.DATA_JOIN_MIMETYPES + 313678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + Tables.DATA + "." + Data._ID + "=?"); 313778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 3138b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 3139b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 3140b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId); 3141b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mDataMimetypeQuery.simpleQueryForString(); 3142b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 3143b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 3144b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 3145b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 3146b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3147b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3148b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey 3149b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey /** 3150b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey * Find the mime-type for the given {@link Activities#_ID}. 3151b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */ 3152b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey public String getActivityMimeType(long activityId) { 315378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mActivitiesMimetypeQuery == null) { 315478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mActivitiesMimetypeQuery = getWritableDatabase().compileStatement( 315578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + MimetypesColumns.MIMETYPE + 315678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + 315778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + Tables.ACTIVITIES + "." + Activities._ID + "=?"); 315878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 3159b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey try { 3160b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // Try database query to find mimetype 3161b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId); 3162b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey String mimetype = mActivitiesMimetypeQuery.simpleQueryForString(); 3163b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return mimetype; 3164b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } catch (SQLiteDoneException e) { 3165b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey // No valid mapping found, so return null 3166b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey return null; 3167b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 3168b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey } 31696bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov 31706bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov /** 3171d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts. 3172ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 3173ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey public void updateAllVisible() { 3174385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov updateCustomContactVisibility(getWritableDatabase(), ""); 3175ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3176ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3177ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3178f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov * Updates contact visibility and return true iff the visibility was actually changed. 3179f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov */ 3180f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov public boolean updateContactVisibleOnlyIfChanged(long contactId) { 3181f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov return updateContactVisible(contactId, true); 3182f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3183f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 3184f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov /** 3185385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * Update {@link Contacts#IN_VISIBLE_GROUP} and 3186385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov * {@link Tables#DEFAULT_DIRECTORY} for a specific contact. 3187ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey */ 3188fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov public void updateContactVisible(long contactId) { 3189f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov updateContactVisible(contactId, false); 3190f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3191f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 3192f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov public boolean updateContactVisible(long contactId, boolean onlyIfChanged) { 31934394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3194f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov updateCustomContactVisibility(db, " AND " + Contacts._ID + "=" + contactId); 3195385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3196385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov String contactIdAsString = String.valueOf(contactId); 3197385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov long mimetype = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 3198385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3199385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // The contact will be included in the default directory if contains 3200d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov // a raw contact that is in any group or in an account that 3201385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov // does not have any AUTO_ADD groups. 3202f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov boolean newVisibility = DatabaseUtils.longForQuery(db, 3203385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT EXISTS (" + 3204385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 3205385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3206385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " JOIN " + Tables.DATA + 3207385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " ON (" + RawContactsColumns.CONCRETE_ID + "=" 3208385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + Data.RAW_CONTACT_ID + ")" + 3209385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3210385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + DataColumns.MIMETYPE_ID + "=?" + 3211385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3212385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3213385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3214385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3215385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND NOT EXISTS" + 3216385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " (SELECT " + Groups._ID + 3217385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.GROUPS + 3218385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " 3219385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_NAME + 3220385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " 3221385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov + GroupsColumns.CONCRETE_ACCOUNT_TYPE + 3222385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + Groups.AUTO_ADD + " != 0" + 3223385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")" + 3224385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ") OR EXISTS (" + 3225385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov "SELECT " + RawContacts._ID + 3226385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 3227385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=?" + 3228385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " + 3229385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov " AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL" + 3230385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov ")", 3231385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { 3232385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 32336c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov String.valueOf(mimetype), 3234385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov contactIdAsString, 32356c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov contactIdAsString 3236f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov }) != 0; 3237385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov 3238f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (onlyIfChanged) { 3239f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov boolean oldVisibility = isContactInDefaultDirectory(db, contactId); 3240f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (oldVisibility == newVisibility) { 3241f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov return false; 3242f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3243f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3244f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 3245f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (newVisibility) { 3246385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + " VALUES(?)", 3247385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3248385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } else { 3249385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.DEFAULT_DIRECTORY + " WHERE " + Contacts._ID + "=?", 3250385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov new String[] { contactIdAsString }); 3251385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 3252f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov return true; 3253f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3254f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 3255f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov public boolean isContactInDefaultDirectory(SQLiteDatabase db, long contactId) { 3256f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (mContactInDefaultDirectoryQuery == null) { 3257f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov mContactInDefaultDirectoryQuery = db.compileStatement( 3258f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov "SELECT EXISTS (" + 3259f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov "SELECT 1 FROM " + Tables.DEFAULT_DIRECTORY + 3260f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov " WHERE " + Contacts._ID + "=?)"); 3261f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 3262f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov mContactInDefaultDirectoryQuery.bindLong(1, contactId); 3263f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov return mContactInDefaultDirectoryQuery.simpleQueryForLong() != 0; 3264385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov } 32654394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 3266385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov private void updateCustomContactVisibility(SQLiteDatabase db, String selection) { 3267ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 32684394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)}; 32694394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov 32704394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // First delete what needs to be deleted, then insert what needs to be added. 32714394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // Since flash writes are very expensive, this approach is much better than 32724394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov // delete-all-insert-all. 32734394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.VISIBLE_CONTACTS + 32744394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + "_id NOT IN" + 32754394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov "(SELECT " + Contacts._ID + 32764394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 32774394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE (" + Clauses.CONTACT_IS_VISIBLE + ")=1) " + selection, 32784394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3279fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov 32804394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS + 32814394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " SELECT " + Contacts._ID + 32824394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " FROM " + Tables.CONTACTS + 32834394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " WHERE " + Contacts._ID + 32844394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " NOT IN " + Tables.VISIBLE_CONTACTS + 32854394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1 " + selection, 32864394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov selectionArgs); 3287ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey } 3288ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey 3289ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey /** 3290d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov * Returns contact ID for the given contact or zero if it is NULL. 32916bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov */ 3292d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov public long getContactId(long rawContactId) { 329378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mContactIdQuery == null) { 329478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mContactIdQuery = getWritableDatabase().compileStatement( 329578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 329678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 329778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 329878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 32996bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov try { 3300d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId); 3301d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov return mContactIdQuery.simpleQueryForLong(); 33026bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } catch (SQLiteDoneException e) { 3303a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana // No valid mapping found, so return 0 33046bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov return 0; 33056bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 33066bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov } 330761bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov 33085ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov public int getAggregationMode(long rawContactId) { 330978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mAggregationModeQuery == null) { 331078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mAggregationModeQuery = getWritableDatabase().compileStatement( 331178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + RawContacts.AGGREGATION_MODE + 331278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 331378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 331478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 3315f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov try { 33165ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId); 3317f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov return (int)mAggregationModeQuery.simpleQueryForLong(); 3318f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } catch (SQLiteDoneException e) { 33196cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov // No valid row found, so return "disabled" 33206cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov return RawContacts.AGGREGATION_MODE_DISABLED; 3321f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3322f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3323f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3324892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov public void buildPhoneLookupAndContactQuery( 3325892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov SQLiteQueryBuilder qb, String normalizedNumber, String numberE164) { 3326892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov String minMatch = PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber); 3327e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 332836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, true); 3329e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.setTables(sb.toString()); 3330e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3331e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb = new StringBuilder(); 3332892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, normalizedNumber, numberE164); 3333e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov qb.appendWhere(sb.toString()); 3334bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov } 3335bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3336e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov public String buildPhoneLookupAsNestedQuery(String number) { 3337e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov StringBuilder sb = new StringBuilder(); 333836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number); 3339e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append("(SELECT DISTINCT raw_contact_id" + " FROM "); 334036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov appendPhoneLookupTables(sb, minMatch, false); 3341e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(" WHERE "); 3342892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov appendPhoneLookupSelection(sb, number, null); 3343e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(")"); 3344e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov return sb.toString(); 3345e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3346e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 334736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov private void appendPhoneLookupTables(StringBuilder sb, final String minMatch, 3348e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov boolean joinContacts) { 3349e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov sb.append(Tables.RAW_CONTACTS); 3350e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov if (joinContacts) { 3351fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov sb.append(" JOIN " + getContactView() + " contacts_view" 3352fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov + " ON (contacts_view._id = raw_contacts.contact_id)"); 3353e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3354892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(", (SELECT data_id, normalized_number, length(normalized_number) as len " 3355892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + " FROM phone_lookup " + " WHERE (" + Tables.PHONE_LOOKUP + "." 3356892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov + PhoneLookupColumns.MIN_MATCH + " = '"); 335736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append(minMatch); 335836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov sb.append("')) AS lookup, " + Tables.DATA); 3359e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov } 3360e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov 3361892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov private void appendPhoneLookupSelection(StringBuilder sb, String number, String numberE164) { 3362892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id"); 3363892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumberE164 = !TextUtils.isEmpty(numberE164); 3364892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov boolean hasNumber = !TextUtils.isEmpty(number); 3365892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 || hasNumber) { 3366892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND ( "); 3367892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164) { 3368892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.normalized_number = "); 3369892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, numberE164); 3370892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3371892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumberE164 && hasNumber) { 3372892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" OR "); 3373892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3374892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov if (hasNumber) { 3375892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov int numberLen = number.length(); 3376892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" lookup.len <= "); 3377892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3378892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" AND substr("); 3379892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov DatabaseUtils.appendEscapedSQLString(sb, number); 3380892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(','); 3381892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(numberLen); 3382892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(" - lookup.len + 1) = lookup.normalized_number"); 3383892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 3384892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov sb.append(')'); 3385892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 338636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov } 338736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov 338836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov public String getUseStrictPhoneNumberComparisonParameter() { 338936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov return mUseStrictPhoneNumberComparison ? "1" : "0"; 3390fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov } 3391bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov 3392619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey /** 3393b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov * Loads common nickname mappings into the database. 3394b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov */ 3395b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov private void loadNicknameLookupTable(SQLiteDatabase db) { 339651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP); 339751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 339828f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar String[] strings = mContext.getResources().getStringArray( 339928f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar com.android.internal.R.array.common_nicknames); 3400b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov if (strings == null || strings.length == 0) { 3401b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov return; 3402b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3403b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3404b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO " 3405b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + "," 3406b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)"); 3407b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 340851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 340951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int clusterId = 0; clusterId < strings.length; clusterId++) { 341051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String[] names = strings[clusterId].split(","); 341151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov for (int j = 0; j < names.length; j++) { 341251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String name = NameNormalizer.normalize(names[j]); 341351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov try { 341451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name); 341551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2, 341651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov String.valueOf(clusterId)); 341751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.executeInsert(); 341851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } catch (SQLiteException e) { 341951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov 342051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov // Print the exception and keep going - this is not a fatal error 342151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov Log.e(TAG, "Cannot insert nickname: " + names[j], e); 342251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } 3423b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3424b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 342551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov } finally { 342651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov nicknameLookupInsert.close(); 3427b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3428b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov } 3429b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov 3430f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyStringValue(ContentValues toValues, String toKey, 3431f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3432f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3433f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, fromValues.getAsString(fromKey)); 3434f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3435f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3436f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 3437f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov public static void copyLongValue(ContentValues toValues, String toKey, 3438f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov ContentValues fromValues, String fromKey) { 3439f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (fromValues.containsKey(fromKey)) { 3440f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov long longValue; 3441f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov Object value = fromValues.get(fromKey); 3442f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if (value instanceof Boolean) { 3443f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov if ((Boolean)value) { 3444f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 1; 3445f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 3446f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov longValue = 0; 3447f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 34481b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov } else if (value instanceof String) { 34491b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = Long.parseLong((String)value); 3450f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } else { 34511b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov longValue = ((Number)value).longValue(); 3452f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3453f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov toValues.put(toKey, longValue); 3454f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3455f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov } 3456f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov 345735ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana public SyncStateContentProviderHelper getSyncState() { 345835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana return mSyncState; 345935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana } 3460c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3461c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov /** 3462c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * Delete the aggregate contact if it has no constituent raw contacts other 3463c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov * than the supplied one. 3464c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov */ 3465c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov public void removeContactIfSingleton(long rawContactId) { 3466c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov SQLiteDatabase db = getWritableDatabase(); 3467c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3468c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Obtain contact ID from the supplied raw contact ID 3469c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM " 3470c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")"; 3471c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3472c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov // Find other raw contacts in the same aggregate contact 3473c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM " 3474c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON (" 3475c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID 3476c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + "" 3477c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")"; 3478c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov 3479c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov db.execSQL("DELETE FROM " + Tables.CONTACTS 3480c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId 3481c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov + " AND NOT EXISTS " + otherRawContacts + ";"); 3482c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov } 34834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 34844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov /** 3485b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Returns the value from the {@link Tables#PROPERTIES} table. 3486b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3487b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public String getProperty(String key, String defaultValue) { 3488b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov Cursor cursor = getReadableDatabase().query(Tables.PROPERTIES, 3489b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{PropertiesColumns.PROPERTY_VALUE}, 3490b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov PropertiesColumns.PROPERTY_KEY + "=?", 3491b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov new String[]{key}, null, null, null); 3492b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov String value = null; 3493b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov try { 3494b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov if (cursor.moveToFirst()) { 3495b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov value = cursor.getString(0); 3496b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3497b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } finally { 3498b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov cursor.close(); 3499b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3500b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3501b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov return value != null ? value : defaultValue; 3502b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3503b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3504b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 3505b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov * Stores a key-value pair in the {@link Tables#PROPERTIES} table. 3506b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov */ 3507b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov public void setProperty(String key, String value) { 35083d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov setProperty(getWritableDatabase(), key, value); 35093d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov } 35103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov 35113d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov private void setProperty(SQLiteDatabase db, String key, String value) { 3512b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov ContentValues values = new ContentValues(); 3513b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_KEY, key); 3514b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov values.put(PropertiesColumns.PROPERTY_VALUE, value); 35153d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov db.replace(Tables.PROPERTIES, null, values); 3516b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov } 3517b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov 3518b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov /** 35194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * Check if {@link Binder#getCallingUid()} should be allowed access to 35204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov * {@link RawContacts#IS_RESTRICTED} data. 35214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov */ 3522d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData() { 35234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 35246ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen int caller = Binder.getCallingUid(); 35256ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen if (caller == 0) return true; // root can do anything 35266ff43a7545880f0b1c0f0a82b3551fb1d0dfa956Marco Nelissen final String[] callerPackages = pm.getPackagesForUid(caller); 35274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 35284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov // Has restricted access if caller matches any packages 35294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov for (String callerPackage : callerPackages) { 3530d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (hasAccessToRestrictedData(callerPackage)) { 3531763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return true; 3532763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3533763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3534763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return false; 3535763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3536763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3537763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar /** 3538763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * Check if requestingPackage should be allowed access to 3539763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar * {@link RawContacts#IS_RESTRICTED} data. 3540763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar */ 3541d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton boolean hasAccessToRestrictedData(String requestingPackage) { 3542d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (mUnrestrictedPackages != null) { 3543d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton for (String allowedPackage : mUnrestrictedPackages) { 3544d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton if (allowedPackage.equals(requestingPackage)) { 3545d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return true; 3546d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton } 35474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov return false; 35504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 35524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getDataView() { 3553d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa return getDataView(false); 3554d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3555d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3556d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa public String getDataView(boolean requireRestrictedView) { 3557d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3558d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa Views.DATA_ALL : Views.DATA_RESTRICTED; 35594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 35614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getRawContactView() { 3562763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getRawContactView(false); 3563763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar } 3564763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar 3565763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getRawContactView(boolean requireRestrictedView) { 3566d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3567763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.RAW_CONTACTS_ALL : Views.RAW_CONTACTS_RESTRICTED; 35684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 35704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov public String getContactView() { 3571763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar return getContactView(false); 35724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 35734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov 3574763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar public String getContactView(boolean requireRestrictedView) { 3575d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3576763100dcfabb368e72f25d24fe181c352bdb66d6Evan Millar Views.CONTACTS_ALL : Views.CONTACTS_RESTRICTED; 3577f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey } 3578f9aeb84d61c01a473819e9173f8311ca5d678a8dJeff Sharkey 357989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov public String getGroupView() { 358089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov return Views.GROUPS_ALL; 358189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov } 358289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov 3583a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView() { 3584a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getRawEntitiesView(false); 3585a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3586a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3587a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getRawEntitiesView(boolean requireRestrictedView) { 3588a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3589a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.RAW_ENTITIES : Views.RAW_ENTITIES_RESTRICTED; 3590a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov } 3591a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov 3592a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView() { 3593a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov return getEntitiesView(false); 3594d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3595d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3596a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov public String getEntitiesView(boolean requireRestrictedView) { 3597d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton return (hasAccessToRestrictedData() && !requireRestrictedView) ? 3598a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov Views.ENTITIES : Views.ENTITIES_RESTRICTED; 3599d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa } 3600d237c80845d8e13164d34278d3c20e31f8d80b4dDaisuke Miyakawa 3601ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov /** 3602ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov * Test if any of the columns appear in the given projection. 3603ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov */ 3604ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov public boolean isInProjection(String[] projection, String... columns) { 360582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (projection == null) { 360682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 360782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 3608ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov 360982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov // Optimized for a single-column test 361082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (columns.length == 1) { 361182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov String column = columns[0]; 361282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 361382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov if (column.equals(test)) { 361482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov return true; 361582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 361682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } 361782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov } else { 361882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String test : projection) { 361982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov for (String column : columns) { 3620ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov if (column.equals(test)) { 3621ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return true; 3622ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3623ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3624ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3625ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov } 3626ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov return false; 36274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov } 3628fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3629fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3630fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3631fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3632fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3633fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(Uri uri) { 3634fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return exceptionMessage(null, uri); 3635fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3636fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3637fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov /** 3638fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * Returns a detailed exception message for the supplied URI. It includes the calling 3639fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov * user and calling package(s). 3640fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov */ 3641fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov public String exceptionMessage(String message, Uri uri) { 3642fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov StringBuilder sb = new StringBuilder(); 3643fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (message != null) { 3644fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(message).append("; "); 3645fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3646fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("URI: ").append(uri); 3647fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final PackageManager pm = mContext.getPackageManager(); 3648fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov int callingUid = Binder.getCallingUid(); 3649fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling user: "); 3650fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov String userName = pm.getNameForUid(callingUid); 3651fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (userName != null) { 3652fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(userName); 3653fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3654fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callingUid); 3655fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3656fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3657fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov final String[] callerPackages = pm.getPackagesForUid(callingUid); 3658fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages != null && callerPackages.length > 0) { 3659fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (callerPackages.length == 1) { 3660fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package:"); 3661fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[0]); 3662fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } else { 3663fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", calling package is one of: ["); 3664fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov for (int i = 0; i < callerPackages.length; i++) { 3665fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov if (i != 0) { 3666fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(", "); 3667fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3668fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append(callerPackages[i]); 3669fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3670fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov sb.append("]"); 3671fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3672fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3673fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov 3674fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov return sb.toString(); 3675fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov } 3676892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov 3677892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov protected String getCountryIso() { 3678892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov CountryDetector detector = 3679892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov (CountryDetector) mContext.getSystemService(Context.COUNTRY_DETECTOR); 3680892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov return detector.detectCountry().getCountryIso(); 3681892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov } 368278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 368378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void deleteStatusUpdate(long dataId) { 368478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mStatusUpdateDelete == null) { 368578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateDelete = getWritableDatabase().compileStatement( 368678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "DELETE FROM " + Tables.STATUS_UPDATES + 368778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + StatusUpdatesColumns.DATA_ID + "=?"); 368878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 368978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateDelete.bindLong(1, dataId); 369078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateDelete.execute(); 369178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 369278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 369378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void replaceStatusUpdate(Long dataId, long timestamp, String status, String resPackage, 369478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov Long iconResource, Integer labelResource) { 369578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mStatusUpdateReplace == null) { 369678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateReplace = getWritableDatabase().compileStatement( 369778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "INSERT OR REPLACE INTO " + Tables.STATUS_UPDATES + "(" 369878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdatesColumns.DATA_ID + ", " 369978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_TIMESTAMP + "," 370078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS + "," 370178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_RES_PACKAGE + "," 370278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_ICON + "," 370378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_LABEL + ")" + 370478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " VALUES (?,?,?,?,?,?)"); 370578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 370678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateReplace.bindLong(1, dataId); 370778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateReplace.bindLong(2, timestamp); 370878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateReplace, 3, status); 370978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateReplace, 4, resPackage); 371078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusUpdateReplace, 5, iconResource); 371178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusUpdateReplace, 6, labelResource); 371278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateReplace.execute(); 371378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 371478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 371578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void insertStatusUpdate(Long dataId, String status, String resPackage, Long iconResource, 371678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov Integer labelResource) { 371778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mStatusUpdateInsert == null) { 371878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateInsert = getWritableDatabase().compileStatement( 371978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "INSERT INTO " + Tables.STATUS_UPDATES + "(" 372078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdatesColumns.DATA_ID + ", " 372178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS + "," 372278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_RES_PACKAGE + "," 372378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_ICON + "," 372478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_LABEL + ")" + 372578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " VALUES (?,?,?,?,?)"); 372678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 372778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov try { 372878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateInsert.bindLong(1, dataId); 372978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateInsert, 2, status); 373078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateInsert, 3, resPackage); 373178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusUpdateInsert, 4, iconResource); 373278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusUpdateInsert, 5, labelResource); 373378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateInsert.executeInsert(); 373478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } catch (SQLiteConstraintException e) { 373578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov // The row already exists - update it 373678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mStatusUpdateAutoTimestamp == null) { 373778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateAutoTimestamp = getWritableDatabase().compileStatement( 373878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.STATUS_UPDATES + 373978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + StatusUpdates.STATUS_TIMESTAMP + "=?," 374078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS + "=?" + 374178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + StatusUpdatesColumns.DATA_ID + "=?" 374278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + " AND " + StatusUpdates.STATUS + "!=?"); 374378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 374478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 374578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov long timestamp = System.currentTimeMillis(); 374678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateAutoTimestamp.bindLong(1, timestamp); 374778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateAutoTimestamp, 2, status); 374878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateAutoTimestamp.bindLong(3, dataId); 374978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusUpdateAutoTimestamp, 4, status); 375078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusUpdateAutoTimestamp.execute(); 375178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 375278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mStatusAttributionUpdate == null) { 375378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusAttributionUpdate = getWritableDatabase().compileStatement( 375478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.STATUS_UPDATES + 375578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + StatusUpdates.STATUS_RES_PACKAGE + "=?," 375678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_ICON + "=?," 375778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + StatusUpdates.STATUS_LABEL + "=?" + 375878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + StatusUpdatesColumns.DATA_ID + "=?"); 375978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 376078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mStatusAttributionUpdate, 1, resPackage); 376178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusAttributionUpdate, 2, iconResource); 376278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindLong(mStatusAttributionUpdate, 3, labelResource); 376378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusAttributionUpdate.bindLong(4, dataId); 376478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mStatusAttributionUpdate.execute(); 376578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 376678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 376778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 376878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** 376978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Resets the {@link RawContacts#NAME_VERIFIED} flag to 0 on all other raw 377078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * contacts in the same aggregate 377178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 377278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void resetNameVerifiedForOtherRawContacts(long rawContactId) { 377378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mResetNameVerifiedForOtherRawContacts == null) { 377478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mResetNameVerifiedForOtherRawContacts = getWritableDatabase().compileStatement( 377578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 377678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + RawContacts.NAME_VERIFIED + "=0" + 377778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + "=(" + 377878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 377978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 378078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?)" + 378178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " AND " + RawContacts._ID + "!=?"); 378278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 378378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mResetNameVerifiedForOtherRawContacts.bindLong(1, rawContactId); 378478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mResetNameVerifiedForOtherRawContacts.bindLong(2, rawContactId); 378578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mResetNameVerifiedForOtherRawContacts.execute(); 378678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 378778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 378878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void setDisplayName(long rawContactId, int displayNameSource, 378978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov String displayNamePrimary, String displayNameAlternative, String phoneticName, 379078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov int phoneticNameStyle, String sortKeyPrimary, String sortKeyAlternative) { 379178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mRawContactDisplayNameUpdate == null) { 379278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate = getWritableDatabase().compileStatement( 379378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.RAW_CONTACTS + 379478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + 379578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.DISPLAY_NAME_SOURCE + "=?," + 379678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.DISPLAY_NAME_PRIMARY + "=?," + 379778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," + 379878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.PHONETIC_NAME + "=?," + 379978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.PHONETIC_NAME_STYLE + "=?," + 380078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.SORT_KEY_PRIMARY + "=?," + 380178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov RawContacts.SORT_KEY_ALTERNATIVE + "=?" + 380278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?"); 380378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 380478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate.bindLong(1, displayNameSource); 380578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mRawContactDisplayNameUpdate, 2, displayNamePrimary); 380678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mRawContactDisplayNameUpdate, 3, displayNameAlternative); 380778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mRawContactDisplayNameUpdate, 4, phoneticName); 380878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate.bindLong(5, phoneticNameStyle); 380978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mRawContactDisplayNameUpdate, 6, sortKeyPrimary); 381078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mRawContactDisplayNameUpdate, 7, sortKeyAlternative); 381178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate.bindLong(8, rawContactId); 381278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mRawContactDisplayNameUpdate.execute(); 381378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 381478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 381578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /* 381678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Sets the given dataId record in the "data" table to primary, and resets all data records of 381778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * the same mimetype and under the same contact to not be primary. 381878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * 381978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * @param dataId the id of the data record to be set to primary. Pass -1 to clear the primary 382078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * flag of all data items of this raw contacts 382178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 382278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void setIsPrimary(long rawContactId, long dataId, long mimeTypeId) { 382378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mSetPrimaryStatement == null) { 382478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement = getWritableDatabase().compileStatement( 382578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.DATA + 382678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + Data.IS_PRIMARY + "=(_id=?)" + 382778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=?" + 382878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " AND " + Data.RAW_CONTACT_ID + "=?"); 382978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 383078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement.bindLong(1, dataId); 383178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement.bindLong(2, mimeTypeId); 383278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement.bindLong(3, rawContactId); 383378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetPrimaryStatement.execute(); 383478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 383578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 383678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /* 383778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Clears the super primary of all data items of the given raw contact. does not touch 383878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * other raw contacts of the same joined aggregate 383978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 384078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void clearSuperPrimary(long rawContactId, long mimeTypeId) { 384178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mClearSuperPrimaryStatement == null) { 384278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mClearSuperPrimaryStatement = getWritableDatabase().compileStatement( 384378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.DATA + 384478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + Data.IS_SUPER_PRIMARY + "=0" + 384578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=?" + 384678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " AND " + Data.RAW_CONTACT_ID + "=?"); 384778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 384878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mClearSuperPrimaryStatement.bindLong(1, mimeTypeId); 384978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mClearSuperPrimaryStatement.bindLong(2, rawContactId); 385078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mClearSuperPrimaryStatement.execute(); 385178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 385278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 385378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /* 385478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Sets the given dataId record in the "data" table to "super primary", and resets all data 385578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * records of the same mimetype and under the same aggregate to not be "super primary". 385678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * 385778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * @param dataId the id of the data record to be set to primary. 385878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 385978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void setIsSuperPrimary(long rawContactId, long dataId, long mimeTypeId) { 386078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mSetSuperPrimaryStatement == null) { 386178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement = getWritableDatabase().compileStatement( 386278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "UPDATE " + Tables.DATA + 386378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " SET " + Data.IS_SUPER_PRIMARY + "=(" + Data._ID + "=?)" + 386478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + DataColumns.MIMETYPE_ID + "=?" + 386578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " AND " + Data.RAW_CONTACT_ID + " IN (" + 386678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + RawContacts._ID + 386778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 386878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts.CONTACT_ID + " =(" + 386978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "SELECT " + RawContacts.CONTACT_ID + 387078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " FROM " + Tables.RAW_CONTACTS + 387178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + RawContacts._ID + "=?))"); 387278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 387378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement.bindLong(1, dataId); 387478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement.bindLong(2, mimeTypeId); 387578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement.bindLong(3, rawContactId); 387678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mSetSuperPrimaryStatement.execute(); 387778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 387878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 387978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** 388078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Inserts a record in the {@link Tables#NAME_LOOKUP} table. 388178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 388278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void insertNameLookup(long rawContactId, long dataId, int lookupType, String name) { 388378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (TextUtils.isEmpty(name)) { 388478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov return; 388578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 388678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 388778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mNameLookupInsert == null) { 388878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert = getWritableDatabase().compileStatement( 388978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "(" 389078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + NameLookupColumns.RAW_CONTACT_ID + "," 389178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + NameLookupColumns.DATA_ID + "," 389278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + NameLookupColumns.NAME_TYPE + "," 389378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + NameLookupColumns.NORMALIZED_NAME 389478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov + ") VALUES (?,?,?,?)"); 389578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 389678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert.bindLong(1, rawContactId); 389778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert.bindLong(2, dataId); 389878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert.bindLong(3, lookupType); 389978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov bindString(mNameLookupInsert, 4, name); 390078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupInsert.executeInsert(); 390178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 390278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov 390378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov /** 390478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov * Deletes all {@link Tables#NAME_LOOKUP} table rows associated with the specified data element. 390578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov */ 390678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov public void deleteNameLookup(long dataId) { 390778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov if (mNameLookupDelete == null) { 390878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupDelete = getWritableDatabase().compileStatement( 390978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov "DELETE FROM " + Tables.NAME_LOOKUP + 391078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov " WHERE " + NameLookupColumns.DATA_ID + "=?"); 391178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 391278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupDelete.bindLong(1, dataId); 391378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov mNameLookupDelete.execute(); 391478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov } 3915189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov 3916e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov public void insertNameLookupForOrganization(long rawContactId, long dataId, String company, 3917e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov String title) { 3918e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov if (!TextUtils.isEmpty(company)) { 3919e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov insertNameLookup(rawContactId, dataId, 3920e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov NameLookupType.ORGANIZATION, NameNormalizer.normalize(company)); 3921e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3922e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov if (!TextUtils.isEmpty(title)) { 3923e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov insertNameLookup(rawContactId, dataId, 3924e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov NameLookupType.ORGANIZATION, NameNormalizer.normalize(title)); 3925e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3926e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3927e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 3928e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov public String insertNameLookupForEmail(long rawContactId, long dataId, String email) { 3929e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov if (TextUtils.isEmpty(email)) { 3930e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov return null; 3931e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3932e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 3933e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov String address = extractHandleFromEmailAddress(email); 3934e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov if (address == null) { 3935e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov return null; 3936e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3937e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 3938e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov insertNameLookup(rawContactId, dataId, 3939e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov NameLookupType.EMAIL_BASED_NICKNAME, NameNormalizer.normalize(address)); 3940e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov return address; 3941e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3942e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 3943e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov /** 3944e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov * Normalizes the nickname and inserts it in the name lookup table. 3945e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov */ 3946e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov public void insertNameLookupForNickname(long rawContactId, long dataId, String nickname) { 3947e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov if (TextUtils.isEmpty(nickname)) { 3948e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov return; 3949e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3950e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 3951e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov insertNameLookup(rawContactId, dataId, 3952e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov NameLookupType.NICKNAME, NameNormalizer.normalize(nickname)); 3953e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 3954e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 39555df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov public void insertNameLookupForPhoneticName(long rawContactId, long dataId, String familyName, 39565df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov String middleName, String givenName) { 39575df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov mSb.setLength(0); 39585df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov if (familyName != null) { 39595df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov mSb.append(familyName.trim()); 39605df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39615df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov if (middleName != null) { 39625df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov mSb.append(middleName.trim()); 39635df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39645df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov if (givenName != null) { 39655df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov mSb.append(givenName.trim()); 39665df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39675df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov 39685df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov if (mSb.length() > 0) { 39695df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov insertNameLookup(rawContactId, dataId, NameLookupType.NAME_COLLATION_KEY, 39705df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov NameNormalizer.normalize(mSb.toString())); 39715df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39725df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov 39735df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov if (givenName != null) { 39745df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov // We want the phonetic given name to be used for search, but not for aggregation, 39755df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov // which is why we are using NAME_SHORTHAND rather than NAME_COLLATION_KEY 39765df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov insertNameLookup(rawContactId, dataId, NameLookupType.NAME_SHORTHAND, 39775df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov NameNormalizer.normalize(givenName.trim())); 39785df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39795df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov } 39805df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov 3981189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov /** 3982189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov * Performs a query and returns true if any Data item of the raw contact with the given 3983189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov * id and mimetype is marked as super-primary 3984189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov */ 3985189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov public boolean rawContactHasSuperPrimary(long rawContactId, long mimeTypeId) { 3986189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov final Cursor existsCursor = getReadableDatabase().rawQuery( 3987189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov "SELECT EXISTS(SELECT 1 FROM " + Tables.DATA + 3988189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov " WHERE " + Data.RAW_CONTACT_ID + "=?" + 3989189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov " AND " + DataColumns.MIMETYPE_ID + "=?" + 3990189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov " AND " + Data.IS_SUPER_PRIMARY + "<>0)", 3991189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov new String[] { String.valueOf(rawContactId), String.valueOf(mimeTypeId) }); 3992189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov try { 3993189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov if (!existsCursor.moveToFirst()) throw new IllegalStateException(); 3994189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov return existsCursor.getInt(0) != 0; 3995189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov } finally { 3996189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov existsCursor.close(); 3997189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov } 3998189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov } 3999e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov 4000e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov public String getCurrentCountryIso() { 4001e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov return mCountryMonitor.getCountryIso(); 4002e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov } 4003b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey} 4004