19f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff/* 29f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Copyright (C) 2009 The Android Open Source Project 39f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * 49f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Licensed under the Apache License, Version 2.0 (the "License"); 59f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * you may not use this file except in compliance with the License. 69f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * You may obtain a copy of the License at 79f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * 89f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * http://www.apache.org/licenses/LICENSE-2.0 99f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * 109f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Unless required by applicable law or agreed to in writing, software 119f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * distributed under the License is distributed on an "AS IS" BASIS, 129f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * See the License for the specific language governing permissions and 149f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * limitations under the License 159f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff */ 169f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 179f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffpackage com.android.providers.calendar; 189f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 199f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.accounts.Account; 209f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.content.ContentResolver; 219f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.content.ContentValues; 229f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.content.Context; 239f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.database.Cursor; 249f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.database.DatabaseUtils; 259f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.database.sqlite.SQLiteDatabase; 26a6357118c223d00ed722ecd40ecdda92d705d211Erikimport android.database.sqlite.SQLiteException; 279f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.database.sqlite.SQLiteOpenHelper; 289f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.os.Bundle; 29b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract; 30b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract.Attendees; 312f251c778c06d21ed7693a70f4a1268ff929242eRoboErikimport android.provider.CalendarContract.Calendars; 322f251c778c06d21ed7693a70f4a1268ff929242eRoboErikimport android.provider.CalendarContract.Colors; 33b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract.Events; 34b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErikimport android.provider.CalendarContract.Reminders; 35d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriffimport android.provider.SyncStateContract; 367b40dde3168f4af2c757cb43955aa3bfe1668666Erikimport android.text.TextUtils; 37ae4f20e120d3107cef20be860a612c9c23816295Erikimport android.text.format.Time; 389f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriffimport android.util.Log; 39470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albertimport com.android.common.content.SyncStateContentProviderHelper; 40470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albertimport com.google.common.annotations.VisibleForTesting; 419f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 42d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriffimport java.io.UnsupportedEncodingException; 43162c7c9bbd53b623fbe913b376e7f7f42915bb59Marc Blankimport java.net.URLDecoder; 44315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglioimport java.util.TimeZone; 45d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff 469f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff/** 479f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Database helper for calendar. Designed as a singleton to make sure that all 489f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * {@link android.content.ContentProvider} users get the same reference. 499f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff */ 509f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff/* package */ class CalendarDatabaseHelper extends SQLiteOpenHelper { 5181d904d66bd746c077cc0baa6cf1f51fe030eac4Mason Tang 529f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private static final String TAG = "CalendarDatabaseHelper"; 539f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 5481d904d66bd746c077cc0baa6cf1f51fe030eac4Mason Tang private static final boolean LOGD = false; 5581d904d66bd746c077cc0baa6cf1f51fe030eac4Mason Tang 56ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private static final String DATABASE_NAME = "calendar.db"; 579f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 587b40dde3168f4af2c757cb43955aa3bfe1668666Erik private static final int DAY_IN_SECONDS = 24 * 60 * 60; 597b40dde3168f4af2c757cb43955aa3bfe1668666Erik 609f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff // Note: if you update the version number, you must also update the code 619f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff // in upgradeDatabase() to modify the database (gracefully, if possible). 62c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // Versions under 100 cover through Froyo, 1xx version are for Gingerbread, 63c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // 2xx for Honeycomb, and 3xx for ICS. For future versions bump this to the 64c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // next hundred at each major release. 652f251c778c06d21ed7693a70f4a1268ff929242eRoboErik static final int DATABASE_VERSION = 308; 669f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 67d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff private static final int PRE_FROYO_SYNC_STATE_VERSION = 3; 68d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff 699ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // columns used to duplicate an event row 7002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik private static final String LAST_SYNCED_EVENT_COLUMNS = 7102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events._SYNC_ID + "," + 7202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.CALENDAR_ID + "," + 7302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.TITLE + "," + 7402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EVENT_LOCATION + "," + 7502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.DESCRIPTION + "," + 7602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EVENT_COLOR + "," + 77387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik Events.EVENT_COLOR_KEY + "," + 7802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.STATUS + "," + 7902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.SELF_ATTENDEE_STATUS + "," + 8002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.DTSTART + "," + 8102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.DTEND + "," + 8202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EVENT_TIMEZONE + "," + 8302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EVENT_END_TIMEZONE + "," + 8402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.DURATION + "," + 8502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ALL_DAY + "," + 8602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ACCESS_LEVEL + "," + 8702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.AVAILABILITY + "," + 8802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.HAS_ALARM + "," + 8902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.HAS_EXTENDED_PROPERTIES + "," + 9002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.RRULE + "," + 9102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.RDATE + "," + 9202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EXRULE + "," + 9302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.EXDATE + "," + 9402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ORIGINAL_SYNC_ID + "," + 9502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ORIGINAL_ID + "," + 9602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ORIGINAL_INSTANCE_TIME + "," + 9702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ORIGINAL_ALL_DAY + "," + 9802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.LAST_DATE + "," + 9902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.HAS_ATTENDEE_DATA + "," + 10002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.GUESTS_CAN_MODIFY + "," + 10102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.GUESTS_CAN_INVITE_OTHERS + "," + 10202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.GUESTS_CAN_SEE_GUESTS + "," + 10302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik Events.ORGANIZER; 1049ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 1059ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // columns used to duplicate a reminder row 10602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik private static final String LAST_SYNCED_REMINDER_COLUMNS = 107470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Reminders.MINUTES + "," + 108470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Reminders.METHOD; 1099ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 1109ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // columns used to duplicate an attendee row 11102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik private static final String LAST_SYNCED_ATTENDEE_COLUMNS = 112470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Attendees.ATTENDEE_NAME + "," + 113470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Attendees.ATTENDEE_EMAIL + "," + 114470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Attendees.ATTENDEE_STATUS + "," + 115470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Attendees.ATTENDEE_RELATIONSHIP + "," + 116470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert Attendees.ATTENDEE_TYPE; 1179ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 1189ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // columns used to duplicate an extended property row 11902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik private static final String LAST_SYNCED_EXTENDED_PROPERTY_COLUMNS = 120b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.NAME + "," + 121b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.VALUE; 1229ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 1237cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public interface Tables { 1247cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String CALENDARS = "Calendars"; 1257cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String EVENTS = "Events"; 1267cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String EVENTS_RAW_TIMES = "EventsRawTimes"; 1277cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String INSTANCES = "Instances"; 1287cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String ATTENDEES = "Attendees"; 1297cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String REMINDERS = "Reminders"; 1307cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String CALENDAR_ALERTS = "CalendarAlerts"; 1317cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String EXTENDED_PROPERTIES = "ExtendedProperties"; 1327cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String CALENDAR_META_DATA = "CalendarMetaData"; 1337cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String CALENDAR_CACHE = "CalendarCache"; 1347cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String SYNC_STATE = "_sync_state"; 1357cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String SYNC_STATE_META = "_sync_state_metadata"; 1362f251c778c06d21ed7693a70f4a1268ff929242eRoboErik public static final String COLORS = "Colors"; 1377cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio } 1387cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 1397cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public interface Views { 140bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden public static final String EVENTS = "view_events"; 1417cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio } 1427cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 143d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff // Copied from SyncStateContentProviderHelper. Don't really want to make them public there. 144d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff private static final String SYNC_STATE_META_VERSION_COLUMN = "version"; 145d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff 1467cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio // This needs to be done when all the tables are already created 1477cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio private static final String EVENTS_CLEANUP_TRIGGER_SQL = 1487cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.INSTANCES + 149b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE "+ CalendarContract.Instances.EVENT_ID + "=" + 150b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";" + 1517cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.EVENTS_RAW_TIMES + 152b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.EventsRawTimes.EVENT_ID + "=" + 153b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";" + 1547cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.ATTENDEES + 155b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.Attendees.EVENT_ID + "=" + 156b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";" + 1577cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.REMINDERS + 158b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.Reminders.EVENT_ID + "=" + 159b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";" + 1607cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.CALENDAR_ALERTS + 161b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.CalendarAlerts.EVENT_ID + "=" + 162b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";" + 1637cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "DELETE FROM " + Tables.EXTENDED_PROPERTIES + 164b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.ExtendedProperties.EVENT_ID + "=" + 165b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";"; 1667cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 16734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // This ensures any exceptions based on an event get their original_sync_id 16834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // column set when an the _sync_id is set. 16934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik private static final String EVENTS_ORIGINAL_SYNC_TRIGGER_SQL = 17034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik "UPDATE " + Tables.EVENTS + 17134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik " SET " + Events.ORIGINAL_SYNC_ID + "=new." + Events._SYNC_ID + 17234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik " WHERE " + Events.ORIGINAL_ID + "=old." + Events._ID + ";"; 17334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 17434c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik private static final String SYNC_ID_UPDATE_TRIGGER_NAME = "original_sync_update"; 17534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik private static final String CREATE_SYNC_ID_UPDATE_TRIGGER = 17634c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik "CREATE TRIGGER " + SYNC_ID_UPDATE_TRIGGER_NAME + " UPDATE OF " + Events._SYNC_ID + 17734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik " ON " + Tables.EVENTS + 17834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik " BEGIN " + 17934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik EVENTS_ORIGINAL_SYNC_TRIGGER_SQL + 18034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik " END"; 18134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 1827cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio private static final String CALENDAR_CLEANUP_TRIGGER_SQL = "DELETE FROM " + Tables.EVENTS + 183b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " WHERE " + CalendarContract.Events.CALENDAR_ID + "=" + 184b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "old." + CalendarContract.Events._ID + ";"; 1857cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 1862f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String CALENDAR_UPDATE_COLOR_TRIGGER_SQL = "UPDATE " + Tables.CALENDARS 1872f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + " SET calendar_color=(SELECT " + Colors.COLOR + " FROM " + Tables.COLORS + " WHERE " 1882f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + Colors.ACCOUNT_NAME + "=" + "new." + Calendars.ACCOUNT_NAME + " AND " 1892f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + Colors.ACCOUNT_TYPE + "=" + "new." + Calendars.ACCOUNT_TYPE + " AND " 190387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + Colors.COLOR_KEY + "=" + "new." + Calendars.CALENDAR_COLOR_KEY + ") " 1912f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + " WHERE " + Calendars._ID + "=" + "old." + Calendars._ID 1922f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + ";"; 1932f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String CALENDAR_COLOR_UPDATE_TRIGGER_NAME = "calendar_color_update"; 1942f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String CREATE_CALENDAR_COLOR_UPDATE_TRIGGER = "CREATE TRIGGER " 195387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + CALENDAR_COLOR_UPDATE_TRIGGER_NAME + " UPDATE OF " + Calendars.CALENDAR_COLOR_KEY 196387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + " ON " + Tables.CALENDARS + " WHEN new." + Calendars.CALENDAR_COLOR_KEY 1972f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + " NOT NULL BEGIN " + CALENDAR_UPDATE_COLOR_TRIGGER_SQL + " END"; 1982f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 1992f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String EVENT_UPDATE_COLOR_TRIGGER_SQL = "UPDATE " + Tables.EVENTS 2002f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + " SET eventColor=(SELECT " + Colors.COLOR + " FROM " + Tables.COLORS + " WHERE " 2012f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + Colors.ACCOUNT_NAME + "=" + "(SELECT " + Calendars.ACCOUNT_NAME + " FROM " 2022f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + Tables.CALENDARS + " WHERE " + Calendars._ID + "=new." + Events.CALENDAR_ID 2032f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + ") AND " + Colors.ACCOUNT_TYPE + "=" + "(SELECT " + Calendars.ACCOUNT_TYPE + " FROM " 2042f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + Tables.CALENDARS + " WHERE " + Calendars._ID + "=new." + Events.CALENDAR_ID 205387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + ") AND " + Colors.COLOR_KEY + "=" + "new." + Events.EVENT_COLOR_KEY + ") " 2062f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + " WHERE " + Events._ID + "=" + "old." + Events._ID + ";"; 2072f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String EVENT_COLOR_UPDATE_TRIGGER_NAME = "event_color_update"; 2082f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private static final String CREATE_EVENT_COLOR_UPDATE_TRIGGER = "CREATE TRIGGER " 209387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + EVENT_COLOR_UPDATE_TRIGGER_NAME + " UPDATE OF " + Events.EVENT_COLOR_KEY + " ON " 210387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + Tables.EVENTS + " WHEN new." + Events.EVENT_COLOR_KEY + " NOT NULL BEGIN " 2112f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + EVENT_UPDATE_COLOR_TRIGGER_SQL + " END"; 2122f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 213935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden /** Selects rows from Attendees for which the event_id refers to a nonexistent Event */ 214935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden private static final String WHERE_ATTENDEES_ORPHANS = 215935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Attendees.EVENT_ID + " IN (SELECT " + Attendees.EVENT_ID + " FROM " + 216935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Tables.ATTENDEES + " LEFT OUTER JOIN " + Tables.EVENTS + " ON " + 217935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Attendees.EVENT_ID + "=" + Tables.EVENTS + "." + Events._ID + 218935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden " WHERE " + Tables.EVENTS + "." + Events._ID + " IS NULL)"; 219935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden /** Selects rows from Reminders for which the event_id refers to a nonexistent Event */ 220935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden private static final String WHERE_REMINDERS_ORPHANS = 221935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Reminders.EVENT_ID + " IN (SELECT " + Reminders.EVENT_ID + " FROM " + 222935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Tables.REMINDERS + " LEFT OUTER JOIN " + Tables.EVENTS + " ON " + 223935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Reminders.EVENT_ID + "=" + Tables.EVENTS + "." + Events._ID + 224935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden " WHERE " + Tables.EVENTS + "." + Events._ID + " IS NULL)"; 225935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 2261b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static final String SCHEMA_HTTPS = "https://"; 2271b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static final String SCHEMA_HTTP = "http://"; 2281b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 2299f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private final SyncStateContentProviderHelper mSyncState; 2309f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2319f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private static CalendarDatabaseHelper sSingleton = null; 2329f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2339f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mCalendarsInserter; 2342f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private DatabaseUtils.InsertHelper mColorsInserter; 2359f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mEventsInserter; 2369f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mEventsRawTimesInserter; 2379f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mInstancesInserter; 2389f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mAttendeesInserter; 2399f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mRemindersInserter; 2409f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mCalendarAlertsInserter; 2419f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private DatabaseUtils.InsertHelper mExtendedPropertiesInserter; 2429f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2439f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long calendarsInsert(ContentValues values) { 2449f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mCalendarsInserter.insert(values); 2459f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2469f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2472f251c778c06d21ed7693a70f4a1268ff929242eRoboErik public long colorsInsert(ContentValues values) { 2482f251c778c06d21ed7693a70f4a1268ff929242eRoboErik return mColorsInserter.insert(values); 2492f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 2502f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 2519f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long eventsInsert(ContentValues values) { 2529f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mEventsInserter.insert(values); 2539f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2549f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2559f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long eventsRawTimesInsert(ContentValues values) { 2569f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mEventsRawTimesInserter.insert(values); 2579f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2589f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2599f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long eventsRawTimesReplace(ContentValues values) { 2609f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mEventsRawTimesInserter.replace(values); 2619f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2629f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2639f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long instancesInsert(ContentValues values) { 2649f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mInstancesInserter.insert(values); 2659f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2669f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 267c874ed5c6cc0fcc6ac06ae7d20db0eab7d749608Ken Shirriff public long instancesReplace(ContentValues values) { 268c874ed5c6cc0fcc6ac06ae7d20db0eab7d749608Ken Shirriff return mInstancesInserter.replace(values); 269c874ed5c6cc0fcc6ac06ae7d20db0eab7d749608Ken Shirriff } 270c874ed5c6cc0fcc6ac06ae7d20db0eab7d749608Ken Shirriff 2719f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long attendeesInsert(ContentValues values) { 2729f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mAttendeesInserter.insert(values); 2739f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2749f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2759f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long remindersInsert(ContentValues values) { 2769f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mRemindersInserter.insert(values); 2779f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2789f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2799f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long calendarAlertsInsert(ContentValues values) { 2809f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mCalendarAlertsInserter.insert(values); 2819f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2829f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2839f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public long extendedPropertiesInsert(ContentValues values) { 2849f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mExtendedPropertiesInserter.insert(values); 2859f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2869f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2879f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public static synchronized CalendarDatabaseHelper getInstance(Context context) { 2889f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff if (sSingleton == null) { 2899f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff sSingleton = new CalendarDatabaseHelper(context); 2909f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2919f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return sSingleton; 2929f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2939f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2949f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff /** 2959f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Private constructor, callers except unit tests should obtain an instance through 2969f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * {@link #getInstance(android.content.Context)} instead. 2979f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff */ 2987e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff /* package */ CalendarDatabaseHelper(Context context) { 2999f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff super(context, DATABASE_NAME, null, DATABASE_VERSION); 30081d904d66bd746c077cc0baa6cf1f51fe030eac4Mason Tang if (LOGD) Log.d(TAG, "Creating OpenHelper"); 3019f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3029f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff mSyncState = new SyncStateContentProviderHelper(); 3039f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 3049f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3059f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff @Override 3069f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public void onOpen(SQLiteDatabase db) { 3079f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff mSyncState.onDatabaseOpened(db); 3089f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3097cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mCalendarsInserter = new DatabaseUtils.InsertHelper(db, Tables.CALENDARS); 3102f251c778c06d21ed7693a70f4a1268ff929242eRoboErik mColorsInserter = new DatabaseUtils.InsertHelper(db, Tables.COLORS); 3117cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mEventsInserter = new DatabaseUtils.InsertHelper(db, Tables.EVENTS); 3127cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mEventsRawTimesInserter = new DatabaseUtils.InsertHelper(db, Tables.EVENTS_RAW_TIMES); 3137cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mInstancesInserter = new DatabaseUtils.InsertHelper(db, Tables.INSTANCES); 3147cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mAttendeesInserter = new DatabaseUtils.InsertHelper(db, Tables.ATTENDEES); 3157cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mRemindersInserter = new DatabaseUtils.InsertHelper(db, Tables.REMINDERS); 3167cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio mCalendarAlertsInserter = new DatabaseUtils.InsertHelper(db, Tables.CALENDAR_ALERTS); 3179f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff mExtendedPropertiesInserter = 3187cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio new DatabaseUtils.InsertHelper(db, Tables.EXTENDED_PROPERTIES); 3199f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 3209f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 321d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff /* 322d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * Upgrade sync state table if necessary. Note that the data bundle 323d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * in the table is not upgraded. 324d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * 325d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * The sync state used to be stored with version 3, but now uses the 326d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * same sync state code as contacts, which is version 1. This code 327d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * upgrades from 3 to 1 if necessary. (Yes, the numbers are unfortunately 328d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * backwards.) 329d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * 330d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * This code is only called when upgrading from an old calendar version, 331d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * so there is no problem if sync state version 3 gets used again in the 332d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff * future. 333d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff */ 334d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff private void upgradeSyncState(SQLiteDatabase db) { 335d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff long version = DatabaseUtils.longForQuery(db, 336d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff "SELECT " + SYNC_STATE_META_VERSION_COLUMN 3377cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio + " FROM " + Tables.SYNC_STATE_META, 338d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff null); 339d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff if (version == PRE_FROYO_SYNC_STATE_VERSION) { 340d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff Log.i(TAG, "Upgrading calendar sync state table"); 341d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff db.execSQL("CREATE TEMPORARY TABLE state_backup(_sync_account TEXT, " 342d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + "_sync_account_type TEXT, data TEXT);"); 343d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff db.execSQL("INSERT INTO state_backup SELECT _sync_account, _sync_account_type, data" 344d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + " FROM " 3457cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio + Tables.SYNC_STATE 346d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + " WHERE _sync_account is not NULL and _sync_account_type is not NULL;"); 3477cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE " + Tables.SYNC_STATE + ";"); 348d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff mSyncState.onDatabaseOpened(db); 3497cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("INSERT INTO " + Tables.SYNC_STATE + "(" 350d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + SyncStateContract.Columns.ACCOUNT_NAME + "," 351d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + SyncStateContract.Columns.ACCOUNT_TYPE + "," 352d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + SyncStateContract.Columns.DATA 353d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff + ") SELECT _sync_account, _sync_account_type, data from state_backup;"); 354d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff db.execSQL("DROP TABLE state_backup;"); 355d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff } else { 356d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff // Wrong version to upgrade. 357d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff // Don't need to do anything more here because mSyncState.onDatabaseOpened() will blow 358d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff // away and recreate the database (which will result in a resync). 359d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff Log.w(TAG, "upgradeSyncState: current version is " + version + ", skipping upgrade."); 360d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff } 361d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff } 362d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff 3639f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff @Override 3649f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public void onCreate(SQLiteDatabase db) { 365a6357118c223d00ed722ecd40ecdda92d705d211Erik bootstrapDB(db); 366a6357118c223d00ed722ecd40ecdda92d705d211Erik } 367a6357118c223d00ed722ecd40ecdda92d705d211Erik 368a6357118c223d00ed722ecd40ecdda92d705d211Erik private void bootstrapDB(SQLiteDatabase db) { 3699f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff Log.i(TAG, "Bootstrapping database"); 3709f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3719f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff mSyncState.createDatabase(db); 3729f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3732f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createColorsTable(db); 3742f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 3751b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio createCalendarsTable(db); 3769f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 377c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik createEventsTable(db); 3789f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3797cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.EVENTS_RAW_TIMES + " (" + 380b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes._ID + " INTEGER PRIMARY KEY," + 381b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes.EVENT_ID + " INTEGER NOT NULL," + 382b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes.DTSTART_2445 + " TEXT," + 383b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes.DTEND_2445 + " TEXT," + 384b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes.ORIGINAL_INSTANCE_TIME_2445 + " TEXT," + 385b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.EventsRawTimes.LAST_DATE_2445 + " TEXT," + 386b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik "UNIQUE (" + CalendarContract.EventsRawTimes.EVENT_ID + ")" + 3879f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 3889f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 3897cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.INSTANCES + " (" + 390b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances._ID + " INTEGER PRIMARY KEY," + 391b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.EVENT_ID + " INTEGER," + 392b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.BEGIN + " INTEGER," + // UTC millis 393b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.END + " INTEGER," + // UTC millis 394b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.START_DAY + " INTEGER," + // Julian start day 395b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.END_DAY + " INTEGER," + // Julian end day 396b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.START_MINUTE + " INTEGER," + // minutes from midnight 397b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.END_MINUTE + " INTEGER," + // minutes from midnight 3987cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "UNIQUE (" + 399b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.EVENT_ID + ", " + 400b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.BEGIN + ", " + 401b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.END + ")" + 4029f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4039f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4047cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE INDEX instancesStartDayIndex ON " + Tables.INSTANCES + " (" + 405b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Instances.START_DAY + 4069f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4079f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4081599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio createCalendarMetaDataTable(db); 4099f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 410315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio createCalendarCacheTable(db, null); 411ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 4127cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.ATTENDEES + " (" + 413b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees._ID + " INTEGER PRIMARY KEY," + 414b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.EVENT_ID + " INTEGER," + 415b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.ATTENDEE_NAME + " TEXT," + 416b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.ATTENDEE_EMAIL + " TEXT," + 417b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.ATTENDEE_STATUS + " INTEGER," + 418b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.ATTENDEE_RELATIONSHIP + " INTEGER," + 419b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.ATTENDEE_TYPE + " INTEGER" + 4209f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4219f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4227cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE INDEX attendeesEventIdIndex ON " + Tables.ATTENDEES + " (" + 423b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Attendees.EVENT_ID + 4249f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4259f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4267cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.REMINDERS + " (" + 427b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Reminders._ID + " INTEGER PRIMARY KEY," + 428b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Reminders.EVENT_ID + " INTEGER," + 429b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Reminders.MINUTES + " INTEGER," + 430b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Reminders.METHOD + " INTEGER NOT NULL" + 431b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik " DEFAULT " + CalendarContract.Reminders.METHOD_DEFAULT + 4329f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4339f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4347cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE INDEX remindersEventIdIndex ON " + Tables.REMINDERS + " (" + 435b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Reminders.EVENT_ID + 4369f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4379f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4387e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff // This table stores the Calendar notifications that have gone off. 4397cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.CALENDAR_ALERTS + " (" + 440b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts._ID + " INTEGER PRIMARY KEY," + 441b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.EVENT_ID + " INTEGER," + 442b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.BEGIN + " INTEGER NOT NULL," + // UTC millis 443b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.END + " INTEGER NOT NULL," + // UTC millis 444b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.ALARM_TIME + " INTEGER NOT NULL," + // UTC millis 445d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik // UTC millis 446b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.CREATION_TIME + " INTEGER NOT NULL DEFAULT 0," + 447d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik // UTC millis 448b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.RECEIVED_TIME + " INTEGER NOT NULL DEFAULT 0," + 449d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik // UTC millis 450b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.NOTIFY_TIME + " INTEGER NOT NULL DEFAULT 0," + 451b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.STATE + " INTEGER NOT NULL," + 452b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.MINUTES + " INTEGER," + 4537cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "UNIQUE (" + 454b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.ALARM_TIME + ", " + 455b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.BEGIN + ", " + 456b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.EVENT_ID + ")" + 4579f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4589f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4597cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE INDEX calendarAlertsEventIdIndex ON " + Tables.CALENDAR_ALERTS + " (" + 460b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarAlerts.EVENT_ID + 4619f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4629f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4637cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.EXTENDED_PROPERTIES + " (" + 464b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties._ID + " INTEGER PRIMARY KEY," + 465b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.EVENT_ID + " INTEGER," + 466b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.NAME + " TEXT," + 467b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.VALUE + " TEXT" + 4689f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4699f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4707cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE INDEX extendedPropertiesEventIdIndex ON " + Tables.EXTENDED_PROPERTIES 4717cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio + " (" + 472b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.ExtendedProperties.EVENT_ID + 4739f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff ");"); 4749f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4757cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio createEventsView(db); 4767cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 4779f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff // Trigger to remove data tied to an event when we delete that event. 4787cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON " + Tables.EVENTS + " " + 4799f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff "BEGIN " + 4807cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio EVENTS_CLEANUP_TRIGGER_SQL + 4819f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff "END"); 4829f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 4832f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // Triggers to update the color stored in an event or a calendar when 4842f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // the color_index is changed. 4852f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createColorsTriggers(db); 4862f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 48734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // Trigger to update exceptions when an original event updates its 48834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // _sync_id 48934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL(CREATE_SYNC_ID_UPDATE_TRIGGER); 49034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 491470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert scheduleSync(null /* all accounts */, false, null); 4929f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 4939f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 494c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik private void createEventsTable(SQLiteDatabase db) { 495bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden // IMPORTANT: when adding new columns, be sure to update ALLOWED_IN_EXCEPTION and 496bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden // DONT_CLONE_INTO_EXCEPTION in CalendarProvider2. 497bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden // 498c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // TODO: do we need both dtend and duration? 49902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // **When updating this be sure to also update LAST_SYNCED_EVENT_COLUMNS 500c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("CREATE TABLE " + Tables.EVENTS + " (" + 501935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden CalendarContract.Events._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + 502b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events._SYNC_ID + " TEXT," + 503b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DIRTY + " INTEGER," + 504b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.LAST_SYNCED + " INTEGER DEFAULT 0," + 505b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.CALENDAR_ID + " INTEGER NOT NULL," + 506b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.TITLE + " TEXT," + 507b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EVENT_LOCATION + " TEXT," + 508b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DESCRIPTION + " TEXT," + 509b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EVENT_COLOR + " INTEGER," + 510387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik CalendarContract.Events.EVENT_COLOR_KEY + " TEXT," + 511b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.STATUS + " INTEGER," + 512b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SELF_ATTENDEE_STATUS + " INTEGER NOT NULL DEFAULT 0," + 513c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // dtstart in millis since epoch 514b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DTSTART + " INTEGER," + 515c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // dtend in millis since epoch 516b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DTEND + " INTEGER," + 517c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // timezone for event 518b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EVENT_TIMEZONE + " TEXT," + 519b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DURATION + " TEXT," + 520b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ALL_DAY + " INTEGER NOT NULL DEFAULT 0," + 521b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ACCESS_LEVEL + " INTEGER NOT NULL DEFAULT 0," + 522b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.AVAILABILITY + " INTEGER NOT NULL DEFAULT 0," + 523b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.HAS_ALARM + " INTEGER NOT NULL DEFAULT 0," + 524b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.HAS_EXTENDED_PROPERTIES + " INTEGER NOT NULL DEFAULT 0," + 525b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.RRULE + " TEXT," + 526b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.RDATE + " TEXT," + 527b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EXRULE + " TEXT," + 528b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EXDATE + " TEXT," + 529b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ORIGINAL_ID + " INTEGER," + 53034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // ORIGINAL_SYNC_ID is the _sync_id of recurring event 531b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ORIGINAL_SYNC_ID + " TEXT," + 53234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // originalInstanceTime is in millis since epoch 533b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ORIGINAL_INSTANCE_TIME + " INTEGER," + 534b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ORIGINAL_ALL_DAY + " INTEGER," + 53534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // lastDate is in millis since epoch 536b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.LAST_DATE + " INTEGER," + 537b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.HAS_ATTENDEE_DATA + " INTEGER NOT NULL DEFAULT 0," + 538b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.GUESTS_CAN_MODIFY + " INTEGER NOT NULL DEFAULT 0," + 539b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.GUESTS_CAN_INVITE_OTHERS + " INTEGER NOT NULL DEFAULT 1," + 540b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.GUESTS_CAN_SEE_GUESTS + " INTEGER NOT NULL DEFAULT 1," + 541b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.ORGANIZER + " STRING," + 542b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.DELETED + " INTEGER NOT NULL DEFAULT 0," + 54334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // timezone for event with allDay events are in local timezone 544b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.EVENT_END_TIMEZONE + " TEXT," + 54502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // SYNC_DATAX columns are available for use by sync adapters 546b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA1 + " TEXT," + 547b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA2 + " TEXT," + 548b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA3 + " TEXT," + 549b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA4 + " TEXT," + 550b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA5 + " TEXT," + 551b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA6 + " TEXT," + 552b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA7 + " TEXT," + 553b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA8 + " TEXT," + 554b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA9 + " TEXT," + 555b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Events.SYNC_DATA10 + " TEXT" + ");"); 55602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 55702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // **When updating this be sure to also update LAST_SYNCED_EVENT_COLUMNS 55834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 55934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL("CREATE INDEX eventsCalendarIdIndex ON " + Tables.EVENTS + " (" 560b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.CALENDAR_ID + ");"); 56134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik } 56234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 5632f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private void createEventsTable307(SQLiteDatabase db) { 5642f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("CREATE TABLE Events (" 5652f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "_id INTEGER PRIMARY KEY AUTOINCREMENT," 5662f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "_sync_id TEXT," 5672f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "dirty INTEGER," 5682f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "lastSynced INTEGER DEFAULT 0," 5692f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "calendar_id INTEGER NOT NULL," 5702f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "title TEXT," 5712f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "eventLocation TEXT," 5722f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "description TEXT," 5732f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "eventColor INTEGER," 5742f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "eventStatus INTEGER," 5752f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "selfAttendeeStatus INTEGER NOT NULL DEFAULT 0," 5762f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // dtstart in millis since epoch 5772f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "dtstart INTEGER," 5782f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // dtend in millis since epoch 5792f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "dtend INTEGER," 5802f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // timezone for event 5812f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "eventTimezone TEXT," 5822f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "duration TEXT," 5832f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "allDay INTEGER NOT NULL DEFAULT 0," 5842f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "accessLevel INTEGER NOT NULL DEFAULT 0," 5852f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "availability INTEGER NOT NULL DEFAULT 0," 5862f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "hasAlarm INTEGER NOT NULL DEFAULT 0," 5872f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "hasExtendedProperties INTEGER NOT NULL DEFAULT 0," 5882f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "rrule TEXT," 5892f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "rdate TEXT," 5902f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "exrule TEXT," 5912f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "exdate TEXT," 5922f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "original_id INTEGER," 5932f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // ORIGINAL_SYNC_ID is the _sync_id of recurring event 5942f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "original_sync_id TEXT," 5952f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // originalInstanceTime is in millis since epoch 5962f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "originalInstanceTime INTEGER," 5972f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "originalAllDay INTEGER," 5982f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // lastDate is in millis since epoch 5992f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "lastDate INTEGER," 6002f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "hasAttendeeData INTEGER NOT NULL DEFAULT 0," 6012f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "guestsCanModify INTEGER NOT NULL DEFAULT 0," 6022f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "guestsCanInviteOthers INTEGER NOT NULL DEFAULT 1," 6032f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "guestsCanSeeGuests INTEGER NOT NULL DEFAULT 1," 6042f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "organizer STRING," 6052f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "deleted INTEGER NOT NULL DEFAULT 0," 6062f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // timezone for event with allDay events are in local timezone 6072f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "eventEndTimezone TEXT," 6082f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // SYNC_DATAX columns are available for use by sync adapters 6092f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data1 TEXT," 6102f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data2 TEXT," 6112f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data3 TEXT," 6122f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data4 TEXT," 6132f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data5 TEXT," 6142f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data6 TEXT," 6152f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data7 TEXT," 6162f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data8 TEXT," 6172f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data9 TEXT," 6182f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "sync_data10 TEXT);"); 6192f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 6202f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // **When updating this be sure to also update LAST_SYNCED_EVENT_COLUMNS 6212f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 6222f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("CREATE INDEX eventsCalendarIdIndex ON Events (calendar_id);"); 6232f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 6242f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 62534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // TODO Remove this method after merging all ICS upgrades 62634c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik private void createEventsTable300(SQLiteDatabase db) { 62702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("CREATE TABLE Events (" + 62802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_id INTEGER PRIMARY KEY," + 62902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_id TEXT," + 63002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_version TEXT," + 63134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // sync time in UTC 63202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_time TEXT," + 63302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_local_id INTEGER," + 63402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dirty INTEGER," + 63534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // sync mark to filter out new rows 63602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_mark INTEGER," + 63702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_id INTEGER NOT NULL," + 63802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "htmlUri TEXT," + 63902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "title TEXT," + 64002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventLocation TEXT," + 64102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "description TEXT," + 64202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventStatus INTEGER," + 64302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "selfAttendeeStatus INTEGER NOT NULL DEFAULT 0," + 64402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "commentsUri TEXT," + 64534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // dtstart in millis since epoch 64602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtstart INTEGER," + 64734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // dtend in millis since epoch 64802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtend INTEGER," + 64934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // timezone for event 65002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventTimezone TEXT," + 65102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "duration TEXT," + 65202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "allDay INTEGER NOT NULL DEFAULT 0," + 65302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "accessLevel INTEGER NOT NULL DEFAULT 0," + 65402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "availability INTEGER NOT NULL DEFAULT 0," + 65502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAlarm INTEGER NOT NULL DEFAULT 0," + 65602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasExtendedProperties INTEGER NOT NULL DEFAULT 0," + 65702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rrule TEXT," + 65802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rdate TEXT," + 65902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exrule TEXT," + 66002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exdate TEXT," + 661c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // originalEvent is the _sync_id of recurring event 66202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "original_sync_id TEXT," + 663c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // originalInstanceTime is in millis since epoch 66402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalInstanceTime INTEGER," + 66502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalAllDay INTEGER," + 666c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // lastDate is in millis since epoch 66702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "lastDate INTEGER," + 66802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAttendeeData INTEGER NOT NULL DEFAULT 0," + 66902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanModify INTEGER NOT NULL DEFAULT 0," + 67002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanInviteOthers INTEGER NOT NULL DEFAULT 1," + 67102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanSeeGuests INTEGER NOT NULL DEFAULT 1," + 67202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "organizer STRING," + 67302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 674c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // timezone for event with allDay events are in local timezone 67502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventEndTimezone TEXT," + 676c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // syncAdapterData is available for use by sync adapters 67702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data1 TEXT);"); 678c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 67902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("CREATE INDEX eventsCalendarIdIndex ON Events (calendar_id);"); 680c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik } 681c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 6829ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert private void createCalendarsTable303(SQLiteDatabase db) { 6839ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("CREATE TABLE " + Tables.CALENDARS + " (" + 6849ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "_id INTEGER PRIMARY KEY," + 6859ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "account_name TEXT," + 6869ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "account_type TEXT," + 6879ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "_sync_id TEXT," + 6889ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "_sync_version TEXT," + 6899ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "_sync_time TEXT," + // UTC 6909ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "dirty INTEGER," + 6919ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "name TEXT," + 6929ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "displayName TEXT," + 6939ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "calendar_color INTEGER," + 6949ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "access_level INTEGER," + 6959ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "visible INTEGER NOT NULL DEFAULT 1," + 6969ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "sync_events INTEGER NOT NULL DEFAULT 0," + 6979ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "calendar_location TEXT," + 6989ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "calendar_timezone TEXT," + 6999ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "ownerAccount TEXT, " + 7009ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "canOrganizerRespond INTEGER NOT NULL DEFAULT 1," + 7019ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "canModifyTimeZone INTEGER DEFAULT 1," + 7029ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "maxReminders INTEGER DEFAULT 5," + 703bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden "allowedReminders TEXT DEFAULT '0,1'," + 7049ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "deleted INTEGER NOT NULL DEFAULT 0," + 7059ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync1 TEXT," + 7069ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync2 TEXT," + 7079ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync3 TEXT," + 7089ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync4 TEXT," + 7099ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync5 TEXT," + 7109ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "cal_sync6 TEXT" + 7119ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert ");"); 7129ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 7139ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // Trigger to remove a calendar's events when we delete the calendar 7149ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON " + Tables.CALENDARS + " " + 7159ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "BEGIN " + 7169ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert CALENDAR_CLEANUP_TRIGGER_SQL + 7179ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "END"); 7189ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 7199ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 7202f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private void createColorsTable(SQLiteDatabase db) { 7212f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 7222f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("CREATE TABLE " + Tables.COLORS + " (" + 7232f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors._ID + " INTEGER PRIMARY KEY," + 7242f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors.ACCOUNT_NAME + " TEXT NOT NULL," + 7252f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors.ACCOUNT_TYPE + " TEXT NOT NULL," + 7262f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors.DATA + " TEXT," + 7272f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors.COLOR_TYPE + " INTEGER NOT NULL," + 728387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik CalendarContract.Colors.COLOR_KEY + " TEXT NOT NULL," + 7292f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Colors.COLOR + " INTEGER NOT NULL" + 7302f251c778c06d21ed7693a70f4a1268ff929242eRoboErik ");"); 7312f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 7322f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 7332f251c778c06d21ed7693a70f4a1268ff929242eRoboErik public void createColorsTriggers(SQLiteDatabase db) { 7342f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL(CREATE_EVENT_COLOR_UPDATE_TRIGGER); 7352f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL(CREATE_CALENDAR_COLOR_UPDATE_TRIGGER); 7362f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 7372f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 7381b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private void createCalendarsTable(SQLiteDatabase db) { 7391b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.CALENDARS + " (" + 740b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars._ID + " INTEGER PRIMARY KEY," + 741b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.ACCOUNT_NAME + " TEXT," + 742b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.ACCOUNT_TYPE + " TEXT," + 743b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars._SYNC_ID + " TEXT," + 744b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.DIRTY + " INTEGER," + 745b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.NAME + " TEXT," + 746b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + " TEXT," + 747b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_COLOR + " INTEGER," + 748387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik CalendarContract.Calendars.CALENDAR_COLOR_KEY + " TEXT," + 749b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL + " INTEGER," + 750b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.VISIBLE + " INTEGER NOT NULL DEFAULT 1," + 751b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.SYNC_EVENTS + " INTEGER NOT NULL DEFAULT 0," + 752b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_LOCATION + " TEXT," + 753b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CALENDAR_TIME_ZONE + " TEXT," + 754b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.OWNER_ACCOUNT + " TEXT, " + 755b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAN_ORGANIZER_RESPOND + " INTEGER NOT NULL DEFAULT 1," + 756b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAN_MODIFY_TIME_ZONE + " INTEGER DEFAULT 1," + 757b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAN_PARTIALLY_UPDATE + " INTEGER DEFAULT 0," + 758b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.MAX_REMINDERS + " INTEGER DEFAULT 5," + 759bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden CalendarContract.Calendars.ALLOWED_REMINDERS + " TEXT DEFAULT '0,1'," + 7602f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Calendars.ALLOWED_AVAILABILITY + " TEXT DEFAULT '0,1'," + 7612f251c778c06d21ed7693a70f4a1268ff929242eRoboErik CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES + " TEXT DEFAULT '0,1,2'," + 762b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.DELETED + " INTEGER NOT NULL DEFAULT 0," + 763b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC1 + " TEXT," + 764b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC2 + " TEXT," + 765b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC3 + " TEXT," + 766b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC4 + " TEXT," + 767b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC5 + " TEXT," + 768b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC6 + " TEXT," + 769b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC7 + " TEXT," + 770b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC8 + " TEXT," + 771b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC9 + " TEXT," + 772b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.Calendars.CAL_SYNC10 + " TEXT" + 773fa332ecedc0c340109811552407142f6e4f600b2RoboErik ");"); 774fa332ecedc0c340109811552407142f6e4f600b2RoboErik 775fa332ecedc0c340109811552407142f6e4f600b2RoboErik // Trigger to remove a calendar's events when we delete the calendar 776fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON " + Tables.CALENDARS + " " + 777fa332ecedc0c340109811552407142f6e4f600b2RoboErik "BEGIN " + 778fa332ecedc0c340109811552407142f6e4f600b2RoboErik CALENDAR_CLEANUP_TRIGGER_SQL + 779fa332ecedc0c340109811552407142f6e4f600b2RoboErik "END"); 780fa332ecedc0c340109811552407142f6e4f600b2RoboErik } 781fa332ecedc0c340109811552407142f6e4f600b2RoboErik 7822f251c778c06d21ed7693a70f4a1268ff929242eRoboErik private void createCalendarsTable305(SQLiteDatabase db) { 7832f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("CREATE TABLE Calendars (" + 7842f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "_id INTEGER PRIMARY KEY," + 7852f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "account_name TEXT," + 7862f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "account_type TEXT," + 7872f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "_sync_id TEXT," + 7882f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "dirty INTEGER," + 7892f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "name TEXT," + 7902f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "calendar_displayName TEXT," + 7912f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "calendar_color INTEGER," + 7922f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "calendar_access_level INTEGER," + 7932f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "visible INTEGER NOT NULL DEFAULT 1," + 7942f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "sync_events INTEGER NOT NULL DEFAULT 0," + 7952f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "calendar_location TEXT," + 7962f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "calendar_timezone TEXT," + 7972f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "ownerAccount TEXT, " + 7982f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "canOrganizerRespond INTEGER NOT NULL DEFAULT 1," + 7992f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "canModifyTimeZone INTEGER DEFAULT 1," + 8002f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "canPartiallyUpdate INTEGER DEFAULT 0," + 8012f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "maxReminders INTEGER DEFAULT 5," + 8022f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "allowedReminders TEXT DEFAULT '0,1'," + 8032f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 8042f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync1 TEXT," + 8052f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync2 TEXT," + 8062f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync3 TEXT," + 8072f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync4 TEXT," + 8082f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync5 TEXT," + 8092f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync6 TEXT," + 8102f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync7 TEXT," + 8112f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync8 TEXT," + 8122f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync9 TEXT," + 8132f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "cal_sync10 TEXT" + 8142f251c778c06d21ed7693a70f4a1268ff929242eRoboErik ");"); 8152f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 8162f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // Trigger to remove a calendar's events when we delete the calendar 8172f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " + 8182f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "BEGIN " + 8192f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "DELETE FROM Events WHERE calendar_id=old._id;" + 8202f251c778c06d21ed7693a70f4a1268ff929242eRoboErik "END"); 8212f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 8222f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 823fa332ecedc0c340109811552407142f6e4f600b2RoboErik private void createCalendarsTable300(SQLiteDatabase db) { 824fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("CREATE TABLE " + Tables.CALENDARS + " (" + 825fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_id INTEGER PRIMARY KEY," + 826fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_name TEXT," + 827fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_type TEXT," + 828fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_id TEXT," + 829fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_version TEXT," + 830fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_time TEXT," + // UTC 831fa332ecedc0c340109811552407142f6e4f600b2RoboErik "dirty INTEGER," + 832fa332ecedc0c340109811552407142f6e4f600b2RoboErik "name TEXT," + 833fa332ecedc0c340109811552407142f6e4f600b2RoboErik "displayName TEXT," + 834fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_color INTEGER," + 835fa332ecedc0c340109811552407142f6e4f600b2RoboErik "access_level INTEGER," + 836fa332ecedc0c340109811552407142f6e4f600b2RoboErik "visible INTEGER NOT NULL DEFAULT 1," + 837fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync_events INTEGER NOT NULL DEFAULT 0," + 838fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_location TEXT," + 839fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_timezone TEXT," + 840fa332ecedc0c340109811552407142f6e4f600b2RoboErik "ownerAccount TEXT, " + 841fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canOrganizerRespond INTEGER NOT NULL DEFAULT 1," + 842fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canModifyTimeZone INTEGER DEFAULT 1," + 843fa332ecedc0c340109811552407142f6e4f600b2RoboErik "maxReminders INTEGER DEFAULT 5," + 844fa332ecedc0c340109811552407142f6e4f600b2RoboErik "allowedReminders TEXT DEFAULT '0,1,2'," + 845fa332ecedc0c340109811552407142f6e4f600b2RoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 846fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync1 TEXT," + 847fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync2 TEXT," + 848fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync3 TEXT," + 849fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync4 TEXT," + 850fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync5 TEXT," + 851fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync6 TEXT" + 8521b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio ");"); 8531b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 8541b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // Trigger to remove a calendar's events when we delete the calendar 8551b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON " + Tables.CALENDARS + " " + 8561b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio "BEGIN " + 8571b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio CALENDAR_CLEANUP_TRIGGER_SQL + 8581b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio "END"); 8591b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 8601b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 861c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik private void createCalendarsTable205(SQLiteDatabase db) { 862c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("CREATE TABLE Calendars (" + 863c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_id INTEGER PRIMARY KEY," + 864c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_account TEXT," + 865c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_account_type TEXT," + 866c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_id TEXT," + 867c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_version TEXT," + 868c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_time TEXT," + // UTC 869c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_dirty INTEGER," + 870c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "name TEXT," + 871c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "displayName TEXT," + 872c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "color INTEGER," + 873c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "access_level INTEGER," + 874c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "visible INTEGER NOT NULL DEFAULT 1," + 875c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync_events INTEGER NOT NULL DEFAULT 0," + 876c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "location TEXT," + 877c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "timezone TEXT," + 878c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "ownerAccount TEXT, " + 879c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canOrganizerRespond INTEGER NOT NULL DEFAULT 1," + 880c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canModifyTimeZone INTEGER DEFAULT 1, " + 881c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "maxReminders INTEGER DEFAULT 5," + 882c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 883c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync1 TEXT," + 884c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync2 TEXT," + 885c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync3 TEXT," + 886c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync4 TEXT," + 887c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync5 TEXT," + 888c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync6 TEXT" + 889c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik ");"); 890c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 891c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik createCalendarsCleanup200(db); 892c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik } 893c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 894180076a810558478f55ade53ebef0a2ddfa6bbc0Andy McFadden private void createCalendarsTable202(SQLiteDatabase db) { 8952cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TABLE Calendars (" + 8962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id INTEGER PRIMARY KEY," + 8972cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account TEXT," + 8982cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type TEXT," + 8992cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id TEXT," + 9002cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version TEXT," + 9012cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time TEXT," + // UTC 9022cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id INTEGER," + 9032cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty INTEGER," + 9042cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark INTEGER," + // Used to filter out new rows 9052cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name TEXT," + 9062cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName TEXT," + 9072cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color INTEGER," + 9082cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level INTEGER," + 9092cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected INTEGER NOT NULL DEFAULT 1," + 9102cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events INTEGER NOT NULL DEFAULT 0," + 9112cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location TEXT," + 9122cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone TEXT," + 9132cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount TEXT, " + 9142cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond INTEGER NOT NULL DEFAULT 1," + 9152cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 9162cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync1 TEXT," + 9172cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync2 TEXT," + 9182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync3 TEXT," + 9192cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync4 TEXT," + 9202cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync5 TEXT" + 9212cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 9222cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 9234067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden createCalendarsCleanup200(db); 9242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 9252cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 9262cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void createCalendarsTable200(SQLiteDatabase db) { 9272cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TABLE Calendars (" + 9282cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id INTEGER PRIMARY KEY," + 9292cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account TEXT," + 9302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type TEXT," + 9312cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id TEXT," + 9322cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version TEXT," + 9332cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time TEXT," + // UTC 9342cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id INTEGER," + 9352cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty INTEGER," + 9362cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark INTEGER," + // Used to filter out new rows 9372cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name TEXT," + 9382cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName TEXT," + 9392cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "hidden INTEGER NOT NULL DEFAULT 0," + 9402cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color INTEGER," + 9412cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level INTEGER," + 9422cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected INTEGER NOT NULL DEFAULT 1," + 9432cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events INTEGER NOT NULL DEFAULT 0," + 9442cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location TEXT," + 9452cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone TEXT," + 9462cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount TEXT, " + 9472cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond INTEGER NOT NULL DEFAULT 1," + 9482cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "deleted INTEGER NOT NULL DEFAULT 0," + 9492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync1 TEXT," + 9502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync2 TEXT," + 9512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync3 TEXT" + 9522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 9532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 9544067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden createCalendarsCleanup200(db); 9554067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden } 9564067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 9574067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden /** Trigger to remove a calendar's events when we delete the calendar */ 9584067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden private void createCalendarsCleanup200(SQLiteDatabase db) { 9592cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " + 9602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "BEGIN " + 9612cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM Events WHERE calendar_id=old._id;" + 9622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "END"); 9632cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 9642cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 9651599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio private void createCalendarMetaDataTable(SQLiteDatabase db) { 9667cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE " + Tables.CALENDAR_META_DATA + " (" + 967b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarMetaData._ID + " INTEGER PRIMARY KEY," + 968b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarMetaData.LOCAL_TIMEZONE + " TEXT," + 969b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarMetaData.MIN_INSTANCE + " INTEGER," + // UTC millis 970b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik CalendarContract.CalendarMetaData.MAX_INSTANCE + " INTEGER" + // UTC millis 9711599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio ");"); 9721599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 9731599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 9742cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void createCalendarMetaDataTable59(SQLiteDatabase db) { 9752cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TABLE CalendarMetaData (" + 9762cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id INTEGER PRIMARY KEY," + 9772cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "localTimezone TEXT," + 9782cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "minInstance INTEGER," + // UTC millis 9792cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "maxInstance INTEGER" + // UTC millis 9802cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 9812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 9822cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 983315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio private void createCalendarCacheTable(SQLiteDatabase db, String oldTimezoneDbVersion) { 984754b6d0e96c7df4cb649a48cde21b72c3dcedf4aErik // This is a hack because versioning skipped version number 61 of schema 985754b6d0e96c7df4cb649a48cde21b72c3dcedf4aErik // TODO after version 70 this can be removed 9867cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.CALENDAR_CACHE + ";"); 987754b6d0e96c7df4cb649a48cde21b72c3dcedf4aErik 988754b6d0e96c7df4cb649a48cde21b72c3dcedf4aErik // IF NOT EXISTS should be normal pattern for table creation 9897cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.CALENDAR_CACHE + " (" + 9907cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio CalendarCache.COLUMN_NAME_ID + " INTEGER PRIMARY KEY," + 9917cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio CalendarCache.COLUMN_NAME_KEY + " TEXT NOT NULL," + 9927cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio CalendarCache.COLUMN_NAME_VALUE + " TEXT" + 993ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio ");"); 994ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 995315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio initCalendarCacheTable(db, oldTimezoneDbVersion); 9962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik updateCalendarCacheTable(db); 997b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio } 998b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio 999315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio private void initCalendarCacheTable(SQLiteDatabase db, String oldTimezoneDbVersion) { 1000315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio String timezoneDbVersion = (oldTimezoneDbVersion != null) ? 1001315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio oldTimezoneDbVersion : CalendarCache.DEFAULT_TIMEZONE_DATABASE_VERSION; 1002315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 1003315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Set the default timezone database version 1004258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio db.execSQL("INSERT OR REPLACE INTO " + Tables.CALENDAR_CACHE + 1005258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio " (" + CalendarCache.COLUMN_NAME_ID + ", " + 1006258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_KEY + ", " + 1007258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_VALUE + ") VALUES (" + 1008b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio CalendarCache.KEY_TIMEZONE_DATABASE_VERSION.hashCode() + "," + 1009470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert "'" + CalendarCache.KEY_TIMEZONE_DATABASE_VERSION + "'," + 1010315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + timezoneDbVersion + "'" + 1011315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio ");"); 1012315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 1013315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 10142cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void updateCalendarCacheTable(SQLiteDatabase db) { 1015315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Define the default timezone type for Instances timezone management 1016258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio db.execSQL("INSERT INTO " + Tables.CALENDAR_CACHE + 1017258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio " (" + CalendarCache.COLUMN_NAME_ID + ", " + 1018258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_KEY + ", " + 1019258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_VALUE + ") VALUES (" + 1020315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio CalendarCache.KEY_TIMEZONE_TYPE.hashCode() + "," + 1021315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + CalendarCache.KEY_TIMEZONE_TYPE + "'," + 1022315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + CalendarCache.TIMEZONE_TYPE_AUTO + "'" + 1023315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio ");"); 1024315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 1025315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio String defaultTimezone = TimeZone.getDefault().getID(); 1026315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 1027315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Define the default timezone for Instances 1028258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio db.execSQL("INSERT INTO " + Tables.CALENDAR_CACHE + 1029258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio " (" + CalendarCache.COLUMN_NAME_ID + ", " + 1030258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_KEY + ", " + 1031258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_VALUE + ") VALUES (" + 1032315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio CalendarCache.KEY_TIMEZONE_INSTANCES.hashCode() + "," + 1033315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + CalendarCache.KEY_TIMEZONE_INSTANCES + "'," + 1034315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + defaultTimezone + "'" + 1035315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio ");"); 1036315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 1037315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Define the default previous timezone for Instances 1038258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio db.execSQL("INSERT INTO " + Tables.CALENDAR_CACHE + 1039258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio " (" + CalendarCache.COLUMN_NAME_ID + ", " + 1040258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_KEY + ", " + 1041258fc0a0054d6aba8556921c270379cea6bf3de1Fabrice Di Meglio CalendarCache.COLUMN_NAME_VALUE + ") VALUES (" + 1042315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS.hashCode() + "," + 1043315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + CalendarCache.KEY_TIMEZONE_INSTANCES_PREVIOUS + "'," + 1044315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio "'" + defaultTimezone + "'" + 1045ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio ");"); 1046ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 1047ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 10482cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void initCalendarCacheTable203(SQLiteDatabase db, String oldTimezoneDbVersion) { 10492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik String timezoneDbVersion = (oldTimezoneDbVersion != null) ? 10502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik oldTimezoneDbVersion : "2009s"; 10512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 10522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik // Set the default timezone database version 10532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT OR REPLACE INTO CalendarCache" + 10542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (_id, " + 10552cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "key, " + 10562cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "value) VALUES (" + 10572cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezoneDatabaseVersion".hashCode() + "," + 10582cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'timezoneDatabaseVersion'," + 10592cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'" + timezoneDbVersion + "'" + 10602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 10612cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 10622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 10632cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void updateCalendarCacheTableTo203(SQLiteDatabase db) { 10642cff10f1a005bd7302245d4c680cf851193c3a97RoboErik // Define the default timezone type for Instances timezone management 10652cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarCache" + 10662cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (_id, key, value) VALUES (" + 10672cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezoneType".hashCode() + "," + 10682cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'timezoneType'," + 10692cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'auto'" + 10702cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 10712cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 10722cff10f1a005bd7302245d4c680cf851193c3a97RoboErik String defaultTimezone = TimeZone.getDefault().getID(); 10732cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 10742cff10f1a005bd7302245d4c680cf851193c3a97RoboErik // Define the default timezone for Instances 10752cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarCache" + 10762cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (_id, key, value) VALUES (" + 10772cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezoneInstances".hashCode() + "," + 10782cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'timezoneInstances'," + 10792cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'" + defaultTimezone + "'" + 10802cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 10812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 10822cff10f1a005bd7302245d4c680cf851193c3a97RoboErik // Define the default previous timezone for Instances 10832cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarCache" + 10842cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (_id, key, value) VALUES (" + 10852cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezoneInstancesPrevious".hashCode() + "," + 10862cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'timezoneInstancesPrevious'," + 10872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'" + defaultTimezone + "'" + 10882cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ");"); 10892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 10902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik 1091935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden /** 1092935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * Removes orphaned data from the database. Specifically: 1093935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * <ul> 1094935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * <li>Attendees with an event_id for a nonexistent Event 1095935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * <li>Reminders with an event_id for a nonexistent Event 1096935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * </ul> 1097935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden */ 1098935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden static void removeOrphans(SQLiteDatabase db) { 1099935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (false) { // debug mode 1100935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden String SELECT_ATTENDEES_ORPHANS = "SELECT " + 1101935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Attendees._ID + ", " + Attendees.EVENT_ID + " FROM " + Tables.ATTENDEES + 1102935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden " WHERE " + WHERE_ATTENDEES_ORPHANS; 1103935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1104935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Cursor cursor = null; 1105935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden try { 1106935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Log.i(TAG, "Attendees orphans:"); 1107935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden cursor = db.rawQuery(SELECT_ATTENDEES_ORPHANS, null); 1108935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden DatabaseUtils.dumpCursor(cursor); 1109935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } finally { 1110935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (cursor != null) { 1111935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden cursor.close(); 1112935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1113935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1114935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1115935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden String SELECT_REMINDERS_ORPHANS = "SELECT " + 1116935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Attendees._ID + ", " + Reminders.EVENT_ID + " FROM " + Tables.REMINDERS + 1117935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden " WHERE " + WHERE_REMINDERS_ORPHANS; 1118935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden cursor = null; 1119935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden try { 1120935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Log.i(TAG, "Reminders orphans:"); 1121935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden cursor = db.rawQuery(SELECT_REMINDERS_ORPHANS, null); 1122935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden DatabaseUtils.dumpCursor(cursor); 1123935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } finally { 1124935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (cursor != null) { 1125935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden cursor.close(); 1126935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1127935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1128935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1129935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden return; 1130935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1131935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1132935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Log.d(TAG, "Checking for orphaned entries"); 1133935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden int count; 1134935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1135935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden count = db.delete(Tables.ATTENDEES, WHERE_ATTENDEES_ORPHANS, null); 1136935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (count != 0) { 1137935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Log.i(TAG, "Deleted " + count + " orphaned Attendees"); 1138935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1139935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1140935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden count = db.delete(Tables.REMINDERS, WHERE_REMINDERS_ORPHANS, null); 1141935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (count != 0) { 1142935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden Log.i(TAG, "Deleted " + count + " orphaned Reminders"); 1143935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1144935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1145935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1146935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 11479f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff @Override 11489f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 11497544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden Log.i(TAG, "Upgrading DB from version " + oldVersion + " to " + newVersion); 11507544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden long startWhen = System.nanoTime(); 11517544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden 1152ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff if (oldVersion < 49) { 11539f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff dropTables(db); 11549f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff mSyncState.createDatabase(db); 11559f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return; // this was lossy 11569f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 11579f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 11581599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // From schema versions 59 to version 66, the CalendarMetaData table definition had lost 11591599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // the primary key leading to having the CalendarMetaData with multiple rows instead of 11601599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // only one. The Instance table was then corrupted (during Instance expansion we are using 11611599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // the localTimezone, minInstance and maxInstance from CalendarMetaData table. 11621599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // This boolean helps us tracking the need to recreate the CalendarMetaData table and 11631599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // clear the Instance table (and thus force an Instance expansion). 1164679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio boolean recreateMetaDataAndInstances = (oldVersion >= 59 && oldVersion <= 66); 11652cff10f1a005bd7302245d4c680cf851193c3a97RoboErik boolean createEventsView = false; 11661599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 1167a6357118c223d00ed722ecd40ecdda92d705d211Erik try { 1168a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion < 51) { 1169a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion51(db); // From 50 or 51 1170a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion = 51; 1171a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1172a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 51) { 1173a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion52(db); 1174a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1175a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1176a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 52) { 1177a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion53(db); 1178a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1179a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1180a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 53) { 1181a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion54(db); 1182a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1183a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1184a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 54) { 1185a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion55(db); 1186a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1187a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1188a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 55 || oldVersion == 56) { 1189a6357118c223d00ed722ecd40ecdda92d705d211Erik // Both require resync, so just schedule it once 1190a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeResync(db); 1191a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1192a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 55) { 1193a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion56(db); 1194a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1195a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1196a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 56) { 1197a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion57(db); 1198a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1199a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1200a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 57) { 1201a6357118c223d00ed722ecd40ecdda92d705d211Erik // Changes are undone upgrading to 60, so don't do anything. 1202a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1203a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1204a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 58) { 1205a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion59(db); 1206a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1207a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1208a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 59) { 1209a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion60(db); 12102cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1211a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1212a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1213a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 60) { 1214a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion61(db); 1215a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1216a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1217a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 61) { 1218a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion62(db); 1219a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1220a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1221a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 62) { 12222cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1223a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1224a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1225a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 63) { 1226a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion64(db); 1227a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1228a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1229a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 64) { 12302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1231a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1232a6357118c223d00ed722ecd40ecdda92d705d211Erik } 1233a6357118c223d00ed722ecd40ecdda92d705d211Erik if (oldVersion == 65) { 1234a6357118c223d00ed722ecd40ecdda92d705d211Erik upgradeToVersion66(db); 1235a6357118c223d00ed722ecd40ecdda92d705d211Erik oldVersion += 1; 1236a6357118c223d00ed722ecd40ecdda92d705d211Erik } 12371599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio if (oldVersion == 66) { 1238679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio // Changes are done thru recreateMetaDataAndInstances() method 12391599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio oldVersion += 1; 12401599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 1241679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio if (recreateMetaDataAndInstances) { 12422cff10f1a005bd7302245d4c680cf851193c3a97RoboErik recreateMetaDataAndInstances67(db); 1243679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio } 124443b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio if (oldVersion == 67 || oldVersion == 68) { 1245e3730b9dce00439666e7ef324a28263a0ee92032Erik upgradeToVersion69(db); 1246e3730b9dce00439666e7ef324a28263a0ee92032Erik oldVersion = 69; 12477b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 1248b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio // 69. 70 are for Froyo/old Gingerbread only and 100s are for Gingerbread only 1249b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio // 70 and 71 have been for Honeycomb but no more used 1250b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio // 72 and 73 and 74 were for Honeycomb only but are considered as obsolete for enabling 1251b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio // room for Froyo version numbers 1252b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if(oldVersion == 69) { 1253315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio upgradeToVersion200(db); 12542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1255315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio oldVersion = 200; 125643b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio } 1257b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if (oldVersion == 70) { 1258b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio upgradeToVersion200(db); 1259b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio oldVersion = 200; 1260b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio } 1261b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if (oldVersion == 100) { 12627544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // note we skip past v101 and v102 1263b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio upgradeToVersion200(db); 1264b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio oldVersion = 200; 1265c59a6b5d8ff6b941fc44e9181e668fe0ec7df088Fabrice Di Meglio } 1266315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio boolean need203Update = true; 12677544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden if (oldVersion == 101 || oldVersion == 102) { 12687544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // v101 is v100 plus updateCalendarCacheTableTo203(). 12697544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // v102 is v101 with Event._id changed to autoincrement. 12707544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // Upgrade to 200 and skip the 203 update. 12717544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden upgradeToVersion200(db); 1272315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio oldVersion = 200; 1273315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio need203Update = false; 1274315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 1275b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if (oldVersion == 200) { 1276b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio upgradeToVersion201(db); 12777e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio oldVersion += 1; 12787e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio } 1279b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if (oldVersion == 201) { 1280b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio upgradeToVersion202(db); 12812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1282b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio oldVersion += 1; 1283b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio } 12847544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden if (oldVersion == 202) { 12857544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden if (need203Update) { 12867544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden upgradeToVersion203(db); 12877544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden } 1288315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio oldVersion += 1; 1289315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 1290c4d44fd028e7f5f44f46439c3410dab3456e6d3fFabrice Di Meglio if (oldVersion == 203) { 12912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView = true; 1292c4d44fd028e7f5f44f46439c3410dab3456e6d3fFabrice Di Meglio oldVersion += 1; 1293c4d44fd028e7f5f44f46439c3410dab3456e6d3fFabrice Di Meglio } 12947544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden if (oldVersion == 206) { 12957544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // v206 exists only in HC (change Event._id to autoincrement). Otherwise 12967544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden // identical to v204, so back it up and let the upgrade path continue. 12977544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden oldVersion -= 2; 12987544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden } 12994067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden if (oldVersion == 204) { 1300c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // This is an ICS update, all following use 300+ versions. 13014067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden upgradeToVersion205(db); 13024067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden createEventsView = true; 13034067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden oldVersion += 1; 13044067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden } 1305c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik if (oldVersion == 205) { 1306c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // Move ICS updates to 300 range 1307c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik upgradeToVersion300(db); 1308c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik createEventsView = true; 1309c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik oldVersion = 300; 1310c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik } 131134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik if (oldVersion == 300) { 131234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik upgradeToVersion301(db); 131334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik createEventsView = true; 131434c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik oldVersion++; 131534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik } 1316da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik if (oldVersion == 301) { 1317da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik upgradeToVersion302(db); 1318da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik oldVersion++; 1319da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik } 1320fa332ecedc0c340109811552407142f6e4f600b2RoboErik if (oldVersion == 302) { 1321fa332ecedc0c340109811552407142f6e4f600b2RoboErik upgradeToVersion303(db); 1322fa332ecedc0c340109811552407142f6e4f600b2RoboErik oldVersion++; 1323fa332ecedc0c340109811552407142f6e4f600b2RoboErik createEventsView = true; 1324fa332ecedc0c340109811552407142f6e4f600b2RoboErik } 13259ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (oldVersion == 303) { 13269ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert upgradeToVersion304(db); 13279ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert oldVersion++; 13289ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert createEventsView = true; 13299ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 133002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik if (oldVersion == 304) { 133102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik upgradeToVersion305(db); 133202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik oldVersion++; 133302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik createEventsView = true; 133402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik } 1335470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert if (oldVersion == 305) { 1336470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert upgradeToVersion306(db); 1337470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert // force a sync to update edit url and etag 1338470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert scheduleSync(null /* all accounts */, false, null); 1339470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert oldVersion++; 1340470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert } 1341935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden if (oldVersion == 306) { 1342935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden upgradeToVersion307(db); 1343935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden oldVersion++; 1344935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 13452f251c778c06d21ed7693a70f4a1268ff929242eRoboErik if (oldVersion == 307) { 13462f251c778c06d21ed7693a70f4a1268ff929242eRoboErik upgradeToVersion308(db); 13472f251c778c06d21ed7693a70f4a1268ff929242eRoboErik oldVersion++; 13482f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createEventsView = true; 13492f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 13502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik if (createEventsView) { 13512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createEventsView(db); 13522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik } 1353b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio if (oldVersion != DATABASE_VERSION) { 1354b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio Log.e(TAG, "Need to recreate Calendar schema because of " 1355b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio + "unknown Calendar database version: " + oldVersion); 1356b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio dropTables(db); 1357b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio bootstrapDB(db); 1358b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio oldVersion = DATABASE_VERSION; 1359935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } else { 1360935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden removeOrphans(db); 1361b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio } 1362a6357118c223d00ed722ecd40ecdda92d705d211Erik } catch (SQLiteException e) { 13637544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden Log.e(TAG, "onUpgrade: SQLiteException, recreating db. ", e); 13647544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden Log.e(TAG, "(oldVersion was " + oldVersion + ")"); 1365a6357118c223d00ed722ecd40ecdda92d705d211Erik dropTables(db); 1366a6357118c223d00ed722ecd40ecdda92d705d211Erik bootstrapDB(db); 1367a6357118c223d00ed722ecd40ecdda92d705d211Erik return; // this was lossy 1368bf897b03effb752368a98cfb89e6b90cfdde50fcMarc Blank } 1369c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 13707544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden long endWhen = System.nanoTime(); 13717544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden Log.d(TAG, "Calendar upgrade took " + ((endWhen - startWhen) / 1000000) + "ms"); 13727544af675ce2fd78f33198e5e9194f2bc7bd129fAndy McFadden 1373c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik /** 1374c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * db versions < 100 correspond to Froyo and earlier. Gingerbread bumped 1375c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * the db versioning to 100. Honeycomb bumped it to 200. ICS will begin 1376c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * in 300. At each major release we should jump to the next 1377c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * centiversion. 1378c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik */ 1379ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 1380ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 13811599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio /** 1382679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio * If the user_version of the database if between 59 and 66 (those versions has been deployed 1383679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio * with no primary key for the CalendarMetaData table) 13841599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio */ 13852cff10f1a005bd7302245d4c680cf851193c3a97RoboErik private void recreateMetaDataAndInstances67(SQLiteDatabase db) { 1386679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio // Recreate the CalendarMetaData table with correct primary key 13872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DROP TABLE CalendarMetaData;"); 13882cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createCalendarMetaDataTable59(db); 1389679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio 1390679d544f38aa33d00c12884b987d8f8af2a6a6d3Fabrice Di Meglio // Also clean the Instance table as this table may be corrupted 13912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DELETE FROM Instances;"); 1392ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 1393ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 13947b40dde3168f4af2c757cb43955aa3bfe1668666Erik private static boolean fixAllDayTime(Time time, String timezone, Long timeInMillis) { 13957b40dde3168f4af2c757cb43955aa3bfe1668666Erik time.set(timeInMillis); 13967b40dde3168f4af2c757cb43955aa3bfe1668666Erik if(time.hour != 0 || time.minute != 0 || time.second != 0) { 13977b40dde3168f4af2c757cb43955aa3bfe1668666Erik time.hour = 0; 13987b40dde3168f4af2c757cb43955aa3bfe1668666Erik time.minute = 0; 13997b40dde3168f4af2c757cb43955aa3bfe1668666Erik time.second = 0; 14007b40dde3168f4af2c757cb43955aa3bfe1668666Erik return true; 14017b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 14027b40dde3168f4af2c757cb43955aa3bfe1668666Erik return false; 14037b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 14047b40dde3168f4af2c757cb43955aa3bfe1668666Erik 14057b40dde3168f4af2c757cb43955aa3bfe1668666Erik @VisibleForTesting 14062f251c778c06d21ed7693a70f4a1268ff929242eRoboErik void upgradeToVersion308(SQLiteDatabase db) { 14072f251c778c06d21ed7693a70f4a1268ff929242eRoboErik /* 14082f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * Changes from version 307 to 308: 14092f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * - add Colors table to db 14102f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * - add eventColor_index to Events table 14112f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * - add calendar_color_index to Calendars table 14122f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * - add allowedAttendeeTypes to Calendars table 14132f251c778c06d21ed7693a70f4a1268ff929242eRoboErik * - add allowedAvailability to Calendars table 14142f251c778c06d21ed7693a70f4a1268ff929242eRoboErik */ 14152f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createColorsTable(db); 14162f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 14172f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("ALTER TABLE Calendars ADD COLUMN allowedAvailability TEXT DEFAULT '0,1';"); 14182f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("ALTER TABLE Calendars ADD COLUMN allowedAttendeeTypes TEXT DEFAULT '0,1,2';"); 14192f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("ALTER TABLE Calendars ADD COLUMN calendar_color_index TEXT;"); 14202f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("ALTER TABLE Events ADD COLUMN eventColor_index TEXT;"); 14212f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 14222f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // Default Exchange calendars to be supporting the 'tentative' 14232f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // availability as well 14242f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("UPDATE Calendars SET allowedAvailability='0,1,2' WHERE _id IN " 14252f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + "(SELECT _id FROM Calendars WHERE account_type='com.android.exchange');"); 14262f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 14272f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // Triggers to update the color stored in an event or a calendar when 14282f251c778c06d21ed7693a70f4a1268ff929242eRoboErik // the color_index is changed. 14292f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createColorsTriggers(db); 14302f251c778c06d21ed7693a70f4a1268ff929242eRoboErik } 14312f251c778c06d21ed7693a70f4a1268ff929242eRoboErik 14322f251c778c06d21ed7693a70f4a1268ff929242eRoboErik @VisibleForTesting 1433935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden void upgradeToVersion307(SQLiteDatabase db) { 1434935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden /* 1435935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * Changes from version 306 to 307: 1436935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden * - Changed _id field to AUTOINCREMENT 1437935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden */ 1438935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("ALTER TABLE Events RENAME TO Events_Backup;"); 1439935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("DROP TRIGGER IF EXISTS events_cleanup_delete"); 1440935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("DROP TRIGGER IF EXISTS original_sync_update"); 1441935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("DROP INDEX IF EXISTS eventsCalendarIdIndex"); 14422f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createEventsTable307(db); 1443935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1444935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden String FIELD_LIST = 1445935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "_id, " + 1446935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "_sync_id, " + 1447935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "dirty, " + 1448935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "lastSynced," + 1449935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "calendar_id, " + 1450935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "title, " + 1451935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "eventLocation, " + 1452935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "description, " + 1453935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "eventColor, " + 1454935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "eventStatus, " + 1455935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "selfAttendeeStatus, " + 1456935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "dtstart, " + 1457935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "dtend, " + 1458935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "eventTimezone, " + 1459935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "duration, " + 1460935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "allDay, " + 1461935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "accessLevel, " + 1462935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "availability, " + 1463935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "hasAlarm, " + 1464935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "hasExtendedProperties, " + 1465935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "rrule, " + 1466935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "rdate, " + 1467935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "exrule, " + 1468935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "exdate, " + 1469935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "original_id," + 1470935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "original_sync_id, " + 1471935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "originalInstanceTime, " + 1472935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "originalAllDay, " + 1473935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "lastDate, " + 1474935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "hasAttendeeData, " + 1475935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "guestsCanModify, " + 1476935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "guestsCanInviteOthers, " + 1477935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "guestsCanSeeGuests, " + 1478935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "organizer, " + 1479935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "deleted, " + 1480935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "eventEndTimezone, " + 1481935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data1," + 1482935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data2," + 1483935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data3," + 1484935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data4," + 1485935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data5," + 1486935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data6," + 1487935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data7," + 1488935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data8," + 1489935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data9," + 1490935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "sync_data10 "; 1491935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1492935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // copy fields from old to new 1493935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("INSERT INTO Events (" + FIELD_LIST + ") SELECT " + FIELD_LIST + 1494935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "FROM Events_Backup;"); 1495935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1496935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("DROP TABLE Events_Backup;"); 1497935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1498935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // Trigger to remove data tied to an event when we delete that event. 1499935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON " + Tables.EVENTS + " " + 1500935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden "BEGIN " + EVENTS_CLEANUP_TRIGGER_SQL + "END"); 1501935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1502935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // Trigger to update exceptions when an original event updates its 1503935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // _sync_id 1504935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden db.execSQL(CREATE_SYNC_ID_UPDATE_TRIGGER); 1505935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden } 1506935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden 1507935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden @VisibleForTesting 1508470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert void upgradeToVersion306(SQLiteDatabase db) { 1509470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert /* 1510470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert * The following changes are for google.com accounts only. 1511470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert * 1512470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert * Change event id's from ".../private/full/... to .../events/... 1513470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert * Set Calendars.canPartiallyUpdate to 1 to support partial updates 1514470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert * Nuke sync state so we re-sync with a fresh etag and edit url 15153ac8148cdc79bde4b009ccb6a9ffda77bdb547d3Andy McFadden * 15163ac8148cdc79bde4b009ccb6a9ffda77bdb547d3Andy McFadden * We need to drop the original_sync_update trigger because it fires whenever the 15173ac8148cdc79bde4b009ccb6a9ffda77bdb547d3Andy McFadden * sync_id field is touched, and dramatically slows this operation. 1518470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert */ 15193ac8148cdc79bde4b009ccb6a9ffda77bdb547d3Andy McFadden db.execSQL("DROP TRIGGER IF EXISTS original_sync_update"); 1520470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert db.execSQL("UPDATE Events SET " 1521470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert + "_sync_id = REPLACE(_sync_id, '/private/full/', '/events/'), " 1522470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert + "original_sync_id = REPLACE(original_sync_id, '/private/full/', '/events/') " 1523470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert + "WHERE _id IN (SELECT Events._id FROM Events " 1524470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert + "JOIN Calendars ON Events.calendar_id = Calendars._id " 1525470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert + "WHERE account_type = 'com.google')" 1526470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert ); 15273ac8148cdc79bde4b009ccb6a9ffda77bdb547d3Andy McFadden db.execSQL(CREATE_SYNC_ID_UPDATE_TRIGGER); 1528470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert 1529470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert db.execSQL("UPDATE Calendars SET canPartiallyUpdate = 1 WHERE account_type = 'com.google'"); 1530470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert 1531470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert db.execSQL("DELETE FROM _sync_state WHERE account_type = 'com.google'"); 1532470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert } 1533470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert 1534470aa5bc291ca33d51dda356f38ac2954026da9aAlon Albert @VisibleForTesting 153502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik void upgradeToVersion305(SQLiteDatabase db) { 153602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik /* 153702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * Changes from version 304 to 305: 153802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Add CAL_SYNC columns up to 10 153902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename Calendars.access_level to calendar_access_level 154002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename calendars _sync_version to cal_sync7 154102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename calendars _sync_time to cal_sync8 154202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename displayName to calendar_displayName 154302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename _sync_local_id to sync_data2 154402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename htmlUri to sync_data3 154502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename events _sync_version to sync_data4 154602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename events _sync_time to sync_data5 154702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Rename commentsUri to sync_data6 154802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Migrate Events _sync_mark to sync_data8 154902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Change sync_data2 from INTEGER to TEXT 155002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Change sync_data8 from INTEGER to TEXT 155102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Add SYNC_DATA columns up to 10 155202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik * -Add EVENT_COLOR to Events table 155302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik */ 155402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 155502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // rename old table, create new table with updated layout 155602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 155702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 15582f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createCalendarsTable305(db); 155902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 156002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // copy fields from old to new 156102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("INSERT INTO Calendars (" + 156202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_id, " + 156302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "account_name, " + 156402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "account_type, " + 156502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_id, " + 156602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync7, " + // rename from _sync_version 156702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync8, " + // rename from _sync_time 156802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dirty, " + 156902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "name, " + 157002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_displayName, " + // rename from displayName 157102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_color, " + 157202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_access_level, " + // rename from access_level 157302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "visible, " + 157402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_events, " + 157502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_location, " + 157602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_timezone, " + 157702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "ownerAccount, " + 157802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canOrganizerRespond, " + 157902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canModifyTimeZone, " + 158002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "maxReminders, " + 158102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "allowedReminders, " + 158202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "deleted, " + 158302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canPartiallyUpdate," + 158402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync1, " + 158502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync2, " + 158602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync3, " + 158702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync4, " + 158802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync5, " + 158902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync6) " + 159002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "SELECT " + 159102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_id, " + 159202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "account_name, " + 159302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "account_type, " + 159402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_id, " + 159502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_version, " + 159602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_time, " + 159702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dirty, " + 159802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "name, " + 159902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "displayName, " + 160002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_color, " + 160102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "access_level, " + 160202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "visible, " + 160302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_events, " + 160402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_location, " + 160502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_timezone, " + 160602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "ownerAccount, " + 160702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canOrganizerRespond, " + 160802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canModifyTimeZone, " + 160902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "maxReminders, " + 161002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "allowedReminders, " + 161102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "deleted, " + 161202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "canPartiallyUpdate," + 161302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync1, " + 161402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync2, " + 161502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync3, " + 161602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync4, " + 161702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync5, " + 161802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "cal_sync6 " + 161902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "FROM Calendars_Backup;"); 162002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 162102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // drop the old table 162202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("DROP TABLE Calendars_Backup;"); 162302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 162402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("ALTER TABLE Events RENAME TO Events_Backup;"); 162502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("DROP TRIGGER IF EXISTS events_cleanup_delete"); 162602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("DROP INDEX IF EXISTS eventsCalendarIdIndex"); 1627935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // 305 and 307 can share the same createEventsTable implementation, because the 1628935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // addition of "autoincrement" to _ID doesn't affect the upgrade path. (Note that 1629935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // much older databases may also already have autoincrement set because the change 1630935132618f821883f101db31af24e6d4c2b1e82cAndy McFadden // was back-ported.) 16312f251c778c06d21ed7693a70f4a1268ff929242eRoboErik createEventsTable307(db); 163202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 163302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // copy fields from old to new 163402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("INSERT INTO Events (" + 163502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_id, " + 163602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_id, " + 163702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data4, " + // renamed from _sync_version 163802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data5, " + // renamed from _sync_time 163902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data2, " + // renamed from _sync_local_id 164002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dirty, " + 164102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data8, " + // renamed from _sync_mark 164202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_id, " + 164302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data3, " + // renamed from htmlUri 164402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "title, " + 164502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventLocation, " + 164602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "description, " + 164702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventStatus, " + 164802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "selfAttendeeStatus, " + 164902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data6, " + // renamed from commentsUri 165002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtstart, " + 165102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtend, " + 165202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventTimezone, " + 165302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventEndTimezone, " + 165402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "duration, " + 165502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "allDay, " + 165602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "accessLevel, " + 165702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "availability, " + 165802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAlarm, " + 165902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasExtendedProperties, " + 166002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rrule, " + 166102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rdate, " + 166202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exrule, " + 166302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exdate, " + 166402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "original_id," + 166502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "original_sync_id, " + 166602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalInstanceTime, " + 166702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalAllDay, " + 166802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "lastDate, " + 166902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAttendeeData, " + 167002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanModify, " + 167102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanInviteOthers, " + 167202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanSeeGuests, " + 167302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "organizer, " + 167402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "deleted, " + 167502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data7," + 167602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "lastSynced," + 167702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data1) " + 167802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 167902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "SELECT " + 168002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_id, " + 168102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_id, " + 168202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_version, " + 168302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_time, " + 168402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_local_id, " + 168502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dirty, " + 168602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "_sync_mark, " + 168702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "calendar_id, " + 168802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "htmlUri, " + 168902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "title, " + 169002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventLocation, " + 169102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "description, " + 169202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventStatus, " + 169302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "selfAttendeeStatus, " + 169402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "commentsUri, " + 169502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtstart, " + 169602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "dtend, " + 169702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventTimezone, " + 169802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "eventEndTimezone, " + 169902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "duration, " + 170002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "allDay, " + 170102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "accessLevel, " + 170202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "availability, " + 170302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAlarm, " + 170402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasExtendedProperties, " + 170502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rrule, " + 170602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "rdate, " + 170702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exrule, " + 170802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "exdate, " + 170902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "original_id," + 171002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "original_sync_id, " + 171102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalInstanceTime, " + 171202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "originalAllDay, " + 171302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "lastDate, " + 171402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "hasAttendeeData, " + 171502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanModify, " + 171602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanInviteOthers, " + 171702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "guestsCanSeeGuests, " + 171802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "organizer, " + 171902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "deleted, " + 172002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data7," + 172102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "lastSynced," + 172202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "sync_data1 " + 172302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 172402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "FROM Events_Backup;" 172502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik ); 172602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 172702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("DROP TABLE Events_Backup;"); 172802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 172902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // Trigger to remove data tied to an event when we delete that event. 173002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON " + Tables.EVENTS + " " + 173102f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "BEGIN " + 173202f97c538fc46a08d857d2c807c76fd0eec12493RoboErik EVENTS_CLEANUP_TRIGGER_SQL + 173302f97c538fc46a08d857d2c807c76fd0eec12493RoboErik "END"); 173402f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 173502f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // Trigger to update exceptions when an original event updates its 173602f97c538fc46a08d857d2c807c76fd0eec12493RoboErik // _sync_id 173702f97c538fc46a08d857d2c807c76fd0eec12493RoboErik db.execSQL(CREATE_SYNC_ID_UPDATE_TRIGGER); 173802f97c538fc46a08d857d2c807c76fd0eec12493RoboErik } 173902f97c538fc46a08d857d2c807c76fd0eec12493RoboErik 174002f97c538fc46a08d857d2c807c76fd0eec12493RoboErik @VisibleForTesting 17419ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert void upgradeToVersion304(SQLiteDatabase db) { 17429ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert /* 17439ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert * Changes from version 303 to 304: 17449ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert * - add canPartiallyUpdate to Calendars table 17459ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert * - add sync_data7 to Calendars to Events table 17469ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert * - add lastSynced to Calendars to Events table 17479ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert */ 17489ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("ALTER TABLE Calendars ADD COLUMN canPartiallyUpdate INTEGER DEFAULT 0;"); 17499ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("ALTER TABLE Events ADD COLUMN sync_data7 TEXT;"); 17509ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("ALTER TABLE Events ADD COLUMN lastSynced INTEGER DEFAULT 0;"); 17519ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 17529ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 17539ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert @VisibleForTesting 1754fa332ecedc0c340109811552407142f6e4f600b2RoboErik void upgradeToVersion303(SQLiteDatabase db) { 1755fa332ecedc0c340109811552407142f6e4f600b2RoboErik /* 1756fa332ecedc0c340109811552407142f6e4f600b2RoboErik * Changes from version 302 to 303: 1757fa332ecedc0c340109811552407142f6e4f600b2RoboErik * - change SYNCx columns to CAL_SYNCx 1758fa332ecedc0c340109811552407142f6e4f600b2RoboErik */ 1759fa332ecedc0c340109811552407142f6e4f600b2RoboErik 1760fa332ecedc0c340109811552407142f6e4f600b2RoboErik // rename old table, create new table with updated layout 1761fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 1762fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 17639ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert createCalendarsTable303(db); 1764fa332ecedc0c340109811552407142f6e4f600b2RoboErik 1765fa332ecedc0c340109811552407142f6e4f600b2RoboErik // copy fields from old to new 1766fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("INSERT INTO Calendars (" + 1767fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_id, " + 1768fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_name, " + 1769fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_type, " + 1770fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_id, " + 1771fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_version, " + 1772fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_time, " + 1773fa332ecedc0c340109811552407142f6e4f600b2RoboErik "dirty, " + 1774fa332ecedc0c340109811552407142f6e4f600b2RoboErik "name, " + 1775fa332ecedc0c340109811552407142f6e4f600b2RoboErik "displayName, " + 1776fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_color, " + 1777fa332ecedc0c340109811552407142f6e4f600b2RoboErik "access_level, " + 1778fa332ecedc0c340109811552407142f6e4f600b2RoboErik "visible, " + 1779fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync_events, " + 1780fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_location, " + 1781fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_timezone, " + 1782fa332ecedc0c340109811552407142f6e4f600b2RoboErik "ownerAccount, " + 1783fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canOrganizerRespond, " + 1784fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canModifyTimeZone, " + 1785fa332ecedc0c340109811552407142f6e4f600b2RoboErik "maxReminders, " + 1786fa332ecedc0c340109811552407142f6e4f600b2RoboErik "allowedReminders, " + 1787fa332ecedc0c340109811552407142f6e4f600b2RoboErik "deleted, " + 1788fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync1, " + // rename from sync1 1789fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync2, " + // rename from sync2 1790fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync3, " + // rename from sync3 1791fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync4, " + // rename from sync4 1792fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync5, " + // rename from sync5 1793fa332ecedc0c340109811552407142f6e4f600b2RoboErik "cal_sync6) " + // rename from sync6 1794fa332ecedc0c340109811552407142f6e4f600b2RoboErik "SELECT " + 1795fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_id, " + 1796fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_name, " + 1797fa332ecedc0c340109811552407142f6e4f600b2RoboErik "account_type, " + 1798fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_id, " + 1799fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_version, " + 1800fa332ecedc0c340109811552407142f6e4f600b2RoboErik "_sync_time, " + 1801fa332ecedc0c340109811552407142f6e4f600b2RoboErik "dirty, " + 1802fa332ecedc0c340109811552407142f6e4f600b2RoboErik "name, " + 1803fa332ecedc0c340109811552407142f6e4f600b2RoboErik "displayName, " + 1804fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_color, " + 1805fa332ecedc0c340109811552407142f6e4f600b2RoboErik "access_level, " + 1806fa332ecedc0c340109811552407142f6e4f600b2RoboErik "visible, " + 1807fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync_events, " + 1808fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_location, " + 1809fa332ecedc0c340109811552407142f6e4f600b2RoboErik "calendar_timezone, " + 1810fa332ecedc0c340109811552407142f6e4f600b2RoboErik "ownerAccount, " + 1811fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canOrganizerRespond, " + 1812fa332ecedc0c340109811552407142f6e4f600b2RoboErik "canModifyTimeZone, " + 1813fa332ecedc0c340109811552407142f6e4f600b2RoboErik "maxReminders, " + 1814fa332ecedc0c340109811552407142f6e4f600b2RoboErik "allowedReminders," + 1815fa332ecedc0c340109811552407142f6e4f600b2RoboErik "deleted, " + 1816fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync1, " + 1817fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync2, " + 1818fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync3, " + 1819fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync4," + 1820fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync5," + 1821fa332ecedc0c340109811552407142f6e4f600b2RoboErik "sync6 " + 1822fa332ecedc0c340109811552407142f6e4f600b2RoboErik "FROM Calendars_Backup;" 1823fa332ecedc0c340109811552407142f6e4f600b2RoboErik ); 1824fa332ecedc0c340109811552407142f6e4f600b2RoboErik 1825fa332ecedc0c340109811552407142f6e4f600b2RoboErik // drop the old table 1826fa332ecedc0c340109811552407142f6e4f600b2RoboErik db.execSQL("DROP TABLE Calendars_Backup;"); 1827fa332ecedc0c340109811552407142f6e4f600b2RoboErik } 1828fa332ecedc0c340109811552407142f6e4f600b2RoboErik 1829fa332ecedc0c340109811552407142f6e4f600b2RoboErik @VisibleForTesting 1830da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik void upgradeToVersion302(SQLiteDatabase db) { 1831da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik /* 1832da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik * Changes from version 301 to 302 1833da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik * - Move Exchange eventEndTimezone values to SYNC_DATA1 1834da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik */ 1835da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik db.execSQL("UPDATE Events SET sync_data1=eventEndTimezone WHERE calendar_id IN " 1836da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik + "(SELECT _id FROM Calendars WHERE account_type='com.android.exchange');"); 1837da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik 1838da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik db.execSQL("UPDATE Events SET eventEndTimezone=NULL WHERE calendar_id IN " 1839da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik + "(SELECT _id FROM Calendars WHERE account_type='com.android.exchange');"); 1840da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik } 1841da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik 1842da641c374b00946f37bfe00e53bb292f4e0103d8RoboErik @VisibleForTesting 184334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik void upgradeToVersion301(SQLiteDatabase db) { 184434c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik /* 184534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik * Changes from version 300 to 301 184634c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik * - Added original_id column to Events table 184734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik * - Added triggers to keep original_id and original_sync_id in sync 184834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik */ 184934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 185034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL("DROP TRIGGER IF EXISTS " + SYNC_ID_UPDATE_TRIGGER_NAME + ";"); 185134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 185234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL("ALTER TABLE Events ADD COLUMN original_id INTEGER;"); 185334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 185434c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // Fill in the original_id for all events that have an original_sync_id 185534c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL("UPDATE Events set original_id=" + 185634c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik "(SELECT Events2._id FROM Events AS Events2 " + 185734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik "WHERE Events2._sync_id=Events.original_sync_id) " + 185834c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik "WHERE Events.original_sync_id NOT NULL"); 185934c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // Trigger to update exceptions when an original event updates its 186034c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik // _sync_id 186134c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL(CREATE_SYNC_ID_UPDATE_TRIGGER); 186234c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik } 186334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik 186434c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik @VisibleForTesting 1865c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik void upgradeToVersion300(SQLiteDatabase db) { 1866c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1867c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik /* 1868c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * Changes from version 205 to 300: 1869c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename _sync_account to account_name in Calendars table 1870c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - remove _sync_account from Events table 1871c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename _sync_account_type to account_type in Calendars table 1872c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - remove _sync_account_type from Events table 1873c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename _sync_dirty to dirty in Calendars/Events table 1874c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename color to calendar_color in Calendars table 1875c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename location to calendar_location in Calendars table 1876c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename timezone to calendar_timezone in Calendars table 1877c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - add allowedReminders in Calendars table 1878c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename visibility to accessLevel in Events table 1879c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename transparency to availability in Events table 1880c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename originalEvent to original_sync_id in Events table 1881c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - remove dtstart2 and dtend2 from Events table 1882c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik * - rename syncAdapterData to sync_data1 in Events table 1883c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik */ 1884c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1885c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // rename old table, create new table with updated layout 1886c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 188734c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup;"); 1888fa332ecedc0c340109811552407142f6e4f600b2RoboErik createCalendarsTable300(db); 1889c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1890c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // copy fields from old to new 1891c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("INSERT INTO Calendars (" + 1892c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_id, " + 1893c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "account_name, " + // rename from _sync_account 1894c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "account_type, " + // rename from _sync_account_type 1895c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_id, " + 1896c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_version, " + 1897c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_time, " + 1898c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dirty, " + // rename from _sync_dirty 1899c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "name, " + 1900c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "displayName, " + 1901c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "calendar_color, " + // rename from color 1902c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "access_level, " + 1903c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "visible, " + 1904c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync_events, " + 1905c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "calendar_location, " + // rename from location 1906c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "calendar_timezone, " + // rename from timezone 1907c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "ownerAccount, " + 1908c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canOrganizerRespond, " + 1909c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canModifyTimeZone, " + 1910c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "maxReminders, " + 1911c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "allowedReminders," + 1912c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "deleted, " + 1913c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync1, " + 1914c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync2, " + 1915c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync3, " + 1916c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync4," + 1917c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync5," + 1918c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync6) " + 1919c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1920c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "SELECT " + 1921c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_id, " + 1922c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_account, " + 1923c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_account_type, " + 1924c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_id, " + 1925c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_version, " + 1926c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_time, " + 1927c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_dirty, " + 1928c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "name, " + 1929c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "displayName, " + 1930c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "color, " + 1931c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "access_level, " + 1932c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "visible, " + 1933c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync_events, " + 1934c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "location, " + 1935c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "timezone, " + 1936c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "ownerAccount, " + 1937c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canOrganizerRespond, " + 1938c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "canModifyTimeZone, " + 1939c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "maxReminders, " + 1940c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "'0,1,2,3'," + 1941c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "deleted, " + 1942c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync1, " + 1943c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync2, " + 1944c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync3, " + 1945c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync4, " + 1946c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync5, " + 1947c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync6 " + 1948c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "FROM Calendars_Backup;" 1949c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik ); 1950c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1951bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden /* expand the set of allowed reminders for Google calendars to include email */ 1952bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden db.execSQL("UPDATE Calendars SET allowedReminders = '0,1,2' " + 1953bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden "WHERE account_type = 'com.google'"); 1954bf986d8deeeed9566e0badeba89d4800533cbca6Andy McFadden 1955c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // drop the old table 1956c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP TABLE Calendars_Backup;"); 1957c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1958c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("ALTER TABLE Events RENAME TO Events_Backup;"); 1959c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP TRIGGER IF EXISTS events_insert"); 1960c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP TRIGGER IF EXISTS events_cleanup_delete"); 1961c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP INDEX IF EXISTS eventSyncAccountAndIdIndex"); 1962c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP INDEX IF EXISTS eventsCalendarIdIndex"); 196334c32cd924eb8ee28381106b37044b78fd8cbc30RoboErik createEventsTable300(db); 1964c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 1965c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // copy fields from old to new 1966c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("INSERT INTO Events (" + 1967c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_id, " + 1968c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_id, " + 1969c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_version, " + 1970c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_time, " + 1971c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_local_id, " + 1972c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dirty, " + // renamed from _sync_dirty 1973c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_mark, " + 1974c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "calendar_id, " + 1975c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "htmlUri, " + 1976c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "title, " + 1977c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventLocation, " + 1978c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "description, " + 1979c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventStatus, " + 1980c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "selfAttendeeStatus, " + 1981c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "commentsUri, " + 1982c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dtstart, " + 1983c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dtend, " + 1984c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventTimezone, " + 1985c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventEndTimezone, " + // renamed from eventTimezone2 1986c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "duration, " + 1987c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "allDay, " + 1988c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "accessLevel, " + // renamed from visibility 1989c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "availability, " + // renamed from transparency 1990c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasAlarm, " + 1991c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasExtendedProperties, " + 1992c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "rrule, " + 1993c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "rdate, " + 1994c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "exrule, " + 1995c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "exdate, " + 1996c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "original_sync_id, " + // renamed from originalEvent 1997c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "originalInstanceTime, " + 1998c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "originalAllDay, " + 1999c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "lastDate, " + 2000c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasAttendeeData, " + 2001c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanModify, " + 2002c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanInviteOthers, " + 2003c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanSeeGuests, " + 2004c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "organizer, " + 2005c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "deleted, " + 2006c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "sync_data1) " + // renamed from syncAdapterData 2007c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2008c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "SELECT " + 2009c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_id, " + 2010c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_id, " + 2011c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_version, " + 2012c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_time, " + 2013c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_local_id, " + 2014c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_dirty, " + 2015c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "_sync_mark, " + 2016c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "calendar_id, " + 2017c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "htmlUri, " + 2018c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "title, " + 2019c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventLocation, " + 2020c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "description, " + 2021c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventStatus, " + 2022c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "selfAttendeeStatus, " + 2023c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "commentsUri, " + 2024c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dtstart, " + 2025c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "dtend, " + 2026c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventTimezone, " + 2027c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "eventTimezone2, " + 2028c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "duration, " + 2029c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "allDay, " + 2030c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "visibility, " + 2031c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "transparency, " + 2032c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasAlarm, " + 2033c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasExtendedProperties, " + 2034c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "rrule, " + 2035c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "rdate, " + 2036c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "exrule, " + 2037c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "exdate, " + 2038c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "originalEvent, " + 2039c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "originalInstanceTime, " + 2040c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "originalAllDay, " + 2041c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "lastDate, " + 2042c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "hasAttendeeData, " + 2043c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanModify, " + 2044c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanInviteOthers, " + 2045c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "guestsCanSeeGuests, " + 2046c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "organizer, " + 2047c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "deleted, " + 2048c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "syncAdapterData " + 2049c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2050c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "FROM Events_Backup;" 2051c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik ); 2052c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2053c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("DROP TABLE Events_Backup;"); 2054c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2055c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik // Trigger to remove data tied to an event when we delete that event. 2056c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON " + Tables.EVENTS + " " + 2057c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "BEGIN " + 2058c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik EVENTS_CLEANUP_TRIGGER_SQL + 2059c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik "END"); 2060c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2061fa332ecedc0c340109811552407142f6e4f600b2RoboErik } 2062c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik 2063c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik @VisibleForTesting 20644067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden void upgradeToVersion205(SQLiteDatabase db) { 20654067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden /* 20664067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * Changes from version 204 to 205: 20674067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - rename+reorder "_sync_mark" to "sync6" (and change type from INTEGER to TEXT) 20684067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - rename "selected" to "visible" 20694067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - rename "organizerCanRespond" to "canOrganizerRespond" 20704067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - add "canModifyTimeZone" 20714067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - add "maxReminders" 20724067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden * - remove "_sync_local_id" (a/k/a _SYNC_DATA) 20734067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden */ 20744067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 20754067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden // rename old table, create new table with updated layout 20764067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 20774067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 2078c8383567db3ade2aea28447ad3bd09ac3033bcd7RoboErik createCalendarsTable205(db); 20794067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 20804067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden // copy fields from old to new 20814067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden db.execSQL("INSERT INTO Calendars (" + 20824067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_id, " + 20834067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_account, " + 20844067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_account_type, " + 20854067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_id, " + 20864067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_version, " + 20874067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_time, " + 20884067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_dirty, " + 20894067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "name, " + 20904067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "displayName, " + 20914067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "color, " + 20924067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "access_level, " + 20934067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "visible, " + // rename from "selected" 20944067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync_events, " + 20954067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "location, " + 20964067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "timezone, " + 20974067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "ownerAccount, " + 20984067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "canOrganizerRespond, " + // rename from "organizerCanRespond" 20994067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "canModifyTimeZone, " + 21004067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "maxReminders, " + 21014067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "deleted, " + 21024067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync1, " + 21034067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync2, " + 21044067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync3, " + 21054067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync4," + 21064067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync5," + 21074067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync6) " + // rename/reorder from _sync_mark 21084067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "SELECT " + 21094067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_id, " + 21104067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_account, " + 21114067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_account_type, " + 21124067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_id, " + 21134067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_version, " + 21144067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_time, " + 21154067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_dirty, " + 21164067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "name, " + 21174067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "displayName, " + 21184067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "color, " + 21194067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "access_level, " + 21204067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "selected, " + 21214067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync_events, " + 21224067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "location, " + 21234067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "timezone, " + 21244067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "ownerAccount, " + 21254067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "organizerCanRespond, " + 21264067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "1, " + 21274067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "5, " + 21284067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "deleted, " + 21294067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync1, " + 21304067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync2, " + 21314067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync3, " + 21324067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync4, " + 21334067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "sync5, " + 21344067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "_sync_mark " + 21354067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "FROM Calendars_Backup;" 21364067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden ); 21374067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 21384067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden // set these fields appropriately for Exchange events 21394067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden db.execSQL("UPDATE Calendars SET canModifyTimeZone=0, maxReminders=1 " + 21404067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden "WHERE _sync_account_type='com.android.exchange'"); 21414067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 21424067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden // drop the old table 21434067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden db.execSQL("DROP TABLE Calendars_Backup;"); 21444067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden } 21454067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden 21464067700dbedcf4c8a379c9ecba9b5603972b4607Andy McFadden @VisibleForTesting 2147315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio void upgradeToVersion203(SQLiteDatabase db) { 2148315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Same as Gingerbread version 100 21492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor cursor = db.rawQuery("SELECT value FROM CalendarCache WHERE key=?", 2150315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio new String[] {"timezoneDatabaseVersion"}); 2151315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 2152315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio String oldTimezoneDbVersion = null; 2153315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio if (cursor != null && cursor.moveToNext()) { 215458313767dd0e7e3823c35ca61b40eddb9dd229bbFabrice Di Meglio try { 215558313767dd0e7e3823c35ca61b40eddb9dd229bbFabrice Di Meglio oldTimezoneDbVersion = cursor.getString(0); 215658313767dd0e7e3823c35ca61b40eddb9dd229bbFabrice Di Meglio } finally { 215758313767dd0e7e3823c35ca61b40eddb9dd229bbFabrice Di Meglio cursor.close(); 215858313767dd0e7e3823c35ca61b40eddb9dd229bbFabrice Di Meglio } 21593443e3ebeaa39e8415b43e7cf3b218caee554e9bFabrice Di Meglio // Also clean the CalendarCache table 21602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DELETE FROM CalendarCache;"); 2161315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 21622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik initCalendarCacheTable203(db, oldTimezoneDbVersion); 2163315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 2164315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // Same as Gingerbread version 101 2165315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio updateCalendarCacheTableTo203(db); 2166315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 2167315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 2168315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio @VisibleForTesting 2169b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio void upgradeToVersion202(SQLiteDatabase db) { 21707e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio // We will drop the "hidden" column from the calendar schema and add the "sync5" column 21712cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 21727e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio 21737e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 2174180076a810558478f55ade53ebef0a2ddfa6bbc0Andy McFadden createCalendarsTable202(db); 21757e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio 21767e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio // Populate the new Calendars table and put into the "sync5" column the value of the 21777e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio // old "hidden" column 21782cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO Calendars (" + 21792cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id, " + 21802cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account, " + 21812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type, " + 21822cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id, " + 21832cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version, " + 21842cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time, " + 21852cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id, " + 21862cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty, " + 21872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark, " + 21882cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name, " + 21892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName, " + 21902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color, " + 21912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level, " + 21922cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected, " + 21932cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events, " + 21942cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location, " + 21952cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone, " + 21962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount, " + 21972cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond, " + 21982cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "deleted, " + 21992cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync1, " + 22002cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync2, " + 22012cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync3, " + 22022cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync4," + 22032cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync5) " + 22047e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio "SELECT " + 22052cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id, " + 22062cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account, " + 22072cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type, " + 22082cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id, " + 22092cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version, " + 22102cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time, " + 22112cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id, " + 22122cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty, " + 22132cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark, " + 22142cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name, " + 22152cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName, " + 22162cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color, " + 22172cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level, " + 22182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected, " + 22192cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events, " + 22202cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location, " + 22212cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone, " + 22222cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount, " + 22232cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond, " + 22242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "deleted, " + 22252cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync1, " + 22262cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync2, " + 22272cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync3, " + 22282cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync4, " + 22292cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "hidden " + 22302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "FROM Calendars_Backup;" 22317e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio ); 22327e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio 22337e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio // Drop the backup table 22342cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DROP TABLE Calendars_Backup;"); 22357e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio } 22367e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio 22377e7329964ddd60c98e93a7eda18b68944a630382Fabrice Di Meglio @VisibleForTesting 2238b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio void upgradeToVersion201(SQLiteDatabase db) { 22392cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars ADD COLUMN sync4 TEXT;"); 2240836bc8e9da32b8231f1b0d57be271730d7a5368dFabrice Di Meglio } 2241836bc8e9da32b8231f1b0d57be271730d7a5368dFabrice Di Meglio 2242836bc8e9da32b8231f1b0d57be271730d7a5368dFabrice Di Meglio @VisibleForTesting 2243b492524403ca34b0cb03bfad6456909494479925Fabrice Di Meglio void upgradeToVersion200(SQLiteDatabase db) { 22441b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // we cannot use here a Calendar.Calendars,URL constant for "url" as we are trying to make 22451b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // it disappear so we are keeping the hardcoded name "url" in all the SQLs 22462cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars RENAME TO Calendars_Backup;"); 22471b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 22481fc162fc3a3bb466a39146cf59a8b51ec5d9de52Fabrice Di Meglio db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 22492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createCalendarsTable200(db); 22501b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 22511b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // Populate the new Calendars table except the SYNC2 / SYNC3 columns 22522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO Calendars (" + 22532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id, " + 22542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account, " + 22552cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type, " + 22562cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id, " + 22572cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version, " + 22582cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time, " + 22592cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id, " + 22602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty, " + 22612cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark, " + 22622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name, " + 22632cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName, " + 22642cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color, " + 22652cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level, " + 22662cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected, " + 22672cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events, " + 22682cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location, " + 22692cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone, " + 22702cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount, " + 22712cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond, " + 22722cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "deleted, " + 22732cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync1) " + 22741b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio "SELECT " + 22752cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id, " + 22762cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account, " + 22772cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type, " + 22782cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_id, " + 22792cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_version, " + 22802cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_time, " + 22812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_local_id, " + 22822cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_dirty, " + 22832cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_mark, " + 22842cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "name, " + 22852cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "displayName, " + 22862cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "color, " + 22872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "access_level, " + 22882cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "selected, " + 22892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync_events, " + 22902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "location, " + 22912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone, " + 22922cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "ownerAccount, " + 22932cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "organizerCanRespond, " + 22942cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "0, " + 22952cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "url " + 22962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "FROM Calendars_Backup;" 22971b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio ); 22981b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 22991b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // Populate SYNC2 and SYNC3 columns - SYNC1 represent the old "url" column 23001b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // We will need to iterate over all the "com.google" type of calendars 23012cff10f1a005bd7302245d4c680cf851193c3a97RoboErik String selectSql = "SELECT _id, url" + 23022cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM Calendars_Backup" + 23032cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE _sync_account_type='com.google'" + 23041b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio " AND url IS NOT NULL;"; 23051b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 23062cff10f1a005bd7302245d4c680cf851193c3a97RoboErik String updateSql = "UPDATE Calendars SET " + 23072cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync2=?, " + // edit Url 23082cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "sync3=? " + // self Url 23092cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE _id=?;"; 23101b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 23111b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Cursor cursor = db.rawQuery(selectSql, null /* selection args */); 23121b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (cursor != null && cursor.getCount() > 0) { 23131b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio try { 23141b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Object[] bindArgs = new Object[3]; 2315c59a6b5d8ff6b941fc44e9181e668fe0ec7df088Fabrice Di Meglio 23161b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio while (cursor.moveToNext()) { 23171b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Long id = cursor.getLong(0); 23181b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio String url = cursor.getString(1); 23191b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio String selfUrl = getSelfUrlFromEventsUrl(url); 23201b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio String editUrl = getEditUrlFromEventsUrl(url); 232143b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio 23221b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio bindArgs[0] = editUrl; 23231b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio bindArgs[1] = selfUrl; 23241b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio bindArgs[2] = id; 232543b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio 23261b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio db.execSQL(updateSql, bindArgs); 23271b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 23281b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } finally { 23291b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio cursor.close(); 23301b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 23311b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 23321b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 23331b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // Drop the backup table 23342cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DROP TABLE Calendars_Backup;"); 233543b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio } 233643b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio 233743b3eba05ef67bdd4b0a2b285b6ed2b377c136c5Fabrice Di Meglio @VisibleForTesting 2338e3730b9dce00439666e7ef324a28263a0ee92032Erik static void upgradeToVersion69(SQLiteDatabase db) { 23397b40dde3168f4af2c757cb43955aa3bfe1668666Erik // Clean up allDay events which could be in an invalid state from an earlier version 23407b40dde3168f4af2c757cb43955aa3bfe1668666Erik // Some allDay events had hour, min, sec not set to zero, which throws elsewhere. This 2341e3730b9dce00439666e7ef324a28263a0ee92032Erik // will go through the allDay events and make sure they have proper values and are in the 2342e3730b9dce00439666e7ef324a28263a0ee92032Erik // correct timezone. Verifies that dtstart and dtend are in UTC and at midnight, that 2343e3730b9dce00439666e7ef324a28263a0ee92032Erik // eventTimezone is set to UTC, tries to make sure duration is in days, and that dtstart2 2344e3730b9dce00439666e7ef324a28263a0ee92032Erik // and dtend2 are at midnight in their timezone. 23452cff10f1a005bd7302245d4c680cf851193c3a97RoboErik final String sql = "SELECT _id, " + 23462cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart, " + 23472cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend, " + 23482cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "duration, " + 23492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart2, " + 23502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend2, " + 23512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone, " + 23522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone2, " + 23532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "rrule " + 23542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "FROM Events " + 23552cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE allDay=?"; 23567cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio Cursor cursor = db.rawQuery(sql, new String[] {"1"}); 23577b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (cursor != null) { 23587b40dde3168f4af2c757cb43955aa3bfe1668666Erik try { 23597b40dde3168f4af2c757cb43955aa3bfe1668666Erik String timezone; 23607b40dde3168f4af2c757cb43955aa3bfe1668666Erik String timezone2; 23617b40dde3168f4af2c757cb43955aa3bfe1668666Erik String duration; 23627b40dde3168f4af2c757cb43955aa3bfe1668666Erik Long dtstart; 23637b40dde3168f4af2c757cb43955aa3bfe1668666Erik Long dtstart2; 23647b40dde3168f4af2c757cb43955aa3bfe1668666Erik Long dtend; 23657b40dde3168f4af2c757cb43955aa3bfe1668666Erik Long dtend2; 23667b40dde3168f4af2c757cb43955aa3bfe1668666Erik Time time = new Time(); 23677b40dde3168f4af2c757cb43955aa3bfe1668666Erik Long id; 2368e3730b9dce00439666e7ef324a28263a0ee92032Erik // some things need to be in utc so we call this frequently, cache to make faster 2369e3730b9dce00439666e7ef324a28263a0ee92032Erik final String utc = Time.TIMEZONE_UTC; 23707b40dde3168f4af2c757cb43955aa3bfe1668666Erik while (cursor.moveToNext()) { 23717b40dde3168f4af2c757cb43955aa3bfe1668666Erik String rrule = cursor.getString(8); 23727b40dde3168f4af2c757cb43955aa3bfe1668666Erik id = cursor.getLong(0); 23737b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart = cursor.getLong(1); 23747b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart2 = null; 23757b40dde3168f4af2c757cb43955aa3bfe1668666Erik timezone = cursor.getString(6); 23767b40dde3168f4af2c757cb43955aa3bfe1668666Erik timezone2 = cursor.getString(7); 23777b40dde3168f4af2c757cb43955aa3bfe1668666Erik duration = cursor.getString(3); 23787b40dde3168f4af2c757cb43955aa3bfe1668666Erik 2379e3730b9dce00439666e7ef324a28263a0ee92032Erik if (TextUtils.isEmpty(rrule)) { 23807b40dde3168f4af2c757cb43955aa3bfe1668666Erik // For non-recurring events dtstart and dtend should both have values 23817b40dde3168f4af2c757cb43955aa3bfe1668666Erik // and duration should be null. 23827b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtend = cursor.getLong(2); 23837b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtend2 = null; 23847b40dde3168f4af2c757cb43955aa3bfe1668666Erik // Since we made all three of these at the same time if timezone2 exists 23857b40dde3168f4af2c757cb43955aa3bfe1668666Erik // so should dtstart2 and dtend2. 23867b40dde3168f4af2c757cb43955aa3bfe1668666Erik if(!TextUtils.isEmpty(timezone2)) { 23877b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart2 = cursor.getLong(4); 23887b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtend2 = cursor.getLong(5); 23897b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 23907b40dde3168f4af2c757cb43955aa3bfe1668666Erik 23917b40dde3168f4af2c757cb43955aa3bfe1668666Erik boolean update = false; 2392e3730b9dce00439666e7ef324a28263a0ee92032Erik if (!TextUtils.equals(timezone, utc)) { 2393e3730b9dce00439666e7ef324a28263a0ee92032Erik update = true; 2394e3730b9dce00439666e7ef324a28263a0ee92032Erik timezone = utc; 2395e3730b9dce00439666e7ef324a28263a0ee92032Erik } 2396e3730b9dce00439666e7ef324a28263a0ee92032Erik 2397e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone); 2398e3730b9dce00439666e7ef324a28263a0ee92032Erik update |= fixAllDayTime(time, timezone, dtstart); 23997b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart = time.normalize(false); 2400e3730b9dce00439666e7ef324a28263a0ee92032Erik 2401e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone); 24027b40dde3168f4af2c757cb43955aa3bfe1668666Erik update |= fixAllDayTime(time, timezone, dtend); 24037b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtend = time.normalize(false); 24047b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24057b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (dtstart2 != null) { 2406e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone2); 24077b40dde3168f4af2c757cb43955aa3bfe1668666Erik update |= fixAllDayTime(time, timezone2, dtstart2); 24087b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart2 = time.normalize(false); 24097b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24107b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24117b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (dtend2 != null) { 2412e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone2); 24137b40dde3168f4af2c757cb43955aa3bfe1668666Erik update |= fixAllDayTime(time, timezone2, dtend2); 24147b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtend2 = time.normalize(false); 24157b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24167b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24177b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (!TextUtils.isEmpty(duration)) { 24187b40dde3168f4af2c757cb43955aa3bfe1668666Erik update = true; 24197b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24207b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24217b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (update) { 24227b40dde3168f4af2c757cb43955aa3bfe1668666Erik // enforce duration being null 24232cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events SET " + 24242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart=?, " + 24252cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend=?, " + 24262cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart2=?, " + 24272cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend2=?, " + 24282cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "duration=?, " + 24292cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone=?, " + 24302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone2=? " + 24312cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE _id=?", 24327cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio new Object[] { 24337cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtstart, 24347cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtend, 24357cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtstart2, 24367cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtend2, 24377cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio null, 24387cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio timezone, 24397cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio timezone2, 24407cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio id} 24417cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio ); 24427b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24437b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24447b40dde3168f4af2c757cb43955aa3bfe1668666Erik } else { 24457b40dde3168f4af2c757cb43955aa3bfe1668666Erik // For recurring events only dtstart and duration should be used. 24467b40dde3168f4af2c757cb43955aa3bfe1668666Erik // We ignore dtend since it will be overwritten if the event changes to a 24477b40dde3168f4af2c757cb43955aa3bfe1668666Erik // non-recurring event and won't be used otherwise. 24487b40dde3168f4af2c757cb43955aa3bfe1668666Erik if(!TextUtils.isEmpty(timezone2)) { 24497b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart2 = cursor.getLong(4); 24507b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24517b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24527b40dde3168f4af2c757cb43955aa3bfe1668666Erik boolean update = false; 2453e3730b9dce00439666e7ef324a28263a0ee92032Erik if (!TextUtils.equals(timezone, utc)) { 2454e3730b9dce00439666e7ef324a28263a0ee92032Erik update = true; 2455e3730b9dce00439666e7ef324a28263a0ee92032Erik timezone = utc; 2456e3730b9dce00439666e7ef324a28263a0ee92032Erik } 2457e3730b9dce00439666e7ef324a28263a0ee92032Erik 2458e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone); 2459e3730b9dce00439666e7ef324a28263a0ee92032Erik update |= fixAllDayTime(time, timezone, dtstart); 24607b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart = time.normalize(false); 24617b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24627b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (dtstart2 != null) { 2463e3730b9dce00439666e7ef324a28263a0ee92032Erik time.clear(timezone2); 24647b40dde3168f4af2c757cb43955aa3bfe1668666Erik update |= fixAllDayTime(time, timezone2, dtstart2); 24657b40dde3168f4af2c757cb43955aa3bfe1668666Erik dtstart2 = time.normalize(false); 24667b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24677b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24687b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (TextUtils.isEmpty(duration)) { 24697b40dde3168f4af2c757cb43955aa3bfe1668666Erik // If duration was missing assume a 1 day duration 24707b40dde3168f4af2c757cb43955aa3bfe1668666Erik duration = "P1D"; 24717b40dde3168f4af2c757cb43955aa3bfe1668666Erik update = true; 24727b40dde3168f4af2c757cb43955aa3bfe1668666Erik } else { 24737b40dde3168f4af2c757cb43955aa3bfe1668666Erik int len = duration.length(); 24747b40dde3168f4af2c757cb43955aa3bfe1668666Erik // TODO fix durations in other formats as well 24757b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (duration.charAt(0) == 'P' && 24767b40dde3168f4af2c757cb43955aa3bfe1668666Erik duration.charAt(len - 1) == 'S') { 24777b40dde3168f4af2c757cb43955aa3bfe1668666Erik int seconds = Integer.parseInt(duration.substring(1, len - 1)); 24787b40dde3168f4af2c757cb43955aa3bfe1668666Erik int days = (seconds + DAY_IN_SECONDS - 1) / DAY_IN_SECONDS; 24797b40dde3168f4af2c757cb43955aa3bfe1668666Erik duration = "P" + days + "D"; 24807b40dde3168f4af2c757cb43955aa3bfe1668666Erik update = true; 24817b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24827b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 24837b40dde3168f4af2c757cb43955aa3bfe1668666Erik 24847b40dde3168f4af2c757cb43955aa3bfe1668666Erik if (update) { 24857b40dde3168f4af2c757cb43955aa3bfe1668666Erik // If there were other problems also enforce dtend being null 24862cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events SET " + 24872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart=?, " + 24882cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend=?, " + 24892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart2=?, " + 24902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend2=?, " + 24912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "duration=?," + 24922cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone=?, " + 24932cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone2=? " + 24942cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE _id=?", 24957cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio new Object[] { 24967cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtstart, 24977cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio null, 24987cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio dtstart2, 24997cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio null, 25007cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio duration, 25017cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio timezone, 25027cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio timezone2, 25037cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio id} 25047cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio ); 25057b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25067b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25077b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25087b40dde3168f4af2c757cb43955aa3bfe1668666Erik } finally { 25097b40dde3168f4af2c757cb43955aa3bfe1668666Erik cursor.close(); 25107b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25117b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25127b40dde3168f4af2c757cb43955aa3bfe1668666Erik } 25137b40dde3168f4af2c757cb43955aa3bfe1668666Erik 2514bf897b03effb752368a98cfb89e6b90cfdde50fcMarc Blank private void upgradeToVersion66(SQLiteDatabase db) { 2515bf897b03effb752368a98cfb89e6b90cfdde50fcMarc Blank // Add a column to indicate whether the event organizer can respond to his own events 2516bf897b03effb752368a98cfb89e6b90cfdde50fcMarc Blank // The UI should not show attendee status for events in calendars with this column = 0 25172cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars" + 25182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN organizerCanRespond INTEGER NOT NULL DEFAULT 1;"); 2519cf9dc6b9bd031b1f6f811a32326ee85429c94debMarc Blank } 2520cf9dc6b9bd031b1f6f811a32326ee85429c94debMarc Blank 2521162c7c9bbd53b623fbe913b376e7f7f42915bb59Marc Blank private void upgradeToVersion64(SQLiteDatabase db) { 2522162c7c9bbd53b623fbe913b376e7f7f42915bb59Marc Blank // Add a column that may be used by sync adapters 25232cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 25242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN syncAdapterData TEXT;"); 25252d1b3d70a6ebce8194932f8a8355d97a89da113fFabrice Di Meglio } 25262d1b3d70a6ebce8194932f8a8355d97a89da113fFabrice Di Meglio 2527ae4f20e120d3107cef20be860a612c9c23816295Erik private void upgradeToVersion62(SQLiteDatabase db) { 2528ae4f20e120d3107cef20be860a612c9c23816295Erik // New columns are to transition to having allDay events in the local timezone 25292cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 25302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN dtstart2 INTEGER;"); 25312cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 25322cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN dtend2 INTEGER;"); 25332cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 25342cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN eventTimezone2 TEXT;"); 2535ae4f20e120d3107cef20be860a612c9c23816295Erik 2536ae4f20e120d3107cef20be860a612c9c23816295Erik String[] allDayBit = new String[] {"0"}; 2537ae4f20e120d3107cef20be860a612c9c23816295Erik // Copy over all the data that isn't an all day event. 25382cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events SET " + 25392cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart2=dtstart," + 25402cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend2=dtend," + 25412cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone2=eventTimezone " + 25422cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE allDay=?;", 2543ae4f20e120d3107cef20be860a612c9c23816295Erik allDayBit /* selection args */); 2544ae4f20e120d3107cef20be860a612c9c23816295Erik 2545ae4f20e120d3107cef20be860a612c9c23816295Erik // "cursor" iterates over all the calendars 2546ae4f20e120d3107cef20be860a612c9c23816295Erik allDayBit[0] = "1"; 25472cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor cursor = db.rawQuery("SELECT Events._id," + 25482cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart," + 25492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend," + 25502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone," + 25512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "timezone " + 25522cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "FROM Events INNER JOIN Calendars " + 25532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE Events.calendar_id=Calendars._id" + 25542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " AND allDay=?", 2555ae4f20e120d3107cef20be860a612c9c23816295Erik allDayBit /* selection args */); 2556ae4f20e120d3107cef20be860a612c9c23816295Erik 2557ae4f20e120d3107cef20be860a612c9c23816295Erik Time oldTime = new Time(); 2558ae4f20e120d3107cef20be860a612c9c23816295Erik Time newTime = new Time(); 2559ae4f20e120d3107cef20be860a612c9c23816295Erik // Update the allday events in the new columns 2560ae4f20e120d3107cef20be860a612c9c23816295Erik if (cursor != null) { 2561ae4f20e120d3107cef20be860a612c9c23816295Erik try { 2562ae4f20e120d3107cef20be860a612c9c23816295Erik String[] newData = new String[4]; 2563ae4f20e120d3107cef20be860a612c9c23816295Erik cursor.moveToPosition(-1); 2564ae4f20e120d3107cef20be860a612c9c23816295Erik while (cursor.moveToNext()) { 2565ae4f20e120d3107cef20be860a612c9c23816295Erik long id = cursor.getLong(0); // Order from query above 2566ae4f20e120d3107cef20be860a612c9c23816295Erik long dtstart = cursor.getLong(1); 2567ae4f20e120d3107cef20be860a612c9c23816295Erik long dtend = cursor.getLong(2); 2568ae4f20e120d3107cef20be860a612c9c23816295Erik String eTz = cursor.getString(3); // current event timezone 2569ae4f20e120d3107cef20be860a612c9c23816295Erik String tz = cursor.getString(4); // Calendar timezone 2570dbaad88527665d5144a8a178fa822f58d2bc7d05Erik //If there's no timezone for some reason use UTC by default. 2571dbaad88527665d5144a8a178fa822f58d2bc7d05Erik if(eTz == null) { 2572dbaad88527665d5144a8a178fa822f58d2bc7d05Erik eTz = Time.TIMEZONE_UTC; 2573dbaad88527665d5144a8a178fa822f58d2bc7d05Erik } 2574ae4f20e120d3107cef20be860a612c9c23816295Erik 2575ae4f20e120d3107cef20be860a612c9c23816295Erik // Convert start time for all day events into the timezone of their calendar 2576ae4f20e120d3107cef20be860a612c9c23816295Erik oldTime.clear(eTz); 2577ae4f20e120d3107cef20be860a612c9c23816295Erik oldTime.set(dtstart); 2578ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.clear(tz); 2579ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.set(oldTime.monthDay, oldTime.month, oldTime.year); 2580ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.normalize(false); 2581ae4f20e120d3107cef20be860a612c9c23816295Erik dtstart = newTime.toMillis(false /*ignoreDst*/); 2582ae4f20e120d3107cef20be860a612c9c23816295Erik 2583ae4f20e120d3107cef20be860a612c9c23816295Erik // Convert end time for all day events into the timezone of their calendar 2584ae4f20e120d3107cef20be860a612c9c23816295Erik oldTime.clear(eTz); 2585ae4f20e120d3107cef20be860a612c9c23816295Erik oldTime.set(dtend); 2586ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.clear(tz); 2587ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.set(oldTime.monthDay, oldTime.month, oldTime.year); 2588ae4f20e120d3107cef20be860a612c9c23816295Erik newTime.normalize(false); 2589ae4f20e120d3107cef20be860a612c9c23816295Erik dtend = newTime.toMillis(false /*ignoreDst*/); 2590ae4f20e120d3107cef20be860a612c9c23816295Erik 2591ae4f20e120d3107cef20be860a612c9c23816295Erik newData[0] = String.valueOf(dtstart); 2592ae4f20e120d3107cef20be860a612c9c23816295Erik newData[1] = String.valueOf(dtend); 2593ae4f20e120d3107cef20be860a612c9c23816295Erik newData[2] = tz; 2594ae4f20e120d3107cef20be860a612c9c23816295Erik newData[3] = String.valueOf(id); 25952cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events SET " + 25962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtstart2=?, " + 25972cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "dtend2=?, " + 25982cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "eventTimezone2=? " + 25992cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE _id=?", 2600ae4f20e120d3107cef20be860a612c9c23816295Erik newData); 2601ae4f20e120d3107cef20be860a612c9c23816295Erik } 2602ae4f20e120d3107cef20be860a612c9c23816295Erik } finally { 2603ae4f20e120d3107cef20be860a612c9c23816295Erik cursor.close(); 2604ae4f20e120d3107cef20be860a612c9c23816295Erik } 2605ae4f20e120d3107cef20be860a612c9c23816295Erik } 2606ae4f20e120d3107cef20be860a612c9c23816295Erik } 2607ae4f20e120d3107cef20be860a612c9c23816295Erik 2608ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private void upgradeToVersion61(SQLiteDatabase db) { 2609315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS CalendarCache;"); 2610315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 2611315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio // IF NOT EXISTS should be normal pattern for table creation 26122cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TABLE IF NOT EXISTS CalendarCache (" + 26132cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id INTEGER PRIMARY KEY," + 26142cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "key TEXT NOT NULL," + 26152cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "value TEXT" + 2616315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio ");"); 2617315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 26182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarCache (" + 26192cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "key, " + 26202cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "value) VALUES (" + 26212cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'timezoneDatabaseVersion'," + 26222cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "'2009s'" + 2623315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio ");"); 2624ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 2625ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 2626ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion60(SQLiteDatabase db) { 2627ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // Switch to CalendarProvider2 2628d5aa3cc17ecda3d72882d9a2e6c48577892df903Ken Shirriff upgradeSyncState(db); 2629ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 26302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " + 2631ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "BEGIN " + 26322cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ("DELETE FROM Events" + 26332cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE calendar_id=old._id;") + 2634ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "END"); 26352cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 26362cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN deleted INTEGER NOT NULL DEFAULT 0;"); 2637ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS events_insert"); 26387cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio // Trigger to set event's sync_account 26392cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TRIGGER events_insert AFTER INSERT ON Events " + 2640ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "BEGIN " + 26412cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "UPDATE Events" + 26422cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " SET _sync_account=" + 26432cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (SELECT _sync_account FROM Calendars" + 26442cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE Calendars._id=new.calendar_id)," + 26452cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type=" + 26462cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " (SELECT _sync_account_type FROM Calendars" + 26472cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE Calendars._id=new.calendar_id) " + 26482cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "WHERE Events._id=new._id;" + 2649ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "END"); 2650ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TABLE IF EXISTS DeletedEvents;"); 2651ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS events_cleanup_delete"); 26527cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio // Trigger to remove data tied to an event when we delete that event. 26532cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TRIGGER events_cleanup_delete DELETE ON Events " + 2654ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "BEGIN " + 26552cff10f1a005bd7302245d4c680cf851193c3a97RoboErik ("DELETE FROM Instances" + 26562cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;" + 26572cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM EventsRawTimes" + 26582cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;" + 26592cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM Attendees" + 26602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;" + 26612cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM Reminders" + 26622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;" + 26632cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM CalendarAlerts" + 26642cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;" + 26652cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM ExtendedProperties" + 26662cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE event_id=old._id;") + 2667ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "END"); 2668ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS attendees_update"); 2669ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS attendees_insert"); 2670ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS attendees_delete"); 2671ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS reminders_update"); 2672ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS reminders_insert"); 2673ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS reminders_delete"); 2674ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS extended_properties_update"); 2675ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS extended_properties_insert"); 2676ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS extended_properties_delete"); 2677ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2678ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2679ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion59(SQLiteDatabase db) { 2680ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TABLE IF EXISTS BusyBits;"); 26812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TEMPORARY TABLE CalendarMetaData_Backup(" + 26822cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id," + 26832cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "localTimezone," + 26842cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "minInstance," + 26852cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "maxInstance" + 26867cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio ");"); 26872cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarMetaData_Backup " + 26887cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "SELECT " + 26892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id," + 26902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "localTimezone," + 26912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "minInstance," + 26922cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "maxInstance" + 26932cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM CalendarMetaData;"); 26942cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DROP TABLE CalendarMetaData;"); 26952cff10f1a005bd7302245d4c680cf851193c3a97RoboErik createCalendarMetaDataTable59(db); 26962cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("INSERT INTO CalendarMetaData " + 26977cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "SELECT " + 26982cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_id," + 26992cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "localTimezone," + 27002cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "minInstance," + 27012cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "maxInstance" + 27022cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM CalendarMetaData_Backup;"); 27032cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DROP TABLE CalendarMetaData_Backup;"); 2704ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2705ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2706ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion57(SQLiteDatabase db) { 27072cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 27082cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN guestsCanModify" + 27097cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " INTEGER NOT NULL DEFAULT 0;"); 27102cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 27112cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN guestsCanInviteOthers" + 27127cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " INTEGER NOT NULL DEFAULT 1;"); 27132cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 27142cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN guestsCanSeeGuests" + 27157cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " INTEGER NOT NULL DEFAULT 1;"); 27162cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 27172cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN organizer" + 27187cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " STRING;"); 27192cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events SET organizer=" + 27202cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "(SELECT attendeeEmail" + 27212cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM Attendees" + 27227cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " WHERE " + 27232cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "Attendees.event_id=" + 27242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "Events._id" + 27257cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio " AND " + 27262cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "Attendees.attendeeRelationship=2);"); 2727ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2728ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 27291599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio private void upgradeToVersion56(SQLiteDatabase db) { 27302cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars" + 27312cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " ADD COLUMN ownerAccount TEXT;"); 27322cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events" + 2733d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik " ADD COLUMN hasAttendeeData INTEGER NOT NULL DEFAULT 0;"); 27347cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 27351599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // Clear _sync_dirty to avoid a client-to-server sync that could blow away 27361599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // server attendees. 27371599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // Clear _sync_version to pull down the server's event (with attendees) 27381599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // Change the URLs from full-selfattendance to full 27392cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events" 27402cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " SET _sync_dirty=0, " 27412cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_version=NULL, " 27422cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_id=" 27432cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "REPLACE(_sync_id, " + 27447cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "'/private/full-selfattendance', '/private/full')," 27452cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "commentsUri=" 27462cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "REPLACE(commentsUri, " + 27477cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio "'/private/full-selfattendance', '/private/full');"); 27487cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio 27492cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Calendars" 27502cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " SET url=" 27512cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "REPLACE(url, '/private/full-selfattendance', '/private/full');"); 27521599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 27531599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // "cursor" iterates over all the calendars 27542cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor cursor = db.rawQuery("SELECT _id, " + 27552cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "url FROM Calendars", 27561599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio null /* selection args */); 27571599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // Add the owner column. 27581599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio if (cursor != null) { 27591599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio try { 27602cff10f1a005bd7302245d4c680cf851193c3a97RoboErik final String updateSql = "UPDATE Calendars" + 27612cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " SET ownerAccount=?" + 27622cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE _id=?"; 27631599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio while (cursor.moveToNext()) { 27641599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio Long id = cursor.getLong(0); 27651599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio String url = cursor.getString(1); 27661599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio String owner = calendarEmailAddressFromFeedUrl(url); 27677cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL(updateSql, new Object[] {owner, id}); 27681599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27691599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } finally { 27701599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio cursor.close(); 27711599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27721599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27731599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27741599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 27751599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio private void upgradeResync(SQLiteDatabase db) { 27761599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // Delete sync state, so all records will be re-synced. 27772cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("DELETE FROM _sync_state;"); 27781599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 27791599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio // "cursor" iterates over all the calendars 27802cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor cursor = db.rawQuery("SELECT _sync_account," + 27812cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type,url FROM Calendars", 27821599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio null /* selection args */); 27831599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio if (cursor != null) { 27841599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio try { 27851599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio while (cursor.moveToNext()) { 27861599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio String accountName = cursor.getString(0); 27871599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio String accountType = cursor.getString(1); 27881599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio final Account account = new Account(accountName, accountType); 27891599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio String calendarUrl = cursor.getString(2); 27901599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio scheduleSync(account, false /* two-way sync */, calendarUrl); 27911599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27921599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } finally { 27931599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio cursor.close(); 27941599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27951599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27961599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio } 27971599ceb270bc70f81dcaf8ecf4568453d7dddd9eFabrice Di Meglio 2798ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion55(SQLiteDatabase db) { 27992cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Calendars ADD COLUMN " + 28002cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type TEXT;"); 28012cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events ADD COLUMN " + 28022cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "_sync_account_type TEXT;"); 2803ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("ALTER TABLE DeletedEvents ADD COLUMN _sync_account_type TEXT;"); 28042cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Calendars" 28052cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " SET _sync_account_type='com.google'" 28062cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " WHERE _sync_account IS NOT NULL"); 28072cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events" 28082cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " SET _sync_account_type='com.google'" 28092cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + " WHERE _sync_account IS NOT NULL"); 2810ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("UPDATE DeletedEvents" 2811ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff + " SET _sync_account_type='com.google'" 2812ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff + " WHERE _sync_account IS NOT NULL"); 2813ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff Log.w(TAG, "re-creating eventSyncAccountAndIdIndex"); 2814ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP INDEX eventSyncAccountAndIdIndex"); 28152cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE INDEX eventSyncAccountAndIdIndex ON Events (" 28162cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_account_type, " 28172cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_account, " 28182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_id);"); 2819ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2820ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2821ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion54(SQLiteDatabase db) { 2822ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff Log.w(TAG, "adding eventSyncAccountAndIdIndex"); 2823ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("CREATE INDEX eventSyncAccountAndIdIndex ON Events (" 28242cff10f1a005bd7302245d4c680cf851193c3a97RoboErik + "_sync_account, _sync_id);"); 2825ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2826ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2827ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion53(SQLiteDatabase db) { 2828ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff Log.w(TAG, "Upgrading CalendarAlerts table"); 28292cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE CalendarAlerts ADD COLUMN " + 2830d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik "creationTime INTEGER NOT NULL DEFAULT 0;"); 28312cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE CalendarAlerts ADD COLUMN " + 2832d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik "receivedTime INTEGER NOT NULL DEFAULT 0;"); 28332cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE CalendarAlerts ADD COLUMN " + 2834d5f4742d7ba16d791edd9fd33a1a2a42eeac709bRoboErik "notifyTime INTEGER NOT NULL DEFAULT 0;"); 2835ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2836ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2837ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion52(SQLiteDatabase db) { 2838ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // We added "originalAllDay" to the Events table to keep track of 2839ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // the allDay status of the original recurring event for entries 2840ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // that are exceptions to that recurring event. We need this so 2841ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // that we can format the date correctly for the "originalInstanceTime" 2842ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // column when we make a change to the recurrence exception and 2843ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // send it to the server. 28442cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("ALTER TABLE Events ADD COLUMN " + 28452cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "originalAllDay INTEGER;"); 2846ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2847ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // Iterate through the Events table and for each recurrence 2848ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // exception, fill in the correct value for "originalAllDay", 2849ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // if possible. The only times where this might not be possible 2850ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // are (1) the original recurring event no longer exists, or 2851ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // (2) the original recurring event does not yet have a _sync_id 2852ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // because it was created on the phone and hasn't been synced to the 2853ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // server yet. In both cases the originalAllDay field will be set 2854ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // to null. In the first case we don't care because the recurrence 2855ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // exception will not be displayed and we won't be able to make 2856ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // any changes to it (and even if we did, the server should ignore 2857ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // them, right?). In the second case, the calendar client already 2858ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // disallows making changes to an instance of a recurring event 2859ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // until the recurring event has been synced to the server so the 2860ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // second case should never occur. 2861ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2862ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // "cursor" iterates over all the recurrences exceptions. 28632cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor cursor = db.rawQuery("SELECT _id," + 28642cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "originalEvent" + 28652cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM Events" + 28662cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE originalEvent IS NOT NULL", 28677cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio null /* selection args */); 2868ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff if (cursor != null) { 2869ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff try { 2870ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff while (cursor.moveToNext()) { 2871ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff long id = cursor.getLong(0); 2872ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff String originalEvent = cursor.getString(1); 2873ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2874ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // Find the original recurring event (if it exists) 28752cff10f1a005bd7302245d4c680cf851193c3a97RoboErik Cursor recur = db.rawQuery("SELECT allDay" + 28762cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " FROM Events" + 28772cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE _sync_id=?", 28787cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio new String[] {originalEvent}); 2879ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff if (recur == null) { 2880ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff continue; 2881ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2882ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2883ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff try { 2884ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // Fill in the "originalAllDay" field of the 2885ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // recurrence exception with the "allDay" value 2886ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // from the recurring event. 2887ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff if (recur.moveToNext()) { 2888ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff int allDay = recur.getInt(0); 28892cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("UPDATE Events" + 28902cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " SET originalAllDay=" + allDay + 28912cff10f1a005bd7302245d4c680cf851193c3a97RoboErik " WHERE _id="+id); 2892ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2893ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } finally { 2894ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff recur.close(); 2895ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2896ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2897ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } finally { 2898ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff cursor.close(); 2899ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 29009f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29019f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29029f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 2903ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff private void upgradeToVersion51(SQLiteDatabase db) { 2904ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff Log.w(TAG, "Upgrading DeletedEvents table"); 2905ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2906ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // We don't have enough information to fill in the correct 2907ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // value of the calendar_id for old rows in the DeletedEvents 2908ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // table, but rows in that table are transient so it is unlikely 2909ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // that there are any rows. Plus, the calendar_id is used only 2910ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // when deleting a calendar, which is a rare event. All new rows 2911ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // will have the correct calendar_id. 2912ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("ALTER TABLE DeletedEvents ADD COLUMN calendar_id INTEGER;"); 2913ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 2914ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff // Trigger to remove a calendar's events when we delete the calendar 2915ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS calendar_cleanup"); 29162cff10f1a005bd7302245d4c680cf851193c3a97RoboErik db.execSQL("CREATE TRIGGER calendar_cleanup DELETE ON Calendars " + 2917ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "BEGIN " + 29182cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "DELETE FROM Events WHERE calendar_id=" + 29192cff10f1a005bd7302245d4c680cf851193c3a97RoboErik "old._id;" + 2920ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "DELETE FROM DeletedEvents WHERE calendar_id = old._id;" + 2921ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff "END"); 2922ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff db.execSQL("DROP TRIGGER IF EXISTS event_to_deleted"); 2923ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff } 2924ad37c99d051aa4e2508b940c8dec91ee87f53056Ken Shirriff 29259f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff private void dropTables(SQLiteDatabase db) { 29262f251c778c06d21ed7693a70f4a1268ff929242eRoboErik db.execSQL("DROP TABLE IF EXISTS " + Tables.COLORS + ";"); 29277cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.CALENDARS + ";"); 29287cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.EVENTS + ";"); 29297cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.EVENTS_RAW_TIMES + ";"); 29307cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.INSTANCES + ";"); 29317cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.CALENDAR_META_DATA + ";"); 29327cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.CALENDAR_CACHE + ";"); 29337cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.ATTENDEES + ";"); 29347cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.REMINDERS + ";"); 29357cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.CALENDAR_ALERTS + ";"); 29367cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio db.execSQL("DROP TABLE IF EXISTS " + Tables.EXTENDED_PROPERTIES + ";"); 29379f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29389f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 29399f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff @Override 29409f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public synchronized SQLiteDatabase getWritableDatabase() { 29419f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff SQLiteDatabase db = super.getWritableDatabase(); 29429f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return db; 29439f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29449f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 29459f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff public SyncStateContentProviderHelper getSyncState() { 29469f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff return mSyncState; 29479f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29489f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 29499f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff /** 29509f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * Schedule a calendar sync for the account. 29519f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * @param account the account for which to schedule a sync 29529f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff * @param uploadChangesOnly if set, specify that the sync should only send 29537e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff * up local changes. This is typically used for a local sync, a user override of 29547e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff * too many deletions, or a sync after a calendar is unselected. 29557e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff * @param url the url feed for the calendar to sync (may be null, in which case a poll of 29567e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff * all feeds is done.) 29579f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff */ 29589f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff void scheduleSync(Account account, boolean uploadChangesOnly, String url) { 29599f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff Bundle extras = new Bundle(); 29607e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff if (uploadChangesOnly) { 29617e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, uploadChangesOnly); 29627e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff } 29639f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff if (url != null) { 29649f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff extras.putString("feed", url); 29659f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 29669f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 2967b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik ContentResolver.requestSync(account, CalendarContract.Calendars.CONTENT_URI.getAuthority(), 2968b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik extras); 29699f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff } 29709f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff 29717e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff private static void createEventsView(SQLiteDatabase db) { 29727e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff db.execSQL("DROP VIEW IF EXISTS " + Views.EVENTS + ";"); 29737e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff String eventsSelect = "SELECT " 2974b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.EVENTS + "." + CalendarContract.Events._ID 2975b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events._ID + "," 2976b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.TITLE + "," 2977b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.DESCRIPTION + "," 2978b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EVENT_LOCATION + "," 2979b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EVENT_COLOR + "," 2980387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + CalendarContract.Events.EVENT_COLOR_KEY + "," 2981b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.STATUS + "," 2982b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SELF_ATTENDEE_STATUS + "," 2983b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.DTSTART + "," 2984b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.DTEND + "," 2985b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.DURATION + "," 2986b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EVENT_TIMEZONE + "," 2987b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EVENT_END_TIMEZONE + "," 2988b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ALL_DAY + "," 2989b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ACCESS_LEVEL + "," 2990b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.AVAILABILITY + "," 2991b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.HAS_ALARM + "," 2992b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.HAS_EXTENDED_PROPERTIES + "," 2993b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.RRULE + "," 2994b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.RDATE + "," 2995b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EXRULE + "," 2996b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.EXDATE + "," 2997b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ORIGINAL_SYNC_ID + "," 2998b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ORIGINAL_ID + "," 2999b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ORIGINAL_INSTANCE_TIME + "," 3000b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ORIGINAL_ALL_DAY + "," 3001b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.LAST_DATE + "," 3002b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.HAS_ATTENDEE_DATA + "," 3003b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.CALENDAR_ID + "," 3004b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.GUESTS_CAN_INVITE_OTHERS + "," 3005b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.GUESTS_CAN_MODIFY + "," 3006b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.GUESTS_CAN_SEE_GUESTS + "," 3007b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.ORGANIZER + "," 3008b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA1 + "," 3009b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA2 + "," 3010b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA3 + "," 3011b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA4 + "," 3012b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA5 + "," 3013b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA6 + "," 3014b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA7 + "," 3015b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA8 + "," 3016b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA9 + "," 3017b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.SYNC_DATA10 + "," 3018b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.EVENTS + "." + CalendarContract.Events.DELETED 3019b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events.DELETED + "," 3020b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.EVENTS + "." + CalendarContract.Events._SYNC_ID 3021b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events._SYNC_ID + "," 3022b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.EVENTS + "." + CalendarContract.Events.DIRTY 3023b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events.DIRTY + "," 3024b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Events.LAST_SYNCED + "," 3025b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.CALENDARS + "." + CalendarContract.Calendars.ACCOUNT_NAME 3026b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events.ACCOUNT_NAME + "," 3027b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + Tables.CALENDARS + "." + CalendarContract.Calendars.ACCOUNT_TYPE 3028b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " AS " + CalendarContract.Events.ACCOUNT_TYPE + "," 3029b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CALENDAR_TIME_ZONE + "," 3030b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + "," 3031b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CALENDAR_LOCATION + "," 3032b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.VISIBLE + "," 3033b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CALENDAR_COLOR + "," 3034387535fec9f646e0b7acb82d5354f2b5ebee4395RoboErik + CalendarContract.Calendars.CALENDAR_COLOR_KEY + "," 3035b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL + "," 3036b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.MAX_REMINDERS + "," 3037b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.ALLOWED_REMINDERS + "," 30382f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES + "," 30392f251c778c06d21ed7693a70f4a1268ff929242eRoboErik + CalendarContract.Calendars.ALLOWED_AVAILABILITY + "," 3040b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAN_ORGANIZER_RESPOND + "," 3041b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAN_MODIFY_TIME_ZONE + "," 3042b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAN_PARTIALLY_UPDATE + "," 3043b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC1 + "," 3044b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC2 + "," 3045b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC3 + "," 3046b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC4 + "," 3047b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC5 + "," 3048b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC6 + "," 3049b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC7 + "," 3050b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC8 + "," 3051b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC9 + "," 3052b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAL_SYNC10 + "," 3053b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.OWNER_ACCOUNT + "," 3054b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.SYNC_EVENTS 30557e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff + " FROM " + Tables.EVENTS + " JOIN " + Tables.CALENDARS 3056b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " ON (" + Tables.EVENTS + "." + CalendarContract.Events.CALENDAR_ID 3057b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + "=" + Tables.CALENDARS + "." + CalendarContract.Calendars._ID 30587e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff + ")"; 30597e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff 30607e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff db.execSQL("CREATE VIEW " + Views.EVENTS + " AS " + eventsSelect); 30617e3ec5f2025164fca508f81a5a01940bc912e064Ken Shirriff } 3062d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff 3063d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff /** 3064d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff * Extracts the calendar email from a calendar feed url. 3065d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff * @param feed the calendar feed url 3066d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff * @return the calendar email that is in the feed url or null if it can't 3067d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff * find the email address. 3068d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff * TODO: this is duplicated in CalendarSyncAdapter; move to a library 3069d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff */ 3070d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff public static String calendarEmailAddressFromFeedUrl(String feed) { 3071d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff // Example feed url: 3072d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff // https://www.google.com/calendar/feeds/foo%40gmail.com/private/full-noattendees 3073d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff String[] pathComponents = feed.split("/"); 3074d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff if (pathComponents.length > 5 && "feeds".equals(pathComponents[4])) { 3075d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff try { 3076d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff return URLDecoder.decode(pathComponents[5], "UTF-8"); 3077d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff } catch (UnsupportedEncodingException e) { 3078d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff Log.e(TAG, "unable to url decode the email address in calendar " + feed); 3079d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff return null; 3080d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff } 3081d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff } 3082d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff 3083d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff Log.e(TAG, "unable to find the email address in calendar " + feed); 3084d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff return null; 3085d39cfe09aa7e752cdc7512ae58d90d49d4b5ef9eKen Shirriff } 30861b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 30871b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio /** 30881b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * Get a "allcalendars" url from a "private/full" or "private/free-busy" url 30891b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @param url 30901b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @return the rewritten Url 30911b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * 30921b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * For example: 30931b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * 30941b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * http://www.google.com/calendar/feeds/joe%40joe.com/private/full 30951b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * http://www.google.com/calendar/feeds/joe%40joe.com/private/free-busy 30961b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * 30971b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * will be rewriten into: 30981b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * 30991b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * http://www.google.com/calendar/feeds/default/allcalendars/full/joe%40joe.com 31001b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * http://www.google.com/calendar/feeds/default/allcalendars/full/joe%40joe.com 31011b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio */ 31021b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio @VisibleForTesting 31031b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static String getAllCalendarsUrlFromEventsUrl(String url) { 31041b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (url == null) { 31051b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (Log.isLoggable(TAG, Log.DEBUG)) { 31061b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Log.d(TAG, "Cannot get AllCalendars url from a NULL url"); 31071b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31081b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return null; 31091b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31101b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (url.contains("/private/full")) { 31111b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return url.replace("/private/full", ""). 31121b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio replace("/calendar/feeds", "/calendar/feeds/default/allcalendars/full"); 31131b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31141b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (url.contains("/private/free-busy")) { 31151b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return url.replace("/private/free-busy", ""). 31161b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio replace("/calendar/feeds", "/calendar/feeds/default/allcalendars/full"); 31171b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31181b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio // Just log as we dont recognize the provided Url 31191b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (Log.isLoggable(TAG, Log.DEBUG)) { 31201b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Log.d(TAG, "Cannot get AllCalendars url from the following url: " + url); 31211b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31221b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return null; 31231b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31241b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 31251b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio /** 31261b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * Get "selfUrl" from "events url" 31271b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @param url the Events url (either "private/full" or "private/free-busy" 31281b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @return the corresponding allcalendar url 31291b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio */ 31301b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static String getSelfUrlFromEventsUrl(String url) { 31311b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return rewriteUrlFromHttpToHttps(getAllCalendarsUrlFromEventsUrl(url)); 31321b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31331b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 31341b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio /** 31351b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * Get "editUrl" from "events url" 31361b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @param url the Events url (either "private/full" or "private/free-busy" 31371b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @return the corresponding allcalendar url 31381b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio */ 31391b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static String getEditUrlFromEventsUrl(String url) { 31401b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return rewriteUrlFromHttpToHttps(getAllCalendarsUrlFromEventsUrl(url)); 31411b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31421b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio 31431b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio /** 31441b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * Rewrite the url from "http" to "https" scheme 31451b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @param url the url to rewrite 31461b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio * @return the rewritten URL 31471b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio */ 31481b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio private static String rewriteUrlFromHttpToHttps(String url) { 31491b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (url == null) { 31501b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (Log.isLoggable(TAG, Log.DEBUG)) { 31511b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio Log.d(TAG, "Cannot rewrite a NULL url"); 31521b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31531b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return null; 31541b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31551b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (url.startsWith(SCHEMA_HTTPS)) { 31561b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return url; 31571b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31581b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio if (!url.startsWith(SCHEMA_HTTP)) { 31591b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio throw new IllegalArgumentException("invalid url parameter, unknown scheme: " + url); 31601b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31611b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio return SCHEMA_HTTPS + url.substring(SCHEMA_HTTP.length()); 31621b6beb61ef04c3da6ab0bdf8504ffecea2b9534cFabrice Di Meglio } 31639ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 31641c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden /** 31651c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * Duplicates an event and its associated tables (Attendees, Reminders, ExtendedProperties). 31661c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * <p> 31671c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * Does not create a duplicate if the Calendar's "canPartiallyUpdate" is 0 or the Event's 31681c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * "dirty" is 1 (so we don't create more than one duplicate). 31691c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * 31701c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * @param id The _id of the event to duplicate. 31711c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden */ 31729ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert protected void duplicateEvent(final long id) { 31739ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert final SQLiteDatabase db = getWritableDatabase(); 3174b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik final long canPartiallyUpdate = DatabaseUtils.longForQuery(db, "SELECT " 3175b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + CalendarContract.Calendars.CAN_PARTIALLY_UPDATE + " FROM " + Views.EVENTS 3176b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " WHERE " + Events._ID + " = ?", new String[] { 3177b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik String.valueOf(id) 3178b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik }); 31799ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (canPartiallyUpdate == 0) { 31809ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert return; 31819ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 31829ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 31839ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("INSERT INTO " + CalendarDatabaseHelper.Tables.EVENTS 31849ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " (" + LAST_SYNCED_EVENT_COLUMNS + "," 31859ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + Events.DIRTY + "," + Events.LAST_SYNCED + ")" 31869ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " SELECT " + LAST_SYNCED_EVENT_COLUMNS + ", 0, 1" 31879ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " FROM " + Tables.EVENTS 31889ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " WHERE " + Events._ID + " = ? AND " + Events.DIRTY + " = ?", 31899ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert new Object[]{ 31909ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert id, 31919ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 0, // Events.DIRTY 31929ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert }); 31939ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert final long newId = DatabaseUtils.longForQuery( 31949ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db, "SELECT CASE changes() WHEN 0 THEN -1 ELSE last_insert_rowid() END", null); 31959ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (newId < 0) { 31969ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert return; 31979ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 31989ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 31999ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (Log.isLoggable(TAG, Log.VERBOSE)) { 32009ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert Log.v(TAG, "Duplicating event " + id + " into new event " + newId); 32019ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32029ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 3203bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden copyEventRelatedTables(db, newId, id); 3204bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden } 3205bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden 32061c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden /** 32071c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * Makes a copy of the Attendees, Reminders, and ExtendedProperties rows associated with 32081c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * a specific event. 32091c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * 32101c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * @param db The database. 32111c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * @param newId The ID of the new event. 32121c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden * @param id The ID of the old event. 32131c72909abbfe7559bcc880c339399f1eaa0478f3Andy McFadden */ 3214bcba82631ab0ee16efe58f0e0b0b9c18d93a6fd2Andy McFadden static void copyEventRelatedTables(SQLiteDatabase db, long newId, long id) { 32159ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("INSERT INTO " + Tables.REMINDERS 3216b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " ( " + CalendarContract.Reminders.EVENT_ID + ", " 3217b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + LAST_SYNCED_REMINDER_COLUMNS + ") " 32189ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + "SELECT ?," + LAST_SYNCED_REMINDER_COLUMNS 32199ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " FROM " + Tables.REMINDERS 3220b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " WHERE " + CalendarContract.Reminders.EVENT_ID + " = ?", 32219ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert new Object[] {newId, id}); 32229ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("INSERT INTO " 32239ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + Tables.ATTENDEES 3224b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " (" + CalendarContract.Attendees.EVENT_ID + "," 3225b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + LAST_SYNCED_ATTENDEE_COLUMNS + ") " 32269ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + "SELECT ?," + LAST_SYNCED_ATTENDEE_COLUMNS + " FROM " + Tables.ATTENDEES 3227b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " WHERE " + CalendarContract.Attendees.EVENT_ID + " = ?", 32289ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert new Object[] {newId, id}); 32299ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("INSERT INTO " + Tables.EXTENDED_PROPERTIES 3230b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " (" + CalendarContract.ExtendedProperties.EVENT_ID + "," 32319ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + LAST_SYNCED_EXTENDED_PROPERTY_COLUMNS + ") " 32329ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + "SELECT ?, " + LAST_SYNCED_EXTENDED_PROPERTY_COLUMNS 32339ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " FROM " + Tables.EXTENDED_PROPERTIES 3234b9644fe24edf9e25f0b21c1394e88d25070e0238RoboErik + " WHERE " + CalendarContract.ExtendedProperties.EVENT_ID + " = ?", 32359ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert new Object[]{newId, id}); 32369ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32379ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 32389ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert protected void removeDuplicateEvent(final long id) { 32399ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert final SQLiteDatabase db = getWritableDatabase(); 32409ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert final Cursor cursor = db.rawQuery("SELECT " + Events._ID + " FROM " + Tables.EVENTS 32419ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " WHERE " + Events._SYNC_ID 32429ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " = (SELECT " + Events._SYNC_ID 32439ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " FROM " + Tables.EVENTS 32449ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + " WHERE " + Events._ID + " = ?) " 32459ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert + "AND " + Events.LAST_SYNCED + " = ?", 32469ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert new String[]{ 32479ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert String.valueOf(id), 32489ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert "1", // Events.LAST_SYNCED 32499ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert }); 32509ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert try { 32519ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // there should only be at most one but this can't hurt 32529ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (cursor.moveToNext()) { 32539ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert final long dupId = cursor.getLong(0); 32549ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert 32559ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert if (Log.isLoggable(TAG, Log.VERBOSE)) { 32569ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert Log.v(TAG, "Removing duplicate event " + dupId + " of original event " + id); 32579ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32589ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert // triggers will clean up related tables. 32599ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert db.execSQL("DELETE FROM Events WHERE " + Events._ID + " = ?", new Object[]{dupId}); 32609ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32619ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } finally { 32629ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert cursor.close(); 32639ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32649ec70fada3d8f7cf56d6b0d0947823ec5bce572cAlon Albert } 32659f005e4843925efe4fa8434361c4ad4ad384ed4cKen Shirriff} 3266