ContactsDatabaseHelper.java revision f9b77edaf5855bf6932fbc4b4b4342273669efef
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;
288ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikovimport android.database.CharArrayBuffer;
2936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.database.Cursor;
30b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.DatabaseUtils;
31f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikovimport android.database.SQLException;
3278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikovimport android.database.sqlite.SQLiteConstraintException;
33b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDatabase;
34b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteDoneException;
35b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikovimport android.database.sqlite.SQLiteException;
36b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteOpenHelper;
37bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.database.sqlite.SQLiteQueryBuilder;
38b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.database.sqlite.SQLiteStatement;
39892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikovimport android.location.CountryDetector;
40fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikovimport android.net.Uri;
414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.os.Binder;
42a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintanaimport android.os.Bundle;
43c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamiltonimport android.os.SystemClock;
44b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.provider.BaseColumns;
45e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikovimport android.provider.CallLog.Calls;
46a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract;
47b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
48a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
49a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
502a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
51a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname;
52a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
53a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
54a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
55a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
56d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.Contacts;
573d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikovimport android.provider.ContactsContract.Contacts.Photo;
58de4c4d84028c6c6999c6d9277b54b661f207b992Evan Millarimport android.provider.ContactsContract.Data;
59d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikovimport android.provider.ContactsContract.Directory;
605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
61b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerdaimport android.provider.ContactsContract.DisplayPhoto;
625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
63ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkeyimport android.provider.ContactsContract.Groups;
648ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
65f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.PhotoFiles;
66d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
67eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkeyimport android.provider.ContactsContract.Settings;
6882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
70ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmannimport android.provider.ContactsContract.StreamItems;
7167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkeyimport android.provider.SocialContract.Activities;
72069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjeeimport android.provider.VoicemailContract;
7359f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjeeimport android.provider.VoicemailContract.Voicemails;
74bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikovimport android.telephony.PhoneNumberUtils;
7536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikovimport android.text.TextUtils;
76b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Token;
77b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikovimport android.text.util.Rfc822Tokenizer;
78b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport android.util.Log;
79b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
80b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkeyimport java.util.HashMap;
815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
82b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
83b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey/**
84b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Database helper for contacts. Designed as a singleton to make sure that all
85b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * {@link android.content.ContentProvider} users get the same reference.
86b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov * Provides handy methods for maintaining package and mime-type lookup tables.
87b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey */
88b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov/* package */ class ContactsDatabaseHelper extends SQLiteOpenHelper {
89b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    private static final String TAG = "ContactsDatabaseHelper";
90b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
9197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    /**
9294c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov     * Contacts DB version ranges:
9397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     * <pre>
9497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   0-98    Cupcake/Donut
9597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   100-199 Eclair
9697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   200-299 Eclair-MR1
9797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   300-349 Froyo
9897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   350-399 Gingerbread
9997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     *   400-499 Honeycomb
10024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *   500-549 Honeycomb-MR1
10124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *   550-599 Honeycomb-MR2
10224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *   600-699 Ice Cream Sandwich
10397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     * </pre>
10497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov     */
105f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    static final int DATABASE_VERSION = 618;
106e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
107b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    private static final String DATABASE_NAME = "contacts2.db";
1081f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey    private static final String DATABASE_PRESENCE = "presence_db";
109b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
1105d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
1115d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
112b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public interface Tables {
113d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONTACTS = "contacts";
1145ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String RAW_CONTACTS = "raw_contacts";
1153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        public static final String STREAM_ITEMS = "stream_items";
1163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        public static final String STREAM_ITEM_PHOTOS = "stream_item_photos";
117f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        public static final String PHOTO_FILES = "photo_files";
118ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String PACKAGES = "packages";
119ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String MIMETYPES = "mimetypes";
120b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String PHONE_LOOKUP = "phone_lookup";
121a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        public static final String NAME_LOOKUP = "name_lookup";
122b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions";
123eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey        public static final String SETTINGS = "settings";
124b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String DATA = "data";
125ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String GROUPS = "groups";
1261f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey        public static final String PRESENCE = "presence";
127e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        public static final String AGGREGATED_PRESENCE = "agg_presence";
128b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        public static final String NICKNAME_LOOKUP = "nickname_lookup";
129e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov        public static final String CALLS = "calls";
130a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        public static final String STATUS_UPDATES = "status_updates";
131b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        public static final String PROPERTIES = "properties";
132743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        public static final String ACCOUNTS = "accounts";
1334394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        public static final String VISIBLE_CONTACTS = "visible_contacts";
134d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        public static final String DIRECTORIES = "directories";
135385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        public static final String DEFAULT_DIRECTORY = "default_directory";
136f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        public static final String SEARCH_INDEX = "search_index";
137069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        public static final String VOICEMAIL_STATUS = "voicemail_status";
138b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
1395d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // This list of tables contains auto-incremented sequences.
1405d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        public static final String[] SEQUENCE_TABLES = new String[] {
1415d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                CONTACTS,
1425d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                RAW_CONTACTS,
1435d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                STREAM_ITEMS,
1445d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                STREAM_ITEM_PHOTOS,
1455d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                PHOTO_FILES,
1465d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                DATA,
1475d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                GROUPS,
1485d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                CALLS,
1495d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                DIRECTORIES
1505d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        };
1515d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
15246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /**
15346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         * For {@link ContactsContract.DataUsageFeedback}. The table structure itself
15446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         * is not exposed outside.
15546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         */
15646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String DATA_USAGE_STAT = "data_usage_stat";
15746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
158ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String DATA_JOIN_MIMETYPES = "data "
1591b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov                + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id)";
160b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
16111944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov        public static final String DATA_JOIN_RAW_CONTACTS = "data "
1628e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)";
16311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov
1645ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String DATA_JOIN_MIMETYPE_RAW_CONTACTS = "data "
165c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
166c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)";
167bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov
168e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        // NOTE: This requires late binding of GroupMembership MIME-type
169e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        public static final String RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS = "raw_contacts "
170e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN settings ON ("
171e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                    + "raw_contacts.account_name = settings.account_name AND "
172f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                    + "raw_contacts.account_type = settings.account_type AND "
173f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                    + "((raw_contacts.data_set IS NULL AND settings.data_set IS NULL) "
174f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                    + "OR (raw_contacts.data_set = settings.data_set))) "
175e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND "
176e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                    + "data.raw_contact_id = raw_contacts._id) "
177e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID
178e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + ")";
179e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
180e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        // NOTE: This requires late binding of GroupMembership MIME-type
181e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        public static final String SETTINGS_JOIN_RAW_CONTACTS_DATA_MIMETYPES_CONTACTS = "settings "
182e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN raw_contacts ON ("
183e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                    + "raw_contacts.account_name = settings.account_name AND "
184e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                    + "raw_contacts.account_type = settings.account_type) "
185e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN data ON (data.mimetype_id=? AND "
186e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                    + "data.raw_contact_id = raw_contacts._id) "
187e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
188e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
189f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        public static final String CONTACTS_JOIN_RAW_CONTACTS_DATA_FILTERED_BY_GROUPMEMBERSHIP =
190f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                Tables.CONTACTS
191f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                    + " INNER JOIN " + Tables.RAW_CONTACTS
192f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + " ON (" + RawContactsColumns.CONCRETE_CONTACT_ID + "="
193f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + ContactsColumns.CONCRETE_ID
194f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + ")"
195f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                    + " INNER JOIN " + Tables.DATA
196f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + " ON (" + DataColumns.CONCRETE_DATA1 + "=" + GroupsColumns.CONCRETE_ID
197f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + " AND "
198f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID
199f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + " AND "
200f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + DataColumns.CONCRETE_MIMETYPE_ID + "="
201f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + "(SELECT " + MimetypesColumns._ID
202f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + " FROM " + Tables.MIMETYPES
203f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + " WHERE "
204f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + MimetypesColumns.CONCRETE_MIMETYPE + "="
205f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                                + "'" + GroupMembership.CONTENT_ITEM_TYPE + "'"
206f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                            + ")"
207f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                        + ")";
208ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
2095ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data "
2101b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov                + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
2111b03c2d019966fba89dad3678dd9f04e4e5f4802Dmitri Plotnikov                + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
21267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) "
2139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                + "LEFT OUTER JOIN groups "
2149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                + "  ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' "
2159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                + "      AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") ";
216ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
217ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String GROUPS_JOIN_PACKAGES = "groups "
218ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)";
219ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
220b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
221b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String ACTIVITIES = "activities";
222b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
223ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String ACTIVITIES_JOIN_MIMETYPES = "activities "
224ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)";
225b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
226d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS =
2275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                "activities "
22867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) "
229ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) "
2305ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " +
231fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        "raw_contacts._id) "
232d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
2337e4676dfcaa8853b81c2133e0e318ed3436fe787Fred Quintana
2345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup "
23503975f7ca8bb2f95ce95b6c694612c2524e91d13Dave Santoro                + "INNER JOIN view_raw_contacts ON (name_lookup.raw_contact_id = "
23603975f7ca8bb2f95ce95b6c694612c2524e91d13Dave Santoro                + "view_raw_contacts._id)";
237b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
238b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
2394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public interface Views {
240ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        public static final String DATA = "view_data";
241ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        public static final String RAW_CONTACTS = "view_raw_contacts";
242ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        public static final String CONTACTS = "view_contacts";
243a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        public static final String ENTITIES = "view_entities";
244a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        public static final String RAW_ENTITIES = "view_raw_entities";
245ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        public static final String GROUPS = "view_groups";
246ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        public static final String DATA_USAGE_STAT = "view_data_usage_stat";
2479b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        public static final String STREAM_ITEMS = "view_stream_items";
2484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
2494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2501f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey    public interface Clauses {
25168936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey        final String HAVING_NO_GROUPS = "COUNT(" + DataColumns.CONCRETE_GROUP_ID + ") == 0";
2529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
25368936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey        final String GROUP_BY_ACCOUNT_CONTACT_ID = SettingsColumns.CONCRETE_ACCOUNT_NAME + ","
25468936cefd4caa779169ea00ffd1adc399e634c9bJeff Sharkey                + SettingsColumns.CONCRETE_ACCOUNT_TYPE + "," + RawContacts.CONTACT_ID;
255e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
256e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        final String RAW_CONTACT_IS_LOCAL = RawContactsColumns.CONCRETE_ACCOUNT_NAME
25743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + " IS NULL AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL AND "
25843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + RawContactsColumns.CONCRETE_DATA_SET + " IS NULL";
259e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
260e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        final String ZERO_GROUP_MEMBERSHIPS = "COUNT(" + GroupsColumns.CONCRETE_ID + ")=0";
261e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
2621a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey        final String OUTER_RAW_CONTACTS = "outer_raw_contacts";
2631a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey        final String OUTER_RAW_CONTACTS_ID = OUTER_RAW_CONTACTS + "." + RawContacts._ID;
2641a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey
265b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov        final String CONTACT_IS_VISIBLE =
266b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                "SELECT " +
2671a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey                    "MAX((SELECT (CASE WHEN " +
268b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                        "(CASE" +
269b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                            " WHEN " + RAW_CONTACT_IS_LOCAL +
270b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                            " THEN 1 " +
271b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                            " WHEN " + ZERO_GROUP_MEMBERSHIPS +
272b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                            " THEN " + Settings.UNGROUPED_VISIBLE +
273b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                            " ELSE MAX(" + Groups.GROUP_VISIBLE + ")" +
274b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                         "END)=1 THEN 1 ELSE 0 END)" +
275b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                " FROM " + Tables.RAW_CONTACTS_JOIN_SETTINGS_DATA_GROUPS +
2761a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey                " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + OUTER_RAW_CONTACTS_ID + "))" +
2771a21fa6383449df4bf0d46138a23aa02dfa235a0Jeff Sharkey                " FROM " + Tables.RAW_CONTACTS + " AS " + OUTER_RAW_CONTACTS +
278b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID +
279b3ce7aaa2390698c9424d17df4d2979dcd902cfdDmitri Plotnikov                " GROUP BY " + RawContacts.CONTACT_ID;
280e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
281e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND "
28243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND "
28343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + Groups.DATA_SET + " IS NULL";
28443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
28543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        final String GROUP_HAS_ACCOUNT_AND_DATA_SET_AND_SOURCE_ID = Groups.SOURCE_ID + "=? AND "
28643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND "
28743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + Groups.DATA_SET + "=?";
2884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
2894394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        public static final String CONTACT_VISIBLE =
2904394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov            "EXISTS (SELECT _id FROM " + Tables.VISIBLE_CONTACTS
2914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                + " WHERE " + Tables.CONTACTS +"." + Contacts._ID
2924394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                        + "=" + Tables.VISIBLE_CONTACTS +"." + Contacts._ID + ")";
2931f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey    }
2941f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey
295d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    public interface ContactsColumns {
296a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        public static final String LAST_STATUS_UPDATE_ID = "status_update_id";
297a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
298d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID;
29967dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey
300f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        public static final String CONCRETE_PHOTO_FILE_ID = Tables.CONTACTS + "."
301f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + Contacts.PHOTO_FILE_ID;
302d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "."
303d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + Contacts.TIMES_CONTACTED;
304d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "."
305d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + Contacts.LAST_TIME_CONTACTED;
306d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED;
307d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "."
308d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + Contacts.CUSTOM_RINGTONE;
309d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "."
310d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + Contacts.SEND_TO_VOICEMAIL;
3112d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill        public static final String CONCRETE_LOOKUP_KEY = Tables.CONTACTS + "."
3122d2ec88b7af615b2f05e987da45425be9cace1baTom O'Neill                + Contacts.LOOKUP_KEY;
313619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    }
314619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
3156cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov    public interface RawContactsColumns {
31633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        public static final String CONCRETE_ID =
3175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + BaseColumns._ID;
3189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        public static final String CONCRETE_ACCOUNT_NAME =
3195ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME;
3209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        public static final String CONCRETE_ACCOUNT_TYPE =
3215ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE;
32243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        public static final String CONCRETE_DATA_SET =
32343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.DATA_SET;
32443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        public static final String CONCRETE_ACCOUNT_TYPE_AND_DATA_SET =
32543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE_AND_DATA_SET;
32633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        public static final String CONCRETE_SOURCE_ID =
3275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID;
32833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        public static final String CONCRETE_VERSION =
3295ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.VERSION;
33033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        public static final String CONCRETE_DIRTY =
3315ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.DIRTY;
33233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        public static final String CONCRETE_DELETED =
3335ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.DELETED;
3347a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana        public static final String CONCRETE_SYNC1 =
3357a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana                Tables.RAW_CONTACTS + "." + RawContacts.SYNC1;
3367a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana        public static final String CONCRETE_SYNC2 =
3377a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana                Tables.RAW_CONTACTS + "." + RawContacts.SYNC2;
3387a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana        public static final String CONCRETE_SYNC3 =
3397a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana                Tables.RAW_CONTACTS + "." + RawContacts.SYNC3;
3407a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana        public static final String CONCRETE_SYNC4 =
3417a4550f2afb24b2112b6c937f416c6f46ece35f4Fred Quintana                Tables.RAW_CONTACTS + "." + RawContacts.SYNC4;
34224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        public static final String CONCRETE_CUSTOM_RINGTONE =
34324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.CUSTOM_RINGTONE;
34424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        public static final String CONCRETE_SEND_TO_VOICEMAIL =
34524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.SEND_TO_VOICEMAIL;
34624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        public static final String CONCRETE_LAST_TIME_CONTACTED =
34724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.LAST_TIME_CONTACTED;
34824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        public static final String CONCRETE_TIMES_CONTACTED =
34924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Tables.RAW_CONTACTS + "." + RawContacts.TIMES_CONTACTED;
350c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey        public static final String CONCRETE_STARRED =
351c76d0a78fe2d3471195cfa555bab016eec154f07Jeff Sharkey                Tables.RAW_CONTACTS + "." + RawContacts.STARRED;
3528e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
3535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        public static final String DISPLAY_NAME = RawContacts.DISPLAY_NAME_PRIMARY;
3545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        public static final String DISPLAY_NAME_SOURCE = RawContacts.DISPLAY_NAME_SOURCE;
3558e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        public static final String AGGREGATION_NEEDED = "aggregation_needed";
356fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
357fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        public static final String CONCRETE_DISPLAY_NAME =
358fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Tables.RAW_CONTACTS + "." + DISPLAY_NAME;
359fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        public static final String CONCRETE_CONTACT_ID =
360fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.CONTACT_ID;
361f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov        public static final String CONCRETE_NAME_VERIFIED =
362f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov                Tables.RAW_CONTACTS + "." + RawContacts.NAME_VERIFIED;
363619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    }
364619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
365619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    public interface DataColumns {
36667dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey        public static final String PACKAGE_ID = "package_id";
367b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String MIMETYPE_ID = "mimetype_id";
368ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
369ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID;
370226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID;
371d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "."
372d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                + Data.RAW_CONTACT_ID;
373ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String CONCRETE_GROUP_ID = Tables.DATA + "."
374ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                + GroupMembership.GROUP_ROW_ID;
375e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov
376e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1;
377e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2;
378e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3;
379e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4;
380e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5;
381e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6;
382e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7;
383e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8;
384e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9;
385e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10;
3860f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11;
3870f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12;
3880f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13;
3890f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14;
3900f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15;
391e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY;
392226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID;
393e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov    }
394e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov
3950f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov    // Used only for legacy API support
3960f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov    public interface ExtensionsColumns {
3970f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String NAME = Data.DATA1;
3980f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String VALUE = Data.DATA2;
3990f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov    }
4000f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov
4010f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov    public interface GroupMembershipColumns {
4025ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID;
4030f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov        public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID;
4040f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov    }
4050f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov
406e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov    public interface PhoneColumns {
407e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String NORMALIZED_NUMBER = Data.DATA4;
408e80e514a6175ad2ee03ea6eff6201e0e47d5a710Dmitri Plotnikov        public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4;
409ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    }
410ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
411ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    public interface GroupsColumns {
41267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey        public static final String PACKAGE_ID = "package_id";
41367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey
414ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID;
41567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey        public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_ID;
4161cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann        public static final String CONCRETE_ACCOUNT_NAME =
4171cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann                Tables.GROUPS + "." + Groups.ACCOUNT_NAME;
4181cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann        public static final String CONCRETE_ACCOUNT_TYPE =
4191cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann                Tables.GROUPS + "." + Groups.ACCOUNT_TYPE;
42043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        public static final String CONCRETE_DATA_SET = Tables.GROUPS + "." + Groups.DATA_SET;
42143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        public static final String CONCRETE_ACCOUNT_TYPE_AND_DATA_SET = Tables.GROUPS + "." +
42243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET;
423341e4621f2ee7614c66bc25dd3da70eaaa866b46Jeff Sharkey    }
424b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
425b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public interface ActivitiesColumns {
426b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String PACKAGE_ID = "package_id";
427b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String MIMETYPE_ID = "mimetype_id";
428b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
429b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
430b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public interface PhoneLookupColumns {
431b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String _ID = BaseColumns._ID;
432b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String DATA_ID = "data_id";
4335ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String RAW_CONTACT_ID = "raw_contact_id";
434b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String NORMALIZED_NUMBER = "normalized_number";
43536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        public static final String MIN_MATCH = "min_match";
436b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
437b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
438a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    public interface NameLookupColumns {
4395ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        public static final String RAW_CONTACT_ID = "raw_contact_id";
44014bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov        public static final String DATA_ID = "data_id";
441a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        public static final String NORMALIZED_NAME = "normalized_name";
442a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        public static final String NAME_TYPE = "name_type";
443a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    }
444a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov
445a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov    public final static class NameLookupType {
4462a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov        public static final int NAME_EXACT = 0;
4472a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov        public static final int NAME_VARIANT = 1;
4482a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov        public static final int NAME_COLLATION_KEY = 2;
4492a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov        public static final int NICKNAME = 3;
4502a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov        public static final int EMAIL_BASED_NICKNAME = 4;
451a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov
452a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov        // This is the highest name lookup type code plus one
45392ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        public static final int TYPE_COUNT = 5;
454a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov
455a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov        public static boolean isBasedOnStructuredName(int nameLookupType) {
4562a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov            return nameLookupType == NameLookupType.NAME_EXACT
4572a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov                    || nameLookupType == NameLookupType.NAME_VARIANT
4582a03d9c2bf627795963561a0f9406b23dc93fec5Dmitri Plotnikov                    || nameLookupType == NameLookupType.NAME_COLLATION_KEY;
459a5ad551e1753086825499f1aeb6415bb986f3588Dmitri Plotnikov        }
460a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    }
461a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov
462ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    public interface PackagesColumns {
463b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String _ID = BaseColumns._ID;
464b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String PACKAGE = "package";
465226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana
466226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        public static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID;
467b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
468b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
469ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    public interface MimetypesColumns {
470b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String _ID = BaseColumns._ID;
471b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        public static final String MIMETYPE = "mimetype";
472ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
473ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID;
474ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE;
475b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
476b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
477b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov    public interface AggregationExceptionColumns {
478b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        public static final String _ID = BaseColumns._ID;
479b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov    }
480b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
481b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov    public interface NicknameLookupColumns {
482b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        public static final String NAME = "name";
483b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        public static final String CLUSTER = "cluster";
484b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov    }
485b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
486e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey    public interface SettingsColumns {
487e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        public static final String CONCRETE_ACCOUNT_NAME = Tables.SETTINGS + "."
488e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + Settings.ACCOUNT_NAME;
489e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey        public static final String CONCRETE_ACCOUNT_TYPE = Tables.SETTINGS + "."
490e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey                + Settings.ACCOUNT_TYPE;
491f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        public static final String CONCRETE_DATA_SET = Tables.SETTINGS + "."
492f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                + Settings.DATA_SET;
493e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey    }
494e07913c61c320b0cc2036db3b714e39534d8cd7aJeff Sharkey
4954dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    public interface PresenceColumns {
4964dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        String RAW_CONTACT_ID = "presence_raw_contact_id";
497bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        String CONTACT_ID = "presence_contact_id";
4984dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
4994dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
500e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov    public interface AggregatedPresenceColumns {
501e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        String CONTACT_ID = "presence_contact_id";
5023296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5033296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_CONTACT_ID = Tables.AGGREGATED_PRESENCE + "." + CONTACT_ID;
504e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov    }
505e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov
506a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    public interface StatusUpdatesColumns {
507a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        String DATA_ID = "status_update_data_id";
5083296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5093296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_DATA_ID = Tables.STATUS_UPDATES + "." + DATA_ID;
5103296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5113296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_PRESENCE = Tables.STATUS_UPDATES + "." + StatusUpdates.PRESENCE;
5123296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS;
5133296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_TIMESTAMP = Tables.STATUS_UPDATES + "."
5143296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey                + StatusUpdates.STATUS_TIMESTAMP;
5153296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_RES_PACKAGE = Tables.STATUS_UPDATES + "."
5163296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey                + StatusUpdates.STATUS_RES_PACKAGE;
5173296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_LABEL = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_LABEL;
5183296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_ICON = Tables.STATUS_UPDATES + "." + StatusUpdates.STATUS_ICON;
5193296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey    }
5203296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5213296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey    public interface ContactsStatusUpdatesColumns {
5223296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String ALIAS = "contacts_" + Tables.STATUS_UPDATES;
5233296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5243296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_DATA_ID = ALIAS + "." + StatusUpdatesColumns.DATA_ID;
5253296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey
5263296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_PRESENCE = ALIAS + "." + StatusUpdates.PRESENCE;
5273296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS = ALIAS + "." + StatusUpdates.STATUS;
5283296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_TIMESTAMP = ALIAS + "." + StatusUpdates.STATUS_TIMESTAMP;
5293296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_RES_PACKAGE = ALIAS + "." + StatusUpdates.STATUS_RES_PACKAGE;
5303296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_LABEL = ALIAS + "." + StatusUpdates.STATUS_LABEL;
5313296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey        String CONCRETE_STATUS_ICON = ALIAS + "." + StatusUpdates.STATUS_ICON;
532a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
533a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
5343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public interface StreamItemsColumns {
5350bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_ID = Tables.STREAM_ITEMS + "." + BaseColumns._ID;
5360bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_RAW_CONTACT_ID =
5370bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                Tables.STREAM_ITEMS + "." + StreamItems.RAW_CONTACT_ID;
5380bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_PACKAGE = Tables.STREAM_ITEMS + "." + StreamItems.RES_PACKAGE;
5390bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_ICON = Tables.STREAM_ITEMS + "." + StreamItems.RES_ICON;
5400bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_LABEL = Tables.STREAM_ITEMS + "." + StreamItems.RES_LABEL;
5410bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_TEXT = Tables.STREAM_ITEMS + "." + StreamItems.TEXT;
5420bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_TIMESTAMP = Tables.STREAM_ITEMS + "." + StreamItems.TIMESTAMP;
5430bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_COMMENTS = Tables.STREAM_ITEMS + "." + StreamItems.COMMENTS;
5440bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC1 = Tables.STREAM_ITEMS + "." + StreamItems.SYNC1;
5450bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC2 = Tables.STREAM_ITEMS + "." + StreamItems.SYNC2;
5460bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC3 = Tables.STREAM_ITEMS + "." + StreamItems.SYNC3;
5470bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC4 = Tables.STREAM_ITEMS + "." + StreamItems.SYNC4;
5483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
5493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
5503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public interface StreamItemPhotosColumns {
5510bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_ID = Tables.STREAM_ITEM_PHOTOS + "." + BaseColumns._ID;
5520bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_STREAM_ITEM_ID = Tables.STREAM_ITEM_PHOTOS + "."
5533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                + StreamItemPhotos.STREAM_ITEM_ID;
5540bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SORT_INDEX =
5550bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                Tables.STREAM_ITEM_PHOTOS + "." + StreamItemPhotos.SORT_INDEX;
5560bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_PHOTO_FILE_ID = Tables.STREAM_ITEM_PHOTOS + "."
5576802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                + StreamItemPhotos.PHOTO_FILE_ID;
5580bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC1 = Tables.STREAM_ITEM_PHOTOS + "." + StreamItemPhotos.SYNC1;
5590bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC2 = Tables.STREAM_ITEM_PHOTOS + "." + StreamItemPhotos.SYNC2;
5600bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC3 = Tables.STREAM_ITEM_PHOTOS + "." + StreamItemPhotos.SYNC3;
5610bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        final String CONCRETE_SYNC4 = Tables.STREAM_ITEM_PHOTOS + "." + StreamItemPhotos.SYNC4;
5623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
5633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
564f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public interface PhotoFilesColumns {
565f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String CONCRETE_ID = Tables.PHOTO_FILES + "." + BaseColumns._ID;
566f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String CONCRETE_HEIGHT = Tables.PHOTO_FILES + "." + PhotoFiles.HEIGHT;
567f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String CONCRETE_WIDTH = Tables.PHOTO_FILES + "." + PhotoFiles.WIDTH;
568f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String CONCRETE_FILESIZE = Tables.PHOTO_FILES + "." + PhotoFiles.FILESIZE;
569f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
570f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
571b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public interface PropertiesColumns {
572b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        String PROPERTY_KEY = "property_key";
573b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        String PROPERTY_VALUE = "property_value";
574b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
575b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
57624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public interface AccountsColumns {
57724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String ACCOUNT_NAME = RawContacts.ACCOUNT_NAME;
57824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String ACCOUNT_TYPE = RawContacts.ACCOUNT_TYPE;
57943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        String DATA_SET = RawContacts.DATA_SET;
58024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
58124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
582e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    public static final class DirectoryColumns {
583e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov        public static final String TYPE_RESOURCE_NAME = "typeResourceName";
584e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    }
585e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov
586f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    public static final class SearchIndexColumns {
587f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        public static final String CONTACT_ID = "contact_id";
588f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        public static final String CONTENT = "content";
589155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        public static final String NAME = "name";
590f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        public static final String TOKENS = "tokens";
591f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    }
592f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
59346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /**
59446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa     * Private table for calculating per-contact-method ranking.
59546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa     */
59646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public static final class DataUsageStatColumns {
59746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /** type: INTEGER (long) */
59846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String _ID = "stat_id";
59946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String CONCRETE_ID = Tables.DATA_USAGE_STAT + "." + _ID;
60046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
60146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /** type: INTEGER (long) */
60246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String DATA_ID = "data_id";
60346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String CONCRETE_DATA_ID = Tables.DATA_USAGE_STAT + "." + DATA_ID;
60446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
60546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /** type: INTEGER (long) */
60646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String LAST_TIME_USED = "last_time_used";
60746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String CONCRETE_LAST_TIME_USED =
60846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                Tables.DATA_USAGE_STAT + "." + LAST_TIME_USED;
60946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
61046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /** type: INTEGER */
61146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String TIMES_USED = "times_used";
61246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String CONCRETE_TIMES_USED =
61346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                Tables.DATA_USAGE_STAT + "." + TIMES_USED;
61446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
61546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /** type: INTEGER */
61646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String USAGE_TYPE_INT = "usage_type";
61746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final String CONCRETE_USAGE_TYPE =
61846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                Tables.DATA_USAGE_STAT + "." + USAGE_TYPE_INT;
61946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
62046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        /**
62146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         * Integer values for USAGE_TYPE.
62246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         *
62346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         * @see ContactsContract.DataUsageFeedback#USAGE_TYPE
62446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa         */
62546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final int USAGE_TYPE_INT_CALL = 0;
62646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final int USAGE_TYPE_INT_LONG_TEXT = 1;
62746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        public static final int USAGE_TYPE_INT_SHORT_TEXT = 2;
62846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
62946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
6303296d3469bce0041a6cefc44d0486a2a7d0c9f82Jeff Sharkey    /** In-memory cache of previously found MIME-type mappings */
631bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov    private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>();
632b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /** In-memory cache of previously found package name mappings */
633bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov    private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>();
634b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
6352a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdEmail;
6362a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdIm;
637a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private long mMimeTypeIdSip;
6382a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdStructuredName;
6392a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdOrganization;
6402a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdNickname;
6412a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private long mMimeTypeIdPhone;
642b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
643b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /** Compiled statements for querying and inserting mappings */
644d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private SQLiteStatement mContactIdQuery;
645f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    private SQLiteStatement mAggregationModeQuery;
646b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    private SQLiteStatement mDataMimetypeQuery;
647b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    private SQLiteStatement mActivitiesMimetypeQuery;
648b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
64978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /** Precompiled sql statement for setting a data record to the primary. */
65078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mSetPrimaryStatement;
65178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /** Precompiled sql statement for setting a data record to the super primary. */
65278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mSetSuperPrimaryStatement;
65378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /** Precompiled sql statement for clearing super primary of a single record. */
65478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mClearSuperPrimaryStatement;
65578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /** Precompiled sql statement for updating a contact display name */
65678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mRawContactDisplayNameUpdate;
65778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
65878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mNameLookupInsert;
65978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mNameLookupDelete;
66078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mStatusUpdateAutoTimestamp;
66178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mStatusUpdateInsert;
66278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mStatusUpdateReplace;
66378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mStatusAttributionUpdate;
66478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mStatusUpdateDelete;
66578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private SQLiteStatement mResetNameVerifiedForOtherRawContacts;
666f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    private SQLiteStatement mContactInDefaultDirectoryQuery;
66778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
668b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov    private final Context mContext;
6692a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private final boolean mDatabaseOptimizationEnabled;
67035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana    private final SyncStateContentProviderHelper mSyncState;
671e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    private final CountryMonitor mCountryMonitor;
6725df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov    private StringBuilder mSb = new StringBuilder();
673f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov
674f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    private boolean mReopenDatabase = false;
675f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
676b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    private static ContactsDatabaseHelper sSingleton = null;
677b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
67836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov    private boolean mUseStrictPhoneNumberComparison;
6793a6a49cfb06272e3e25f3c390a9cf4002da6e34dDaisuke Miyakawa
6808ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    private String[] mSelectionArgs1 = new String[1];
6818ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    private NameSplitter.Name mName = new NameSplitter.Name();
6828ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    private CharArrayBuffer mCharArrayBuffer = new CharArrayBuffer(128);
6838ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    private NameSplitter mNameSplitter;
684f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov
685b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    public static synchronized ContactsDatabaseHelper getInstance(Context context) {
686b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        if (sSingleton == null) {
6872a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            sSingleton = new ContactsDatabaseHelper(context, DATABASE_NAME, true);
688b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        }
689b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        return sSingleton;
690b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
691b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
6921f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey    /**
69331b86315536573a72dc7fff1baac3b314e5a04c3Dmitri Plotnikov     * Private constructor, callers except unit tests should obtain an instance through
69435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana     * {@link #getInstance(android.content.Context)} instead.
6951f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey     */
696b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikov    ContactsDatabaseHelper(Context context) {
6972a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        this(context, null, false);
6982a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
6992a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
7005d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    protected ContactsDatabaseHelper(
7012a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            Context context, String databaseName, boolean optimizationEnabled) {
7022a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        super(context, databaseName, null, DATABASE_VERSION);
7032a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        mDatabaseOptimizationEnabled = optimizationEnabled;
704d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton        Resources resources = context.getResources();
705619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
706b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        mContext = context;
70728b3769e3fcecae56c3fc70cbcb0f95282b9640eFred Quintana        mSyncState = new SyncStateContentProviderHelper();
708e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        mCountryMonitor = new CountryMonitor(context);
70936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        mUseStrictPhoneNumberComparison =
710d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton                resources.getBoolean(
711d91272b48f97243533c6580981e12a4847b5783fJeff Hamilton                        com.android.internal.R.bool.config_use_strict_phone_number_comparation);
712b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
713b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
7142a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    private void refreshDatabaseCaches(SQLiteDatabase db) {
71578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateDelete = null;
71678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateReplace = null;
71778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateInsert = null;
71878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateAutoTimestamp = null;
71978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusAttributionUpdate = null;
72078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mResetNameVerifiedForOtherRawContacts = null;
72178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mRawContactDisplayNameUpdate = null;
72278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetPrimaryStatement = null;
72378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mClearSuperPrimaryStatement = null;
72478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetSuperPrimaryStatement = null;
72578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupInsert = null;
72678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupDelete = null;
72778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mDataMimetypeQuery = null;
72878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mActivitiesMimetypeQuery = null;
72978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mContactIdQuery = null;
73078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mAggregationModeQuery = null;
731f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        mContactInDefaultDirectoryQuery = null;
7322a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
73355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        populateMimeTypeCache(db);
73455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov    }
73555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
73655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov    private void populateMimeTypeCache(SQLiteDatabase db) {
7372a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        mMimetypeCache.clear();
7382a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        mPackageCache.clear();
7392a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
74011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        // TODO: This could be optimized into one query instead of 7
74111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        //        Also: We shouldn't have those fields in the first place. This should just be
74211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        //        in the cache
74311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdEmail = lookupMimeTypeId(Email.CONTENT_ITEM_TYPE, db);
74411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdIm = lookupMimeTypeId(Im.CONTENT_ITEM_TYPE, db);
74511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdSip = lookupMimeTypeId(SipAddress.CONTENT_ITEM_TYPE, db);
74611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdStructuredName = lookupMimeTypeId(StructuredName.CONTENT_ITEM_TYPE, db);
74711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdOrganization = lookupMimeTypeId(Organization.CONTENT_ITEM_TYPE, db);
74811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdNickname = lookupMimeTypeId(Nickname.CONTENT_ITEM_TYPE, db);
74911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        mMimeTypeIdPhone = lookupMimeTypeId(Phone.CONTENT_ITEM_TYPE, db);
75078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
75178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
752b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    @Override
753b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public void onOpen(SQLiteDatabase db) {
7542a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        refreshDatabaseCaches(db);
75535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana
75678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSyncState.onDatabaseOpened(db);
7571f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey
7581f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey        db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";");
759e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        db.execSQL("CREATE TABLE IF NOT EXISTS " + DATABASE_PRESENCE + "." + Tables.PRESENCE + " ("+
76082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," +
76182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.PROTOCOL + " INTEGER NOT NULL," +
76282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL + " TEXT," +
76382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.IM_HANDLE + " TEXT," +
76482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.IM_ACCOUNT + " TEXT," +
765a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov                PresenceColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," +
766a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," +
76782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.PRESENCE + " INTEGER," +
768aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0," +
76982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                "UNIQUE(" + StatusUpdates.PROTOCOL + ", " + StatusUpdates.CUSTOM_PROTOCOL
77082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                    + ", " + StatusUpdates.IM_HANDLE + ", " + StatusUpdates.IM_ACCOUNT + ")" +
7711f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey        ");");
7721f42f1958113b2dadc6cf26b51192b42f883f3b0Jeff Sharkey
773e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex" + " ON "
7744dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + Tables.PRESENCE + " (" + PresenceColumns.RAW_CONTACT_ID + ");");
77509562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori        db.execSQL("CREATE INDEX IF NOT EXISTS " + DATABASE_PRESENCE + ".presenceIndex2" + " ON "
77609562b6c3a420ded0d02b9bd2290de2dbab9e304Vasu Nori                + Tables.PRESENCE + " (" + PresenceColumns.CONTACT_ID + ");");
777e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov
778e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        db.execSQL("CREATE TABLE IF NOT EXISTS "
779aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                + DATABASE_PRESENCE + "." + Tables.AGGREGATED_PRESENCE + " ("+
780e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov                AggregatedPresenceColumns.CONTACT_ID
781e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov                        + " INTEGER PRIMARY KEY REFERENCES contacts(_id)," +
782632248ae0053fa99b1f5b4cfaab3e55b7453fcb1Vasu Nori                StatusUpdates.PRESENCE + " INTEGER," +
783aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CHAT_CAPABILITY + " INTEGER NOT NULL DEFAULT 0" +
784e46667e641cd1c60998e1ccab4b60531d5b12ef7Dmitri Plotnikov        ");");
785bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
786bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
787bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_deleted"
788bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " BEFORE DELETE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE
789bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " BEGIN "
790bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + "   DELETE FROM " + Tables.AGGREGATED_PRESENCE
791bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + "     WHERE " + AggregatedPresenceColumns.CONTACT_ID + " = " +
792bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                        "(SELECT " + PresenceColumns.CONTACT_ID +
793bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                        " FROM " + Tables.PRESENCE +
794bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                        " WHERE " + PresenceColumns.RAW_CONTACT_ID
795bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                + "=OLD." + PresenceColumns.RAW_CONTACT_ID +
796bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                        " AND NOT EXISTS" +
797bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                "(SELECT " + PresenceColumns.RAW_CONTACT_ID +
798bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                " FROM " + Tables.PRESENCE +
799bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                " WHERE " + PresenceColumns.CONTACT_ID
800bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                        + "=OLD." + PresenceColumns.CONTACT_ID +
801bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                " AND " + PresenceColumns.RAW_CONTACT_ID
802bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                                        + "!=OLD." + PresenceColumns.RAW_CONTACT_ID + "));"
803bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " END");
804bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
805aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        final String replaceAggregatePresenceSql =
806aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "("
807093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + AggregatedPresenceColumns.CONTACT_ID + ", "
808093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + StatusUpdates.PRESENCE + ", "
809093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + StatusUpdates.CHAT_CAPABILITY + ")"
810093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                + " SELECT "
811093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + PresenceColumns.CONTACT_ID + ","
812093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + StatusUpdates.PRESENCE + ","
813093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + StatusUpdates.CHAT_CAPABILITY
814aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                + " FROM " + Tables.PRESENCE
815aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                + " WHERE "
816093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    + " (ifnull(" + StatusUpdates.PRESENCE + ",0)  * 10 "
817093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                            + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))"
818093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    + " = (SELECT "
819093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + "MAX (ifnull(" + StatusUpdates.PRESENCE + ",0)  * 10 "
820093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                                + "+ ifnull(" + StatusUpdates.CHAT_CAPABILITY + ", 0))"
821093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + " FROM " + Tables.PRESENCE
822093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                        + " WHERE " + PresenceColumns.CONTACT_ID
823093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                            + "=NEW." + PresenceColumns.CONTACT_ID
824093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    + ")"
825093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                + " AND " + PresenceColumns.CONTACT_ID + "=NEW." + PresenceColumns.CONTACT_ID + ";";
826bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
827bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_inserted"
828bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " AFTER INSERT ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE
829bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " BEGIN "
830bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + replaceAggregatePresenceSql
831bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " END");
832bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
833bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + DATABASE_PRESENCE + "." + Tables.PRESENCE + "_updated"
834bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " AFTER UPDATE ON " + DATABASE_PRESENCE + "." + Tables.PRESENCE
835bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " BEGIN "
836bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + replaceAggregatePresenceSql
837bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov                + " END");
838b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
839b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
840b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    @Override
841b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public void onCreate(SQLiteDatabase db) {
842069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        Log.i(TAG, "Bootstrapping database version: " + DATABASE_VERSION);
843b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
84435ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana        mSyncState.createDatabase(db);
84535ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana
846b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // One row per group of contacts corresponding to the same person
847d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" +
848b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
849fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," +
850d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," +
851f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID + " INTEGER REFERENCES photo_files(_id)," +
852d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE + " TEXT," +
853d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," +
854d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," +
855d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED + " INTEGER," +
856d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," +
857f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER + " INTEGER NOT NULL DEFAULT 0," +
8585870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov                Contacts.LOOKUP_KEY + " TEXT," +
859ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann                ContactsColumns.LAST_STATUS_UPDATE_ID + " INTEGER REFERENCES data(_id)" +
860b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
861b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
86254d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov        db.execSQL("CREATE INDEX contacts_has_phone_index ON " + Tables.CONTACTS + " (" +
86354d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER +
86454d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov        ");");
86554d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov
866fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" +
867fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID +
868fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        ");");
869fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
870b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // Contacts table
8715ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" +
8726cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
8736cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " +
8746cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " +
87543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET + " STRING DEFAULT NULL, " +
8766cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.SOURCE_ID + " TEXT," +
87797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                RawContacts.RAW_CONTACT_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," +
8786cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," +
87973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov                RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 0," +
88033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," +
88154d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov                RawContacts.CONTACT_ID + " INTEGER REFERENCES contacts(_id)," +
8826cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " +
8836cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                        RawContacts.AGGREGATION_MODE_DEFAULT + "," +
8848e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                RawContactsColumns.AGGREGATION_NEEDED + " INTEGER NOT NULL DEFAULT 1," +
8856cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.CUSTOM_RINGTONE + " TEXT," +
8866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," +
8876cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," +
8886cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED + " INTEGER," +
88933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," +
8905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY + " TEXT," +
8915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT," +
8925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE + " INTEGER NOT NULL DEFAULT " +
89325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov                        DisplayNameSources.UNDEFINED + "," +
8945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.PHONETIC_NAME + " TEXT," +
8955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE + " TEXT," +
896de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                RawContacts.SORT_KEY_PRIMARY + " TEXT COLLATE " +
897de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                        ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," +
898de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                RawContacts.SORT_KEY_ALTERNATIVE + " TEXT COLLATE " +
899de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                        ContactsProvider2.PHONEBOOK_COLLATOR_NAME + "," +
900f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov                RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0," +
9013cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                RawContacts.SYNC1 + " TEXT, " +
9023cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                RawContacts.SYNC2 + " TEXT, " +
9033cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                RawContacts.SYNC3 + " TEXT, " +
9043cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                RawContacts.SYNC4 + " TEXT " +
905b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
906b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
90754d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contacts_contact_id_index ON " + Tables.RAW_CONTACTS + " (" +
90854d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov                RawContacts.CONTACT_ID +
90954d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov        ");");
91054d6316486a810f45abade9d985dbb52b6cb17e2Dmitri Plotnikov
9115f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contacts_source_id_index ON " + Tables.RAW_CONTACTS + " (" +
9125f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                RawContacts.SOURCE_ID + ", " +
9135f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE + ", " +
9145f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                RawContacts.ACCOUNT_NAME +
9155f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov        ");");
9165f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov
91743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("CREATE INDEX raw_contacts_source_id_data_set_index ON " +
91843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Tables.RAW_CONTACTS + " (" +
91943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    RawContacts.SOURCE_ID + ", " +
92043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    RawContacts.ACCOUNT_TYPE + ", " +
92143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    RawContacts.ACCOUNT_NAME + ", " +
92243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    RawContacts.DATA_SET +
92343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                ");");
92443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
9253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        db.execSQL("CREATE TABLE " + Tables.STREAM_ITEMS + " (" +
9263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
9273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + " INTEGER NOT NULL, " +
9286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.RES_PACKAGE + " TEXT, " +
9290bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.RES_ICON + " TEXT, " +
9300bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.RES_LABEL + " TEXT, " +
9310bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.TEXT + " TEXT, " +
9323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.TIMESTAMP + " INTEGER NOT NULL, " +
9330bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.COMMENTS + " TEXT, " +
9340bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.SYNC1 + " TEXT, " +
9350bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.SYNC2 + " TEXT, " +
9360bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.SYNC3 + " TEXT, " +
9370bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItems.SYNC4 + " TEXT, " +
9383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                "FOREIGN KEY(" + StreamItems.RAW_CONTACT_ID + ") REFERENCES " +
9393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Tables.RAW_CONTACTS + "(" + RawContacts._ID + "));");
9403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
9413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        db.execSQL("CREATE TABLE " + Tables.STREAM_ITEM_PHOTOS + " (" +
9423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
9433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + " INTEGER NOT NULL, " +
9443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.SORT_INDEX + " INTEGER, " +
9456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID + " INTEGER NOT NULL, " +
9460bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItemPhotos.SYNC1 + " TEXT, " +
9470bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItemPhotos.SYNC2 + " TEXT, " +
9480bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItemPhotos.SYNC3 + " TEXT, " +
9490bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                StreamItemPhotos.SYNC4 + " TEXT, " +
9503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                "FOREIGN KEY(" + StreamItemPhotos.STREAM_ITEM_ID + ") REFERENCES " +
9513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Tables.STREAM_ITEMS + "(" + StreamItems._ID + "));");
9523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
953f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        db.execSQL("CREATE TABLE " + Tables.PHOTO_FILES + " (" +
954f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
955f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles.HEIGHT + " INTEGER NOT NULL, " +
956f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles.WIDTH + " INTEGER NOT NULL, " +
957f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles.FILESIZE + " INTEGER NOT NULL);");
958f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
959f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        // TODO readd the index and investigate a controlled use of it
960f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov//        db.execSQL("CREATE INDEX raw_contacts_agg_index ON " + Tables.RAW_CONTACTS + " (" +
961f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov//                RawContactsColumns.AGGREGATION_NEEDED +
962f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov//        ");");
9638e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
964b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // Package name mapping table
965ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" +
966ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
967ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                PackagesColumns.PACKAGE + " TEXT NOT NULL" +
968b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
969b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
970ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        // Mimetype mapping table
971ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" +
972ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
973ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                MimetypesColumns.MIMETYPE + " TEXT NOT NULL" +
974b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
975b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
97608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        // Mimetype table requires an index on mime type
97708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        db.execSQL("CREATE UNIQUE INDEX mime_type ON " + Tables.MIMETYPES + " (" +
97808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov                MimetypesColumns.MIMETYPE +
97908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        ");");
98008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
981b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // Public generic data table
982b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.DATA + " (" +
983b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
98467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                DataColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
985b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
98611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                Data.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
98797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                Data.IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," +
988f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," +
989f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," +
990f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," +
991f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA1 + " TEXT," +
992f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA2 + " TEXT," +
993f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA3 + " TEXT," +
994f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA4 + " TEXT," +
995f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA5 + " TEXT," +
996f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA6 + " TEXT," +
997f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA7 + " TEXT," +
998f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA8 + " TEXT," +
999f5b20724819e51b339ff6ba5b8eb6b444cc31452Fred Quintana                Data.DATA9 + " TEXT," +
100067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Data.DATA10 + " TEXT," +
100167dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Data.DATA11 + " TEXT," +
100267dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Data.DATA12 + " TEXT," +
100367dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Data.DATA13 + " TEXT," +
100467dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Data.DATA14 + " TEXT," +
10053cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Data.DATA15 + " TEXT," +
10063cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Data.SYNC1 + " TEXT, " +
10073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Data.SYNC2 + " TEXT, " +
10083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Data.SYNC3 + " TEXT, " +
10093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Data.SYNC4 + " TEXT " +
1010b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
1011b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
101211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov        db.execSQL("CREATE INDEX data_raw_contact_id ON " + Tables.DATA + " (" +
101311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                Data.RAW_CONTACT_ID +
101411944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov        ");");
101511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov
101611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov        /**
101711944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov         * For email lookup and similar queries.
101811944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov         */
1019f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov        db.execSQL("CREATE INDEX data_mimetype_data1_index ON " + Tables.DATA + " (" +
102011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "," +
1021f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov                Data.DATA1 +
102211944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov        ");");
102311944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov
1024b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // Private phone numbers table used for lookup
1025b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +
1026f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov                PhoneLookupColumns.DATA_ID
1027892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                        + " INTEGER REFERENCES data(_id) NOT NULL," +
10285ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID
10295ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                        + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
103036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," +
103136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" +
1032b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
1033b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
1034b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" +
1035f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov                PhoneLookupColumns.NORMALIZED_NUMBER + "," +
1036f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID + "," +
1037b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                PhoneLookupColumns.DATA_ID +
1038b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
1039b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
104036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" +
104136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.MIN_MATCH + "," +
104236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID + "," +
104336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.DATA_ID +
104436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        ");");
104536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
1046d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_data_id_min_match_index ON " + Tables.PHONE_LOOKUP +
1047d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov                " (" + PhoneLookupColumns.DATA_ID + ", " + PhoneLookupColumns.MIN_MATCH + ");");
1048d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov
1049a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        // Private name/nickname table used for lookup
1050a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" +
105114bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov                NameLookupColumns.DATA_ID
105214bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov                        + " INTEGER REFERENCES data(_id) NOT NULL," +
10535ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                NameLookupColumns.RAW_CONTACT_ID
10545ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                        + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
105511944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                NameLookupColumns.NORMALIZED_NAME + " TEXT NOT NULL," +
105611944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                NameLookupColumns.NAME_TYPE + " INTEGER NOT NULL," +
105714bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov                "PRIMARY KEY ("
105814bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov                        + NameLookupColumns.DATA_ID + ", "
105911944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                        + NameLookupColumns.NORMALIZED_NAME + ", "
106011944a13b31aa7c98f1079697f24b3a1999ca571Dmitri Plotnikov                        + NameLookupColumns.NAME_TYPE + ")" +
1061a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        ");");
1062a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov
106314bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov        db.execSQL("CREATE INDEX name_lookup_raw_contact_id_index ON " + Tables.NAME_LOOKUP + " (" +
106414bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov                NameLookupColumns.RAW_CONTACT_ID +
106514bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov        ");");
106614bba94bbe0f2e215ad7b3b9417754a1ba0d95bfDmitri Plotnikov
1067b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" +
1068b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                NicknameLookupColumns.NAME + " TEXT," +
1069b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                NicknameLookupColumns.CLUSTER + " TEXT" +
1070b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        ");");
1071b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
1072b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" +
1073b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                NicknameLookupColumns.NAME + ", " +
1074b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                NicknameLookupColumns.CLUSTER +
1075b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        ");");
1076b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
1077ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        // Groups table
1078ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" +
1079ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
108067dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
1081035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana                Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " +
1082035b4cc204be2641079a0b04e9ee9791a8f8248bFred Quintana                Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " +
108343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET + " STRING DEFAULT NULL, " +
1084ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                Groups.SOURCE_ID + " TEXT," +
10859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," +
108673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov                Groups.DIRTY + " INTEGER NOT NULL DEFAULT 0," +
1087ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey                Groups.TITLE + " TEXT," +
108867dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                Groups.TITLE_RES + " INTEGER," +
10890f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov                Groups.NOTES + " TEXT," +
10900f8f3b3e4a6ad18c5868d0215cc137845a2ddc74Dmitri Plotnikov                Groups.SYSTEM_ID + " TEXT," +
109194021b213e4db367f60b30fcbfe9019e28571784Fred Quintana                Groups.DELETED + " INTEGER NOT NULL DEFAULT 0," +
1092eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey                Groups.GROUP_VISIBLE + " INTEGER NOT NULL DEFAULT 0," +
1093ea547d55f864133861b2db44221ae0c2ac6c1a68Fred Quintana                Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1," +
1094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0," +
1095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0," +
1096c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0," +
10973cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Groups.SYNC1 + " TEXT, " +
10983cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Groups.SYNC2 + " TEXT, " +
10993cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Groups.SYNC3 + " TEXT, " +
11003cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov                Groups.SYNC4 + " TEXT " +
1101ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        ");");
1102ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
11035f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov        db.execSQL("CREATE INDEX groups_source_id_index ON " + Tables.GROUPS + " (" +
11045f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                Groups.SOURCE_ID + ", " +
11055f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                Groups.ACCOUNT_TYPE + ", " +
11065f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov                Groups.ACCOUNT_NAME +
11075f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov        ");");
11085f515d93c04729e6cdc9b704d18579162d71d5f2Dmitri Plotnikov
110943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("CREATE INDEX groups_source_id_data_set_index ON " + Tables.GROUPS + " (" +
111043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.SOURCE_ID + ", " +
111143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE + ", " +
111243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_NAME + ", " +
111343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET +
111443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        ");");
111543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
1116b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" +
1117b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov                AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
1118b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov                AggregationExceptions.TYPE + " INTEGER NOT NULL, " +
11190c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1
11205ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                        + " INTEGER REFERENCES raw_contacts(_id), " +
11210c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2
11225ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                        + " INTEGER REFERENCES raw_contacts(_id)" +
1123b0160a0bcf6d59eaa43fd501e124b95f873e0157Marc Blank        ");");
1124b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov
1125b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " +
1126b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov                Tables.AGGREGATION_EXCEPTIONS + " (" +
11270c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1 + ", " +
11280c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2 +
1129b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        ");");
1130b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov
1131b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " +
1132b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov                Tables.AGGREGATION_EXCEPTIONS + " (" +
11330c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2 + ", " +
11340c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1 +
1135b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        ");");
1136b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov
1137eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.SETTINGS + " (" +
1138eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey                Settings.ACCOUNT_NAME + " STRING NOT NULL," +
1139eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey                Settings.ACCOUNT_TYPE + " STRING NOT NULL," +
1140f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET + " STRING," +
1141eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey                Settings.UNGROUPED_VISIBLE + " INTEGER NOT NULL DEFAULT 0," +
1142f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 1" +
1143eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey        ");");
1144eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey
11454394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" +
11464394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                Contacts._ID + " INTEGER PRIMARY KEY" +
11474394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        ");");
11484394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
1149385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.DEFAULT_DIRECTORY + " (" +
1150385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                Contacts._ID + " INTEGER PRIMARY KEY" +
1151385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        ");");
1152385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
1153e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov        // The table for recent calls is here so we can do table joins
1154e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov        // on people, phones, and calls all in one place.
1155e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.CALLS + " (" +
1156e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
1157e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.NUMBER + " TEXT," +
1158e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.DATE + " INTEGER," +
1159e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.DURATION + " INTEGER," +
1160e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.TYPE + " INTEGER," +
1161e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.NEW + " INTEGER," +
1162e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.CACHED_NAME + " TEXT," +
1163e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov                Calls.CACHED_NUMBER_TYPE + " INTEGER," +
11642530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                Calls.CACHED_NUMBER_LABEL + " TEXT," +
116559f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Calls.COUNTRY_ISO + " TEXT," +
116659f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Calls.VOICEMAIL_URI + " TEXT," +
1167b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda                Calls.IS_READ + " INTEGER," +
1168aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda                Calls.GEOCODED_LOCATION + " TEXT," +
11697a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda                Calls.CACHED_LOOKUP_URI + " TEXT," +
11707a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda                Calls.CACHED_MATCHED_NUMBER + " TEXT," +
11717a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda                Calls.CACHED_NORMALIZED_NUMBER + " TEXT," +
11727a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda                Calls.CACHED_PHOTO_ID + " INTEGER NOT NULL DEFAULT 0," +
117359f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails._DATA + " TEXT," +
117459f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails.HAS_CONTENT + " INTEGER," +
117559f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails.MIME_TYPE + " TEXT," +
117659f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails.SOURCE_DATA + " TEXT," +
117759f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails.SOURCE_PACKAGE + " TEXT," +
117859f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee                Voicemails.STATE + " INTEGER" +
117959f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        ");");
1180e99988b266dd1263162583e81e2b408e7329b1c8Dmitri Plotnikov
1181069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        // Voicemail source status table.
1182069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        db.execSQL("CREATE TABLE " + Tables.VOICEMAIL_STATUS + " (" +
1183069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
1184069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.SOURCE_PACKAGE + " TEXT UNIQUE NOT NULL," +
1185069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.SETTINGS_URI + " TEXT," +
1186069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.VOICEMAIL_ACCESS_URI + " TEXT," +
1187069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.CONFIGURATION_STATE + " INTEGER," +
1188069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.DATA_CHANNEL_STATE + " INTEGER," +
1189069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE + " INTEGER" +
1190069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        ");");
1191069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee
1192b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        // Activities table
1193b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" +
1194b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
119567dde51ab932dc84d95a203b113989b13437f13dJeff Sharkey                ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
1196b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
1197b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities.RAW_ID + " TEXT," +
1198499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov                Activities.IN_REPLY_TO + " TEXT," +
11995ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Activities.AUTHOR_CONTACT_ID +  " INTEGER REFERENCES raw_contacts(_id)," +
12005ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov                Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)," +
1201b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities.PUBLISHED + " INTEGER NOT NULL," +
1202499791a4f9ab29fa94ff48dd7acff55b2ac089a7Dmitri Plotnikov                Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," +
1203b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities.TITLE + " TEXT NOT NULL," +
1204b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities.SUMMARY + " TEXT," +
1205adb55c2d8295d300961d86a3605c8ddc469cd4a2Dmitri Plotnikov                Activities.LINK + " TEXT, " +
1206b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey                Activities.THUMBNAIL + " BLOB" +
1207b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        ");");
1208b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
1209a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.STATUS_UPDATES + " (" +
1210a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov                StatusUpdatesColumns.DATA_ID + " INTEGER PRIMARY KEY REFERENCES data(_id)," +
12110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.STATUS + " TEXT," +
12120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP + " INTEGER," +
12130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE + " TEXT, " +
12140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.STATUS_LABEL + " INTEGER, " +
12150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.STATUS_ICON + " INTEGER" +
1216a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ");");
1217a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
1218b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.PROPERTIES + " (" +
1219b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                PropertiesColumns.PROPERTY_KEY + " TEXT PRIMARY KEY, " +
1220b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                PropertiesColumns.PROPERTY_VALUE + " TEXT " +
1221b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ");");
1222b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
1223743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" +
122424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                AccountsColumns.ACCOUNT_NAME + " TEXT, " +
122524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                AccountsColumns.ACCOUNT_TYPE + " TEXT, " +
12265d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                AccountsColumns.DATA_SET + " TEXT" +
1227743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ");");
1228743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
1229743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        // Allow contacts without any account to be created for now.  Achieve that
1230743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        // by inserting a fake account with both type and name as NULL.
12315d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL, NULL)");
1232743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
1233d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        createDirectoriesTable(db);
1234f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        createSearchIndexTable(db);
1235d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov
123646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        db.execSQL("CREATE TABLE " + Tables.DATA_USAGE_STAT + "(" +
123746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
123846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.DATA_ID + " INTEGER NOT NULL, " +
123946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.USAGE_TYPE_INT + " INTEGER NOT NULL DEFAULT 0, " +
124046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.TIMES_USED + " INTEGER NOT NULL DEFAULT 0, " +
124146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.LAST_TIME_USED + " INTERGER NOT NULL DEFAULT 0, " +
124246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "FOREIGN KEY(" + DataUsageStatColumns.DATA_ID + ") REFERENCES "
124346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        + Tables.DATA + "(" + Data._ID + ")" +
124446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ");");
124546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        db.execSQL("CREATE UNIQUE INDEX data_usage_stat_index ON " +
124646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                Tables.DATA_USAGE_STAT + " (" +
124746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.DATA_ID + ", " +
124846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                DataUsageStatColumns.USAGE_TYPE_INT +
124946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ");");
125046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1251a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        createContactsViews(db);
1252a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        createGroupsView(db);
1253fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        createContactsTriggers(db);
1254916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        createContactsIndexes(db);
12554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1256a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        loadNicknameLookupTable(db);
1257a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
12585d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // Set sequence starts.
12595d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        initializeAutoIncrementSequences(db);
12605d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
1261a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        // Add the legacy API support views, etc
1262a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        LegacyApiSupport.createDatabase(db);
1263a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
12642a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        if (mDatabaseOptimizationEnabled) {
12652a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            // This will create a sqlite_stat1 table that is used for query optimization
12662a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            db.execSQL("ANALYZE;");
1267a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
12682a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            updateSqliteStats(db);
1269a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
12702a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            // We need to close and reopen the database connection so that the stats are
12712a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            // taken into account. Make a note of it and do the actual reopening in the
12722a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            // getWritableDatabase method.
12732a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            mReopenDatabase = true;
12742a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        }
1275a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
1276a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        ContentResolver.requestSync(null /* all accounts */,
1277a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                ContactsContract.AUTHORITY, new Bundle());
1278a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov    }
1279a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
12805d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    protected void initializeAutoIncrementSequences(SQLiteDatabase db) {
12815d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // Default implementation does nothing.
12825d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    }
12835d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
1284d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov    private void createDirectoriesTable(SQLiteDatabase db) {
1285d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.DIRECTORIES + "(" +
1286d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
1287d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.PACKAGE_NAME + " TEXT NOT NULL," +
1288d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.DIRECTORY_AUTHORITY + " TEXT NOT NULL," +
1289d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.TYPE_RESOURCE_ID + " INTEGER," +
1290e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov                DirectoryColumns.TYPE_RESOURCE_NAME + " TEXT," +
1291d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.ACCOUNT_TYPE + " TEXT," +
1292d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.ACCOUNT_NAME + " TEXT," +
1293d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.DISPLAY_NAME + " TEXT, " +
1294d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov                Directory.EXPORT_SUPPORT + " INTEGER NOT NULL" +
129597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                        " DEFAULT " + Directory.EXPORT_SUPPORT_NONE + "," +
129697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                Directory.SHORTCUT_SUPPORT + " INTEGER NOT NULL" +
12973d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        " DEFAULT " + Directory.SHORTCUT_SUPPORT_NONE + "," +
12983d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Directory.PHOTO_SUPPORT + " INTEGER NOT NULL" +
12993d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        " DEFAULT " + Directory.PHOTO_SUPPORT_NONE +
1300d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        ");");
1301d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov
13023d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        // Trigger a full scan of directories in the system
13033d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        setProperty(db, ContactDirectoryManager.PROPERTY_DIRECTORY_SCAN_COMPLETE, "0");
1304d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov    }
1305d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov
130605e50fbf9809bf04eceec3d2a2753630dc4f9315Dmitri Plotnikov    public void createSearchIndexTable(SQLiteDatabase db) {
1307f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS " + Tables.SEARCH_INDEX);
1308f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        db.execSQL("CREATE VIRTUAL TABLE " + Tables.SEARCH_INDEX
1309f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                + " USING FTS4 ("
1310f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                    + SearchIndexColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL,"
1311f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                    + SearchIndexColumns.CONTENT + " TEXT, "
1312155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov                    + SearchIndexColumns.NAME + " TEXT, "
1313f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                    + SearchIndexColumns.TOKENS + " TEXT"
1314f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                + ")");
1315f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    }
1316f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
13175d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    private void createContactsTriggers(SQLiteDatabase db) {
1318fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1319fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        /*
1320fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         * Automatically delete Data rows when a raw contact is deleted.
1321fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         */
1322fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_deleted;");
1323fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted "
1324fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   BEFORE DELETE ON " + Tables.RAW_CONTACTS
1325fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " BEGIN "
1326fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.DATA
1327fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + Data.RAW_CONTACT_ID
1328fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                                + "=OLD." + RawContacts._ID + ";"
1329fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS
1330fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + AggregationExceptions.RAW_CONTACT_ID1
1331fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                                + "=OLD." + RawContacts._ID
1332fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "        OR " + AggregationExceptions.RAW_CONTACT_ID2
1333fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                                + "=OLD." + RawContacts._ID + ";"
133435da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov                + "   DELETE FROM " + Tables.VISIBLE_CONTACTS
133535da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov                + "     WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID
133635da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov                + "       AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS
133735da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov                + "            WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID
133835da06eb902047d8f3eb1698450d7bfdc41f22d4Dmitri Plotnikov                + "           )=1;"
1339385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                + "   DELETE FROM " + Tables.DEFAULT_DIRECTORY
1340385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                + "     WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID
1341385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                + "       AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS
1342385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                + "            WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID
1343385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                + "           )=1;"
1344fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.CONTACTS
1345fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + Contacts._ID + "=OLD." + RawContacts.CONTACT_ID
1346fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "       AND (SELECT COUNT(*) FROM " + Tables.RAW_CONTACTS
1347fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "            WHERE " + RawContacts.CONTACT_ID + "=OLD." + RawContacts.CONTACT_ID
1348fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "           )=1;"
1349fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " END");
1350fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1351fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1352fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS contacts_times_contacted;");
13536c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook        db.execSQL("DROP TRIGGER IF EXISTS raw_contacts_times_contacted;");
1354fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1355fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        /*
1356fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         * Triggers that update {@link RawContacts#VERSION} when the contact is
1357fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         * marked for deletion or any time a data row is inserted, updated or
1358fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         * deleted.
1359fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov         */
1360fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.RAW_CONTACTS + "_marked_deleted;");
1361fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted "
13627f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori                + "   AFTER UPDATE ON " + Tables.RAW_CONTACTS
1363fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " BEGIN "
1364fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   UPDATE " + Tables.RAW_CONTACTS
1365fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     SET "
1366fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                +         RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1 "
1367fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID
1368fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "       AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";"
1369fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " END");
1370fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1371fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_updated;");
13727f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA
1373fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " BEGIN "
1374fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   UPDATE " + Tables.DATA
1375fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 "
1376fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + Data._ID + "=OLD." + Data._ID + ";"
1377fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   UPDATE " + Tables.RAW_CONTACTS
1378fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 "
1379fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";"
1380fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " END");
1381fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1382fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.DATA + "_deleted;");
1383fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA
1384fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " BEGIN "
1385fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   UPDATE " + Tables.RAW_CONTACTS
1386fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     SET " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 "
1387fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";"
1388fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.PHONE_LOOKUP
1389fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";"
1390fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.STATUS_UPDATES
1391fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + StatusUpdatesColumns.DATA_ID + "=OLD." + Data._ID + ";"
1392fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   DELETE FROM " + Tables.NAME_LOOKUP
1393fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + NameLookupColumns.DATA_ID + "=OLD." + Data._ID + ";"
1394fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " END");
1395fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1396fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
1397fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_updated1;");
1398fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 "
13997f61664c2b587e27f52edcb9a8b91986154ec637Vasu Nori                + "   AFTER UPDATE ON " + Tables.GROUPS
1400fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " BEGIN "
1401fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "   UPDATE " + Tables.GROUPS
1402fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     SET "
1403fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                +         Groups.VERSION + "=OLD." + Groups.VERSION + "+1"
1404fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + "     WHERE " + Groups._ID + "=OLD." + Groups._ID + ";"
1405fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov                + " END");
14063e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa
14073e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        // Update DEFAULT_FILTER table per AUTO_ADD column update.
14083e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        // See also upgradeToVersion411().
14093e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        final String insertContactsWithoutAccount = (
14103e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY +
14113e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     SELECT " + RawContacts.CONTACT_ID +
14123e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     FROM " + Tables.RAW_CONTACTS +
14133e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " +
14143e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL; ");
14153e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        final String insertContactsWithAccountNoDefaultGroup = (
14163e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY +
14173e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     SELECT " + RawContacts.CONTACT_ID +
14183e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "         FROM " + Tables.RAW_CONTACTS +
14193e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     WHERE NOT EXISTS" +
14203e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "         (SELECT " + Groups._ID +
14213e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "             FROM " + Tables.GROUPS +
14223e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "             WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " +
14233e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                        GroupsColumns.CONCRETE_ACCOUNT_NAME +
14243e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "             AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " +
14253e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                        GroupsColumns.CONCRETE_ACCOUNT_TYPE +
14263e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "             AND " + Groups.AUTO_ADD + " != 0" + ");");
14273e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        final String insertContactsWithAccountDefaultGroup = (
14283e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY +
14293e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     SELECT " + RawContacts.CONTACT_ID +
14303e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "         FROM " + Tables.RAW_CONTACTS +
14313e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     JOIN " + Tables.DATA +
14323e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "           ON (" + RawContactsColumns.CONCRETE_ID + "=" +
14333e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                        Data.RAW_CONTACT_ID + ")" +
143406c4a28bcdd9ca7c396de41b3bae5f6f43978fb5Daisuke Miyakawa                "     WHERE " + DataColumns.MIMETYPE_ID + "=" +
143506c4a28bcdd9ca7c396de41b3bae5f6f43978fb5Daisuke Miyakawa                    "(SELECT " + MimetypesColumns._ID + " FROM " + Tables.MIMETYPES +
143606c4a28bcdd9ca7c396de41b3bae5f6f43978fb5Daisuke Miyakawa                        " WHERE " + MimetypesColumns.MIMETYPE +
143706c4a28bcdd9ca7c396de41b3bae5f6f43978fb5Daisuke Miyakawa                            "='" + GroupMembership.CONTENT_ITEM_TYPE + "')" +
14383e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "     AND EXISTS" +
14393e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "         (SELECT " + Groups._ID +
14403e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "             FROM " + Tables.GROUPS +
14413e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "                 WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = " +
14423e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                        GroupsColumns.CONCRETE_ACCOUNT_NAME +
14433e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "                 AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = " +
14443e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                        GroupsColumns.CONCRETE_ACCOUNT_TYPE +
14453e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "                 AND " + Groups.AUTO_ADD + " != 0" + ");");
14463e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa
14473e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("DROP TRIGGER IF EXISTS " + Tables.GROUPS + "_auto_add_updated1;");
14483e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_auto_add_updated1 "
14493e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                + "   AFTER UPDATE OF " + Groups.AUTO_ADD + " ON " + Tables.GROUPS
14503e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                + " BEGIN "
14513e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                + "   DELETE FROM " + Tables.DEFAULT_DIRECTORY + ";"
14523e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                    + insertContactsWithoutAccount
14533e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                    + insertContactsWithAccountNoDefaultGroup
14543e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                    + insertContactsWithAccountDefaultGroup
14553e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                + " END");
1456fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov    }
1457fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
14585d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    private void createContactsIndexes(SQLiteDatabase db) {
1459916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        db.execSQL("DROP INDEX IF EXISTS name_lookup_index");
1460916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" +
1461916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov                NameLookupColumns.NORMALIZED_NAME + "," +
1462916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov                NameLookupColumns.NAME_TYPE + ", " +
1463916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov                NameLookupColumns.RAW_CONTACT_ID + ", " +
1464916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov                NameLookupColumns.DATA_ID +
1465916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ");");
146604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
146704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key1_index");
146804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" +
146904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY +
147004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        ");");
147104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
147204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        db.execSQL("DROP INDEX IF EXISTS raw_contact_sort_key2_index");
147304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" +
147404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE +
147504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        ");");
1476916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
1477916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
14785d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    private void createContactsViews(SQLiteDatabase db) {
1479ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.CONTACTS + ";");
1480ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.DATA + ";");
1481ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_CONTACTS + ";");
1482a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        db.execSQL("DROP VIEW IF EXISTS " + Views.RAW_ENTITIES + ";");
1483a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        db.execSQL("DROP VIEW IF EXISTS " + Views.ENTITIES + ";");
1484ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.DATA_USAGE_STAT + ";");
14859b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.STREAM_ITEMS + ";");
1486a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
14874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String dataColumns =
14884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Data.IS_PRIMARY + ", "
14894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.IS_SUPER_PRIMARY + ", "
14904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA_VERSION + ", "
14914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + ","
14924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + MimetypesColumns.MIMETYPE + " AS " + Data.MIMETYPE + ", "
149397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                + Data.IS_READ_ONLY + ", "
14944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA1 + ", "
14954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA2 + ", "
14964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA3 + ", "
14974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA4 + ", "
14984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA5 + ", "
14994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA6 + ", "
15004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA7 + ", "
15014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA8 + ", "
15024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA9 + ", "
15034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA10 + ", "
15044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA11 + ", "
15054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA12 + ", "
15064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA13 + ", "
15074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA14 + ", "
15084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.DATA15 + ", "
15094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.SYNC1 + ", "
15104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.SYNC2 + ", "
15114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.SYNC3 + ", "
15124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.SYNC4;
15134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String syncColumns =
15154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + ","
15164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + ","
151743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + RawContactsColumns.CONCRETE_DATA_SET + " AS " + RawContacts.DATA_SET + ","
151843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + "(CASE WHEN " + RawContactsColumns.CONCRETE_DATA_SET + " IS NULL THEN "
151943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        + RawContactsColumns.CONCRETE_ACCOUNT_TYPE
152043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        + " ELSE " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + "||'/'||"
152143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        + RawContactsColumns.CONCRETE_DATA_SET + " END) AS "
152243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        + RawContacts.ACCOUNT_TYPE_AND_DATA_SET + ","
15234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + ","
152443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + RawContactsColumns.CONCRETE_NAME_VERIFIED + " AS "
152543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        + RawContacts.NAME_VERIFIED + ","
15264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + ","
15274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + ","
15284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_SYNC1 + " AS " + RawContacts.SYNC1 + ","
15294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_SYNC2 + " AS " + RawContacts.SYNC2 + ","
15304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_SYNC3 + " AS " + RawContacts.SYNC3 + ","
15314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_SYNC4 + " AS " + RawContacts.SYNC4;
15324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15333d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        String baseContactColumns =
15343d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER + ", "
15353d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + Contacts.NAME_RAW_CONTACT_ID + ", "
15363d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + Contacts.LOOKUP_KEY + ", "
15373d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + Contacts.PHOTO_ID + ", "
1538f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + Contacts.PHOTO_FILE_ID + ", "
15393d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + Clauses.CONTACT_VISIBLE + " AS " + Contacts.IN_VISIBLE_GROUP + ", "
15403d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + ContactsColumns.LAST_STATUS_UPDATE_ID;
15413d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov
15424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String contactOptionColumns =
15434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                ContactsColumns.CONCRETE_CUSTOM_RINGTONE
15444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + RawContacts.CUSTOM_RINGTONE + ","
15454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL
15464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + RawContacts.SEND_TO_VOICEMAIL + ","
15474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED
15484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + RawContacts.LAST_TIME_CONTACTED + ","
15494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_TIMES_CONTACTED
15504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + RawContacts.TIMES_CONTACTED + ","
15514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_STARRED
15524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + RawContacts.STARRED;
15534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        String contactNameColumns =
15555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                "name_raw_contact." + RawContacts.DISPLAY_NAME_SOURCE
15565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.DISPLAY_NAME_SOURCE + ", "
15575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.DISPLAY_NAME_PRIMARY
15585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.DISPLAY_NAME_PRIMARY + ", "
15595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.DISPLAY_NAME_ALTERNATIVE
15605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.DISPLAY_NAME_ALTERNATIVE + ", "
15615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.PHONETIC_NAME
15625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.PHONETIC_NAME + ", "
15635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.PHONETIC_NAME_STYLE
15645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.PHONETIC_NAME_STYLE + ", "
15655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.SORT_KEY_PRIMARY
15665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + " AS " + Contacts.SORT_KEY_PRIMARY + ", "
15675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + "name_raw_contact." + RawContacts.SORT_KEY_ALTERNATIVE
15684394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                        + " AS " + Contacts.SORT_KEY_ALTERNATIVE;
15695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
15704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String dataSelect = "SELECT "
15714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + DataColumns.CONCRETE_ID + " AS " + Data._ID + ","
15724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Data.RAW_CONTACT_ID + ", "
1573fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", "
15744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + syncColumns + ", "
15754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + dataColumns + ", "
15764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + contactOptionColumns + ", "
15775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + contactNameColumns + ", "
15783d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + baseContactColumns + ", "
1579f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildDisplayPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID,
15803d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        Contacts.PHOTO_URI) + ", "
1581f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildThumbnailPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID,
15823d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        Contacts.PHOTO_THUMBNAIL_URI) + ", "
15835d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                + dbForProfile() + " AS " + RawContacts.RAW_CONTACT_IS_USER_PROFILE + ", "
15844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID
15854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + " FROM " + Tables.DATA
1586a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                + " JOIN " + Tables.MIMETYPES + " ON ("
15874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                +   DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")"
1588a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                + " JOIN " + Tables.RAW_CONTACTS + " ON ("
15894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                +   DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")"
1590a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                + " JOIN " + Tables.CONTACTS + " ON ("
1591fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                +   RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")"
1592fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON("
1593fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                +   Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"
1594a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON ("
1595a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                +   DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")"
15964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.GROUPS + " ON ("
15974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                +   MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE
1598f23764675b35b5262a39c79aad8e9842460274b2Dmitri Plotnikov                +   "' AND " + GroupsColumns.CONCRETE_ID + "="
1599a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                        + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")";
16004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1601ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("CREATE VIEW " + Views.DATA + " AS " + dataSelect);
16024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String rawContactOptionColumns =
16044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                RawContacts.CUSTOM_RINGTONE + ","
16054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.SEND_TO_VOICEMAIL + ","
16064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.LAST_TIME_CONTACTED + ","
16074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.TIMES_CONTACTED + ","
16084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.STARRED;
16094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String rawContactsSelect = "SELECT "
16114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ","
16124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.CONTACT_ID + ", "
16134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.AGGREGATION_MODE + ", "
161497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                + RawContacts.RAW_CONTACT_IS_READ_ONLY + ", "
16154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + RawContacts.DELETED + ", "
16165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.DISPLAY_NAME_SOURCE  + ", "
16175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.DISPLAY_NAME_PRIMARY  + ", "
16185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.DISPLAY_NAME_ALTERNATIVE  + ", "
16195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.PHONETIC_NAME  + ", "
16205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.PHONETIC_NAME_STYLE  + ", "
16215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.SORT_KEY_PRIMARY  + ", "
16225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + RawContacts.SORT_KEY_ALTERNATIVE + ", "
16235d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                + dbForProfile() + " AS " + RawContacts.RAW_CONTACT_IS_USER_PROFILE + ", "
16244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + rawContactOptionColumns + ", "
16254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + syncColumns
16264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + " FROM " + Tables.RAW_CONTACTS;
16274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1628ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("CREATE VIEW " + Views.RAW_CONTACTS + " AS " + rawContactsSelect);
16294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String contactsColumns =
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                ContactsColumns.CONCRETE_CUSTOM_RINGTONE
16324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + Contacts.CUSTOM_RINGTONE + ", "
16335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + contactNameColumns + ", "
16343d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + baseContactColumns + ", "
16354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_LAST_TIME_CONTACTED
16364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + Contacts.LAST_TIME_CONTACTED + ", "
16374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL
16384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + Contacts.SEND_TO_VOICEMAIL + ", "
16394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_STARRED
16404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                        + " AS " + Contacts.STARRED + ", "
16414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_TIMES_CONTACTED
16423d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        + " AS " + Contacts.TIMES_CONTACTED;
16434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        String contactsSelect = "SELECT "
16454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID + ","
16463d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                + contactsColumns + ", "
1647f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildDisplayPhotoUriAlias(ContactsColumns.CONCRETE_ID, Contacts.PHOTO_URI) + ", "
1648f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildThumbnailPhotoUriAlias(ContactsColumns.CONCRETE_ID,
164924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                        Contacts.PHOTO_THUMBNAIL_URI) + ", "
16505d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                + dbForProfile() + " AS " + Contacts.IS_USER_PROFILE
16514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                + " FROM " + Tables.CONTACTS
1652fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON("
1653fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                +   Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")";
16544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1655ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("CREATE VIEW " + Views.CONTACTS + " AS " + contactsSelect);
1656a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
1657a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String rawEntitiesSelect = "SELECT "
1658a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContacts.CONTACT_ID + ", "
1659a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + ","
1660a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + dataColumns + ", "
1661a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + syncColumns + ", "
1662a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC1 + ", "
1663a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC2 + ", "
1664a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC3 + ", "
1665a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC4 + ", "
1666a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_ID + " AS " + RawContacts._ID + ", "
1667a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + DataColumns.CONCRETE_ID + " AS " + RawContacts.Entity.DATA_ID + ","
1668a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_STARRED + " AS " + RawContacts.STARRED + ","
16695d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                + dbForProfile() + " AS " + RawContacts.RAW_CONTACT_IS_USER_PROFILE + ","
1670a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID
1671a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " FROM " + Tables.RAW_CONTACTS
1672a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.DATA + " ON ("
1673a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")"
1674a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON ("
1675a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")"
1676a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON ("
1677a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")"
1678a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.GROUPS + " ON ("
1679a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE
1680a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   "' AND " + GroupsColumns.CONCRETE_ID + "="
1681a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")";
1682a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
1683a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        db.execSQL("CREATE VIEW " + Views.RAW_ENTITIES + " AS "
1684a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + rawEntitiesSelect);
1685a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
1686a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String entitiesSelect = "SELECT "
1687a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + Contacts._ID + ", "
1688a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", "
1689a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_DELETED + " AS " + RawContacts.DELETED + ","
1690a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + dataColumns + ", "
1691a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + syncColumns + ", "
1692a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + contactsColumns + ", "
1693f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildDisplayPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID,
16943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        Contacts.PHOTO_URI) + ", "
1695f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + buildThumbnailPhotoUriAlias(RawContactsColumns.CONCRETE_CONTACT_ID,
16963d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                        Contacts.PHOTO_THUMBNAIL_URI) + ", "
16975d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                + dbForProfile() + " AS " + Contacts.IS_USER_PROFILE + ", "
1698a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC1 + ", "
1699a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC2 + ", "
1700a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC3 + ", "
1701a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Data.SYNC4 + ", "
1702a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + RawContactsColumns.CONCRETE_ID + " AS " + Contacts.Entity.RAW_CONTACT_ID + ", "
1703a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + DataColumns.CONCRETE_ID + " AS " + Contacts.Entity.DATA_ID + ","
1704a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID
1705a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " FROM " + Tables.RAW_CONTACTS
1706a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " JOIN " + Tables.CONTACTS + " ON ("
1707a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")"
1708a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " JOIN " + Tables.RAW_CONTACTS + " AS name_raw_contact ON("
1709a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   Contacts.NAME_RAW_CONTACT_ID + "=name_raw_contact." + RawContacts._ID + ")"
1710a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.DATA + " ON ("
1711a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")"
1712a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON ("
1713a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")"
1714a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON ("
1715a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")"
1716a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + " LEFT OUTER JOIN " + Tables.GROUPS + " ON ("
1717a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE
1718a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                +   "' AND " + GroupsColumns.CONCRETE_ID + "="
1719a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID + ")";
1720a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
1721a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        db.execSQL("CREATE VIEW " + Views.ENTITIES + " AS "
1722a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                + entitiesSelect);
17232f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17242f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        String dataUsageStatSelect = "SELECT "
17252f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + DataUsageStatColumns.CONCRETE_ID + " AS " + DataUsageStatColumns._ID + ", "
17262f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + DataUsageStatColumns.DATA_ID + ", "
17272f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + RawContactsColumns.CONCRETE_CONTACT_ID + " AS " + RawContacts.CONTACT_ID + ", "
17282f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + MimetypesColumns.CONCRETE_MIMETYPE + " AS " + Data.MIMETYPE + ", "
17292f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + DataUsageStatColumns.USAGE_TYPE_INT + ", "
17302f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + DataUsageStatColumns.TIMES_USED + ", "
17312f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + DataUsageStatColumns.LAST_TIME_USED
17322f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + " FROM " + Tables.DATA_USAGE_STAT
17332f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + " JOIN " + Tables.DATA + " ON ("
17342f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                +   DataColumns.CONCRETE_ID + "=" + DataUsageStatColumns.CONCRETE_DATA_ID + ")"
17352f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + " JOIN " + Tables.RAW_CONTACTS + " ON ("
17362f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                +   RawContactsColumns.CONCRETE_ID + "=" + DataColumns.CONCRETE_RAW_CONTACT_ID
17372f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                    + " )"
17382f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                + " JOIN " + Tables.MIMETYPES + " ON ("
17392f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                +   MimetypesColumns.CONCRETE_ID + "=" + DataColumns.CONCRETE_MIMETYPE_ID + ")";
17402f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
1741ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("CREATE VIEW " + Views.DATA_USAGE_STAT + " AS " + dataUsageStatSelect);
17429b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann
17439b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        String streamItemSelect = "SELECT " +
17449b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_ID + ", " +
17459b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                ContactsColumns.CONCRETE_ID + " AS " + StreamItems.CONTACT_ID + ", " +
1746af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann                ContactsColumns.CONCRETE_LOOKUP_KEY +
1747af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann                        " AS " + StreamItems.CONTACT_LOOKUP_KEY + ", " +
17489b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                RawContactsColumns.CONCRETE_ACCOUNT_NAME + ", " +
17499b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                RawContactsColumns.CONCRETE_ACCOUNT_TYPE + ", " +
17509b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                RawContactsColumns.CONCRETE_DATA_SET + ", " +
17519b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_RAW_CONTACT_ID +
17529b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                        " as " + StreamItems.RAW_CONTACT_ID + ", " +
17539b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                RawContactsColumns.CONCRETE_SOURCE_ID +
17549b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                        " as " + StreamItems.RAW_CONTACT_SOURCE_ID + ", " +
17559b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_PACKAGE + ", " +
17569b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_ICON + ", " +
17579b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_LABEL + ", " +
17589b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_TEXT + ", " +
17599b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_TIMESTAMP + ", " +
17609b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_COMMENTS + ", " +
17619b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_SYNC1 + ", " +
17629b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_SYNC2 + ", " +
17639b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_SYNC3 + ", " +
17649b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                StreamItemsColumns.CONCRETE_SYNC4 +
17659b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                " FROM " + Tables.STREAM_ITEMS
17669b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                + " JOIN " + Tables.RAW_CONTACTS + " ON ("
17679b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                + StreamItemsColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID
17689b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                + ") JOIN " + Tables.CONTACTS + " ON ("
17699b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann                + RawContactsColumns.CONCRETE_CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + ")";
17709b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann
17719b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        db.execSQL("CREATE VIEW " + Views.STREAM_ITEMS + " AS " + streamItemSelect);
1772a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov    }
17734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1774f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private static String buildDisplayPhotoUriAlias(String contactIdColumn, String alias) {
1775f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        return "(CASE WHEN " + Contacts.PHOTO_FILE_ID + " IS NULL THEN (CASE WHEN "
1776f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + Contacts.PHOTO_ID + " IS NULL"
1777f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " OR " + Contacts.PHOTO_ID + "=0"
1778f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " THEN NULL"
1779f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " ELSE '" + Contacts.CONTENT_URI + "/'||"
1780f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        + contactIdColumn + "|| '/" + Photo.CONTENT_DIRECTORY + "'"
1781f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " END) ELSE '" + DisplayPhoto.CONTENT_URI + "/'||"
1782f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        + Contacts.PHOTO_FILE_ID + " END)"
1783f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " AS " + alias;
1784f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
1785f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
1786f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private static String buildThumbnailPhotoUriAlias(String contactIdColumn, String alias) {
1787f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        return "(CASE WHEN "
1788f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + Contacts.PHOTO_ID + " IS NULL"
17892b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov                + " OR " + Contacts.PHOTO_ID + "=0"
17902b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov                + " THEN NULL"
1791f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                + " ELSE '" + Contacts.CONTENT_URI + "/'||"
17922b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov                        + contactIdColumn + "|| '/" + Photo.CONTENT_DIRECTORY + "'"
17932b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov                + " END)"
17942b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov                + " AS " + alias;
17953d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov    }
17963d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov
17975d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    /**
17985d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro     * Returns the value to be returned when querying the column indicating that the contact
17995d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro     * or raw contact belongs to the user's personal profile.  Overridden in the profile
18005d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro     * DB helper subclass.
18015d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro     */
18025d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    protected int dbForProfile() {
18035d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        return 0;
18045d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    }
18055d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
18065d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    private void createGroupsView(SQLiteDatabase db) {
1807ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS " + Views.GROUPS + ";");
180889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        String groupsColumns =
180989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                Groups.ACCOUNT_NAME + ","
181089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.ACCOUNT_TYPE + ","
181143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + Groups.DATA_SET + ","
181243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                + "(CASE WHEN " + Groups.DATA_SET + " IS NULL THEN " + Groups.ACCOUNT_TYPE
181343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    + " ELSE " + Groups.ACCOUNT_TYPE + "||" + Groups.DATA_SET + " END) AS "
181443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    + Groups.ACCOUNT_TYPE_AND_DATA_SET + ","
181589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SOURCE_ID + ","
181689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.VERSION + ","
181789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.DIRTY + ","
181889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.TITLE + ","
181989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.TITLE_RES + ","
182089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.NOTES + ","
182189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SYSTEM_ID + ","
182289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.DELETED + ","
182389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.GROUP_VISIBLE + ","
182489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SHOULD_SYNC + ","
1825dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                + Groups.AUTO_ADD + ","
1826dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                + Groups.FAVORITES + ","
1827c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                + Groups.GROUP_IS_READ_ONLY + ","
182889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SYNC1 + ","
182989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SYNC2 + ","
183089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SYNC3 + ","
183189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + Groups.SYNC4 + ","
183289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE;
183389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
183489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        String groupsSelect = "SELECT "
183589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + GroupsColumns.CONCRETE_ID + " AS " + Groups._ID + ","
183689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + groupsColumns
183789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov                + " FROM " + Tables.GROUPS_JOIN_PACKAGES;
183889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
1839ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("CREATE VIEW " + Views.GROUPS + " AS " + groupsSelect);
1840b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
1841b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
1842b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    @Override
1843b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
184446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        if (oldVersion < 99) {
184546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion
184646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana                    + ", data will be lost!");
184746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana
184846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";");
184946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_CONTACTS + ";");
185046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";");
185146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";");
185246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";");
185346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";");
185446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";");
185546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";");
185646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";");
185746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";");
185846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS + ";");
185946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.SETTINGS + ";");
186046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.STATUS_UPDATES + ";");
186146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana
186246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            // TODO: we should not be dropping agg_exceptions and contact_options. In case that
186346b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            // table's schema changes, we should try to preserve the data, because it was entered
186446b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            // by the user and has never been synched to the server.
186546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";");
186646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana
186746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            onCreate(db);
186846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            return;
186946b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        }
1870f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
187146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion);
1872a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
187308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov        boolean upgradeViewsAndTriggers = false;
187404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        boolean upgradeNameLookup = false;
18758d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov        boolean upgradeLegacyApiSupport = false;
1876155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        boolean upgradeSearchIndex = false;
187708e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov
187846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        if (oldVersion == 99) {
187908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
188046b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            oldVersion++;
188146b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        }
188246b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana
1883a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        if (oldVersion == 100) {
1884a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov            db.execSQL("CREATE INDEX IF NOT EXISTS mimetypes_mimetype_index ON "
1885a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                    + Tables.MIMETYPES + " ("
1886a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                            + MimetypesColumns.MIMETYPE + ","
1887a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                            + MimetypesColumns._ID + ");");
1888a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov            updateIndexStats(db, Tables.MIMETYPES,
1889a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov                    "mimetypes_mimetype_index", "50 1 1");
1890a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
189108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
1892a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov            oldVersion++;
1893a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov        }
1894a0e72d9b20207ec244f92ace2917932990f2bc8bDmitri Plotnikov
1895fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        if (oldVersion == 101) {
189608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
1897fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov            oldVersion++;
1898fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov        }
1899fda634f3eeff6aed8e8dddca92fc07aa44befeddDmitri Plotnikov
190047ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov        if (oldVersion == 102) {
190108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
190247ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov            oldVersion++;
190347ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov        }
190447ab23770b9f010a5e5277cda68267fe0613a1ccDmitri Plotnikov
190536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        if (oldVersion == 103) {
190608e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
1907bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey            oldVersion++;
1908bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey        }
1909bf6a7e4dece49ba4e7cda17f7ed9250aeb82f731Jeff Sharkey
191071037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov        if (oldVersion == 104 || oldVersion == 201) {
191171037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov            LegacyApiSupport.createSettingsTable(db);
191208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
19133410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov            oldVersion++;
19143410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov        }
19153410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov
191671037c010a0b7c882284fc1ed8584a378d926b83Dmitri Plotnikov        if (oldVersion == 105) {
19175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            upgradeToVersion202(db);
191804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            upgradeNameLookup = true;
19193410a80f4aafe5685da61c217808d2bf21d55dfcDmitri Plotnikov            oldVersion = 202;
192036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        }
192136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
1922fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        if (oldVersion == 202) {
19235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            upgradeToVersion203(db);
192408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
1925fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov            oldVersion++;
1926fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        }
1927fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
19289b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori        if (oldVersion == 203) {
192908e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
19309b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori            oldVersion++;
19319b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori        }
19329b1bd62417ef1764829398a61c3d5df93a924106Vasu Nori
19335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (oldVersion == 204) {
19345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            upgradeToVersion205(db);
193508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            upgradeViewsAndTriggers = true;
19365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            oldVersion++;
19375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
19385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
1939f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov        if (oldVersion == 205) {
1940f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov            upgrateToVersion206(db);
1941f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov            upgradeViewsAndTriggers = true;
1942f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov            oldVersion++;
1943f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov        }
1944f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov
194531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        if (oldVersion == 206) {
1946b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            upgradeToVersion300(db);
194734469970fb04b9b188b5430f592b0c956a6ea2aaDmitri Plotnikov            oldVersion = 300;
194831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        }
194931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
19506c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook        if (oldVersion == 300) {
19516c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook            upgradeViewsAndTriggers = true;
19526c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook            oldVersion = 301;
19536c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook        }
19546c0d1eb7a960d7f8c4a42a9e0ae10487654f5f7ePaul Westbrook
1955916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        if (oldVersion == 301) {
1956916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov            upgradeViewsAndTriggers = true;
1957916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov            oldVersion = 302;
1958916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        }
1959916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
1960b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        if (oldVersion == 302) {
1961b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            upgradeEmailToVersion303(db);
1962b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            upgradeNicknameToVersion303(db);
1963b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            oldVersion = 303;
1964b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
1965b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
196608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        if (oldVersion == 303) {
196708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov            upgradeToVersion304(db);
196808768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov            oldVersion = 304;
196908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        }
197008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
1971f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee        if (oldVersion == 304) {
1972f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee            upgradeNameLookup = true;
1973f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee            oldVersion = 305;
1974f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee        }
1975f84478382761d74b9fb98c4189de66002c04cef8Sang-il, Lee
197660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        if (oldVersion == 305) {
197760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            upgradeToVersion306(db);
197860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            oldVersion = 306;
197960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        }
198060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
1981b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        if (oldVersion == 306) {
1982b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov            upgradeToVersion307(db);
1983b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov            oldVersion = 307;
1984b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        }
1985b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
1986743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        if (oldVersion == 307) {
1987743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov            upgradeToVersion308(db);
1988743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov            oldVersion = 308;
1989743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        }
1990743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
199194c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov        // Gingerbread upgrades
199294c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov        if (oldVersion < 350) {
1993afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann            upgradeViewsAndTriggers = true;
199494c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov            oldVersion = 351;
1995afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann        }
1996afbf2a3343d0f8e7ae7cbfbbec60004ed37caf3fDaniel Lehmann
199794c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov        if (oldVersion == 351) {
199894c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov            upgradeNameLookup = true;
199994c6c5a4a2666efc9236237b5650c73d576e8a61Dmitri Plotnikov            oldVersion = 352;
200080d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann        }
200180d7871ca31d604cbfd857661d5300bb090076dbDaniel Lehmann
20027da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov        if (oldVersion == 352) {
20037da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov            upgradeToVersion353(db);
20047da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov            oldVersion = 353;
20057da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov        }
20067da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov
2007f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov        // Honeycomb upgrades
2008f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov        if (oldVersion < 400) {
2009dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            upgradeViewsAndTriggers = true;
2010f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov            upgradeToVersion400(db);
2011f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov            oldVersion = 400;
2012dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
2013dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
2014f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov        if (oldVersion == 400) {
20154394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov            upgradeViewsAndTriggers = true;
20164394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov            upgradeToVersion401(db);
20174394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov            oldVersion = 401;
20184394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        }
20194394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
2020d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        if (oldVersion == 401) {
2021d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov            upgradeToVersion402(db);
2022d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov            oldVersion = 402;
2023d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        }
2024d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov
202597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        if (oldVersion == 402) {
202697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov            upgradeViewsAndTriggers = true;
202797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov            upgradeToVersion403(db);
202897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov            oldVersion = 403;
202997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        }
203097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
2031a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        if (oldVersion == 403) {
2032a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            upgradeViewsAndTriggers = true;
2033a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            oldVersion = 404;
2034a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        }
2035a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
2036892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        if (oldVersion == 404) {
2037892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            upgradeViewsAndTriggers = true;
2038892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            upgradeToVersion405(db);
2039892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            oldVersion = 405;
2040892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        }
2041892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
20422530512f639c4979fd7371c7dd25dd67e8118124Bai Tao        if (oldVersion == 405) {
20432530512f639c4979fd7371c7dd25dd67e8118124Bai Tao            upgradeViewsAndTriggers = true;
20442530512f639c4979fd7371c7dd25dd67e8118124Bai Tao            upgradeToVersion406(db);
20452530512f639c4979fd7371c7dd25dd67e8118124Bai Tao            oldVersion = 406;
20462530512f639c4979fd7371c7dd25dd67e8118124Bai Tao        }
20472530512f639c4979fd7371c7dd25dd67e8118124Bai Tao
2048cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov        if (oldVersion == 406) {
2049cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov            upgradeViewsAndTriggers = true;
2050cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov            oldVersion = 407;
2051cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov        }
2052cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov
2053385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        if (oldVersion == 407) {
2054d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov            // Obsolete
2055385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov            oldVersion = 408;
2056385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        }
2057385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
20583d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        if (oldVersion == 408) {
20593d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov            upgradeViewsAndTriggers = true;
20603d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov            upgradeToVersion409(db);
20613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov            oldVersion = 409;
20623d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        }
20633d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov
20642b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov        if (oldVersion == 409) {
20652b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov            upgradeViewsAndTriggers = true;
20662b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov            oldVersion = 410;
20672b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov        }
20682b07b826e208e464bbd85d4679aab956bef0bafcDmitri Plotnikov
2069d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        if (oldVersion == 410) {
2070d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov            upgradeToVersion411(db);
2071d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov            oldVersion = 411;
2072d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        }
2073d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov
20747da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov        if (oldVersion == 411) {
20757da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov            // Same upgrade as 353, only on Honeycomb devices
20767da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov            upgradeToVersion353(db);
20777da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov            oldVersion = 412;
20787da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov        }
20797da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov
2080e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov        if (oldVersion == 412) {
2081e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov            upgradeToVersion413(db);
2082e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov            oldVersion = 413;
2083e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov        }
2084e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov
208556f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee        if (oldVersion == 413) {
208656f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee            upgradeNameLookup = true;
208756f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee            oldVersion = 414;
208856f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee        }
208956f2638b49e6bca97f6aa7b0768a8f1fe6e7b72eSang-il, Lee
2090c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov        if (oldVersion == 414) {
2091c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov            upgradeToVersion415(db);
2092c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov            upgradeViewsAndTriggers = true;
2093c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov            oldVersion = 415;
2094c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov        }
2095c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov
2096d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov        if (oldVersion == 415) {
2097d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov            upgradeToVersion416(db);
2098d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov            oldVersion = 416;
2099d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov        }
2100d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov
21018d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov        if (oldVersion == 416) {
21028d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov            upgradeLegacyApiSupport = true;
21038d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov            oldVersion = 417;
21048d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov        }
21058d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov
2106f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        // Honeycomb-MR1 upgrades
2107f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        if (oldVersion < 500) {
2108155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            upgradeSearchIndex = true;
2109f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        }
2110f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
2111197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov        if (oldVersion < 501) {
2112155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            upgradeSearchIndex = true;
2113197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov            upgradeToVersion501(db);
2114197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov            oldVersion = 501;
2115197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov        }
2116197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov
211792ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        if (oldVersion < 502) {
2118155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            upgradeSearchIndex = true;
211992ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov            upgradeToVersion502(db);
212092ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov            oldVersion = 502;
212192ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        }
212292ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov
2123155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        if (oldVersion < 503) {
2124155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            upgradeSearchIndex = true;
2125155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            oldVersion = 503;
2126155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        }
2127155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov
212855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        if (oldVersion < 504) {
212955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            upgradeToVersion504(db);
213055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            oldVersion = 504;
213155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        }
213255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
213324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        if (oldVersion < 600) {
213424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            upgradeToVersion600(db);
213524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            upgradeViewsAndTriggers = true;
213624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            oldVersion = 600;
213724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
213824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        if (oldVersion < 601) {
214046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa            upgradeToVersion601(db);
214146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa            oldVersion = 601;
214246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        }
214346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
214459f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        if (oldVersion < 602) {
214559f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee            upgradeToVersion602(db);
214659f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee            oldVersion = 602;
214759f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        }
214859f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee
21492f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        if (oldVersion < 603) {
21502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa            upgradeViewsAndTriggers = true;
21512f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa            oldVersion = 603;
21522f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        }
21532f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
2154069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        if (oldVersion < 604) {
2155069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee            upgradeToVersion604(db);
2156069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee            oldVersion = 604;
2157069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        }
2158069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee
21593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        if (oldVersion < 605) {
2160f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            upgradeViewsAndTriggers = true;
21613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            upgradeToVersion605(db);
21623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            oldVersion = 605;
21633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
21643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
2165ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        if (oldVersion < 606) {
2166ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann            upgradeViewsAndTriggers = true;
2167ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann            upgradeLegacyApiSupport = true;
2168ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann            upgradeToVersion606(db);
2169ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann            oldVersion = 606;
2170ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        }
2171ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann
21721cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann        if (oldVersion < 607) {
21731cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann            upgradeViewsAndTriggers = true;
21741cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann            upgradeToVersion607(db);
21751cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann            oldVersion = 607;
21761cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann        }
21771cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann
2178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        if (oldVersion < 608) {
2179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            upgradeViewsAndTriggers = true;
2180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            upgradeToVersion608(db);
2181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            oldVersion = 608;
2182f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
2183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
21846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        if (oldVersion < 609) {
21856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            upgradeToVersion609(db);
21866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            oldVersion = 609;
21876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        }
21886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
2189b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda        if (oldVersion < 610) {
2190b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda            upgradeToVersion610(db);
2191b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda            oldVersion = 610;
2192b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda        }
2193b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda
219443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        if (oldVersion < 611) {
219543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro            upgradeViewsAndTriggers = true;
219643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro            upgradeToVersion611(db);
219743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro            oldVersion = 611;
219843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        }
2199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
2200aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda        if (oldVersion < 612) {
2201aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda            upgradeViewsAndTriggers = true;
2202aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda            upgradeToVersion612(db);
2203aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda            oldVersion = 612;
2204aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda        }
2205aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda
22060bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        if (oldVersion < 613) {
22070bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann            upgradeToVersion613(db);
22080bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann            oldVersion = 613;
22090bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        }
22100bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann
22119b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        if (oldVersion < 614) {
22129b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann            // this creates the view "view_stream_items"
22139b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann            upgradeViewsAndTriggers = true;
22149b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann            oldVersion = 614;
22159b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann        }
22169b002837367674b7403769f52dc50ab4dbecef71Daniel Lehmann
22177a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        if (oldVersion < 615) {
22187a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda            upgradeToVersion615(db);
22197a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda            oldVersion = 615;
22207a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        }
22217a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda
2222af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann        if (oldVersion < 616) {
2223af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann            // this updates the "view_stream_items" view
2224af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann            upgradeViewsAndTriggers = true;
2225af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann            oldVersion = 616;
2226af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann        }
2227af10329f85c5d8c4196c495a9f0f9a6c6ecbc231Daniel Lehmann
22285d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        if (oldVersion < 617) {
22295d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            // This version upgrade obsoleted the profile_raw_contact_id field of the Accounts
22305d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            // table, but we aren't removing the column because it is very little data (and not
22315d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            // referenced anymore).  We do need to upgrade the views to handle the simplified
22325d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            // per-database "is profile" columns.
22335d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            upgradeViewsAndTriggers = true;
22345d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro            oldVersion = 617;
22355d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        }
22365d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
2237f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        if (oldVersion < 618) {
2238f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro            upgradeToVersion618(db);
2239f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro            oldVersion = 618;
2240f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        }
2241f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
224208e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov        if (upgradeViewsAndTriggers) {
224308e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            createContactsViews(db);
224408e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            createGroupsView(db);
224508e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov            createContactsTriggers(db);
2246916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov            createContactsIndexes(db);
2247916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov            updateSqliteStats(db);
22488d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov            upgradeLegacyApiSupport = true;
2249916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov            mReopenDatabase = true;
225008e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov        }
225108e50780099971e8927b258ef2ae93d44f98668cDmitri Plotnikov
22528d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov        if (upgradeLegacyApiSupport) {
22538d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov            LegacyApiSupport.createViews(db);
22548d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov        }
22558d2a74522d7b6f792edc74742b594fcb5251fbe2Dmitri Plotnikov
225604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        if (upgradeNameLookup) {
225704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            rebuildNameLookup(db);
225804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
225904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
2260155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        if (upgradeSearchIndex) {
22612c4caaa35be9f8909e8eee26142c4747bbf65aacDaniel Lehmann            createSearchIndexTable(db);
2262155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov            setProperty(db, SearchIndexManager.PROPERTY_SEARCH_INDEX_VERSION, "0");
2263155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        }
2264155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov
226546b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        if (oldVersion != newVersion) {
226646b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana            throw new IllegalStateException(
226746b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana                    "error upgrading the database to version " + newVersion);
226846b7bfa3728bf878d1a9dac9fea35fa629975e1bFred Quintana        }
2269b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
2270b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
22715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeToVersion202(SQLiteDatabase db) {
227236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        db.execSQL(
227336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                "ALTER TABLE " + Tables.PHONE_LOOKUP +
227436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                " ADD " + PhoneLookupColumns.MIN_MATCH + " TEXT;");
227536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
227636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" +
227736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.MIN_MATCH + "," +
227836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID + "," +
227936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                PhoneLookupColumns.DATA_ID +
228036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        ");");
228136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
228236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        updateIndexStats(db, Tables.PHONE_LOOKUP,
228336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                "phone_lookup_min_match_index", "10000 2 2 1");
228436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
228536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        SQLiteStatement update = db.compileStatement(
228636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                "UPDATE " + Tables.PHONE_LOOKUP +
228736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                " SET " + PhoneLookupColumns.MIN_MATCH + "=?" +
228836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                " WHERE " + PhoneLookupColumns.DATA_ID + "=?");
228936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
229036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        // Populate the new column
229136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        Cursor c = db.query(Tables.PHONE_LOOKUP + " JOIN " + Tables.DATA +
229236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                " ON (" + PhoneLookupColumns.DATA_ID + "=" + DataColumns.CONCRETE_ID + ")",
229336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                new String[]{Data._ID, Phone.NUMBER}, null, null, null, null, null);
229436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        try {
229536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov            while (c.moveToNext()) {
229636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                long dataId = c.getLong(0);
229736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                String number = c.getString(1);
229836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                if (!TextUtils.isEmpty(number)) {
229936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                    update.bindString(1, PhoneNumberUtils.toCallerIDMinMatch(number));
230036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                    update.bindLong(2, dataId);
230136045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                    update.execute();
230236045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                }
230336045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov            }
230436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        } finally {
230536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov            c.close();
230636045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        }
230736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov    }
230836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
23095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeToVersion203(SQLiteDatabase db) {
2310758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov        // Garbage-collect first. A bug in Eclair was sometimes leaving
2311758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov        // raw_contacts in the database that no longer had contacts associated
2312758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov        // with them.  To avoid failures during this database upgrade, drop
2313758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov        // the orphaned raw_contacts.
2314758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov        db.execSQL(
2315758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov                "DELETE FROM raw_contacts" +
2316758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov                " WHERE contact_id NOT NULL" +
2317758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov                " AND contact_id NOT IN (SELECT _id FROM contacts)");
2318758a7562d72b0a6ed336beac508eedf7b369fa20Dmitri Plotnikov
2319fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2320fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "ALTER TABLE " + Tables.CONTACTS +
2321fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                " ADD " + Contacts.NAME_RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_id)");
2322fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2323fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "ALTER TABLE " + Tables.RAW_CONTACTS +
23244394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                " ADD contact_in_visible_group INTEGER NOT NULL DEFAULT 0");
2325fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2326fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // For each Contact, find the RawContact that contributed the display name
2327fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2328fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "UPDATE " + Tables.CONTACTS +
2329fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" +
2330fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " SELECT " + RawContacts._ID +
2331fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " FROM " + Tables.RAW_CONTACTS +
2332fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID +
2333fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " AND " + RawContactsColumns.CONCRETE_DISPLAY_NAME + "=" +
2334fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                                Tables.CONTACTS + "." + Contacts.DISPLAY_NAME +
2335fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " ORDER BY " + RawContacts._ID +
2336fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " LIMIT 1)"
2337fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        );
2338fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2339fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL("CREATE INDEX contacts_name_raw_contact_id_index ON " + Tables.CONTACTS + " (" +
2340fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID +
2341fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        ");");
2342fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2343fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // If for some unknown reason we missed some names, let's make sure there are
2344fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // no contacts without a name, picking a raw contact "at random".
2345fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2346fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "UPDATE " + Tables.CONTACTS +
2347fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                " SET " + Contacts.NAME_RAW_CONTACT_ID + "=(" +
2348fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " SELECT " + RawContacts._ID +
2349fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " FROM " + Tables.RAW_CONTACTS +
2350fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " WHERE " + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID +
2351fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " ORDER BY " + RawContacts._ID +
2352fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " LIMIT 1)" +
2353fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                " WHERE " + Contacts.NAME_RAW_CONTACT_ID + " IS NULL"
2354fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        );
2355fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2356fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // Wipe out DISPLAY_NAME on the Contacts table as it is no longer in use.
2357fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2358fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "UPDATE " + Tables.CONTACTS +
2359fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                " SET " + Contacts.DISPLAY_NAME + "=NULL"
2360fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        );
2361fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2362fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // Copy the IN_VISIBLE_GROUP flag down to all raw contacts to allow
2363fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        // indexing on (display_name, in_visible_group)
2364fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL(
2365fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                "UPDATE " + Tables.RAW_CONTACTS +
23664394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                " SET contact_in_visible_group=(" +
2367fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        "SELECT " + Contacts.IN_VISIBLE_GROUP +
2368fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                        " FROM " + Tables.CONTACTS +
2369bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov                        " WHERE " + Contacts._ID + "=" + RawContacts.CONTACT_ID + ")" +
2370bcbd6a5cdd2d1aa6531c592428dc20e0282486c3Dmitri Plotnikov                " WHERE " + RawContacts.CONTACT_ID + " NOT NULL"
2371fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        );
2372fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2373fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" +
23744394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "contact_in_visible_group" + "," +
2375fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                RawContactsColumns.DISPLAY_NAME + " COLLATE LOCALIZED ASC" +
2376fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        ");");
2377fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
2378fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL("DROP INDEX contacts_visible_index");
2379fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        db.execSQL("CREATE INDEX contacts_visible_index ON " + Tables.CONTACTS + " (" +
2380fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP +
2381fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov        ");");
2382fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov    }
2383fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
23845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeToVersion205(SQLiteDatabase db) {
23855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
23865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + " ADD " + RawContacts.DISPLAY_NAME_ALTERNATIVE + " TEXT;");
23875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
23885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + " ADD " + RawContacts.PHONETIC_NAME + " TEXT;");
23895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
23905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                + " ADD " + RawContacts.PHONETIC_NAME_STYLE + " INTEGER;");
23915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
2392de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                + " ADD " + RawContacts.SORT_KEY_PRIMARY
2393de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";");
23945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
2395de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                + " ADD " + RawContacts.SORT_KEY_ALTERNATIVE
2396de8f19d5cc1ef7d5bd76ede6be888dad37112966Daisuke Miyakawa                + " TEXT COLLATE " + ContactsProvider2.PHONEBOOK_COLLATOR_NAME + ";");
23975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        final Locale locale = Locale.getDefault();
23995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
240051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        NameSplitter splitter = createNameSplitter();
24015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        SQLiteStatement rawContactUpdate = db.compileStatement(
24035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                "UPDATE " + Tables.RAW_CONTACTS +
24045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " SET " +
24055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.DISPLAY_NAME_PRIMARY + "=?," +
24065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," +
24075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.PHONETIC_NAME + "=?," +
24085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.PHONETIC_NAME_STYLE + "=?," +
24095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.SORT_KEY_PRIMARY + "=?," +
24105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        RawContacts.SORT_KEY_ALTERNATIVE + "=?" +
24115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " WHERE " + RawContacts._ID + "=?");
24125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        upgradeStructuredNamesToVersion205(db, rawContactUpdate, splitter);
24145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        upgradeOrganizationsToVersion205(db, rawContactUpdate, splitter);
24155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("DROP INDEX raw_contact_sort_key1_index");
24175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contact_sort_key1_index ON " + Tables.RAW_CONTACTS + " (" +
24184394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "contact_in_visible_group" + "," +
24195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY +
24205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ");");
24215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        db.execSQL("CREATE INDEX raw_contact_sort_key2_index ON " + Tables.RAW_CONTACTS + " (" +
24234394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "contact_in_visible_group" + "," +
24245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE +
24255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ");");
24265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
24275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private interface StructName205Query {
24295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        String TABLE = Tables.DATA_JOIN_RAW_CONTACTS;
24305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        String COLUMNS[] = {
24325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                DataColumns.CONCRETE_ID,
24335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                Data.RAW_CONTACT_ID,
24345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
24355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
24365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.PREFIX,
24375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.GIVEN_NAME,
24385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.MIDDLE_NAME,
24395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.FAMILY_NAME,
24405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.SUFFIX,
24415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.PHONETIC_FAMILY_NAME,
24425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.PHONETIC_MIDDLE_NAME,
24435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructuredName.PHONETIC_GIVEN_NAME,
24445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        };
24455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int ID = 0;
24475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int RAW_CONTACT_ID = 1;
24485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int DISPLAY_NAME_SOURCE = 2;
24495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int DISPLAY_NAME = 3;
24505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int PREFIX = 4;
24515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int GIVEN_NAME = 5;
24525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int MIDDLE_NAME = 6;
24535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int FAMILY_NAME = 7;
24545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int SUFFIX = 8;
24555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int PHONETIC_FAMILY_NAME = 9;
24565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int PHONETIC_MIDDLE_NAME = 10;
24575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int PHONETIC_GIVEN_NAME = 11;
24585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
24595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeStructuredNamesToVersion205(SQLiteDatabase db,
24615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            SQLiteStatement rawContactUpdate, NameSplitter splitter) {
24625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // Process structured names to detect the style of the full name and phonetic name
24645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long mMimeType;
24665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        try {
24675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            mMimeType = DatabaseUtils.longForQuery(db,
24685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    "SELECT " + MimetypesColumns._ID +
24695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    " FROM " + Tables.MIMETYPES +
24705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    " WHERE " + MimetypesColumns.MIMETYPE
24715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                            + "='" + StructuredName.CONTENT_ITEM_TYPE + "'", null);
24725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        } catch (SQLiteDoneException e) {
24735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            // No structured names in the database
24745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
24755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
24765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        SQLiteStatement structuredNameUpdate = db.compileStatement(
24785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                "UPDATE " + Tables.DATA +
24795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " SET " +
24805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        StructuredName.FULL_NAME_STYLE + "=?," +
24815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        StructuredName.DISPLAY_NAME + "=?," +
24825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        StructuredName.PHONETIC_NAME_STYLE + "=?" +
24835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " WHERE " + Data._ID + "=?");
24845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        NameSplitter.Name name = new NameSplitter.Name();
24865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        StringBuilder sb = new StringBuilder();
24875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Cursor cursor = db.query(StructName205Query.TABLE,
24885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                StructName205Query.COLUMNS,
24895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=" + mMimeType, null, null, null, null);
24905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        try {
24915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            while (cursor.moveToNext()) {
24925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                long dataId = cursor.getLong(StructName205Query.ID);
24935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                long rawContactId = cursor.getLong(StructName205Query.RAW_CONTACT_ID);
24945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                int displayNameSource = cursor.getInt(StructName205Query.DISPLAY_NAME_SOURCE);
24955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                String displayName = cursor.getString(StructName205Query.DISPLAY_NAME);
24965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.clear();
24985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.prefix = cursor.getString(StructName205Query.PREFIX);
24995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.givenNames = cursor.getString(StructName205Query.GIVEN_NAME);
25005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.middleName = cursor.getString(StructName205Query.MIDDLE_NAME);
25015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.familyName = cursor.getString(StructName205Query.FAMILY_NAME);
25025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.suffix = cursor.getString(StructName205Query.SUFFIX);
25035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.phoneticFamilyName = cursor.getString(StructName205Query.PHONETIC_FAMILY_NAME);
25045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.phoneticMiddleName = cursor.getString(StructName205Query.PHONETIC_MIDDLE_NAME);
25055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                name.phoneticGivenName = cursor.getString(StructName205Query.PHONETIC_GIVEN_NAME);
25065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                upgradeNameToVersion205(dataId, rawContactId, displayNameSource, displayName, name,
25085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        structuredNameUpdate, rawContactUpdate, splitter, sb);
25095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            }
25105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        } finally {
25115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            cursor.close();
25125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
25135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
25145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeNameToVersion205(long dataId, long rawContactId, int displayNameSource,
25165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String currentDisplayName, NameSplitter.Name name,
25175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            SQLiteStatement structuredNameUpdate, SQLiteStatement rawContactUpdate,
25185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            NameSplitter splitter, StringBuilder sb) {
25195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        splitter.guessNameStyle(name);
2521ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao        int unadjustedFullNameStyle = name.fullNameStyle;
25225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        name.fullNameStyle = splitter.getAdjustedFullNameStyle(name.fullNameStyle);
252355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        String displayName = splitter.join(name, true, true);
25245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
2525ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao        // Don't update database with the adjusted fullNameStyle as it is locale
2526ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao        // related
2527ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao        structuredNameUpdate.bindLong(1, unadjustedFullNameStyle);
25285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        DatabaseUtils.bindObjectToProgram(structuredNameUpdate, 2, displayName);
25295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        structuredNameUpdate.bindLong(3, name.phoneticNameStyle);
25305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        structuredNameUpdate.bindLong(4, dataId);
25315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        structuredNameUpdate.execute();
25325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (displayNameSource == DisplayNameSources.STRUCTURED_NAME) {
253455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            String displayNameAlternative = splitter.join(name, false, false);
25355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String phoneticName = splitter.joinPhoneticName(name);
25365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String sortKey = null;
25375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String sortKeyAlternative = null;
25385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            if (phoneticName != null) {
25405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                sortKey = sortKeyAlternative = phoneticName;
2541ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao            } else if (name.fullNameStyle == FullNameStyle.CHINESE ||
2542ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                    name.fullNameStyle == FullNameStyle.CJK) {
2543ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                sortKey = sortKeyAlternative = ContactLocaleUtils.getIntance()
2544ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                        .getSortKey(displayName, name.fullNameStyle);
25455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            }
25465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            if (sortKey == null) {
25485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                sortKey = displayName;
25495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                sortKeyAlternative = displayNameAlternative;
25505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            }
25515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            updateRawContact205(rawContactUpdate, rawContactId, displayName,
25535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    displayNameAlternative, name.phoneticNameStyle, phoneticName, sortKey,
25545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    sortKeyAlternative);
25555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
25565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
25575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private interface Organization205Query {
25595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        String TABLE = Tables.DATA_JOIN_RAW_CONTACTS;
25605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        String COLUMNS[] = {
25625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                DataColumns.CONCRETE_ID,
25635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                Data.RAW_CONTACT_ID,
25645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                Organization.COMPANY,
25655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                Organization.PHONETIC_NAME,
25665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        };
25675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int ID = 0;
25695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int RAW_CONTACT_ID = 1;
25705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int COMPANY = 2;
25715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        int PHONETIC_NAME = 3;
25725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
25735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void upgradeOrganizationsToVersion205(SQLiteDatabase db,
25755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            SQLiteStatement rawContactUpdate, NameSplitter splitter) {
2576b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        final long mimeType = lookupMimeTypeId(db, Organization.CONTENT_ITEM_TYPE);
25775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        SQLiteStatement organizationUpdate = db.compileStatement(
25795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                "UPDATE " + Tables.DATA +
25805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " SET " +
25815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        Organization.PHONETIC_NAME_STYLE + "=?" +
25825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                " WHERE " + Data._ID + "=?");
25835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Cursor cursor = db.query(Organization205Query.TABLE, Organization205Query.COLUMNS,
2585b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=" + mimeType + " AND "
25865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        + RawContacts.DISPLAY_NAME_SOURCE + "=" + DisplayNameSources.ORGANIZATION,
25875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                null, null, null, null);
25885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        try {
25895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            while (cursor.moveToNext()) {
25905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                long dataId = cursor.getLong(Organization205Query.ID);
25915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                long rawContactId = cursor.getLong(Organization205Query.RAW_CONTACT_ID);
25925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                String company = cursor.getString(Organization205Query.COMPANY);
25935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                String phoneticName = cursor.getString(Organization205Query.PHONETIC_NAME);
25945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                int phoneticNameStyle = splitter.guessPhoneticNameStyle(phoneticName);
25965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                organizationUpdate.bindLong(1, phoneticNameStyle);
25985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                organizationUpdate.bindLong(2, dataId);
25995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                organizationUpdate.execute();
26005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                String sortKey = null;
26025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                if (phoneticName == null && company != null) {
26035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    int nameStyle = splitter.guessFullNameStyle(company);
26045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    nameStyle = splitter.getAdjustedFullNameStyle(nameStyle);
2605ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                    if (nameStyle == FullNameStyle.CHINESE ||
2606ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                            nameStyle == FullNameStyle.CJK ) {
2607ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                        sortKey = ContactLocaleUtils.getIntance()
2608ee0e6b105832366143e4ddb30beb5bb0e5c81ec5Bai Tao                                .getSortKey(company, nameStyle);
26095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    }
26105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                }
26115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                if (sortKey == null) {
26135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                    sortKey = company;
26145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                }
26155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                updateRawContact205(rawContactUpdate, rawContactId, company,
26175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                        company, phoneticNameStyle, phoneticName, sortKey, sortKey);
26185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            }
26195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        } finally {
26205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            cursor.close();
26215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
26225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void updateRawContact205(SQLiteStatement rawContactUpdate, long rawContactId,
26255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String displayName, String displayNameAlternative, int phoneticNameStyle,
26265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String phoneticName, String sortKeyPrimary, String sortKeyAlternative) {
26275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        bindString(rawContactUpdate, 1, displayName);
26285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        bindString(rawContactUpdate, 2, displayNameAlternative);
26295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        bindString(rawContactUpdate, 3, phoneticName);
26305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        rawContactUpdate.bindLong(4, phoneticNameStyle);
26315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        bindString(rawContactUpdate, 5, sortKeyPrimary);
26325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        bindString(rawContactUpdate, 6, sortKeyAlternative);
26335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        rawContactUpdate.bindLong(7, rawContactId);
26345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        rawContactUpdate.execute();
26355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
2637f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov    private void upgrateToVersion206(SQLiteDatabase db) {
2638f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov        db.execSQL("ALTER TABLE " + Tables.RAW_CONTACTS
2639f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov                + " ADD " + RawContacts.NAME_VERIFIED + " INTEGER NOT NULL DEFAULT 0;");
2640f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov    }
2641f01c876a92b9c950a0450ed8b706ac5eb2c9b660Dmitri Plotnikov
264231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    /**
264331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov     * Fix for the bug where name lookup records for organizations would get removed by
264431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov     * unrelated updates of the data rows.
264531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov     */
2646b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    private void upgradeToVersion300(SQLiteDatabase db) {
2647197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov        // No longer needed
264831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
264931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
2650b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    private static final class Upgrade303Query {
2651b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final String TABLE = Tables.DATA;
2652b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2653b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final String SELECTION =
2654b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=?" +
2655b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                    " AND " + Data._ID + " NOT IN " +
2656b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                    "(SELECT " + NameLookupColumns.DATA_ID + " FROM " + Tables.NAME_LOOKUP + ")" +
2657b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                    " AND " + Data.DATA1 + " NOT NULL";
2658b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2659b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final String COLUMNS[] = {
2660b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                Data._ID,
2661b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                Data.RAW_CONTACT_ID,
2662b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                Data.DATA1,
2663b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        };
2664b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2665b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final int ID = 0;
2666b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final int RAW_CONTACT_ID = 1;
2667b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        public static final int DATA1 = 2;
2668b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    }
2669b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2670b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    /**
2671b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     * The {@link ContactsProvider2#update} method was deleting name lookup for new
2672b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     * emails during the sync.  We need to restore the lost name lookup rows.
2673b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     */
2674b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    private void upgradeEmailToVersion303(SQLiteDatabase db) {
2675b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE);
2676b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        if (mimeTypeId == -1) {
2677b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return;
2678b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
2679b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2680b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        ContentValues values = new ContentValues();
2681b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2682b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        // Find all data rows with the mime type "email" that are missing name lookup
2683b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS,
2684b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)},
2685b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                null, null, null);
2686b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        try {
2687b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            while (cursor.moveToNext()) {
2688b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                long dataId = cursor.getLong(Upgrade303Query.ID);
2689b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID);
2690b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                String value = cursor.getString(Upgrade303Query.DATA1);
2691b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                value = extractHandleFromEmailAddress(value);
2692b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2693b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                if (value != null) {
2694b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    values.put(NameLookupColumns.DATA_ID, dataId);
2695b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId);
2696b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    values.put(NameLookupColumns.NAME_TYPE, NameLookupType.EMAIL_BASED_NICKNAME);
2697b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value));
2698b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    db.insert(Tables.NAME_LOOKUP, null, values);
2699b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                }
2700b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            }
2701b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        } finally {
2702b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            cursor.close();
2703b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
2704b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    }
2705b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2706b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    /**
2707b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     * The {@link ContactsProvider2#update} method was deleting name lookup for new
2708b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     * nicknames during the sync.  We need to restore the lost name lookup rows.
2709b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov     */
2710b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    private void upgradeNicknameToVersion303(SQLiteDatabase db) {
2711b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE);
2712b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        if (mimeTypeId == -1) {
2713b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return;
2714b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
2715b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2716b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        ContentValues values = new ContentValues();
2717b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2718b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        // Find all data rows with the mime type "nickname" that are missing name lookup
2719b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        Cursor cursor = db.query(Upgrade303Query.TABLE, Upgrade303Query.COLUMNS,
2720b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                Upgrade303Query.SELECTION, new String[] {String.valueOf(mimeTypeId)},
2721b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                null, null, null);
2722b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        try {
2723b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            while (cursor.moveToNext()) {
2724b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                long dataId = cursor.getLong(Upgrade303Query.ID);
2725b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                long rawContactId = cursor.getLong(Upgrade303Query.RAW_CONTACT_ID);
2726b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                String value = cursor.getString(Upgrade303Query.DATA1);
2727b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
2728b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                values.put(NameLookupColumns.DATA_ID, dataId);
2729b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                values.put(NameLookupColumns.RAW_CONTACT_ID, rawContactId);
2730b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                values.put(NameLookupColumns.NAME_TYPE, NameLookupType.NICKNAME);
2731b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                values.put(NameLookupColumns.NORMALIZED_NAME, NameNormalizer.normalize(value));
2732b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                db.insert(Tables.NAME_LOOKUP, null, values);
2733b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            }
2734b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        } finally {
2735b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            cursor.close();
2736b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
2737b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    }
2738b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
273951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    private void upgradeToVersion304(SQLiteDatabase db) {
274051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        // Mimetype table requires an index on mime type
274151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS mime_type ON " + Tables.MIMETYPES + " (" +
274251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                MimetypesColumns.MIMETYPE +
274351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        ");");
274451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    }
274551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
274660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    private void upgradeToVersion306(SQLiteDatabase db) {
274760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        // Fix invalid lookup that was used for Exchange contacts (it was not escaped)
274860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        // It happened when a new contact was created AND synchronized
274960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        final StringBuilder lookupKeyBuilder = new StringBuilder();
275060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        final SQLiteStatement updateStatement = db.compileStatement(
275160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "UPDATE contacts " +
275260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "SET lookup=? " +
275360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "WHERE _id=?");
275460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        final Cursor contactIdCursor = db.rawQuery(
275560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "SELECT DISTINCT contact_id " +
275660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "FROM raw_contacts " +
275760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                "WHERE deleted=0 AND account_type='com.android.exchange'",
275860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                null);
275960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        try {
276060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            while (contactIdCursor.moveToNext()) {
276160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                final long contactId = contactIdCursor.getLong(0);
276260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                lookupKeyBuilder.setLength(0);
276360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                final Cursor c = db.rawQuery(
276460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        "SELECT account_type, account_name, _id, sourceid, display_name " +
276560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        "FROM raw_contacts " +
276660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        "WHERE contact_id=? " +
276760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        "ORDER BY _id",
276860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        new String[] { String.valueOf(contactId) });
276960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                try {
277060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                    while (c.moveToNext()) {
277160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                        ContactLookupKey.appendToLookupKey(lookupKeyBuilder,
277260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                                c.getString(0),
277360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                                c.getString(1),
277460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                                c.getLong(2),
277560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                                c.getString(3),
277660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                                c.getString(4));
277760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                    }
277860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                } finally {
277960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                    c.close();
278060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                }
278160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
278260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                if (lookupKeyBuilder.length() == 0) {
278360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                    updateStatement.bindNull(1);
278460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                } else {
278560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                    updateStatement.bindString(1, Uri.encode(lookupKeyBuilder.toString()));
278660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                }
278760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                updateStatement.bindLong(2, contactId);
278860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
278960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann                updateStatement.execute();
279060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            }
279160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        } finally {
279260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            updateStatement.close();
279360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann            contactIdCursor.close();
279460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        }
279560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
279660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
2797b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    private void upgradeToVersion307(SQLiteDatabase db) {
2798b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        db.execSQL("CREATE TABLE properties (" +
2799b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                "property_key TEXT PRIMARY_KEY, " +
2800b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                "property_value TEXT" +
2801b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ");");
2802b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
2803b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
2804743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov    private void upgradeToVersion308(SQLiteDatabase db) {
28054394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("CREATE TABLE accounts (" +
28064394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "account_name TEXT, " +
28074394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "account_type TEXT " +
28084394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        ");");
2809743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
28104394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("INSERT INTO accounts " +
28114394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                "SELECT DISTINCT account_name, account_type FROM raw_contacts");
2812743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov    }
2813743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
2814f3082210d83492b4a8591c82e56291514547f5a5Dmitri Plotnikov    private void upgradeToVersion400(SQLiteDatabase db) {
2815dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        db.execSQL("ALTER TABLE " + Tables.GROUPS
2816dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                + " ADD " + Groups.FAVORITES + " INTEGER NOT NULL DEFAULT 0;");
2817dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        db.execSQL("ALTER TABLE " + Tables.GROUPS
2818dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                + " ADD " + Groups.AUTO_ADD + " INTEGER NOT NULL DEFAULT 0;");
2819dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
2820dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
28217da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov    private void upgradeToVersion353(SQLiteDatabase db) {
28227da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov        db.execSQL("DELETE FROM contacts " +
28237da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov                "WHERE NOT EXISTS (SELECT 1 FROM raw_contacts WHERE contact_id=contacts._id)");
28247da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov    }
28257da074dc59f256a63201439cc9ae24bd2e347a06Dmitri Plotnikov
282651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    private void rebuildNameLookup(SQLiteDatabase db) {
282751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        db.execSQL("DROP INDEX IF EXISTS name_lookup_index");
282851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        insertNameLookup(db);
282951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        createContactsIndexes(db);
283051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    }
283151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
283204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    /**
283351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov     * Regenerates all locale-sensitive data: nickname_lookup, name_lookup and sort keys.
283404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     */
283551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    public void setLocale(ContactsProvider2 provider, Locale locale) {
283651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        Log.i(TAG, "Switching to locale " + locale);
283704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
2838c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton        long start = SystemClock.uptimeMillis();
283951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        SQLiteDatabase db = getWritableDatabase();
284051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        db.setLocale(locale);
284151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        db.beginTransaction();
284251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        try {
284351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            db.execSQL("DROP INDEX raw_contact_sort_key1_index");
284451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            db.execSQL("DROP INDEX raw_contact_sort_key2_index");
284551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            db.execSQL("DROP INDEX IF EXISTS name_lookup_index");
284651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
284751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            loadNicknameLookupTable(db);
284851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            insertNameLookup(db);
284951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            rebuildSortKeys(db, provider);
285051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            createContactsIndexes(db);
285151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            db.setTransactionSuccessful();
285251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        } finally {
285351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            db.endTransaction();
285451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        }
285551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
2856c085b3eeebf13ebdfb197444747354a1d6eced2bJeff Hamilton        Log.i(TAG, "Locale change completed in " + (SystemClock.uptimeMillis() - start) + "ms");
285751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    }
285851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
285951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    /**
286051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov     * Regenerates sort keys for all contacts.
286151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov     */
286251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    private void rebuildSortKeys(SQLiteDatabase db, ContactsProvider2 provider) {
286351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        Cursor cursor = db.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID},
286451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                null, null, null, null, null);
286551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        try {
286651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            while (cursor.moveToNext()) {
286751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                long rawContactId = cursor.getLong(0);
28688ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                updateRawContactDisplayName(db, rawContactId);
286951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            }
287051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        } finally {
287151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            cursor.close();
287251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        }
287351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    }
287451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
287551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov    private void insertNameLookup(SQLiteDatabase db) {
287604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP);
287704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
287804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        SQLiteStatement nameLookupInsert = db.compileStatement(
287904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "("
288004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        + NameLookupColumns.RAW_CONTACT_ID + ","
288104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        + NameLookupColumns.DATA_ID + ","
288204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        + NameLookupColumns.NAME_TYPE + ","
288304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        + NameLookupColumns.NORMALIZED_NAME +
288404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                ") VALUES (?,?,?,?)");
288504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
288651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        try {
288751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            insertStructuredNameLookup(db, nameLookupInsert);
288851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            insertEmailLookup(db, nameLookupInsert);
288951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            insertNicknameLookup(db, nameLookupInsert);
289051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        } finally {
289151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            nameLookupInsert.close();
289251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        }
289304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
289404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
289504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private static final class StructuredNameQuery {
289604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String TABLE = Tables.DATA;
289704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
289804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String SELECTION =
289904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL";
290004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
290104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String COLUMNS[] = {
290204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                StructuredName._ID,
290304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                StructuredName.RAW_CONTACT_ID,
290404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                StructuredName.DISPLAY_NAME,
290504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        };
290604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
290704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int ID = 0;
290804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int RAW_CONTACT_ID = 1;
290904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int DISPLAY_NAME = 2;
291004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
291104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
291204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private class StructuredNameLookupBuilder extends NameLookupBuilder {
291304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
291404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        private final SQLiteStatement mNameLookupInsert;
291504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        private final CommonNicknameCache mCommonNicknameCache;
291604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
291704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public StructuredNameLookupBuilder(NameSplitter splitter,
291804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                CommonNicknameCache commonNicknameCache, SQLiteStatement nameLookupInsert) {
291904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            super(splitter);
292004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            this.mCommonNicknameCache = commonNicknameCache;
292104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            this.mNameLookupInsert = nameLookupInsert;
292204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
292304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
292404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        @Override
292504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        protected void insertNameLookup(long rawContactId, long dataId, int lookupType,
292604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                String name) {
292704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            if (!TextUtils.isEmpty(name)) {
292804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                ContactsDatabaseHelper.this.insertNormalizedNameLookup(mNameLookupInsert,
292904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        rawContactId, dataId, lookupType, name);
293004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            }
293104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
293204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
293304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        @Override
293404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        protected String[] getCommonNicknameClusters(String normalizedName) {
293504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            return mCommonNicknameCache.getCommonNicknameClusters(normalizedName);
293604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
293704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
293804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
293904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    /**
294004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     * Inserts name lookup rows for all structured names in the database.
294104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     */
294204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private void insertStructuredNameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) {
2943d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov        NameSplitter nameSplitter = createNameSplitter();
2944d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov        NameLookupBuilder nameLookupBuilder = new StructuredNameLookupBuilder(nameSplitter,
294504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                new CommonNicknameCache(db), nameLookupInsert);
294604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, StructuredName.CONTENT_ITEM_TYPE);
294704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        Cursor cursor = db.query(StructuredNameQuery.TABLE, StructuredNameQuery.COLUMNS,
294804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                StructuredNameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)},
294904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                null, null, null);
295004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        try {
295104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            while (cursor.moveToNext()) {
295204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long dataId = cursor.getLong(StructuredNameQuery.ID);
295304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long rawContactId = cursor.getLong(StructuredNameQuery.RAW_CONTACT_ID);
295404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                String name = cursor.getString(StructuredNameQuery.DISPLAY_NAME);
2955d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov                int fullNameStyle = nameSplitter.guessFullNameStyle(name);
295651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                fullNameStyle = nameSplitter.getAdjustedFullNameStyle(fullNameStyle);
2957d806946b6561dca3f34ded156c6ee89a5113996eDmitri Plotnikov                nameLookupBuilder.insertNameLookup(rawContactId, dataId, name, fullNameStyle);
295804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            }
295904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        } finally {
296004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            cursor.close();
296104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
296204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
296304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
296404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private static final class OrganizationQuery {
296504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String TABLE = Tables.DATA;
296604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
296704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String SELECTION =
296804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL";
296904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
297004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String COLUMNS[] = {
297104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Organization._ID,
297204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Organization.RAW_CONTACT_ID,
297304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Organization.COMPANY,
297404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Organization.TITLE,
297504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        };
297604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
297704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int ID = 0;
297804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int RAW_CONTACT_ID = 1;
297904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int COMPANY = 2;
298004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int TITLE = 3;
298104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
298204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
298304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private static final class EmailQuery {
298404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String TABLE = Tables.DATA;
298504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
298604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String SELECTION =
298704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL";
298804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
298904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String COLUMNS[] = {
299004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Email._ID,
299104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Email.RAW_CONTACT_ID,
299204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Email.ADDRESS,
299304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        };
299404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
299504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int ID = 0;
299604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int RAW_CONTACT_ID = 1;
299704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int ADDRESS = 2;
299804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
299904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
300004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    /**
300104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     * Inserts name lookup rows for all email addresses in the database.
300204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     */
300304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private void insertEmailLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) {
300404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, Email.CONTENT_ITEM_TYPE);
300504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        Cursor cursor = db.query(EmailQuery.TABLE, EmailQuery.COLUMNS,
300604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                EmailQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)},
300704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                null, null, null);
300804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        try {
300904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            while (cursor.moveToNext()) {
301004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long dataId = cursor.getLong(EmailQuery.ID);
301104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long rawContactId = cursor.getLong(EmailQuery.RAW_CONTACT_ID);
301204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                String address = cursor.getString(EmailQuery.ADDRESS);
301304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                address = extractHandleFromEmailAddress(address);
301404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                insertNameLookup(nameLookupInsert, rawContactId, dataId,
301504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        NameLookupType.EMAIL_BASED_NICKNAME, address);
301604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            }
301704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        } finally {
301804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            cursor.close();
301904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
302004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
302104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
302204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private static final class NicknameQuery {
302304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String TABLE = Tables.DATA;
302404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
302504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String SELECTION =
302604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                DataColumns.MIMETYPE_ID + "=? AND " + Data.DATA1 + " NOT NULL";
302704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
302804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final String COLUMNS[] = {
302904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Nickname._ID,
303004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Nickname.RAW_CONTACT_ID,
303104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Nickname.NAME,
303204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        };
303304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
303404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int ID = 0;
303504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int RAW_CONTACT_ID = 1;
303604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        public static final int NAME = 2;
303704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
303804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
303904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    /**
304004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     * Inserts name lookup rows for all nicknames in the database.
304104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     */
304204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private void insertNicknameLookup(SQLiteDatabase db, SQLiteStatement nameLookupInsert) {
304304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, Nickname.CONTENT_ITEM_TYPE);
304404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        Cursor cursor = db.query(NicknameQuery.TABLE, NicknameQuery.COLUMNS,
304504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                NicknameQuery.SELECTION, new String[] {String.valueOf(mimeTypeId)},
304604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                null, null, null);
304704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        try {
304804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            while (cursor.moveToNext()) {
304904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long dataId = cursor.getLong(NicknameQuery.ID);
305004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                long rawContactId = cursor.getLong(NicknameQuery.RAW_CONTACT_ID);
305104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                String nickname = cursor.getString(NicknameQuery.NAME);
305204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                insertNameLookup(nameLookupInsert, rawContactId, dataId,
305304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                        NameLookupType.NICKNAME, nickname);
305404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            }
305504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        } finally {
305604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            cursor.close();
305704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
305804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
305904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
306004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    /**
306104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     * Inserts a record in the {@link Tables#NAME_LOOKUP} table.
306204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov     */
306304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    public void insertNameLookup(SQLiteStatement stmt, long rawContactId, long dataId,
306404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            int lookupType, String name) {
306504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        if (TextUtils.isEmpty(name)) {
306604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            return;
306704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
306804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
306904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        String normalized = NameNormalizer.normalize(name);
307004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        if (TextUtils.isEmpty(normalized)) {
307104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            return;
307204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        }
307304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
307404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        insertNormalizedNameLookup(stmt, rawContactId, dataId, lookupType, normalized);
307504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
307604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
307704b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    private void insertNormalizedNameLookup(SQLiteStatement stmt, long rawContactId, long dataId,
307804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov            int lookupType, String normalizedName) {
307904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        stmt.bindLong(1, rawContactId);
308004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        stmt.bindLong(2, dataId);
308104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        stmt.bindLong(3, lookupType);
308204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        stmt.bindString(4, normalizedName);
308304b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov        stmt.executeInsert();
308404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
308504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
30864394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov    /**
30874394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov     * Changing the VISIBLE bit from a field on both RawContacts and Contacts to a separate table.
30884394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov     */
30894394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov    private void upgradeToVersion401(SQLiteDatabase db) {
30904394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.VISIBLE_CONTACTS + " (" +
30914394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                Contacts._ID + " INTEGER PRIMARY KEY" +
30924394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        ");");
30934394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS +
30944394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                " SELECT " + Contacts._ID +
30954394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                " FROM " + Tables.CONTACTS +
30964394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                " WHERE " + Contacts.IN_VISIBLE_GROUP + "!=0");
30974394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("DROP INDEX contacts_visible_index");
30984394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov    }
30994394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
3100d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov    /**
3101d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov     * Introducing a new table: directories.
3102d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov     */
3103d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov    private void upgradeToVersion402(SQLiteDatabase db) {
3104d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov        createDirectoriesTable(db);
3105d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov    }
3106d3d812af96f7d77e13dc60652626b39f25907147Dmitri Plotnikov
310797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    private void upgradeToVersion403(SQLiteDatabase db) {
310897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS directories;");
310997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        createDirectoriesTable(db);
311097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
311197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        db.execSQL("ALTER TABLE raw_contacts"
311297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                + " ADD raw_contact_is_read_only INTEGER NOT NULL DEFAULT 0;");
311397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
311497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        db.execSQL("ALTER TABLE data"
311597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                + " ADD is_read_only INTEGER NOT NULL DEFAULT 0;");
311697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
311797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
3118892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    private void upgradeToVersion405(SQLiteDatabase db) {
3119892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS phone_lookup;");
3120892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Private phone numbers table used for lookup
3121892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +
3122892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.DATA_ID
3123892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                + " INTEGER REFERENCES data(_id) NOT NULL," +
3124892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID
3125892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                + " INTEGER REFERENCES raw_contacts(_id) NOT NULL," +
3126892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL," +
3127892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.MIN_MATCH + " TEXT NOT NULL" +
3128892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ");");
3129892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
3130892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" +
3131892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.NORMALIZED_NUMBER + "," +
3132892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID + "," +
3133892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.DATA_ID +
3134892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ");");
3135892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
3136892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_min_match_index ON " + Tables.PHONE_LOOKUP + " (" +
3137892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.MIN_MATCH + "," +
3138892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.RAW_CONTACT_ID + "," +
3139892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                PhoneLookupColumns.DATA_ID +
3140892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ");");
3141892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
3142892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        final long mimeTypeId = lookupMimeTypeId(db, Phone.CONTENT_ITEM_TYPE);
3143892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        if (mimeTypeId == -1) {
3144892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            return;
3145892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        }
3146892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
3147892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Cursor cursor = db.rawQuery(
3148892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    "SELECT _id, " + Phone.RAW_CONTACT_ID + ", " + Phone.NUMBER +
3149892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    " FROM " + Tables.DATA +
3150892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    " WHERE " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId
3151892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                            + " AND " + Phone.NUMBER + " NOT NULL", null);
3152892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
3153892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues phoneValues = new ContentValues();
3154892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        try {
3155892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            while (cursor.moveToNext()) {
3156892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                long dataID = cursor.getLong(0);
3157892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                long rawContactID = cursor.getLong(1);
3158892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                String number = cursor.getString(2);
3159892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                String normalizedNumber = PhoneNumberUtils.normalizeNumber(number);
3160892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                if (!TextUtils.isEmpty(normalizedNumber)) {
3161892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    phoneValues.clear();
3162892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactID);
3163892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    phoneValues.put(PhoneLookupColumns.DATA_ID, dataID);
3164892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
3165892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    phoneValues.put(PhoneLookupColumns.MIN_MATCH,
3166892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                            PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber));
3167892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                    db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
3168892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                }
3169892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            }
3170892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        } finally {
3171892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            cursor.close();
3172892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        }
3173892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
3174892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
31752530512f639c4979fd7371c7dd25dd67e8118124Bai Tao    private void upgradeToVersion406(SQLiteDatabase db) {
31762530512f639c4979fd7371c7dd25dd67e8118124Bai Tao        db.execSQL("ALTER TABLE calls ADD countryiso TEXT;");
31772530512f639c4979fd7371c7dd25dd67e8118124Bai Tao    }
31782530512f639c4979fd7371c7dd25dd67e8118124Bai Tao
3179d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov    private void upgradeToVersion409(SQLiteDatabase db) {
3180d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS directories;");
3181d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        createDirectoriesTable(db);
3182d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov    }
3183d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov
3184385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov    /**
3185d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov     * Adding DEFAULT_DIRECTORY table.
31863e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * DEFAULT_DIRECTORY should contain every contact which should be shown to users in default.
31873e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * - if a contact doesn't belong to any account (local contact), it should be in
31883e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     *   default_directory
31893e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * - if a contact belongs to an account that doesn't have a "default" group, it should be in
31903e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     *   default_directory
31913e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * - if a contact belongs to an account that has a "default" group (like Google directory,
31923e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     *   which has "My contacts" group as default), it should be in default_directory.
31933e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     *
31943e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * This logic assumes that accounts with the "default" group should have at least one
31953e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa     * group with AUTO_ADD (implying it is the default group) flag in the groups table.
3196385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov     */
3197d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov    private void upgradeToVersion411(SQLiteDatabase db) {
3198d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS " + Tables.DEFAULT_DIRECTORY);
31993e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("CREATE TABLE default_directory (_id INTEGER PRIMARY KEY);");
3200385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3201385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        // Process contacts without an account
32023e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("INSERT OR IGNORE INTO default_directory " +
32033e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " SELECT contact_id " +
32043e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " FROM raw_contacts " +
32053e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " WHERE raw_contacts.account_name IS NULL " +
32063e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "   AND raw_contacts.account_type IS NULL ");
32073e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa
32083e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        // Process accounts that don't have a default group (e.g. Exchange).
32093e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("INSERT OR IGNORE INTO default_directory " +
32103e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " SELECT contact_id " +
32113e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " FROM raw_contacts " +
3212385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                " WHERE NOT EXISTS" +
32133e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " (SELECT _id " +
32143e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "  FROM groups " +
32153e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "  WHERE raw_contacts.account_name = groups.account_name" +
32163e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "    AND raw_contacts.account_type = groups.account_type" +
32173e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "    AND groups.auto_add != 0)");
3218385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
32193e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        final long mimetype = lookupMimeTypeId(db, GroupMembership.CONTENT_ITEM_TYPE);
3220385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3221d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        // Process accounts that do have a default group (e.g. Google)
32223e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa        db.execSQL("INSERT OR IGNORE INTO default_directory " +
32233e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " SELECT contact_id " +
32243e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " FROM raw_contacts " +
32253e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " JOIN data " +
32263e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "   ON (raw_contacts._id=raw_contact_id)" +
32273e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " WHERE mimetype_id=" + mimetype +
3228d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov                " AND EXISTS" +
32293e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                " (SELECT _id" +
32303e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "  FROM groups" +
32313e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "  WHERE raw_contacts.account_name = groups.account_name" +
32323e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "    AND raw_contacts.account_type = groups.account_type" +
32333e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa                "    AND groups.auto_add != 0)");
32343d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov    }
3235385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3236e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    private void upgradeToVersion413(SQLiteDatabase db) {
32373ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov        db.execSQL("DROP TABLE IF EXISTS directories;");
32383ea7932a47027c8629d3a301e1a16e7d2c8a298dDmitri Plotnikov        createDirectoriesTable(db);
3239e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov    }
3240e0e24418cba10a5184e2966aaa32d5458fa6a387Dmitri Plotnikov
3241c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov    private void upgradeToVersion415(SQLiteDatabase db) {
3242c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov        db.execSQL(
3243c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                "ALTER TABLE " + Tables.GROUPS +
3244c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                " ADD " + Groups.GROUP_IS_READ_ONLY + " INTEGER NOT NULL DEFAULT 0");
3245c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov        db.execSQL(
3246c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                "UPDATE " + Tables.GROUPS +
3247c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                "   SET " + Groups.GROUP_IS_READ_ONLY + "=1" +
3248c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                " WHERE " + Groups.SYSTEM_ID + " NOT NULL");
3249c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov    }
3250c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov
3251d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov    private void upgradeToVersion416(SQLiteDatabase db) {
3252d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov        db.execSQL("CREATE INDEX phone_lookup_data_id_min_match_index ON " + Tables.PHONE_LOOKUP +
3253d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov                " (" + PhoneLookupColumns.DATA_ID + ", " + PhoneLookupColumns.MIN_MATCH + ");");
3254d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov    }
3255d97464c056e8f247e1b33dce0ea2f77eb7f6c009Dmitri Plotnikov
3256197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov    private void upgradeToVersion501(SQLiteDatabase db) {
3257197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov        // Remove organization rows from the name lookup, we now use search index for that
3258197411a6cc3f81b94a34ca207f267d43d8548f04Dmitri Plotnikov        db.execSQL("DELETE FROM name_lookup WHERE name_type=5");
3259f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    }
3260f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
326192ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov    private void upgradeToVersion502(SQLiteDatabase db) {
326292ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        // Remove Chinese and Korean name lookup - this data is now in the search index
326392ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov        db.execSQL("DELETE FROM name_lookup WHERE name_type IN (6, 7)");
326492ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov    }
326592ddc5cdc4d89ee2c6e861ae7b3a3a913ffa0100Dmitri Plotnikov
326655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov    private void upgradeToVersion504(SQLiteDatabase db) {
326755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        populateMimeTypeCache(db);
326855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
326955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        // Find all names with prefixes and recreate display name
327055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        Cursor cursor = db.rawQuery(
327155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                "SELECT " + StructuredName.RAW_CONTACT_ID +
327255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                " FROM " + Tables.DATA +
327355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                " WHERE " + DataColumns.MIMETYPE_ID + "=?"
327455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                        + " AND " + StructuredName.PREFIX + " NOT NULL",
327555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                new String[]{ String.valueOf(mMimeTypeIdStructuredName) });
327655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
327755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        try {
327855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            while(cursor.moveToNext()) {
327955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                long rawContactId = cursor.getLong(0);
328055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                updateRawContactDisplayName(db, rawContactId);
328155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            }
328255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
328355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        } finally {
328455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            cursor.close();
328555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        }
328655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov    }
328755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
328824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private void upgradeToVersion600(SQLiteDatabase db) {
32895d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // This change used to add the profile raw contact ID to the Accounts table.  That
32905d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // column is no longer needed (as of version 614) since the profile records are stored in
32915d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        // a separate copy of the database for security reasons.  So this change is now a no-op.
329224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
329324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
329446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    private void upgradeToVersion601(SQLiteDatabase db) {
329546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        db.execSQL("CREATE TABLE data_usage_stat(" +
329646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "stat_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
329746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "data_id INTEGER NOT NULL, " +
329846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "usage_type INTEGER NOT NULL DEFAULT 0, " +
329946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "times_used INTEGER NOT NULL DEFAULT 0, " +
330046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "last_time_used INTERGER NOT NULL DEFAULT 0, " +
330146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "FOREIGN KEY(data_id) REFERENCES data(_id));");
330246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        db.execSQL("CREATE UNIQUE INDEX data_usage_stat_index ON " +
330346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                "data_usage_stat (data_id, usage_type)");
330446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
330546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
330659f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee    private void upgradeToVersion602(SQLiteDatabase db) {
330759f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD voicemail_uri TEXT;");
330859f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD _data TEXT;");
330959f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD has_content INTEGER;");
331059f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD mime_type TEXT;");
331159f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD source_data TEXT;");
331259f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD source_package TEXT;");
331359f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee        db.execSQL("ALTER TABLE calls ADD state INTEGER;");
331459f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee    }
331559f6477e10203617f504857f7e9aee2fda393f4fDebashish Chatterjee
3316069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee    private void upgradeToVersion604(SQLiteDatabase db) {
3317069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        db.execSQL("CREATE TABLE voicemail_status (" +
3318069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
3319069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "source_package TEXT UNIQUE NOT NULL," +
3320069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "settings_uri TEXT," +
3321069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "voicemail_access_uri TEXT," +
3322069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "configuration_state INTEGER," +
3323069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "data_channel_state INTEGER," +
3324069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee                "notification_channel_state INTEGER" +
3325069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee        ");");
3326069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee    }
3327069fdf5902415ebd6c92e5d889740e0d50cfec8dDebashish Chatterjee
33283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private void upgradeToVersion605(SQLiteDatabase db) {
33296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This version used to create the stream item and stream item photos tables, but a newer
33306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // version of those tables is created in version 609 below.  So omitting the creation in
33316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // this upgrade step to avoid a create->drop->create.
33323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
3334ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann    private void upgradeToVersion606(SQLiteDatabase db) {
3335ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_contacts_restricted;");
3336ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_data_restricted;");
3337ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_raw_contacts_restricted;");
3338ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_raw_entities_restricted;");
3339ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_entities_restricted;");
3340ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP VIEW IF EXISTS view_data_usage_stat_restricted;");
3341ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        db.execSQL("DROP INDEX IF EXISTS contacts_restricted_index");
3342ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann
3343ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        // We should remove the restricted columns here as well, but unfortunately SQLite doesn't
3344ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann        // provide ALTER TABLE DROP COLUMN. As they have DEFAULT 0, we can keep but ignore them
3345ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann    }
3346ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann
33471cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann    private void upgradeToVersion607(SQLiteDatabase db) {
33480bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // We added "action" and "action_uri" to groups here, but realized this was not a smart
33490bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // move. This upgrade step has been removed (all dogfood phones that executed this step
33500bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // will have those columns, but that shouldn't hurt. Unfortunately, SQLite makes it hard
33510bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // to remove columns)
33521cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann    }
33531cdfc9dacc136e99d3c0bc5b4212bc3c973be337Daniel Lehmann
3354f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private void upgradeToVersion608(SQLiteDatabase db) {
3355f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        db.execSQL("ALTER TABLE contacts ADD photo_file_id INTEGER REFERENCES photo_files(_id);");
3356f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
3357f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        db.execSQL("CREATE TABLE photo_files(" +
3358f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
3359f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                "height INTEGER NOT NULL, " +
3360f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                "width INTEGER NOT NULL, " +
3361f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                "filesize INTEGER NOT NULL);");
3362f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
3363f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
33646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    private void upgradeToVersion609(SQLiteDatabase db) {
33650bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // This version used to create the stream item and stream item photos tables, but a newer
33660bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // version of those tables is created in version 613 below.  So omitting the creation in
33670bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // this upgrade step to avoid a create->drop->create.
33686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
33696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
3370b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda    private void upgradeToVersion610(SQLiteDatabase db) {
3371b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda        db.execSQL("ALTER TABLE calls ADD is_read INTEGER;");
3372b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda    }
3373b2197b235e3d96e7f70c24d548b7dac52dab88d8Flavio Lerda
337443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro    private void upgradeToVersion611(SQLiteDatabase db) {
337543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("ALTER TABLE raw_contacts ADD data_set TEXT DEFAULT NULL;");
337643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("ALTER TABLE groups ADD data_set TEXT DEFAULT NULL;");
337743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("ALTER TABLE accounts ADD data_set TEXT DEFAULT NULL;");
337843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
337943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("CREATE INDEX raw_contacts_source_id_data_set_index ON raw_contacts " +
338043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                "(sourceid, account_type, account_name, data_set);");
338143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
338243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro        db.execSQL("CREATE INDEX groups_source_id_data_set_index ON groups " +
338343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                "(sourceid, account_type, account_name, data_set);");
338443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro    }
338543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro
3386aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda    private void upgradeToVersion612(SQLiteDatabase db) {
3387aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda        db.execSQL("ALTER TABLE calls ADD geocoded_location TEXT DEFAULT NULL;");
3388aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda        // Old calls will not have a geocoded location; new calls will get it when inserted.
3389aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda    }
3390aeaba441ddb05dede8bd86291ca78f42d670d54cFlavio Lerda
33910bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann    private void upgradeToVersion613(SQLiteDatabase db) {
33920bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // The stream item and stream item photos APIs were not in-use by anyone in the time
33930bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // between their initial creation (in v609) and this update.  So we're just dropping
33940bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // and re-creating them to get appropriate columns.  The delta is as follows:
33950bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - In stream_items, package_id was replaced by res_package.
33960bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - In stream_item_photos, picture was replaced by photo_file_id.
33970bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - Instead of resource ids for icon and label, we use resource name strings now
33980bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - Added sync columns
33990bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - Removed action and action_uri
34000bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        // - Text and comments are now nullable
34010bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann
34020bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        db.execSQL("DROP TABLE IF EXISTS stream_items");
34030bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        db.execSQL("DROP TABLE IF EXISTS stream_item_photos");
34040bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann
34050bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        db.execSQL("CREATE TABLE stream_items(" +
34060bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
34070bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "raw_contact_id INTEGER NOT NULL, " +
34080bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "res_package TEXT, " +
34090bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "icon TEXT, " +
34100bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "label TEXT, " +
34110bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "text TEXT, " +
34120bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "timestamp INTEGER NOT NULL, " +
34130bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "comments TEXT, " +
34140bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_sync1 TEXT, " +
34150bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_sync2 TEXT, " +
34160bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_sync3 TEXT, " +
34170bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_sync4 TEXT, " +
34180bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "FOREIGN KEY(raw_contact_id) REFERENCES raw_contacts(_id));");
34190bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann
34200bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann        db.execSQL("CREATE TABLE stream_item_photos(" +
34210bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
34220bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_id INTEGER NOT NULL, " +
34230bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "sort_index INTEGER, " +
34240bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "photo_file_id INTEGER NOT NULL, " +
34250bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_photo_sync1 TEXT, " +
34260bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_photo_sync2 TEXT, " +
34270bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_photo_sync3 TEXT, " +
34280bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "stream_item_photo_sync4 TEXT, " +
34290bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann                "FOREIGN KEY(stream_item_id) REFERENCES stream_items(_id));");
34300bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann    }
34310bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann
34327a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda    private void upgradeToVersion615(SQLiteDatabase db) {
34337a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        // Old calls will not have up to date values for these columns, they will be filled in
34347a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        // as needed.
34357a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        db.execSQL("ALTER TABLE calls ADD lookup_uri TEXT DEFAULT NULL;");
34367a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        db.execSQL("ALTER TABLE calls ADD matched_number TEXT DEFAULT NULL;");
34377a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        db.execSQL("ALTER TABLE calls ADD normalized_number TEXT DEFAULT NULL;");
34387a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda        db.execSQL("ALTER TABLE calls ADD photo_id INTEGER NOT NULL DEFAULT 0;");
34397a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda    }
34407a24e1c1476b57a6268de8d57e5ef4a2d5f46794Flavio Lerda
3441f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    private void upgradeToVersion618(SQLiteDatabase db) {
3442f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        // The Settings table needs a data_set column which technically should be part of the
3443f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        // primary key but can't be because it may be null.  Since SQLite doesn't support nuking
3444f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        // the primary key, we'll drop the old table, re-create it, and copy the settings back in.
3445f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("CREATE TEMPORARY TABLE settings_backup(" +
3446f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "account_name STRING NOT NULL," +
3447f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "account_type STRING NOT NULL," +
3448f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "ungrouped_visible INTEGER NOT NULL DEFAULT 0," +
3449f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "should_sync INTEGER NOT NULL DEFAULT 1" +
3450f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        ");");
3451f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("INSERT INTO settings_backup " +
3452f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "SELECT account_name, account_type, ungrouped_visible, should_sync" +
3453f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                " FROM settings");
3454f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("DROP TABLE settings");
3455f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("CREATE TABLE settings (" +
3456f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "account_name STRING NOT NULL," +
3457f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "account_type STRING NOT NULL," +
3458f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "data_set STRING," +
3459f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "ungrouped_visible INTEGER NOT NULL DEFAULT 0," +
3460f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "should_sync INTEGER NOT NULL DEFAULT 1" +
3461f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        ");");
3462f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("INSERT INTO settings " +
3463f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "SELECT account_name, account_type, NULL, ungrouped_visible, should_sync " +
3464f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                "FROM settings_backup");
3465f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        db.execSQL("DROP TABLE settings_backup");
3466f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
3467f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
3468b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    public String extractHandleFromEmailAddress(String email) {
3469b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email);
3470b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        if (tokens.length == 0) {
3471b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return null;
3472b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
3473b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
3474b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        String address = tokens[0].getAddress();
3475b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        int at = address.indexOf('@');
3476b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        if (at != -1) {
3477b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return address.substring(0, at);
3478b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
3479b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        return null;
3480b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    }
3481b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
348208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov    public String extractAddressFromEmailAddress(String email) {
348308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email);
348408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        if (tokens.length == 0) {
348508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov            return null;
348608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        }
348708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
348850a7c86b4b49870bd19d5270722be3f1fccaf226Dmitri Plotnikov        return tokens[0].getAddress().trim();
348908768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov    }
349008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
34913e2aeb5c57d968d1dc98ba3f92f658eb7dd0cb7dDaisuke Miyakawa    private static long lookupMimeTypeId(SQLiteDatabase db, String mimeType) {
3492b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        try {
3493b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return DatabaseUtils.longForQuery(db,
3494b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    "SELECT " + MimetypesColumns._ID +
3495b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    " FROM " + Tables.MIMETYPES +
3496b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                    " WHERE " + MimetypesColumns.MIMETYPE
3497b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov                            + "='" + mimeType + "'", null);
3498b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        } catch (SQLiteDoneException e) {
3499b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            // No rows of this type in the database
3500b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov            return -1;
3501b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov        }
3502b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov    }
3503b06484032125877d1a89785a1a912ca58c12d448Dmitri Plotnikov
35045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void bindString(SQLiteStatement stmt, int index, String value) {
35055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (value == null) {
35065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            stmt.bindNull(index);
35075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        } else {
35085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            stmt.bindString(index, value);
35095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
35105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
351278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    private void bindLong(SQLiteStatement stmt, int index, Number value) {
351378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (value == null) {
351478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            stmt.bindNull(index);
351578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        } else {
351678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            stmt.bindLong(index, value.longValue());
351778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
351878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
351978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
3520a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    /**
3521f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     * Adds index stats into the SQLite database to force it to always use the lookup indexes.
3522f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     */
3523f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    private void updateSqliteStats(SQLiteDatabase db) {
3524f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
3525f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        // Specific stats strings are based on an actual large database after running ANALYZE
3526f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        try {
35278fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.CONTACTS,
35288fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "contacts_has_phone_index", "10000 500");
35298fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35308fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.RAW_CONTACTS,
35318fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "raw_contacts_source_id_index", "10000 1 1 1");
35328fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.RAW_CONTACTS,
35338fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "raw_contacts_contact_id_index", "10000 2");
35348fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35358fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.NAME_LOOKUP,
35368fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "name_lookup_raw_contact_id_index", "10000 3");
35378fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.NAME_LOOKUP,
3538916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov                    "name_lookup_index", "10000 3 2 2 1");
35398fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.NAME_LOOKUP,
35408fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "sqlite_autoindex_name_lookup_1", "10000 3 2 1");
35418fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35428fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.PHONE_LOOKUP,
35438fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "phone_lookup_index", "10000 2 2 1");
354436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov            updateIndexStats(db, Tables.PHONE_LOOKUP,
354536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov                    "phone_lookup_min_match_index", "10000 2 2 1");
35468fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35478fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.DATA,
35488fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "data_mimetype_data1_index", "60000 5000 2");
35498fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.DATA,
35508fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "data_raw_contact_id", "60000 10");
35518fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35528fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.GROUPS,
35538fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "groups_source_id_index", "50 1 1 1");
35548fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
35558fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov            updateIndexStats(db, Tables.NICKNAME_LOOKUP,
35568fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov                    "sqlite_autoindex_name_lookup_1", "500 2 1");
35578fddc066662d58e8d6a436decb8dafbf28ce652eDmitri Plotnikov
3558f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        } catch (SQLException e) {
3559f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov            Log.e(TAG, "Could not update index stats", e);
3560f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        }
3561f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    }
3562f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
3563f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    /**
3564f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     * Stores statistics for a given index.
3565f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     *
3566f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     * @param stats has the following structure: the first index is the expected size of
3567f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     * the table.  The following integer(s) are the expected number of records selected with the
3568f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     * index.  There should be one integer per indexed column.
3569f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov     */
35705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    private void updateIndexStats(SQLiteDatabase db, String table, String index,
35715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            String stats) {
3572f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        db.execSQL("DELETE FROM sqlite_stat1 WHERE tbl='" + table + "' AND idx='" + index + "';");
3573f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        db.execSQL("INSERT INTO sqlite_stat1 (tbl,idx,stat)"
3574f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov                + " VALUES ('" + table + "','" + index + "','" + stats + "');");
3575f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    }
3576f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
3577f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    @Override
3578f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    public synchronized SQLiteDatabase getWritableDatabase() {
3579f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        SQLiteDatabase db = super.getWritableDatabase();
3580f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        if (mReopenDatabase) {
3581f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov            mReopenDatabase = false;
3582f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov            close();
3583f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov            db = super.getWritableDatabase();
3584f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        }
3585f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov        return db;
3586f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    }
3587f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov
3588f79538095a1af16dcd6e641448b627f60f197802Dmitri Plotnikov    /**
3589a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov     * Wipes all data except mime type and package lookup tables.
3590a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov     */
3591a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    public void wipeData() {
3592a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        SQLiteDatabase db = getWritableDatabase();
35933d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov
359433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.ACCOUNTS + ";");
35955d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        db.execSQL("INSERT INTO " + Tables.ACCOUNTS + " VALUES(NULL, NULL, NULL)");
359633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
3597d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.CONTACTS + ";");
35985ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";");
35993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        db.execSQL("DELETE FROM " + Tables.STREAM_ITEMS + ";");
36003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        db.execSQL("DELETE FROM " + Tables.STREAM_ITEM_PHOTOS + ";");
3601f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        db.execSQL("DELETE FROM " + Tables.PHOTO_FILES + ";");
3602a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.DATA + ";");
3603a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";");
3604a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";");
3605ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        db.execSQL("DELETE FROM " + Tables.GROUPS + ";");
3606b174c7ccd337a7bea6269139c9b09acc69ae40c1Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";");
3607eb9ffdccfa19f5b2f22e688f733fd77e39605f9eJeff Sharkey        db.execSQL("DELETE FROM " + Tables.SETTINGS + ";");
3608a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";");
36093d8b043c3341a5b6c2e781b7eba9767d5cd13267Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.CALLS + ";");
361072e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.DIRECTORIES + ";");
3611f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.SEARCH_INDEX + ";");
361272e3003a810fb4793a1513d17a40f8ab83d7d0afDmitri Plotnikov
3613b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP
3614a8dc456684a104c7e5547ba17d44f952022cd8c5Dmitri Plotnikov    }
3615b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
361604b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    public NameSplitter createNameSplitter() {
36178ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        mNameSplitter = new NameSplitter(
361804b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                mContext.getString(com.android.internal.R.string.common_name_prefixes),
361904b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                mContext.getString(com.android.internal.R.string.common_last_name_prefixes),
362004b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                mContext.getString(com.android.internal.R.string.common_name_suffixes),
362104b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                mContext.getString(com.android.internal.R.string.common_name_conjunctions),
362204b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov                Locale.getDefault());
36238ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        return mNameSplitter;
362404b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov    }
362504b7ce026c73077d9d982742bc662ea4b3ac74e7Dmitri Plotnikov
3626b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /**
3627619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey     * Return the {@link ApplicationInfo#uid} for the given package name.
3628619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey     */
3629619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    public static int getUidForPackageName(PackageManager pm, String packageName) {
3630619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        try {
3631619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey            ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */);
3632619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey            return clientInfo.uid;
3633619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        } catch (NameNotFoundException e) {
3634619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey            throw new RuntimeException(e);
3635619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey        }
3636619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    }
3637619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey
3638619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    /**
3639b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * Perform an internal string-to-integer lookup using the compiled
364011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann     * {@link SQLiteStatement} provided. If a mapping isn't found in database, it will be
3641b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * created. All new, uncached answers are added to the cache automatically.
3642b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     *
3643b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * @param query Compiled statement used to query for the mapping.
3644b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * @param insert Compiled statement used to insert a new mapping when no
3645b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     *            existing one is found in cache or from query.
3646b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * @param value Value to find mapping for.
3647b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * @param cache In-memory cache of previous answers.
3648b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * @return An unique integer mapping for the given value.
3649b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     */
365011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann    private long lookupAndCacheId(SQLiteStatement query, SQLiteStatement insert,
3651b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            String value, HashMap<String, Long> cache) {
365211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        long id = -1;
365311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        try {
365411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            // Try searching database for mapping
365511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            DatabaseUtils.bindObjectToProgram(query, 1, value);
365611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            id = query.simpleQueryForLong();
365711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        } catch (SQLiteDoneException e) {
365811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            // Nothing found, so try inserting new mapping
365911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            DatabaseUtils.bindObjectToProgram(insert, 1, value);
366011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            id = insert.executeInsert();
366111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        }
366211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        if (id != -1) {
366311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            // Cache and return the new answer
366411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            cache.put(value, id);
366511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            return id;
366611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        } else {
366711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            // Otherwise throw if no mapping found or created
366811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            throw new IllegalStateException("Couldn't find or create internal "
366911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                    + "lookup table entry for value " + value);
3670b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        }
3671b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
3672b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
3673b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /**
3674ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey     * Convert a package name into an integer, using {@link Tables#PACKAGES} for
3675b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * lookups and possible allocation of new IDs as needed.
3676b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     */
3677b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public long getPackageId(String packageName) {
367811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        // Try an in-memory cache lookup
367911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        if (mPackageCache.containsKey(packageName)) return mPackageCache.get(packageName);
368078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
368111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        final SQLiteStatement packageQuery = getWritableDatabase().compileStatement(
368211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                "SELECT " + PackagesColumns._ID +
368311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                " FROM " + Tables.PACKAGES +
368411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                " WHERE " + PackagesColumns.PACKAGE + "=?");
368511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann
368611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        final SQLiteStatement packageInsert = getWritableDatabase().compileStatement(
368711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                "INSERT INTO " + Tables.PACKAGES + "("
368811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                        + PackagesColumns.PACKAGE +
368911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                ") VALUES (?)");
369011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        try {
369111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            return lookupAndCacheId(packageQuery, packageInsert, packageName, mPackageCache);
369211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        } finally {
369311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            packageQuery.close();
369411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            packageInsert.close();
369578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
3696b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
3697b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
3698b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /**
3699ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey     * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for
3700b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * lookups and possible allocation of new IDs as needed.
3701b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     */
3702b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public long getMimeTypeId(String mimetype) {
370311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        // Try an in-memory cache lookup
370411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        if (mMimetypeCache.containsKey(mimetype)) return mMimetypeCache.get(mimetype);
370511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann
370611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        return lookupMimeTypeId(mimetype, getWritableDatabase());
370711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann    }
370811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann
370911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann    private long lookupMimeTypeId(String mimetype, SQLiteDatabase db) {
371011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        final SQLiteStatement mimetypeQuery = db.compileStatement(
371111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                "SELECT " + MimetypesColumns._ID +
371211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                " FROM " + Tables.MIMETYPES +
371311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                " WHERE " + MimetypesColumns.MIMETYPE + "=?");
371411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann
371511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        final SQLiteStatement mimetypeInsert = db.compileStatement(
371611a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                "INSERT INTO " + Tables.MIMETYPES + "("
371711a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                        + MimetypesColumns.MIMETYPE +
371811a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann                ") VALUES (?)");
371911a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann
372011a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        try {
372111a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            return lookupAndCacheId(mimetypeQuery, mimetypeInsert, mimetype, mMimetypeCache);
372211a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        } finally {
372311a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            mimetypeQuery.close();
372411a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann            mimetypeInsert.close();
372511a83441a0f66440dcf1a560194dcc11979f0c2cDaniel Lehmann        }
3726b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
3727b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
37282a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    public long getMimeTypeIdForStructuredName() {
37292a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        return mMimeTypeIdStructuredName;
37302a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
37312a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
37322a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    public long getMimeTypeIdForOrganization() {
37332a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        return mMimeTypeIdOrganization;
37342a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
37352a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
37362a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    public long getMimeTypeIdForIm() {
37372a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        return mMimeTypeIdIm;
37382a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
37392a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
37402a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    public long getMimeTypeIdForEmail() {
37412a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        return mMimeTypeIdEmail;
37422a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
37432a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
3744a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public long getMimeTypeIdForSip() {
3745a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        return mMimeTypeIdSip;
3746a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
3747a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
37482a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    public int getDisplayNameSourceForMimeTypeId(int mimeTypeId) {
37492a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        if (mimeTypeId == mMimeTypeIdStructuredName) {
37502a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.STRUCTURED_NAME;
37512a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        } else if (mimeTypeId == mMimeTypeIdEmail) {
37522a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.EMAIL;
37532a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        } else if (mimeTypeId == mMimeTypeIdPhone) {
37542a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.PHONE;
37552a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        } else if (mimeTypeId == mMimeTypeIdOrganization) {
37562a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.ORGANIZATION;
37572a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        } else if (mimeTypeId == mMimeTypeIdNickname) {
37582a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.NICKNAME;
37592a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        } else {
37602a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov            return DisplayNameSources.UNDEFINED;
37612a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        }
37622a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov    }
37632a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov
3764b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /**
3765ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey     * Find the mimetype for the given {@link Data#_ID}.
3766b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     */
3767b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public String getDataMimeType(long dataId) {
376878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mDataMimetypeQuery == null) {
376978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mDataMimetypeQuery = getWritableDatabase().compileStatement(
377078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "SELECT " + MimetypesColumns.MIMETYPE +
377178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " FROM " + Tables.DATA_JOIN_MIMETYPES +
377278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + Tables.DATA + "." + Data._ID + "=?");
377378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
3774b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        try {
3775b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            // Try database query to find mimetype
3776b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId);
3777b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            String mimetype = mDataMimetypeQuery.simpleQueryForString();
3778b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            return mimetype;
3779b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        } catch (SQLiteDoneException e) {
3780b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            // No valid mapping found, so return null
3781b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            return null;
3782b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        }
3783b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
3784b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey
3785b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    /**
3786b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     * Find the mime-type for the given {@link Activities#_ID}.
3787b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey     */
3788b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    public String getActivityMimeType(long activityId) {
378978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mActivitiesMimetypeQuery == null) {
379078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mActivitiesMimetypeQuery = getWritableDatabase().compileStatement(
379178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "SELECT " + MimetypesColumns.MIMETYPE +
379278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES +
379378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + Tables.ACTIVITIES + "." + Activities._ID + "=?");
379478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
3795b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        try {
3796b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            // Try database query to find mimetype
3797b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId);
3798b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            String mimetype = mActivitiesMimetypeQuery.simpleQueryForString();
3799b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            return mimetype;
3800b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        } catch (SQLiteDoneException e) {
3801b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            // No valid mapping found, so return null
3802b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey            return null;
3803b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey        }
3804b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey    }
38056bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov
38066bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov    /**
3807d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov     * Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts.
3808ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey     */
3809ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    public void updateAllVisible() {
3810385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        updateCustomContactVisibility(getWritableDatabase(), "");
3811ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    }
3812ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
3813ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    /**
3814f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov     * Updates contact visibility and return true iff the visibility was actually changed.
3815f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov     */
3816bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov    public boolean updateContactVisibleOnlyIfChanged(TransactionContext txContext, long contactId) {
3817bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov        return updateContactVisible(txContext, contactId, true);
3818f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    }
3819f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov
3820f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    /**
3821385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov     * Update {@link Contacts#IN_VISIBLE_GROUP} and
3822385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov     * {@link Tables#DEFAULT_DIRECTORY} for a specific contact.
3823ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey     */
3824bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov    public void updateContactVisible(TransactionContext txContext, long contactId) {
3825bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov        updateContactVisible(txContext, contactId, false);
3826f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    }
3827f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov
3828bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov    public boolean updateContactVisible(
3829bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov            TransactionContext txContext, long contactId, boolean onlyIfChanged) {
38304394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        SQLiteDatabase db = getWritableDatabase();
3831f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        updateCustomContactVisibility(db, " AND " + Contacts._ID + "=" + contactId);
3832385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3833385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        String contactIdAsString = String.valueOf(contactId);
3834385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        long mimetype = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
3835385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3836385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        // The contact will be included in the default directory if contains
3837d6ef718d85724dc482dc88f8c8a87b356e63c0f6Dmitri Plotnikov        // a raw contact that is in any group or in an account that
3838385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        // does not have any AUTO_ADD groups.
3839f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        boolean newVisibility = DatabaseUtils.longForQuery(db,
3840385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                "SELECT EXISTS (" +
3841385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "SELECT " + RawContacts.CONTACT_ID +
3842385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " FROM " + Tables.RAW_CONTACTS +
3843385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " JOIN " + Tables.DATA +
3844385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "   ON (" + RawContactsColumns.CONCRETE_ID + "="
3845385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                            + Data.RAW_CONTACT_ID + ")" +
3846385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " WHERE " + RawContacts.CONTACT_ID + "=?" +
3847385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "   AND " + DataColumns.MIMETYPE_ID + "=?" +
3848385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                ") OR EXISTS (" +
3849385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "SELECT " + RawContacts._ID +
3850385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " FROM " + Tables.RAW_CONTACTS +
3851385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " WHERE " + RawContacts.CONTACT_ID + "=?" +
3852385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "   AND NOT EXISTS" +
3853385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        " (SELECT " + Groups._ID +
3854385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        "  FROM " + Tables.GROUPS +
3855385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        "  WHERE " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " = "
3856385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                                + GroupsColumns.CONCRETE_ACCOUNT_NAME +
3857385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        "  AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " = "
3858385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                                + GroupsColumns.CONCRETE_ACCOUNT_TYPE +
385943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                        "  AND (" + RawContactsColumns.CONCRETE_DATA_SET + " = "
386043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                                + GroupsColumns.CONCRETE_DATA_SET
386143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                                + " OR " + RawContactsColumns.CONCRETE_DATA_SET + " IS NULL AND "
386243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                                + GroupsColumns.CONCRETE_DATA_SET + " IS NULL)" +
3863385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        "  AND " + Groups.AUTO_ADD + " != 0" +
3864385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                        ")" +
3865385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                ") OR EXISTS (" +
3866385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "SELECT " + RawContacts._ID +
3867385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " FROM " + Tables.RAW_CONTACTS +
3868385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    " WHERE " + RawContacts.CONTACT_ID + "=?" +
3869385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "   AND " + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " IS NULL " +
3870385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    "   AND " + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " IS NULL" +
387143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                    "   AND " + RawContactsColumns.CONCRETE_DATA_SET + " IS NULL" +
3872385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                ")",
3873385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                new String[] {
3874385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    contactIdAsString,
38756c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov                    String.valueOf(mimetype),
3876385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    contactIdAsString,
38776c47e208236a62c55f396116e087331e05e148f3Dmitri Plotnikov                    contactIdAsString
3878f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov                }) != 0;
3879385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov
3880f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        if (onlyIfChanged) {
3881f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov            boolean oldVisibility = isContactInDefaultDirectory(db, contactId);
3882f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov            if (oldVisibility == newVisibility) {
3883f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov                return false;
3884f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov            }
3885f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        }
3886f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov
3887f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        if (newVisibility) {
3888385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov            db.execSQL("INSERT OR IGNORE INTO " + Tables.DEFAULT_DIRECTORY + " VALUES(?)",
3889385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    new String[] { contactIdAsString });
3890bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov            txContext.invalidateSearchIndexForContact(contactId);
3891385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        } else {
3892bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov            db.execSQL("DELETE FROM " + Tables.DEFAULT_DIRECTORY +
3893bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov                        " WHERE " + Contacts._ID + "=?",
3894bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov                    new String[] { contactIdAsString });
3895bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov            db.execSQL("DELETE FROM " + Tables.SEARCH_INDEX +
3896bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov                        " WHERE " + SearchIndexColumns.CONTACT_ID + "=CAST(? AS int)",
3897385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov                    new String[] { contactIdAsString });
3898385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov        }
3899f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        return true;
3900f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    }
3901f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov
3902f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov    public boolean isContactInDefaultDirectory(SQLiteDatabase db, long contactId) {
3903f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        if (mContactInDefaultDirectoryQuery == null) {
3904f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov            mContactInDefaultDirectoryQuery = db.compileStatement(
3905f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov                    "SELECT EXISTS (" +
3906f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov                            "SELECT 1 FROM " + Tables.DEFAULT_DIRECTORY +
3907f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov                            " WHERE " + Contacts._ID + "=?)");
3908f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        }
3909f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        mContactInDefaultDirectoryQuery.bindLong(1, contactId);
3910f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov        return mContactInDefaultDirectoryQuery.simpleQueryForLong() != 0;
3911385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov    }
39124394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
3913385182830ff0ed84edce9aba2424d2afe99453ceDmitri Plotnikov    private void updateCustomContactVisibility(SQLiteDatabase db, String selection) {
3914ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey        final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
39154394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        String[] selectionArgs = new String[]{String.valueOf(groupMembershipMimetypeId)};
39164394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov
39174394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        // First delete what needs to be deleted, then insert what needs to be added.
39184394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        // Since flash writes are very expensive, this approach is much better than
39194394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        // delete-all-insert-all.
39204394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.VISIBLE_CONTACTS +
39214394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                   " WHERE " + "_id NOT IN" +
39224394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                        "(SELECT " + Contacts._ID +
39234394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                        " FROM " + Tables.CONTACTS +
39244394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                        " WHERE (" + Clauses.CONTACT_IS_VISIBLE + ")=1) " + selection,
39254394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                selectionArgs);
3926fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov
39274394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov        db.execSQL("INSERT INTO " + Tables.VISIBLE_CONTACTS +
39284394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                   " SELECT " + Contacts._ID +
39294394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                   " FROM " + Tables.CONTACTS +
39304394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                   " WHERE " + Contacts._ID +
39314394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                   " NOT IN " + Tables.VISIBLE_CONTACTS +
39324394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                           " AND (" + Clauses.CONTACT_IS_VISIBLE + ")=1 " + selection,
39334394086494fe7909aaca70f56fb4bb08beebf303Dmitri Plotnikov                selectionArgs);
3934ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    }
3935ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey
3936ca8172420c0913dff96ea607d477d8b8abfe5ddbJeff Sharkey    /**
3937d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov     * Returns contact ID for the given contact or zero if it is NULL.
39386bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov     */
3939d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    public long getContactId(long rawContactId) {
394078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mContactIdQuery == null) {
394178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mContactIdQuery = getWritableDatabase().compileStatement(
394278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "SELECT " + RawContacts.CONTACT_ID +
394378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " FROM " + Tables.RAW_CONTACTS +
394478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + RawContacts._ID + "=?");
394578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
39466bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov        try {
3947d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId);
3948d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            return mContactIdQuery.simpleQueryForLong();
39496bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov        } catch (SQLiteDoneException e) {
3950a3bd0246ca3741877488bca7aadd91c79b2fd8d2Fred Quintana            // No valid mapping found, so return 0
39516bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov            return 0;
39526bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov        }
39536bccc079d8fea5c51f9fa6fd06044bd8f5109c6fDmitri Plotnikov    }
395461bbb2287e8102b7e03922c03809c34b7b317d1cDmitri Plotnikov
39555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov    public int getAggregationMode(long rawContactId) {
395678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mAggregationModeQuery == null) {
395778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mAggregationModeQuery = getWritableDatabase().compileStatement(
395878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "SELECT " + RawContacts.AGGREGATION_MODE +
395978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " FROM " + Tables.RAW_CONTACTS +
396078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + RawContacts._ID + "=?");
396178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
3962f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        try {
39635ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov            DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId);
3964f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            return (int)mAggregationModeQuery.simpleQueryForLong();
3965f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        } catch (SQLiteDoneException e) {
39666cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov            // No valid row found, so return "disabled"
39676cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov            return RawContacts.AGGREGATION_MODE_DISABLED;
3968f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        }
3969f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    }
3970f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov
3971892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void buildPhoneLookupAndContactQuery(
3972892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            SQLiteQueryBuilder qb, String normalizedNumber, String numberE164) {
3973892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        String minMatch = PhoneNumberUtils.toCallerIDMinMatch(normalizedNumber);
3974e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        StringBuilder sb = new StringBuilder();
397536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        appendPhoneLookupTables(sb, minMatch, true);
3976e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        qb.setTables(sb.toString());
3977e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
3978e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        sb = new StringBuilder();
3979892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        appendPhoneLookupSelection(sb, normalizedNumber, numberE164);
3980e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        qb.appendWhere(sb.toString());
3981bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov    }
3982bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov
3983e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public String buildPhoneLookupAsNestedQuery(String number) {
3984e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        StringBuilder sb = new StringBuilder();
398536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        final String minMatch = PhoneNumberUtils.toCallerIDMinMatch(number);
3986e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        sb.append("(SELECT DISTINCT raw_contact_id" + " FROM ");
398736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        appendPhoneLookupTables(sb, minMatch, false);
3988e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        sb.append(" WHERE ");
3989892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        appendPhoneLookupSelection(sb, number, null);
3990e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        sb.append(")");
3991e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        return sb.toString();
3992e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    }
3993e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
399436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov    private void appendPhoneLookupTables(StringBuilder sb, final String minMatch,
3995e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov            boolean joinContacts) {
3996e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        sb.append(Tables.RAW_CONTACTS);
3997e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        if (joinContacts) {
3998ed6bfd922fd84db21de08c1d12e93c501b86560dDaniel Lehmann            sb.append(" JOIN " + Views.CONTACTS + " contacts_view"
3999fada1f08e7ffc8012bf2175f61f3ef3270eba9ecDmitri Plotnikov                    + " ON (contacts_view._id = raw_contacts.contact_id)");
4000e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        }
4001892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        sb.append(", (SELECT data_id, normalized_number, length(normalized_number) as len "
4002892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                + " FROM phone_lookup " + " WHERE (" + Tables.PHONE_LOOKUP + "."
4003892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                + PhoneLookupColumns.MIN_MATCH + " = '");
400436045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        sb.append(minMatch);
400536045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        sb.append("')) AS lookup, " + Tables.DATA);
4006e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    }
4007e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
4008892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    private void appendPhoneLookupSelection(StringBuilder sb, String number, String numberE164) {
4009892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        sb.append("lookup.data_id=data._id AND data.raw_contact_id=raw_contacts._id");
4010892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        boolean hasNumberE164 = !TextUtils.isEmpty(numberE164);
4011892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        boolean hasNumber = !TextUtils.isEmpty(number);
4012892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        if (hasNumberE164 || hasNumber) {
4013892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            sb.append(" AND ( ");
4014892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            if (hasNumberE164) {
4015892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(" lookup.normalized_number = ");
4016892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                DatabaseUtils.appendEscapedSQLString(sb, numberE164);
4017892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            }
4018892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            if (hasNumberE164 && hasNumber) {
4019892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(" OR ");
4020892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            }
4021892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            if (hasNumber) {
4022892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                int numberLen = number.length();
4023892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(" lookup.len <= ");
4024892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(numberLen);
4025892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(" AND substr(");
4026892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                DatabaseUtils.appendEscapedSQLString(sb, number);
4027892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(',');
4028892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(numberLen);
4029892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov                sb.append(" - lookup.len + 1) = lookup.normalized_number");
403034984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                // Some countries (e.g. Brazil) can have incoming calls which contain only the local
403134984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                // number (no country calling code and no area code). This case is handled below.
403234984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                // Details see b/5197612.
403334984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                if (!hasNumberE164) {
403434984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(" OR (");
403534984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(" lookup.len > ");
403634984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(numberLen);
403734984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(" AND substr(lookup.normalized_number,");
403834984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append("lookup.len + 1 - ");
403934984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(numberLen);
404034984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(") = ");
404134984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  DatabaseUtils.appendEscapedSQLString(sb, number);
404234984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                  sb.append(")");
404334984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia                }
4044892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            }
4045892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            sb.append(')');
4046892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        }
404736045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov    }
404836045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov
404936045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov    public String getUseStrictPhoneNumberComparisonParameter() {
405036045476d2cc7c9c2f985307e87cb6bbc4cfe434Dmitri Plotnikov        return mUseStrictPhoneNumberComparison ? "1" : "0";
4051fb362d1a5df250a49fad06db323b0d41fe0e3757Dmitri Plotnikov    }
4052bf659107617a6291ba8bfeebc3f2e50138075ab5Dmitri Plotnikov
4053619871b0fb0175d75ff9336bfe5aec0b27b9bdadJeff Sharkey    /**
4054b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov     * Loads common nickname mappings into the database.
4055b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov     */
4056b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov    private void loadNicknameLookupTable(SQLiteDatabase db) {
405751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.NICKNAME_LOOKUP);
405851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
405928f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar        String[] strings = mContext.getResources().getStringArray(
406028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar                com.android.internal.R.array.common_nicknames);
4061b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        if (strings == null || strings.length == 0) {
4062b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov            return;
4063b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        }
4064b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
4065b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO "
4066b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + ","
4067b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)");
4068b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
406951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        try {
407051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            for (int clusterId = 0; clusterId < strings.length; clusterId++) {
407151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                String[] names = strings[clusterId].split(",");
407251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                for (int j = 0; j < names.length; j++) {
407351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                    String name = NameNormalizer.normalize(names[j]);
407451f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                    try {
407551f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                        DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name);
407651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                        DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2,
407751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                                String.valueOf(clusterId));
407851f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                        nicknameLookupInsert.executeInsert();
407951f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                    } catch (SQLiteException e) {
408051f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov
408151f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                        // Print the exception and keep going - this is not a fatal error
408251f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                        Log.e(TAG, "Cannot insert nickname: " + names[j], e);
408351f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov                    }
4084b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov                }
4085b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov            }
408651f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov        } finally {
408751f41be3b905c63ccffcdc82ec58cf5f7ded2c34Dmitri Plotnikov            nicknameLookupInsert.close();
4088b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov        }
4089b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov    }
4090b597adb79f1f57a24be2be09e3f45fa0f04f6f8fDmitri Plotnikov
4091f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    public static void copyStringValue(ContentValues toValues, String toKey,
4092f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            ContentValues fromValues, String fromKey) {
4093f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        if (fromValues.containsKey(fromKey)) {
4094f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            toValues.put(toKey, fromValues.getAsString(fromKey));
4095f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        }
4096f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    }
4097f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov
4098f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    public static void copyLongValue(ContentValues toValues, String toKey,
4099f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            ContentValues fromValues, String fromKey) {
4100f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        if (fromValues.containsKey(fromKey)) {
4101f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            long longValue;
4102f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            Object value = fromValues.get(fromKey);
4103f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            if (value instanceof Boolean) {
4104f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov                if ((Boolean)value) {
4105f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov                    longValue = 1;
4106f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov                } else {
4107f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov                    longValue = 0;
4108f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov                }
41091b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            } else if (value instanceof String) {
41101b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                longValue = Long.parseLong((String)value);
4111f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            } else {
41121b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                longValue = ((Number)value).longValue();
4113f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            }
4114f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov            toValues.put(toKey, longValue);
4115f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov        }
4116f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov    }
4117f4e1358f1c8f5fe5e9e7689e36e04c57c2385169Dmitri Plotnikov
411835ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana    public SyncStateContentProviderHelper getSyncState() {
411935ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana        return mSyncState;
412035ed95769096bb5dd406ad7d1fcaa49a0e35a307Fred Quintana    }
4121c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov
4122c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov    /**
4123c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov     * Delete the aggregate contact if it has no constituent raw contacts other
4124c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov     * than the supplied one.
4125c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov     */
4126c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov    public void removeContactIfSingleton(long rawContactId) {
4127c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        SQLiteDatabase db = getWritableDatabase();
4128c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov
4129c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        // Obtain contact ID from the supplied raw contact ID
4130c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM "
4131c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")";
4132c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov
4133c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        // Find other raw contacts in the same aggregate contact
4134c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM "
4135c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON ("
4136c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID
4137c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + ""
4138c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")";
4139c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov
4140c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        db.execSQL("DELETE FROM " + Tables.CONTACTS
4141c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId
4142c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov                + " AND NOT EXISTS " + otherRawContacts + ";");
4143c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov    }
41444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
41454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    /**
4146b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov     * Returns the value from the {@link Tables#PROPERTIES} table.
4147b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov     */
4148b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public String getProperty(String key, String defaultValue) {
4149b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        Cursor cursor = getReadableDatabase().query(Tables.PROPERTIES,
4150b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                new String[]{PropertiesColumns.PROPERTY_VALUE},
4151b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                PropertiesColumns.PROPERTY_KEY + "=?",
4152b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                new String[]{key}, null, null, null);
4153b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        String value = null;
4154b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        try {
4155b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov            if (cursor.moveToFirst()) {
4156b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov                value = cursor.getString(0);
4157b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov            }
4158b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        } finally {
4159b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov            cursor.close();
4160b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        }
4161b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
4162b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        return value != null ? value : defaultValue;
4163b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
4164b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
4165b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    /**
4166b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov     * Stores a key-value pair in the {@link Tables#PROPERTIES} table.
4167b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov     */
4168b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void setProperty(String key, String value) {
41693d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        setProperty(getWritableDatabase(), key, value);
41703d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov    }
41713d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov
41723d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov    private void setProperty(SQLiteDatabase db, String key, String value) {
4173b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContentValues values = new ContentValues();
4174b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        values.put(PropertiesColumns.PROPERTY_KEY, key);
4175b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        values.put(PropertiesColumns.PROPERTY_VALUE, value);
41763d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        db.replace(Tables.PROPERTIES, null, values);
4177b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
4178b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
4179b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    /**
4180ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov     * Test if any of the columns appear in the given projection.
4181ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov     */
4182ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public boolean isInProjection(String[] projection, String... columns) {
418382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        if (projection == null) {
418482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            return true;
418582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        }
4186ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov
418782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        // Optimized for a single-column test
418882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        if (columns.length == 1) {
418982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String column = columns[0];
419082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            for (String test : projection) {
419182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                if (column.equals(test)) {
419282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                    return true;
419382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                }
419482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            }
419582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        } else {
419682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            for (String test : projection) {
419782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                for (String column : columns) {
4198ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov                    if (column.equals(test)) {
4199ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov                        return true;
4200ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov                    }
4201ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov                }
4202ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov            }
4203ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        }
4204ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        return false;
42054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
4206fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov
4207fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    /**
4208fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     * Returns a detailed exception message for the supplied URI.  It includes the calling
4209fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     * user and calling package(s).
4210fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     */
4211fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    public String exceptionMessage(Uri uri) {
4212fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        return exceptionMessage(null, uri);
4213fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    }
4214fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov
4215fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    /**
4216fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     * Returns a detailed exception message for the supplied URI.  It includes the calling
4217fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     * user and calling package(s).
4218fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov     */
4219fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    public String exceptionMessage(String message, Uri uri) {
4220fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        StringBuilder sb = new StringBuilder();
4221fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        if (message != null) {
4222fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            sb.append(message).append("; ");
4223fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        }
4224fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        sb.append("URI: ").append(uri);
4225fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        final PackageManager pm = mContext.getPackageManager();
4226fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        int callingUid = Binder.getCallingUid();
4227fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        sb.append(", calling user: ");
4228fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        String userName = pm.getNameForUid(callingUid);
4229fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        if (userName != null) {
4230fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            sb.append(userName);
4231fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        } else {
4232fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            sb.append(callingUid);
4233fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        }
4234fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov
4235fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        final String[] callerPackages = pm.getPackagesForUid(callingUid);
4236fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        if (callerPackages != null && callerPackages.length > 0) {
4237fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            if (callerPackages.length == 1) {
4238fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                sb.append(", calling package:");
4239fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                sb.append(callerPackages[0]);
4240fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            } else {
4241fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                sb.append(", calling package is one of: [");
4242fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                for (int i = 0; i < callerPackages.length; i++) {
4243fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                    if (i != 0) {
4244fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                        sb.append(", ");
4245fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                    }
4246fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                    sb.append(callerPackages[i]);
4247fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                }
4248fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov                sb.append("]");
4249fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov            }
4250fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        }
4251fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov
4252fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov        return sb.toString();
4253fa4a38c9d54f3e3aad4674867bb1250f450c0b95Dmitri Plotnikov    }
4254892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
4255892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    protected String getCountryIso() {
4256892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        CountryDetector detector =
4257892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov            (CountryDetector) mContext.getSystemService(Context.COUNTRY_DETECTOR);
4258892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        return detector.detectCountry().getCountryIso();
4259892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
426078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
426178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void deleteStatusUpdate(long dataId) {
426278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mStatusUpdateDelete == null) {
426378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateDelete = getWritableDatabase().compileStatement(
426478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "DELETE FROM " + Tables.STATUS_UPDATES +
426578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + StatusUpdatesColumns.DATA_ID + "=?");
426678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
426778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateDelete.bindLong(1, dataId);
426878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateDelete.execute();
426978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
427078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
427178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void replaceStatusUpdate(Long dataId, long timestamp, String status, String resPackage,
42720bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann            Integer iconResource, Integer labelResource) {
427378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mStatusUpdateReplace == null) {
427478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateReplace = getWritableDatabase().compileStatement(
427578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "INSERT OR REPLACE INTO " + Tables.STATUS_UPDATES + "("
427678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdatesColumns.DATA_ID + ", "
427778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_TIMESTAMP + ","
427878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS + ","
427978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_RES_PACKAGE + ","
428078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_ICON + ","
428178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_LABEL + ")" +
428278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " VALUES (?,?,?,?,?,?)");
428378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
428478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateReplace.bindLong(1, dataId);
428578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateReplace.bindLong(2, timestamp);
428678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mStatusUpdateReplace, 3, status);
428778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mStatusUpdateReplace, 4, resPackage);
428878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindLong(mStatusUpdateReplace, 5, iconResource);
428978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindLong(mStatusUpdateReplace, 6, labelResource);
429078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mStatusUpdateReplace.execute();
429178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
429278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
42930bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann    public void insertStatusUpdate(Long dataId, String status, String resPackage,
42940bf6b318e3c994294d4a885f57906debd4a0e64eDaniel Lehmann            Integer iconResource, Integer labelResource) {
429578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mStatusUpdateInsert == null) {
429678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateInsert = getWritableDatabase().compileStatement(
429778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "INSERT INTO " + Tables.STATUS_UPDATES + "("
429878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdatesColumns.DATA_ID + ", "
429978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS + ","
430078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_RES_PACKAGE + ","
430178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_ICON + ","
430278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + StatusUpdates.STATUS_LABEL + ")" +
430378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " VALUES (?,?,?,?,?)");
430478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
430578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        try {
430678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateInsert.bindLong(1, dataId);
430778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindString(mStatusUpdateInsert, 2, status);
430878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindString(mStatusUpdateInsert, 3, resPackage);
430978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindLong(mStatusUpdateInsert, 4, iconResource);
431078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindLong(mStatusUpdateInsert, 5, labelResource);
431178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateInsert.executeInsert();
431278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        } catch (SQLiteConstraintException e) {
431378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            // The row already exists - update it
431478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            if (mStatusUpdateAutoTimestamp == null) {
431578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                mStatusUpdateAutoTimestamp = getWritableDatabase().compileStatement(
431678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        "UPDATE " + Tables.STATUS_UPDATES +
431778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        " SET " + StatusUpdates.STATUS_TIMESTAMP + "=?,"
431878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                + StatusUpdates.STATUS + "=?" +
431978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        " WHERE " + StatusUpdatesColumns.DATA_ID + "=?"
432078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                + " AND " + StatusUpdates.STATUS + "!=?");
432178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            }
432278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
432378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            long timestamp = System.currentTimeMillis();
432478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateAutoTimestamp.bindLong(1, timestamp);
432578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindString(mStatusUpdateAutoTimestamp, 2, status);
432678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateAutoTimestamp.bindLong(3, dataId);
432778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindString(mStatusUpdateAutoTimestamp, 4, status);
432878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusUpdateAutoTimestamp.execute();
432978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
433078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            if (mStatusAttributionUpdate == null) {
433178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                mStatusAttributionUpdate = getWritableDatabase().compileStatement(
433278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        "UPDATE " + Tables.STATUS_UPDATES +
433378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        " SET " + StatusUpdates.STATUS_RES_PACKAGE + "=?,"
433478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                + StatusUpdates.STATUS_ICON + "=?,"
433578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                + StatusUpdates.STATUS_LABEL + "=?" +
433678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                        " WHERE " + StatusUpdatesColumns.DATA_ID + "=?");
433778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            }
433878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindString(mStatusAttributionUpdate, 1, resPackage);
433978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindLong(mStatusAttributionUpdate, 2, iconResource);
434078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            bindLong(mStatusAttributionUpdate, 3, labelResource);
434178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusAttributionUpdate.bindLong(4, dataId);
434278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mStatusAttributionUpdate.execute();
434378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
434478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
434578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
434678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /**
434778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Resets the {@link RawContacts#NAME_VERIFIED} flag to 0 on all other raw
434878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * contacts in the same aggregate
434978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
435078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void resetNameVerifiedForOtherRawContacts(long rawContactId) {
435178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mResetNameVerifiedForOtherRawContacts == null) {
435278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mResetNameVerifiedForOtherRawContacts = getWritableDatabase().compileStatement(
435378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "UPDATE " + Tables.RAW_CONTACTS +
435478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " SET " + RawContacts.NAME_VERIFIED + "=0" +
435578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + RawContacts.CONTACT_ID + "=(" +
435678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            "SELECT " + RawContacts.CONTACT_ID +
435778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            " FROM " + Tables.RAW_CONTACTS +
435878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            " WHERE " + RawContacts._ID + "=?)" +
435978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " AND " + RawContacts._ID + "!=?");
436078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
436178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mResetNameVerifiedForOtherRawContacts.bindLong(1, rawContactId);
436278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mResetNameVerifiedForOtherRawContacts.bindLong(2, rawContactId);
436378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mResetNameVerifiedForOtherRawContacts.execute();
436478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
436578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
43668ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    private interface RawContactNameQuery {
43678ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final String RAW_SQL =
43688ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                "SELECT "
43698ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + DataColumns.MIMETYPE_ID + ","
43708ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.IS_PRIMARY + ","
43718ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA1 + ","
43728ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA2 + ","
43738ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA3 + ","
43748ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA4 + ","
43758ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA5 + ","
43768ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA6 + ","
43778ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA7 + ","
43788ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA8 + ","
43798ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA9 + ","
43808ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA10 + ","
43818ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        + Data.DATA11 +
43828ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                " FROM " + Tables.DATA +
43838ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                " WHERE " + Data.RAW_CONTACT_ID + "=?" +
43848ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        " AND (" + Data.DATA1 + " NOT NULL OR " +
43858ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                Organization.TITLE + " NOT NULL)";
43868ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
43878ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int MIMETYPE = 0;
43888ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int IS_PRIMARY = 1;
43898ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int DATA1 = 2;
43908ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int GIVEN_NAME = 3;                         // data2
43918ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int FAMILY_NAME = 4;                        // data3
43928ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int PREFIX = 5;                             // data4
43938ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int TITLE = 5;                              // data4
43948ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int MIDDLE_NAME = 6;                        // data5
43958ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int SUFFIX = 7;                             // data6
43968ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int PHONETIC_GIVEN_NAME = 8;                // data7
43978ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int PHONETIC_MIDDLE_NAME = 9;               // data8
43988ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int ORGANIZATION_PHONETIC_NAME = 9;         // data8
43998ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int PHONETIC_FAMILY_NAME = 10;              // data9
44008ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int FULL_NAME_STYLE = 11;                   // data10
44018ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int ORGANIZATION_PHONETIC_NAME_STYLE = 11;  // data10
44028ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        public static final int PHONETIC_NAME_STYLE = 12;               // data11
44038ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    }
44048ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44058ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    /**
44068ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov     * Updates a raw contact display name based on data rows, e.g. structured name,
44078ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov     * organization, email etc.
44088ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov     */
44098ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov    public void updateRawContactDisplayName(SQLiteDatabase db, long rawContactId) {
44108ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        if (mNameSplitter == null) {
44118ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            createNameSplitter();
44128ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        }
44138ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44148ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        int bestDisplayNameSource = DisplayNameSources.UNDEFINED;
44158ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        NameSplitter.Name bestName = null;
44168ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String bestDisplayName = null;
44178ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String bestPhoneticName = null;
44188ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        int bestPhoneticNameStyle = PhoneticNameStyle.UNDEFINED;
44198ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44208ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        mSelectionArgs1[0] = String.valueOf(rawContactId);
44218ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        Cursor c = db.rawQuery(RawContactNameQuery.RAW_SQL, mSelectionArgs1);
44228ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        try {
44238ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            while (c.moveToNext()) {
44248ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                int mimeType = c.getInt(RawContactNameQuery.MIMETYPE);
44258ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                int source = getDisplayNameSourceForMimeTypeId(mimeType);
44268ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                if (source < bestDisplayNameSource || source == DisplayNameSources.UNDEFINED) {
44278ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    continue;
44288ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                }
44298ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44308ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                if (source == bestDisplayNameSource
44318ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        && c.getInt(RawContactNameQuery.IS_PRIMARY) == 0) {
44328ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    continue;
44338ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                }
44348ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44358ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                if (mimeType == getMimeTypeIdForStructuredName()) {
44368ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    NameSplitter.Name name;
44378ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    if (bestName != null) {
44388ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        name = new NameSplitter.Name();
44398ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    } else {
44408ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        name = mName;
44418ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        name.clear();
44428ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    }
44438ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.prefix = c.getString(RawContactNameQuery.PREFIX);
44448ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.givenNames = c.getString(RawContactNameQuery.GIVEN_NAME);
44458ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.middleName = c.getString(RawContactNameQuery.MIDDLE_NAME);
44468ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.familyName = c.getString(RawContactNameQuery.FAMILY_NAME);
44478ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.suffix = c.getString(RawContactNameQuery.SUFFIX);
44488ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.fullNameStyle = c.isNull(RawContactNameQuery.FULL_NAME_STYLE)
44498ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            ? FullNameStyle.UNDEFINED
44508ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            : c.getInt(RawContactNameQuery.FULL_NAME_STYLE);
44518ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.phoneticFamilyName = c.getString(RawContactNameQuery.PHONETIC_FAMILY_NAME);
44528ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.phoneticMiddleName = c.getString(RawContactNameQuery.PHONETIC_MIDDLE_NAME);
44538ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.phoneticGivenName = c.getString(RawContactNameQuery.PHONETIC_GIVEN_NAME);
44548ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    name.phoneticNameStyle = c.isNull(RawContactNameQuery.PHONETIC_NAME_STYLE)
44558ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            ? PhoneticNameStyle.UNDEFINED
44568ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            : c.getInt(RawContactNameQuery.PHONETIC_NAME_STYLE);
44578ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    if (!name.isEmpty()) {
44588ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestDisplayNameSource = source;
44598ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestName = name;
44608ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    }
44618ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                } else if (mimeType == getMimeTypeIdForOrganization()) {
44628ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    mCharArrayBuffer.sizeCopied = 0;
44638ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    c.copyStringToBuffer(RawContactNameQuery.DATA1, mCharArrayBuffer);
44648ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    if (mCharArrayBuffer.sizeCopied != 0) {
44658ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestDisplayNameSource = source;
44668ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestDisplayName = new String(mCharArrayBuffer.data, 0,
44678ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                mCharArrayBuffer.sizeCopied);
44688ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestPhoneticName = c.getString(
44698ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                RawContactNameQuery.ORGANIZATION_PHONETIC_NAME);
44708ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestPhoneticNameStyle =
44718ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                c.isNull(RawContactNameQuery.ORGANIZATION_PHONETIC_NAME_STYLE)
44728ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                   ? PhoneticNameStyle.UNDEFINED
44738ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                   : c.getInt(RawContactNameQuery.ORGANIZATION_PHONETIC_NAME_STYLE);
44748ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    } else {
44758ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        c.copyStringToBuffer(RawContactNameQuery.TITLE, mCharArrayBuffer);
44768ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        if (mCharArrayBuffer.sizeCopied != 0) {
44778ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            bestDisplayNameSource = source;
44788ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            bestDisplayName = new String(mCharArrayBuffer.data, 0,
44798ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                    mCharArrayBuffer.sizeCopied);
44808ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            bestPhoneticName = null;
44818ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            bestPhoneticNameStyle = PhoneticNameStyle.UNDEFINED;
44828ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        }
44838ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    }
44848ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                } else {
44858ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    // Display name is at DATA1 in all other types.
44868ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    // This is ensured in the constructor.
44878ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
44888ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    mCharArrayBuffer.sizeCopied = 0;
44898ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    c.copyStringToBuffer(RawContactNameQuery.DATA1, mCharArrayBuffer);
44908ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    if (mCharArrayBuffer.sizeCopied != 0) {
44918ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestDisplayNameSource = source;
44928ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestDisplayName = new String(mCharArrayBuffer.data, 0,
44938ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                                mCharArrayBuffer.sizeCopied);
44948ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestPhoneticName = null;
44958ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        bestPhoneticNameStyle = PhoneticNameStyle.UNDEFINED;
44968ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    }
44978ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                }
44988ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            }
44998ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45008ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        } finally {
45018ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            c.close();
45028ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        }
45038ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45048ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String displayNamePrimary;
45058ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String displayNameAlternative;
450655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        String sortNamePrimary;
450755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        String sortNameAlternative;
45088ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String sortKeyPrimary = null;
45098ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        String sortKeyAlternative = null;
45108ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        int displayNameStyle = FullNameStyle.UNDEFINED;
45118ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45128ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        if (bestDisplayNameSource == DisplayNameSources.STRUCTURED_NAME) {
45138ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            displayNameStyle = bestName.fullNameStyle;
45148ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            if (displayNameStyle == FullNameStyle.CJK
45158ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    || displayNameStyle == FullNameStyle.UNDEFINED) {
45168ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                displayNameStyle = mNameSplitter.getAdjustedFullNameStyle(displayNameStyle);
45178ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                bestName.fullNameStyle = displayNameStyle;
45188ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            }
45198ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
452055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            displayNamePrimary = mNameSplitter.join(bestName, true, true);
452155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            displayNameAlternative = mNameSplitter.join(bestName, false, true);
452255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
452355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            if (TextUtils.isEmpty(bestName.prefix)) {
452455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                sortNamePrimary = displayNamePrimary;
452555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                sortNameAlternative = displayNameAlternative;
452655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            } else {
452755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                sortNamePrimary = mNameSplitter.join(bestName, true, false);
452855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                sortNameAlternative = mNameSplitter.join(bestName, false, false);
452955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            }
45308ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45318ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            bestPhoneticName = mNameSplitter.joinPhoneticName(bestName);
45328ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            bestPhoneticNameStyle = bestName.phoneticNameStyle;
45338ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        } else {
45348ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            displayNamePrimary = displayNameAlternative = bestDisplayName;
453555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            sortNamePrimary = sortNameAlternative = bestDisplayName;
45368ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        }
45378ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45388ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        if (bestPhoneticName != null) {
45398ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            sortKeyPrimary = sortKeyAlternative = bestPhoneticName;
45408ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            if (bestPhoneticNameStyle == PhoneticNameStyle.UNDEFINED) {
45418ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                bestPhoneticNameStyle = mNameSplitter.guessPhoneticNameStyle(bestPhoneticName);
45428ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            }
45438ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        } else {
45448ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            if (displayNameStyle == FullNameStyle.UNDEFINED) {
45458ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                displayNameStyle = mNameSplitter.guessFullNameStyle(bestDisplayName);
45468ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                if (displayNameStyle == FullNameStyle.UNDEFINED
45478ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        || displayNameStyle == FullNameStyle.CJK) {
45488ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    displayNameStyle = mNameSplitter.getAdjustedNameStyleBasedOnPhoneticNameStyle(
45498ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                            displayNameStyle, bestPhoneticNameStyle);
45508ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                }
45518ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                displayNameStyle = mNameSplitter.getAdjustedFullNameStyle(displayNameStyle);
45528ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            }
45538ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            if (displayNameStyle == FullNameStyle.CHINESE ||
45548ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                    displayNameStyle == FullNameStyle.CJK) {
45558ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                sortKeyPrimary = sortKeyAlternative =
45568ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov                        ContactLocaleUtils.getIntance().getSortKey(
455755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov                                sortNamePrimary, displayNameStyle);
45588ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov            }
45598ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        }
45608ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
45618ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        if (sortKeyPrimary == null) {
456255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            sortKeyPrimary = sortNamePrimary;
456355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            sortKeyAlternative = sortNameAlternative;
45648ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov        }
45658ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov
456678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mRawContactDisplayNameUpdate == null) {
456755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov            mRawContactDisplayNameUpdate = db.compileStatement(
456878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "UPDATE " + Tables.RAW_CONTACTS +
456978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " SET " +
457078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.DISPLAY_NAME_SOURCE + "=?," +
457178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.DISPLAY_NAME_PRIMARY + "=?," +
457278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.DISPLAY_NAME_ALTERNATIVE + "=?," +
457378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.PHONETIC_NAME + "=?," +
457478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.PHONETIC_NAME_STYLE + "=?," +
457578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.SORT_KEY_PRIMARY + "=?," +
457678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            RawContacts.SORT_KEY_ALTERNATIVE + "=?" +
457778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + RawContacts._ID + "=?");
457878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
457955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov
458055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        mRawContactDisplayNameUpdate.bindLong(1, bestDisplayNameSource);
458178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mRawContactDisplayNameUpdate, 2, displayNamePrimary);
458278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mRawContactDisplayNameUpdate, 3, displayNameAlternative);
458355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        bindString(mRawContactDisplayNameUpdate, 4, bestPhoneticName);
458455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        mRawContactDisplayNameUpdate.bindLong(5, bestPhoneticNameStyle);
458578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mRawContactDisplayNameUpdate, 6, sortKeyPrimary);
458678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mRawContactDisplayNameUpdate, 7, sortKeyAlternative);
458778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mRawContactDisplayNameUpdate.bindLong(8, rawContactId);
458878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mRawContactDisplayNameUpdate.execute();
458978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
459078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
459178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /*
459278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Sets the given dataId record in the "data" table to primary, and resets all data records of
459378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * the same mimetype and under the same contact to not be primary.
459478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     *
459578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * @param dataId the id of the data record to be set to primary. Pass -1 to clear the primary
459678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * flag of all data items of this raw contacts
459778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
459878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void setIsPrimary(long rawContactId, long dataId, long mimeTypeId) {
459978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mSetPrimaryStatement == null) {
460078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mSetPrimaryStatement = getWritableDatabase().compileStatement(
460178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "UPDATE " + Tables.DATA +
460278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " SET " + Data.IS_PRIMARY + "=(_id=?)" +
460378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + DataColumns.MIMETYPE_ID + "=?" +
460478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "   AND " + Data.RAW_CONTACT_ID + "=?");
460578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
460678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetPrimaryStatement.bindLong(1, dataId);
460778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetPrimaryStatement.bindLong(2, mimeTypeId);
460878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetPrimaryStatement.bindLong(3, rawContactId);
460978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetPrimaryStatement.execute();
461078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
461178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
461278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /*
461378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Clears the super primary of all data items of the given raw contact. does not touch
461478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * other raw contacts of the same joined aggregate
461578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
461678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void clearSuperPrimary(long rawContactId, long mimeTypeId) {
461778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mClearSuperPrimaryStatement == null) {
461878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mClearSuperPrimaryStatement = getWritableDatabase().compileStatement(
461978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "UPDATE " + Tables.DATA +
462078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " SET " + Data.IS_SUPER_PRIMARY + "=0" +
462178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + DataColumns.MIMETYPE_ID + "=?" +
462278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "   AND " + Data.RAW_CONTACT_ID + "=?");
462378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
462478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mClearSuperPrimaryStatement.bindLong(1, mimeTypeId);
462578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mClearSuperPrimaryStatement.bindLong(2, rawContactId);
462678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mClearSuperPrimaryStatement.execute();
462778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
462878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
462978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /*
463078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Sets the given dataId record in the "data" table to "super primary", and resets all data
463178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * records of the same mimetype and under the same aggregate to not be "super primary".
463278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     *
463378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * @param dataId the id of the data record to be set to primary.
463478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
463578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void setIsSuperPrimary(long rawContactId, long dataId, long mimeTypeId) {
463678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mSetSuperPrimaryStatement == null) {
463778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mSetSuperPrimaryStatement = getWritableDatabase().compileStatement(
463878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "UPDATE " + Tables.DATA +
463978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " SET " + Data.IS_SUPER_PRIMARY + "=(" + Data._ID + "=?)" +
464078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + DataColumns.MIMETYPE_ID + "=?" +
464178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "   AND " + Data.RAW_CONTACT_ID + " IN (" +
464278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            "SELECT " + RawContacts._ID +
464378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            " FROM " + Tables.RAW_CONTACTS +
464478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            " WHERE " + RawContacts.CONTACT_ID + " =(" +
464578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                    "SELECT " + RawContacts.CONTACT_ID +
464678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                    " FROM " + Tables.RAW_CONTACTS +
464778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                                    " WHERE " + RawContacts._ID + "=?))");
464878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
464978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetSuperPrimaryStatement.bindLong(1, dataId);
465078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetSuperPrimaryStatement.bindLong(2, mimeTypeId);
465178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetSuperPrimaryStatement.bindLong(3, rawContactId);
465278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mSetSuperPrimaryStatement.execute();
465378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
465478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
465578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /**
465678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Inserts a record in the {@link Tables#NAME_LOOKUP} table.
465778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
465878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void insertNameLookup(long rawContactId, long dataId, int lookupType, String name) {
465978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (TextUtils.isEmpty(name)) {
466078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            return;
466178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
466278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
466378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mNameLookupInsert == null) {
466478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mNameLookupInsert = getWritableDatabase().compileStatement(
466578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "INSERT OR IGNORE INTO " + Tables.NAME_LOOKUP + "("
466678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + NameLookupColumns.RAW_CONTACT_ID + ","
466778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + NameLookupColumns.DATA_ID + ","
466878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + NameLookupColumns.NAME_TYPE + ","
466978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                            + NameLookupColumns.NORMALIZED_NAME
467078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    + ") VALUES (?,?,?,?)");
467178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
467278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupInsert.bindLong(1, rawContactId);
467378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupInsert.bindLong(2, dataId);
467478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupInsert.bindLong(3, lookupType);
467578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        bindString(mNameLookupInsert, 4, name);
467678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupInsert.executeInsert();
467778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
467878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov
467978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    /**
468078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     * Deletes all {@link Tables#NAME_LOOKUP} table rows associated with the specified data element.
468178fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov     */
468278fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    public void deleteNameLookup(long dataId) {
468378fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        if (mNameLookupDelete == null) {
468478fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov            mNameLookupDelete = getWritableDatabase().compileStatement(
468578fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    "DELETE FROM " + Tables.NAME_LOOKUP +
468678fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov                    " WHERE " + NameLookupColumns.DATA_ID + "=?");
468778fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        }
468878fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupDelete.bindLong(1, dataId);
468978fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov        mNameLookupDelete.execute();
469078fb53bfd973760996fe3a5fe260b1d367574de6Dmitri Plotnikov    }
4691189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov
4692e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    public String insertNameLookupForEmail(long rawContactId, long dataId, String email) {
4693e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        if (TextUtils.isEmpty(email)) {
4694e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov            return null;
4695e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        }
4696e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
4697e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        String address = extractHandleFromEmailAddress(email);
4698e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        if (address == null) {
4699e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov            return null;
4700e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        }
4701e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
4702e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        insertNameLookup(rawContactId, dataId,
4703e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov                NameLookupType.EMAIL_BASED_NICKNAME, NameNormalizer.normalize(address));
4704e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        return address;
4705e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    }
4706e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
4707e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    /**
4708e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov     * Normalizes the nickname and inserts it in the name lookup table.
4709e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov     */
4710e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    public void insertNameLookupForNickname(long rawContactId, long dataId, String nickname) {
4711e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        if (TextUtils.isEmpty(nickname)) {
4712e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov            return;
4713e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        }
4714e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
4715e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        insertNameLookup(rawContactId, dataId,
4716e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov                NameLookupType.NICKNAME, NameNormalizer.normalize(nickname));
4717e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    }
4718e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
47195df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov    public void insertNameLookupForPhoneticName(long rawContactId, long dataId, String familyName,
47205df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov            String middleName, String givenName) {
47215df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        mSb.setLength(0);
47225df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        if (familyName != null) {
47235df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov            mSb.append(familyName.trim());
47245df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        }
47255df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        if (middleName != null) {
47265df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov            mSb.append(middleName.trim());
47275df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        }
47285df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        if (givenName != null) {
47295df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov            mSb.append(givenName.trim());
47305df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        }
47315df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov
47325df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        if (mSb.length() > 0) {
47335df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov            insertNameLookup(rawContactId, dataId, NameLookupType.NAME_COLLATION_KEY,
47345df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov                    NameNormalizer.normalize(mSb.toString()));
47355df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov        }
47365df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov    }
47375df7e46835c4f103b05407660b4769edd515760fDmitri Plotnikov
4738189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov    /**
4739189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov     * Performs a query and returns true if any Data item of the raw contact with the given
4740189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov     * id and mimetype is marked as super-primary
4741189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov     */
4742189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov    public boolean rawContactHasSuperPrimary(long rawContactId, long mimeTypeId) {
4743189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov        final Cursor existsCursor = getReadableDatabase().rawQuery(
4744189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov                "SELECT EXISTS(SELECT 1 FROM " + Tables.DATA +
4745189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov                " WHERE " + Data.RAW_CONTACT_ID + "=?" +
4746189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov                " AND " + DataColumns.MIMETYPE_ID + "=?" +
4747189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov                " AND " + Data.IS_SUPER_PRIMARY + "<>0)",
4748189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov                new String[] { String.valueOf(rawContactId), String.valueOf(mimeTypeId) });
4749189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov        try {
4750189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov            if (!existsCursor.moveToFirst()) throw new IllegalStateException();
4751189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov            return existsCursor.getInt(0) != 0;
4752189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov        } finally {
4753189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov            existsCursor.close();
4754189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov        }
4755189273b8a9ae75d88690febfbed2d635138799ecDmitri Plotnikov    }
4756e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov
4757e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    public String getCurrentCountryIso() {
4758e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov        return mCountryMonitor.getCountryIso();
4759e8b3427e88d28a00cdcad7d296544f2459dfc629Dmitri Plotnikov    }
4760f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
4761383d8aa53aa2f74a4b71642de7df2e4b9f2242c8Dmitri Plotnikov    /* package */ String querySearchIndexContentForTest(long contactId) {
4762f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        return DatabaseUtils.stringForQuery(getReadableDatabase(),
4763f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                "SELECT " + SearchIndexColumns.CONTENT +
4764f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                " FROM " + Tables.SEARCH_INDEX +
4765f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                " WHERE " + SearchIndexColumns.CONTACT_ID + "=CAST(? AS int)",
4766f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                new String[] { String.valueOf(contactId) });
4767f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    }
4768f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov
4769383d8aa53aa2f74a4b71642de7df2e4b9f2242c8Dmitri Plotnikov    /* package */ String querySearchIndexTokensForTest(long contactId) {
4770f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov        return DatabaseUtils.stringForQuery(getReadableDatabase(),
4771f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                "SELECT " + SearchIndexColumns.TOKENS +
4772f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                " FROM " + Tables.SEARCH_INDEX +
4773f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                " WHERE " + SearchIndexColumns.CONTACT_ID + "=CAST(? AS int)",
4774f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov                new String[] { String.valueOf(contactId) });
4775f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov    }
4776b650982af7aeb2800efdcea587b8ce153259cf1cJeff Sharkey}
4777