MmsSmsDatabaseHelper.java revision 62f78e4e0ae991f0df285488a1af382bd5105483
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.providers.telephony; 18 19import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_DELIVERY_IND; 20import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; 21import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_ORIG_IND; 22import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_READ_REC_IND; 23import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF; 24import static com.google.android.mms.pdu.PduHeaders.MESSAGE_TYPE_SEND_REQ; 25 26import android.content.Context; 27import android.database.Cursor; 28import android.database.sqlite.SQLiteDatabase; 29import android.database.sqlite.SQLiteOpenHelper; 30import android.provider.BaseColumns; 31import android.provider.Telephony.Mms; 32import android.provider.Telephony.MmsSms; 33import android.provider.Telephony.Sms; 34import android.provider.Telephony.Threads; 35import android.provider.Telephony.Mms.Addr; 36import android.provider.Telephony.Mms.Part; 37import android.provider.Telephony.Mms.Rate; 38import android.provider.Telephony.MmsSms.PendingMessages; 39import android.util.Log; 40 41public class MmsSmsDatabaseHelper extends SQLiteOpenHelper { 42 private static final String TAG = "MmsSmsDatabaseHelper"; 43 44 private static final String SMS_UPDATE_THREAD_READ_BODY = 45 " UPDATE threads SET read = " + 46 " CASE (SELECT COUNT(*)" + 47 " FROM sms" + 48 " WHERE " + Sms.READ + " = 0" + 49 " AND " + Sms.THREAD_ID + " = threads._id)" + 50 " WHEN 0 THEN 1" + 51 " ELSE 0" + 52 " END" + 53 " WHERE threads._id = new." + Sms.THREAD_ID + "; "; 54 55 private static final String UPDATE_THREAD_COUNT_ON_NEW = 56 " UPDATE threads SET message_count = " + 57 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 58 " ON threads._id = " + Sms.THREAD_ID + 59 " WHERE " + Sms.THREAD_ID + " = new.thread_id" + 60 " AND sms." + Sms.TYPE + " != 3) + " + 61 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 62 " ON threads._id = " + Mms.THREAD_ID + 63 " WHERE " + Mms.THREAD_ID + " = new.thread_id" + 64 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 65 " AND " + Mms.MESSAGE_BOX + " != 3) " + 66 " WHERE threads._id = new.thread_id; "; 67 68 private static final String UPDATE_THREAD_COUNT_ON_OLD = 69 " UPDATE threads SET message_count = " + 70 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 71 " ON threads._id = " + Sms.THREAD_ID + 72 " WHERE " + Sms.THREAD_ID + " = old.thread_id" + 73 " AND sms." + Sms.TYPE + " != 3) + " + 74 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 75 " ON threads._id = " + Mms.THREAD_ID + 76 " WHERE " + Mms.THREAD_ID + " = old.thread_id" + 77 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 78 " AND " + Mms.MESSAGE_BOX + " != 3) " + 79 " WHERE threads._id = old.thread_id; "; 80 81 private static final String SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE = 82 "BEGIN" + 83 " UPDATE threads SET" + 84 " date = (strftime('%s','now') * 1000), " + 85 " snippet = new." + Sms.BODY + ", " + 86 " snippet_cs = 0" + 87 " WHERE threads._id = new." + Sms.THREAD_ID + "; " + 88 UPDATE_THREAD_COUNT_ON_NEW + 89 SMS_UPDATE_THREAD_READ_BODY + 90 "END;"; 91 92 private static final String PDU_UPDATE_THREAD_CONSTRAINTS = 93 " WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_RETRIEVE_CONF + 94 " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND + 95 " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ + " "; 96 97 private static final String PDU_UPDATE_THREAD_READ_BODY = 98 " UPDATE threads SET read = " + 99 " CASE (SELECT COUNT(*)" + 100 " FROM " + MmsProvider.TABLE_PDU + 101 " WHERE " + Mms.READ + " = 0" + 102 " AND " + Mms.THREAD_ID + " = threads._id)" + 103 " WHEN 0 THEN 1" + 104 " ELSE 0" + 105 " END" + 106 " WHERE threads._id = new." + Mms.THREAD_ID + "; "; 107 108 private static final String PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE = 109 "BEGIN" + 110 " UPDATE threads SET" + 111 " date = (strftime('%s','now') * 1000), " + 112 " snippet = new." + Mms.SUBJECT + ", " + 113 " snippet_cs = new." + Mms.SUBJECT_CHARSET + 114 " WHERE threads._id = new." + Mms.THREAD_ID + "; " + 115 UPDATE_THREAD_COUNT_ON_NEW + 116 PDU_UPDATE_THREAD_READ_BODY + 117 "END;"; 118 119 private static final String UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE = 120 " UPDATE threads SET snippet = " + 121 " (SELECT snippet FROM" + 122 " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" + 123 " UNION SELECT date, body AS snippet, thread_id FROM sms)" + 124 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 125 " WHERE threads._id = OLD.thread_id; " + 126 " UPDATE threads SET snippet_cs = " + 127 " (SELECT snippet_cs FROM" + 128 " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" + 129 " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" + 130 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 131 " WHERE threads._id = OLD.thread_id; "; 132 133 private static MmsSmsDatabaseHelper mInstance = null; 134 135 static final String DATABASE_NAME = "mmssms.db"; 136 static final int DATABASE_VERSION = 41; 137 138 private MmsSmsDatabaseHelper(Context context) { 139 super(context, DATABASE_NAME, null, DATABASE_VERSION); 140 } 141 142 /** 143 * Return a singleton helper for the combined MMS and SMS 144 * database. 145 */ 146 /* package */ static synchronized MmsSmsDatabaseHelper getInstance(Context context) { 147 if (mInstance == null) { 148 mInstance = new MmsSmsDatabaseHelper(context); 149 } 150 return mInstance; 151 } 152 153 public static void updateThread(SQLiteDatabase db, long thread_id) { 154 if (thread_id < 0) { 155 updateAllThreads(db); 156 return; 157 } 158 159 // Delete the row for this thread in the threads table if 160 // there are no more messages attached to it in either 161 // the sms or pdu tables. 162 int rows = db.delete("threads", 163 "_id = ? AND _id NOT IN" + 164 " (SELECT thread_id FROM sms " + 165 " UNION SELECT thread_id FROM pdu)", 166 new String[] { String.valueOf(thread_id) }); 167 if (rows > 0) { 168 // If this deleted a row, we have no more work to do. 169 return; 170 } 171 // Update the message count in the threads table as the sum 172 // of all messages in both the sms and pdu tables. 173 db.execSQL( 174 " UPDATE threads SET message_count = " + 175 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 176 " ON threads._id = " + Sms.THREAD_ID + 177 " WHERE " + Sms.THREAD_ID + " = " + thread_id + 178 " AND sms." + Sms.TYPE + " != 3) + " + 179 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 180 " ON threads._id = " + Mms.THREAD_ID + 181 " WHERE " + Mms.THREAD_ID + " = " + thread_id + 182 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 183 " AND " + Mms.MESSAGE_BOX + " != 3) " + 184 " WHERE threads._id = " + thread_id + ";"); 185 186 // Update the date and the snippet (and its character set) in 187 // the threads table to be that of the most recent message in 188 // the thread. 189 db.execSQL( 190 " UPDATE threads" + 191 " SET" + 192 " date =" + 193 " (SELECT date FROM" + 194 " (SELECT date * 1000 AS date, thread_id FROM pdu" + 195 " UNION SELECT date, thread_id FROM sms)" + 196 " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)," + 197 " snippet =" + 198 " (SELECT snippet FROM" + 199 " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" + 200 " UNION SELECT date, body AS snippet, thread_id FROM sms)" + 201 " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)," + 202 " snippet_cs =" + 203 " (SELECT snippet_cs FROM" + 204 " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" + 205 " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" + 206 " WHERE thread_id = " + thread_id + " ORDER BY date DESC LIMIT 1)" + 207 " WHERE threads._id = " + thread_id + ";"); 208 209 // Update the error column of the thread to indicate if there 210 // are any messages in it that have failed to send. 211 db.execSQL( 212 "UPDATE threads SET error =" + 213 " (SELECT COUNT(*) FROM sms WHERE type=5" + 214 " AND thread_id = " + thread_id + " LIMIT 1)" + 215 " WHERE threads._id = " + thread_id + ";"); 216 } 217 218 public static void updateAllThreads(SQLiteDatabase db) { 219 Cursor c = db.query("threads", new String[] { "_id" }, 220 null, null, null, null, null); 221 if (c != null) { 222 while (c.moveToNext()) { 223 updateThread(db, c.getInt(0)); 224 } 225 c.close(); 226 } 227 } 228 229 public static int deleteOneSms(SQLiteDatabase db, int message_id) { 230 int thread_id = -1; 231 // Find the thread ID that the specified SMS belongs to. 232 Cursor c = db.query("sms", new String[] { "thread_id" }, 233 "_id=" + message_id, null, null, null, null); 234 if (c != null) { 235 if (c.moveToFirst()) { 236 thread_id = c.getInt(0); 237 } 238 c.close(); 239 } 240 241 // Delete the specified message. 242 int rows = db.delete("sms", "_id=" + message_id, null); 243 if (thread_id > 0) { 244 // Update its thread. 245 updateThread(db, thread_id); 246 } 247 return rows; 248 } 249 250 @Override 251 public void onCreate(SQLiteDatabase db) { 252 createMmsTables(db); 253 createSmsTables(db); 254 createCommonTables(db); 255 createCommonTriggers(db); 256 createMmsTriggers(db); 257 } 258 259 private void createMmsTables(SQLiteDatabase db) { 260 // N.B.: Whenever the columns here are changed, the columns in 261 // {@ref MmsSmsProvider} must be changed to match. 262 db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PDU + " (" + 263 Mms._ID + " INTEGER PRIMARY KEY," + 264 Mms.THREAD_ID + " INTEGER," + 265 Mms.DATE + " INTEGER," + 266 Mms.MESSAGE_BOX + " INTEGER," + 267 Mms.READ + " INTEGER DEFAULT 0," + 268 Mms.MESSAGE_ID + " TEXT," + 269 Mms.SUBJECT + " TEXT," + 270 Mms.SUBJECT_CHARSET + " INTEGER," + 271 Mms.CONTENT_TYPE + " TEXT," + 272 Mms.CONTENT_LOCATION + " TEXT," + 273 Mms.EXPIRY + " INTEGER," + 274 Mms.MESSAGE_CLASS + " TEXT," + 275 Mms.MESSAGE_TYPE + " INTEGER," + 276 Mms.MMS_VERSION + " INTEGER," + 277 Mms.MESSAGE_SIZE + " INTEGER," + 278 Mms.PRIORITY + " INTEGER," + 279 Mms.READ_REPORT + " INTEGER," + 280 Mms.REPORT_ALLOWED + " INTEGER," + 281 Mms.RESPONSE_STATUS + " INTEGER," + 282 Mms.STATUS + " INTEGER," + 283 Mms.TRANSACTION_ID + " TEXT," + 284 Mms.RETRIEVE_STATUS + " INTEGER," + 285 Mms.RETRIEVE_TEXT + " TEXT," + 286 Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," + 287 Mms.READ_STATUS + " INTEGER," + 288 Mms.CONTENT_CLASS + " INTEGER," + 289 Mms.RESPONSE_TEXT + " TEXT," + 290 Mms.DELIVERY_TIME + " INTEGER," + 291 Mms.DELIVERY_REPORT + " INTEGER);"); 292 293 db.execSQL("CREATE TABLE " + MmsProvider.TABLE_ADDR + " (" + 294 Addr._ID + " INTEGER PRIMARY KEY," + 295 Addr.MSG_ID + " INTEGER," + 296 Addr.CONTACT_ID + " INTEGER," + 297 Addr.ADDRESS + " TEXT," + 298 Addr.TYPE + " INTEGER," + 299 Addr.CHARSET + " INTEGER);"); 300 301 db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PART + " (" + 302 Part._ID + " INTEGER PRIMARY KEY," + 303 Part.MSG_ID + " INTEGER," + 304 Part.SEQ + " INTEGER DEFAULT 0," + 305 Part.CONTENT_TYPE + " TEXT," + 306 Part.NAME + " TEXT," + 307 Part.CHARSET + " INTEGER," + 308 Part.CONTENT_DISPOSITION + " TEXT," + 309 Part.FILENAME + " TEXT," + 310 Part.CONTENT_ID + " TEXT," + 311 Part.CONTENT_LOCATION + " TEXT," + 312 Part.CT_START + " INTEGER," + 313 Part.CT_TYPE + " TEXT," + 314 Part._DATA + " TEXT);"); 315 316 db.execSQL("CREATE TABLE " + MmsProvider.TABLE_RATE + " (" + 317 Rate.SENT_TIME + " INTEGER);"); 318 319 db.execSQL("CREATE TABLE " + MmsProvider.TABLE_DRM + " (" + 320 BaseColumns._ID + " INTEGER PRIMARY KEY," + 321 "_data TEXT);"); 322 } 323 324 private void createMmsTriggers(SQLiteDatabase db) { 325 // Cleans up parts when a MM is deleted. 326 db.execSQL("CREATE TRIGGER part_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " + 327 "BEGIN " + 328 " DELETE FROM " + MmsProvider.TABLE_PART + 329 " WHERE " + Part.MSG_ID + "=old._id;" + 330 "END;"); 331 332 // Cleans up address info when a MM is deleted. 333 db.execSQL("CREATE TRIGGER addr_cleanup DELETE ON " + MmsProvider.TABLE_PDU + " " + 334 "BEGIN " + 335 " DELETE FROM " + MmsProvider.TABLE_ADDR + 336 " WHERE " + Addr.MSG_ID + "=old._id;" + 337 "END;"); 338 339 // Delete obsolete delivery-report, read-report while deleting their 340 // associated Send.req. 341 db.execSQL("CREATE TRIGGER cleanup_delivery_and_read_report " + 342 "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " + 343 "WHEN old." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ + " " + 344 "BEGIN " + 345 " DELETE FROM " + MmsProvider.TABLE_PDU + 346 " WHERE (" + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_DELIVERY_IND + 347 " OR " + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_READ_ORIG_IND + ")" + 348 " AND " + Mms.MESSAGE_ID + "=old." + Mms.MESSAGE_ID + "; " + 349 "END;"); 350 } 351 352 private void createSmsTables(SQLiteDatabase db) { 353 // N.B.: Whenever the columns here are changed, the columns in 354 // {@ref MmsSmsProvider} must be changed to match. 355 db.execSQL("CREATE TABLE sms (" + 356 "_id INTEGER PRIMARY KEY," + 357 "thread_id INTEGER," + 358 "address TEXT," + 359 "person INTEGER," + 360 "date INTEGER," + 361 "protocol INTEGER," + 362 "read INTEGER DEFAULT 0," + 363 "status INTEGER DEFAULT -1," + // a TP-Status value 364 // or -1 if it 365 // status hasn't 366 // been received 367 "type INTEGER," + 368 "reply_path_present INTEGER," + 369 "subject TEXT," + 370 "body TEXT," + 371 "service_center TEXT);"); 372 373 /** 374 * This table is used by the SMS dispatcher to hold 375 * incomplete partial messages until all the parts arrive. 376 */ 377 db.execSQL("CREATE TABLE raw (" + 378 "_id INTEGER PRIMARY KEY," + 379 "date INTEGER," + 380 "reference_number INTEGER," + // one per full message 381 "count INTEGER," + // the number of parts 382 "sequence INTEGER," + // the part number of this message 383 "destination_port INTEGER," + 384 "address TEXT," + 385 "pdu TEXT);"); // the raw PDU for this part 386 387 db.execSQL("CREATE TABLE attachments (" + 388 "sms_id INTEGER," + 389 "content_url TEXT," + 390 "offset INTEGER);"); 391 392 /** 393 * This table is used by the SMS dispatcher to hold pending 394 * delivery status report intents. 395 */ 396 db.execSQL("CREATE TABLE sr_pending (" + 397 "reference_number INTEGER," + 398 "action TEXT," + 399 "data TEXT);"); 400 } 401 402 private void createCommonTables(SQLiteDatabase db) { 403 // TODO Ensure that each entry is removed when the last use of 404 // any address equivalent to its address is removed. 405 406 /** 407 * This table maps the first instance seen of any particular 408 * MMS/SMS address to an ID, which is then used as its 409 * canonical representation. If the same address or an 410 * equivalent address (as determined by our Sqlite 411 * PHONE_NUMBERS_EQUAL extension) is seen later, this same ID 412 * will be used. 413 */ 414 db.execSQL("CREATE TABLE canonical_addresses (" + 415 "_id INTEGER PRIMARY KEY," + 416 "address TEXT);"); 417 418 /** 419 * This table maps the subject and an ordered set of recipient 420 * IDs, separated by spaces, to a unique thread ID. The IDs 421 * come from the canonical_addresses table. This works 422 * because messages are considered to be part of the same 423 * thread if they have the same subject (or a null subject) 424 * and the same set of recipients. 425 */ 426 db.execSQL("CREATE TABLE threads (" + 427 Threads._ID + " INTEGER PRIMARY KEY," + 428 Threads.DATE + " INTEGER DEFAULT 0," + 429 Threads.MESSAGE_COUNT + " INTEGER DEFAULT 0," + 430 Threads.RECIPIENT_IDS + " TEXT," + 431 Threads.SNIPPET + " TEXT," + 432 Threads.SNIPPET_CHARSET + " INTEGER DEFAULT 0," + 433 Threads.READ + " INTEGER DEFAULT 1," + 434 Threads.TYPE + " INTEGER DEFAULT 0," + 435 Threads.ERROR + " INTEGER DEFAULT 0);"); 436 437 /** 438 * This table stores the queue of messages to be sent/downloaded. 439 */ 440 db.execSQL("CREATE TABLE " + MmsSmsProvider.TABLE_PENDING_MSG +" (" + 441 PendingMessages._ID + " INTEGER PRIMARY KEY," + 442 PendingMessages.PROTO_TYPE + " INTEGER," + 443 PendingMessages.MSG_ID + " INTEGER," + 444 PendingMessages.MSG_TYPE + " INTEGER," + 445 PendingMessages.ERROR_TYPE + " INTEGER," + 446 PendingMessages.ERROR_CODE + " INTEGER," + 447 PendingMessages.RETRY_INDEX + " INTEGER NOT NULL DEFAULT 0," + 448 PendingMessages.DUE_TIME + " INTEGER," + 449 PendingMessages.LAST_TRY + " INTEGER);"); 450 451 } 452 453 // TODO Check the query plans for these triggers. 454 private void createCommonTriggers(SQLiteDatabase db) { 455 // Updates threads table whenever a message is added to pdu. 456 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON " + 457 MmsProvider.TABLE_PDU + " " + 458 PDU_UPDATE_THREAD_CONSTRAINTS + 459 PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE); 460 461 // Updates threads table whenever a message is added to sms. 462 db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " + 463 SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE); 464 465 // Updates threads table whenever a message in pdu is updated. 466 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 467 " UPDATE OF " + Mms.DATE + ", " + Mms.SUBJECT + ", " + Mms.MESSAGE_BOX + 468 " ON " + MmsProvider.TABLE_PDU + " " + 469 PDU_UPDATE_THREAD_CONSTRAINTS + 470 PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE); 471 472 // Updates threads table whenever a message in sms is updated. 473 db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" + 474 " UPDATE OF " + Sms.DATE + ", " + Sms.BODY + ", " + Sms.TYPE + 475 " ON sms " + 476 SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE); 477 478 // Updates threads table whenever a message in pdu is updated. 479 db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" + 480 " UPDATE OF " + Mms.READ + 481 " ON " + MmsProvider.TABLE_PDU + " " + 482 PDU_UPDATE_THREAD_CONSTRAINTS + 483 "BEGIN " + 484 PDU_UPDATE_THREAD_READ_BODY + 485 "END;"); 486 487 // Updates threads table whenever a message in sms is updated. 488 db.execSQL("CREATE TRIGGER sms_update_thread_read_on_update AFTER" + 489 " UPDATE OF " + Sms.READ + 490 " ON sms " + 491 "BEGIN " + 492 SMS_UPDATE_THREAD_READ_BODY + 493 "END;"); 494 495 // Update threads table whenever a message in pdu is deleted 496 db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " + 497 "AFTER DELETE ON pdu " + 498 "BEGIN " + 499 " UPDATE threads SET " + 500 " date = (strftime('%s','now') * 1000)" + 501 " WHERE threads._id = old." + Mms.THREAD_ID + "; " + 502 UPDATE_THREAD_COUNT_ON_OLD + 503 UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE + 504 "END;"); 505 506 // When the last message in a thread is deleted, these 507 // triggers ensure that the entry for its thread ID is removed 508 // from the threads table. 509 db.execSQL("CREATE TRIGGER delete_obsolete_threads_pdu " + 510 "AFTER DELETE ON pdu " + 511 "BEGIN " + 512 " DELETE FROM threads " + 513 " WHERE " + 514 " _id = old.thread_id " + 515 " AND _id NOT IN " + 516 " (SELECT thread_id FROM sms " + 517 " UNION SELECT thread_id from pdu); " + 518 "END;"); 519 520 db.execSQL("CREATE TRIGGER delete_obsolete_threads_when_update_pdu " + 521 "AFTER UPDATE OF " + Mms.THREAD_ID + " ON pdu " + 522 "WHEN old." + Mms.THREAD_ID + " != new." + Mms.THREAD_ID + " " + 523 "BEGIN " + 524 " DELETE FROM threads " + 525 " WHERE " + 526 " _id = old.thread_id " + 527 " AND _id NOT IN " + 528 " (SELECT thread_id FROM sms " + 529 " UNION SELECT thread_id from pdu); " + 530 "END;"); 531 // Insert pending status for M-Notification.ind or M-ReadRec.ind 532 // when they are inserted into Inbox/Outbox. 533 db.execSQL("CREATE TRIGGER insert_mms_pending_on_insert " + 534 "AFTER INSERT ON pdu " + 535 "WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_NOTIFICATION_IND + 536 " OR new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_READ_REC_IND + " " + 537 "BEGIN " + 538 " INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG + 539 " (" + PendingMessages.PROTO_TYPE + "," + 540 " " + PendingMessages.MSG_ID + "," + 541 " " + PendingMessages.MSG_TYPE + "," + 542 " " + PendingMessages.ERROR_TYPE + "," + 543 " " + PendingMessages.ERROR_CODE + "," + 544 " " + PendingMessages.RETRY_INDEX + "," + 545 " " + PendingMessages.DUE_TIME + ") " + 546 " VALUES " + 547 " (" + MmsSms.MMS_PROTO + "," + 548 " new." + BaseColumns._ID + "," + 549 " new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" + 550 "END;"); 551 552 // Insert pending status for M-Send.req when it is moved into Outbox. 553 db.execSQL("CREATE TRIGGER insert_mms_pending_on_update " + 554 "AFTER UPDATE ON pdu " + 555 "WHEN new." + Mms.MESSAGE_TYPE + "=" + MESSAGE_TYPE_SEND_REQ + 556 " AND new." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX + 557 " AND old." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " + 558 "BEGIN " + 559 " INSERT INTO " + MmsSmsProvider.TABLE_PENDING_MSG + 560 " (" + PendingMessages.PROTO_TYPE + "," + 561 " " + PendingMessages.MSG_ID + "," + 562 " " + PendingMessages.MSG_TYPE + "," + 563 " " + PendingMessages.ERROR_TYPE + "," + 564 " " + PendingMessages.ERROR_CODE + "," + 565 " " + PendingMessages.RETRY_INDEX + "," + 566 " " + PendingMessages.DUE_TIME + ") " + 567 " VALUES " + 568 " (" + MmsSms.MMS_PROTO + "," + 569 " new." + BaseColumns._ID + "," + 570 " new." + Mms.MESSAGE_TYPE + ",0,0,0,0);" + 571 "END;"); 572 573 // When a message is moved out of Outbox, delete its pending status. 574 db.execSQL("CREATE TRIGGER delete_mms_pending_on_update " + 575 "AFTER UPDATE ON " + MmsProvider.TABLE_PDU + " " + 576 "WHEN old." + Mms.MESSAGE_BOX + "=" + Mms.MESSAGE_BOX_OUTBOX + 577 " AND new." + Mms.MESSAGE_BOX + "!=" + Mms.MESSAGE_BOX_OUTBOX + " " + 578 "BEGIN " + 579 " DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG + 580 " WHERE " + PendingMessages.MSG_ID + "=new._id; " + 581 "END;"); 582 583 // Delete pending status for a message when it is deleted. 584 db.execSQL("CREATE TRIGGER delete_mms_pending_on_delete " + 585 "AFTER DELETE ON " + MmsProvider.TABLE_PDU + " " + 586 "BEGIN " + 587 " DELETE FROM " + MmsSmsProvider.TABLE_PENDING_MSG + 588 " WHERE " + PendingMessages.MSG_ID + "=old._id; " + 589 "END;"); 590 591 // TODO Add triggers for SMS retry-status management. 592 593 // Update the error flag of threads when the error type of 594 // a pending MM is updated. 595 db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " + 596 " AFTER UPDATE OF err_type ON pending_msgs " + 597 " WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" + 598 " OR (OLD.err_type >= 10 AND NEW.err_type < 10) " + 599 "BEGIN" + 600 " UPDATE threads SET error = " + 601 " CASE" + 602 " WHEN NEW.err_type >= 10 THEN error + 1" + 603 " ELSE error - 1" + 604 " END " + 605 " WHERE _id =" + 606 " (SELECT DISTINCT thread_id" + 607 " FROM pdu" + 608 " WHERE _id = NEW.msg_id); " + 609 "END;"); 610 611 // Update the error flag of threads when delete pending message. 612 db.execSQL("CREATE TRIGGER update_threads_error_on_delete_mms " + 613 " BEFORE DELETE ON pdu" + 614 " WHEN OLD._id IN (SELECT DISTINCT msg_id" + 615 " FROM pending_msgs" + 616 " WHERE err_type >= 10) " + 617 "BEGIN " + 618 " UPDATE threads SET error = error - 1" + 619 " WHERE _id = OLD.thread_id; " + 620 "END;"); 621 622 // Update the error flag of threads while moving an MM out of Outbox, 623 // which was failed to be sent permanently. 624 db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " + 625 " BEFORE UPDATE OF msg_box ON pdu " + 626 " WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " + 627 " AND (OLD._id IN (SELECT DISTINCT msg_id" + 628 " FROM pending_msgs" + 629 " WHERE err_type >= 10)) " + 630 "BEGIN " + 631 " UPDATE threads SET error = error - 1" + 632 " WHERE _id = OLD.thread_id; " + 633 "END;"); 634 635 // Update the error flag of threads after a text message was 636 // failed to send/receive. 637 db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " + 638 " AFTER UPDATE OF type ON sms" + 639 " WHEN (OLD.type != 5 AND NEW.type = 5)" + 640 " OR (OLD.type = 5 AND NEW.type != 5) " + 641 "BEGIN " + 642 " UPDATE threads SET error = " + 643 " CASE" + 644 " WHEN NEW.type = 5 THEN error + 1" + 645 " ELSE error - 1" + 646 " END " + 647 " WHERE _id = NEW.thread_id; " + 648 "END;"); 649 } 650 651 @Override 652 public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { 653 Log.w(TAG, "Upgrading database from version " + oldVersion 654 + " to " + currentVersion + "."); 655 656 switch (oldVersion) { 657 case 24: 658 if (currentVersion <= 24) { 659 return; 660 } 661 662 db.beginTransaction(); 663 try { 664 upgradeDatabaseToVersion25(db); 665 db.setTransactionSuccessful(); 666 } catch (Throwable ex) { 667 Log.e(TAG, ex.getMessage(), ex); 668 break; // force to destroy all old data; 669 } finally { 670 db.endTransaction(); 671 } 672 // fall-through 673 case 25: 674 if (currentVersion <= 25) { 675 return; 676 } 677 678 db.beginTransaction(); 679 try { 680 upgradeDatabaseToVersion26(db); 681 db.setTransactionSuccessful(); 682 } catch (Throwable ex) { 683 Log.e(TAG, ex.getMessage(), ex); 684 break; // force to destroy all old data; 685 } finally { 686 db.endTransaction(); 687 } 688 // fall-through 689 case 26: 690 if (currentVersion <= 26) { 691 return; 692 } 693 694 db.beginTransaction(); 695 try { 696 upgradeDatabaseToVersion27(db); 697 db.setTransactionSuccessful(); 698 } catch (Throwable ex) { 699 Log.e(TAG, ex.getMessage(), ex); 700 break; // force to destroy all old data; 701 } finally { 702 db.endTransaction(); 703 } 704 // fall-through 705 case 27: 706 if (currentVersion <= 27) { 707 return; 708 } 709 710 db.beginTransaction(); 711 try { 712 upgradeDatabaseToVersion28(db); 713 db.setTransactionSuccessful(); 714 } catch (Throwable ex) { 715 Log.e(TAG, ex.getMessage(), ex); 716 break; // force to destroy all old data; 717 } finally { 718 db.endTransaction(); 719 } 720 // fall-through 721 case 28: 722 if (currentVersion <= 28) { 723 return; 724 } 725 726 // Test whether this database file is from TC2 branch. 727 Cursor c = db.rawQuery("SELECT * FROM threads", null); 728 if (c != null) { 729 try { 730 c.getColumnIndexOrThrow("snippet_cs"); 731 } catch (IllegalArgumentException e) { 732 // Column 'snippet_cs' doesn't exist, which means 733 // this database file was maintained by TC2 branch 734 // and its version is inconsistent. 735 Log.w(TAG, "Upgrade database file from TC2!!!"); 736 db.beginTransaction(); 737 try { 738 upgradeDatabaseToVersion28(db); 739 db.setTransactionSuccessful(); 740 } catch (Throwable ex) { 741 Log.e(TAG, ex.getMessage(), ex); 742 break; // force to destroy all old data; 743 } finally { 744 db.endTransaction(); 745 } 746 } finally { 747 c.close(); 748 } 749 } 750 751 db.beginTransaction(); 752 try { 753 upgradeDatabaseToVersion29(db); 754 db.setTransactionSuccessful(); 755 } catch (Throwable ex) { 756 Log.e(TAG, ex.getMessage(), ex); 757 break; // force to destroy all old data; 758 } finally { 759 db.endTransaction(); 760 } 761 // fall-through 762 case 29: 763 if (currentVersion <= 29) { 764 return; 765 } 766 767 db.beginTransaction(); 768 try { 769 upgradeDatabaseToVersion30(db); 770 db.setTransactionSuccessful(); 771 } catch (Throwable ex) { 772 Log.e(TAG, ex.getMessage(), ex); 773 break; // force to destroy all old data; 774 } finally { 775 db.endTransaction(); 776 } 777 // fall-through 778 case 30: 779 if (currentVersion <= 30) { 780 return; 781 } 782 783 db.beginTransaction(); 784 try { 785 upgradeDatabaseToVersion31(db); 786 db.setTransactionSuccessful(); 787 } catch (Throwable ex) { 788 Log.e(TAG, ex.getMessage(), ex); 789 break; // force to destroy all old data; 790 } finally { 791 db.endTransaction(); 792 } 793 // fall-through 794 case 31: 795 if (currentVersion <= 31) { 796 return; 797 } 798 799 db.beginTransaction(); 800 try { 801 upgradeDatabaseToVersion32(db); 802 db.setTransactionSuccessful(); 803 } catch (Throwable ex) { 804 Log.e(TAG, ex.getMessage(), ex); 805 break; // force to destroy all old data; 806 } finally { 807 db.endTransaction(); 808 } 809 // fall-through 810 case 32: 811 if (currentVersion <= 32) { 812 return; 813 } 814 815 db.beginTransaction(); 816 try { 817 upgradeDatabaseToVersion33(db); 818 db.setTransactionSuccessful(); 819 } catch (Throwable ex) { 820 Log.e(TAG, ex.getMessage(), ex); 821 break; // force to destroy all old data; 822 } finally { 823 db.endTransaction(); 824 } 825 // fall-through 826 case 33: 827 if (currentVersion <= 33) { 828 return; 829 } 830 831 db.beginTransaction(); 832 try { 833 upgradeDatabaseToVersion34(db); 834 db.setTransactionSuccessful(); 835 } catch (Throwable ex) { 836 Log.e(TAG, ex.getMessage(), ex); 837 break; // force to destroy all old data; 838 } finally { 839 db.endTransaction(); 840 } 841 // fall-through 842 case 34: 843 if (currentVersion <= 34) { 844 return; 845 } 846 847 db.beginTransaction(); 848 try { 849 upgradeDatabaseToVersion35(db); 850 db.setTransactionSuccessful(); 851 } catch (Throwable ex) { 852 Log.e(TAG, ex.getMessage(), ex); 853 break; // force to destroy all old data; 854 } finally { 855 db.endTransaction(); 856 } 857 // fall-through 858 case 35: 859 if (currentVersion <= 35) { 860 return; 861 } 862 863 db.beginTransaction(); 864 try { 865 upgradeDatabaseToVersion36(db); 866 db.setTransactionSuccessful(); 867 } catch (Throwable ex) { 868 Log.e(TAG, ex.getMessage(), ex); 869 break; // force to destroy all old data; 870 } finally { 871 db.endTransaction(); 872 } 873 // fall-through 874 case 36: 875 if (currentVersion <= 36) { 876 return; 877 } 878 879 db.beginTransaction(); 880 try { 881 upgradeDatabaseToVersion37(db); 882 db.setTransactionSuccessful(); 883 } catch (Throwable ex) { 884 Log.e(TAG, ex.getMessage(), ex); 885 break; // force to destroy all old data; 886 } finally { 887 db.endTransaction(); 888 } 889 // fall-through 890 case 37: 891 if (currentVersion <= 37) { 892 return; 893 } 894 895 db.beginTransaction(); 896 try { 897 upgradeDatabaseToVersion38(db); 898 db.setTransactionSuccessful(); 899 } catch (Throwable ex) { 900 Log.e(TAG, ex.getMessage(), ex); 901 break; // force to destroy all old data; 902 } finally { 903 db.endTransaction(); 904 } 905 // fall-through 906 case 38: 907 if (currentVersion <= 38) { 908 return; 909 } 910 911 db.beginTransaction(); 912 try { 913 upgradeDatabaseToVersion39(db); 914 db.setTransactionSuccessful(); 915 } catch (Throwable ex) { 916 Log.e(TAG, ex.getMessage(), ex); 917 break; // force to destroy all old data; 918 } finally { 919 db.endTransaction(); 920 } 921 // fall-through 922 case 39: 923 if (currentVersion <= 39) { 924 return; 925 } 926 927 db.beginTransaction(); 928 try { 929 upgradeDatabaseToVersion40(db); 930 db.setTransactionSuccessful(); 931 } catch (Throwable ex) { 932 Log.e(TAG, ex.getMessage(), ex); 933 break; // force to destroy all old data; 934 } finally { 935 db.endTransaction(); 936 } 937 // fall-through 938 case 40: 939 if (currentVersion <= 40) { 940 return; 941 } 942 943 db.beginTransaction(); 944 try { 945 upgradeDatabaseToVersion41(db); 946 db.setTransactionSuccessful(); 947 } catch (Throwable ex) { 948 Log.e(TAG, ex.getMessage(), ex); 949 break; // force to destroy all old data; 950 } finally { 951 db.endTransaction(); 952 } 953 // fall-through 954 case 41: 955 if (currentVersion <= 41) { 956 return; 957 } 958 db.beginTransaction(); 959 try { 960 upgradeDatabaseToVersion42(db); 961 db.setTransactionSuccessful(); 962 } catch (Throwable ex) { 963 Log.e(TAG, ex.getMessage(), ex); 964 break; 965 } finally { 966 db.endTransaction(); 967 } 968 return; 969 } 970 971 Log.w(TAG, "Destroying all old data."); 972 dropCommonTriggers(db); 973 dropMmsTriggers(db); 974 dropCommonTables(db); 975 dropMmsTables(db); 976 dropSmsTables(db); 977 onCreate(db); 978 } 979 980 private void dropCommonTables(SQLiteDatabase db) { 981 db.execSQL("DROP TABLE IF EXISTS canonical_addresses"); 982 db.execSQL("DROP TABLE IF EXISTS threads"); 983 db.execSQL("DROP TABLE IF EXISTS " + MmsSmsProvider.TABLE_PENDING_MSG); 984 } 985 986 private void dropCommonTriggers(SQLiteDatabase db) { 987 db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_pdu"); 988 db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_when_update_pdu"); 989 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 990 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert"); 991 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 992 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update"); 993 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update"); 994 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_read_on_update"); 995 db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_insert"); 996 db.execSQL("DROP TRIGGER IF EXISTS insert_mms_pending_on_update"); 997 db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_update"); 998 db.execSQL("DROP TRIGGER IF EXISTS delete_mms_pending_on_delete"); 999 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update_mms"); 1000 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_mms"); 1001 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms"); 1002 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update_sms"); 1003 } 1004 1005 private void dropSmsTables(SQLiteDatabase db) { 1006 db.execSQL("DROP TABLE IF EXISTS sms"); 1007 db.execSQL("DROP TABLE IF EXISTS newSmsIndicator"); 1008 db.execSQL("DROP TABLE IF EXISTS raw"); 1009 db.execSQL("DROP TABLE IF EXISTS attachments"); 1010 db.execSQL("DROP TABLE IF EXISTS thread_ids"); 1011 db.execSQL("DROP TABLE IF EXISTS sr_pending"); 1012 } 1013 1014 private void dropMmsTables(SQLiteDatabase db) { 1015 db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PDU + ";"); 1016 db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_ADDR + ";"); 1017 db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_PART + ";"); 1018 db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_RATE + ";"); 1019 db.execSQL("DROP TABLE IF EXISTS " + MmsProvider.TABLE_DRM + ";"); 1020 } 1021 1022 private void dropMmsTriggers(SQLiteDatabase db) { 1023 db.execSQL("DROP TRIGGER IF EXISTS part_cleanup;"); 1024 db.execSQL("DROP TRIGGER IF EXISTS addr_cleanup;"); 1025 db.execSQL("DROP TRIGGER IF EXISTS cleanup_delivery_and_read_report;"); 1026 } 1027 1028 private void upgradeDatabaseToVersion25(SQLiteDatabase db) { 1029 db.execSQL("ALTER TABLE threads " + 1030 "ADD COLUMN type INTEGER NOT NULL DEFAULT 0;"); 1031 } 1032 1033 private void upgradeDatabaseToVersion26(SQLiteDatabase db) { 1034 db.execSQL("ALTER TABLE threads " + 1035 "ADD COLUMN error INTEGER DEFAULT 0;"); 1036 1037 // Do NOT use defined symbols when upgrading database 1038 // because they may be changed and cannot be applied 1039 // to old database. 1040 db.execSQL("UPDATE threads SET error = 1 WHERE _id IN" + 1041 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1042 " ON pdu.thread_id = pending_msgs.msg_id" + 1043 " WHERE proto_type = 1 AND err_type >= 10" + 1044 " GROUP BY thread_id); " + 1045 "UPDATE threads SET error = 1 WHERE _id IN" + 1046 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1047 " ON sms.thread_id = pending_msgs.msg_id" + 1048 " WHERE proto_type = 0 AND err_type >= 10" + 1049 " GROUP BY thread_id); "); 1050 1051 db.execSQL("CREATE TRIGGER update_threads_error_on_update " + 1052 " AFTER UPDATE OF err_type ON pending_msgs " + 1053 "BEGIN " + 1054 "UPDATE threads SET error = 1 WHERE _id IN" + 1055 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1056 " ON pdu.thread_id = pending_msgs.msg_id" + 1057 " WHERE proto_type = 1 AND err_type >= 10" + 1058 " GROUP BY thread_id); " + 1059 "UPDATE threads SET error = 1 WHERE _id IN" + 1060 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1061 " ON sms.thread_id = pending_msgs.msg_id" + 1062 " WHERE proto_type = 0 AND err_type >= 10" + 1063 " GROUP BY thread_id); " + 1064 "END;"); 1065 1066 db.execSQL("CREATE TRIGGER update_threads_error_on_delete " + 1067 " AFTER DELETE ON pending_msgs " + 1068 "BEGIN " + 1069 "UPDATE threads SET error = 1 WHERE _id IN" + 1070 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1071 " ON pdu.thread_id = pending_msgs.msg_id" + 1072 " WHERE proto_type = 1 AND err_type >= 10" + 1073 " GROUP BY thread_id); " + 1074 "UPDATE threads SET error = 1 WHERE _id IN" + 1075 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1076 " ON sms.thread_id = pending_msgs.msg_id" + 1077 " WHERE proto_type = 0 AND err_type >= 10" + 1078 " GROUP BY thread_id); " + 1079 "END;"); 1080 } 1081 1082 private void upgradeDatabaseToVersion27(SQLiteDatabase db) { 1083 db.execSQL("UPDATE threads SET error = 1 WHERE _id IN" + 1084 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1085 " ON pdu._id = pending_msgs.msg_id" + 1086 " WHERE proto_type = 1 AND err_type >= 10" + 1087 " GROUP BY thread_id); " + 1088 "UPDATE threads SET error = 1 WHERE _id IN" + 1089 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1090 " ON sms._id = pending_msgs.msg_id" + 1091 " WHERE proto_type = 0 AND err_type >= 10" + 1092 " GROUP BY thread_id); "); 1093 1094 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update"); 1095 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete"); 1096 1097 db.execSQL("CREATE TRIGGER update_threads_error_on_update " + 1098 " AFTER UPDATE OF err_type ON pending_msgs " + 1099 "BEGIN " + 1100 "UPDATE threads SET error = 1 WHERE _id IN" + 1101 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1102 " ON pdu._id = pending_msgs.msg_id" + 1103 " WHERE proto_type = 1 AND err_type >= 10" + 1104 " GROUP BY thread_id); " + 1105 "UPDATE threads SET error = 1 WHERE _id IN" + 1106 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1107 " ON sms._id = pending_msgs.msg_id" + 1108 " WHERE proto_type = 0 AND err_type >= 10" + 1109 " GROUP BY thread_id); " + 1110 "END;"); 1111 1112 db.execSQL("CREATE TRIGGER update_threads_error_on_delete " + 1113 " AFTER DELETE ON pending_msgs " + 1114 "BEGIN " + 1115 "UPDATE threads SET error = 1 WHERE _id IN" + 1116 " (SELECT thread_id FROM pdu LEFT JOIN pending_msgs" + 1117 " ON pdu._id = pending_msgs.msg_id" + 1118 " WHERE proto_type = 1 AND err_type >= 10" + 1119 " GROUP BY thread_id); " + 1120 "UPDATE threads SET error = 1 WHERE _id IN" + 1121 " (SELECT thread_id FROM sms LEFT JOIN pending_msgs" + 1122 " ON sms._id = pending_msgs.msg_id" + 1123 " WHERE proto_type = 0 AND err_type >= 10" + 1124 " GROUP BY thread_id); " + 1125 "END;"); 1126 } 1127 1128 private void upgradeDatabaseToVersion28(SQLiteDatabase db) { 1129 db.execSQL("ALTER TABLE threads " + 1130 "ADD COLUMN snippet_cs INTEGER NOT NULL DEFAULT 0;"); 1131 1132 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 1133 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 1134 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update"); 1135 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete"); 1136 1137 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " + 1138 " WHEN new.msg_box!=5 AND new.msg_box!=3" + 1139 " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " + 1140 "BEGIN" + 1141 " UPDATE threads SET" + 1142 " date = (strftime('%s','now') * 1000), " + 1143 " snippet = new.sub, " + 1144 " snippet_cs = new.sub_cs" + 1145 " WHERE threads._id = new.thread_id; " + 1146 " UPDATE threads SET read = " + 1147 " CASE (SELECT COUNT(*)" + 1148 " FROM pdu" + 1149 " WHERE read = 0 AND thread_id = threads._id)" + 1150 " WHEN 0 THEN 1 ELSE 0" + 1151 " END" + 1152 " WHERE threads._id = new.thread_id; " + 1153 "END;"); 1154 1155 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 1156 " UPDATE OF date, sub, msg_box ON pdu " + 1157 " WHEN new.msg_box!=5 AND new.msg_box!=3" + 1158 " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " + 1159 "BEGIN" + 1160 " UPDATE threads SET" + 1161 " date = (strftime('%s','now') * 1000), " + 1162 " snippet = new.sub, " + 1163 " snippet_cs = new.sub_cs" + 1164 " WHERE threads._id = new.thread_id; " + 1165 " UPDATE threads SET read = " + 1166 " CASE (SELECT COUNT(*)" + 1167 " FROM pdu" + 1168 " WHERE read = 0 AND thread_id = threads._id)" + 1169 " WHEN 0 THEN 1 ELSE 0" + 1170 " END" + 1171 " WHERE threads._id = new.thread_id; " + 1172 "END;"); 1173 1174 db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" + 1175 " UPDATE OF read ON pdu " + 1176 " WHEN new.msg_box!=5 AND new.msg_box!=3" + 1177 " AND (new.m_type=132 OR new.m_type=130 OR new.m_type=128) " + 1178 "BEGIN " + 1179 " UPDATE threads SET read = " + 1180 " CASE (SELECT COUNT(*)" + 1181 " FROM pdu" + 1182 " WHERE read = 0 AND thread_id = threads._id)" + 1183 " WHEN 0 THEN 1 ELSE 0" + 1184 " END" + 1185 " WHERE threads._id = new.thread_id; " + 1186 "END;"); 1187 1188 db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " + 1189 "AFTER DELETE ON sms " + 1190 "BEGIN " + 1191 " UPDATE threads SET " + 1192 " date = (strftime('%s','now') * 1000), " + 1193 " snippet = (SELECT body FROM SMS ORDER BY date DESC LIMIT 1)" + 1194 " WHERE threads._id = old.thread_id; " + 1195 "END;"); 1196 } 1197 1198 private void upgradeDatabaseToVersion29(SQLiteDatabase db) { 1199 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 1200 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 1201 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_read_on_update"); 1202 1203 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " + 1204 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1205 "BEGIN" + 1206 " UPDATE threads SET" + 1207 " date = (strftime('%s','now') * 1000), " + 1208 " snippet = new.sub, " + 1209 " snippet_cs = new.sub_cs" + 1210 " WHERE threads._id = new.thread_id; " + 1211 " UPDATE threads SET read = " + 1212 " CASE (SELECT COUNT(*)" + 1213 " FROM pdu" + 1214 " WHERE read = 0 AND thread_id = threads._id)" + 1215 " WHEN 0 THEN 1 ELSE 0" + 1216 " END" + 1217 " WHERE threads._id = new.thread_id; " + 1218 "END;"); 1219 1220 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 1221 " UPDATE OF date, sub, msg_box ON pdu " + 1222 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1223 "BEGIN" + 1224 " UPDATE threads SET" + 1225 " date = (strftime('%s','now') * 1000), " + 1226 " snippet = new.sub, " + 1227 " snippet_cs = new.sub_cs" + 1228 " WHERE threads._id = new.thread_id; " + 1229 " UPDATE threads SET read = " + 1230 " CASE (SELECT COUNT(*)" + 1231 " FROM pdu" + 1232 " WHERE read = 0 AND thread_id = threads._id)" + 1233 " WHEN 0 THEN 1 ELSE 0" + 1234 " END" + 1235 " WHERE threads._id = new.thread_id; " + 1236 "END;"); 1237 1238 db.execSQL("CREATE TRIGGER pdu_update_thread_read_on_update AFTER" + 1239 " UPDATE OF read ON pdu " + 1240 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1241 "BEGIN " + 1242 " UPDATE threads SET read = " + 1243 " CASE (SELECT COUNT(*)" + 1244 " FROM pdu" + 1245 " WHERE read = 0 AND thread_id = threads._id)" + 1246 " WHEN 0 THEN 1 ELSE 0" + 1247 " END" + 1248 " WHERE threads._id = new.thread_id; " + 1249 "END;"); 1250 } 1251 1252 private void upgradeDatabaseToVersion30(SQLiteDatabase db) { 1253 // Since SQLite doesn't support altering constraints 1254 // of an existing table, I have to create a new table 1255 // with updated constraints, copy old data into this 1256 // table, drop old table and then rename the new table 1257 // to 'threads'. 1258 db.execSQL("CREATE TABLE temp_threads (" + 1259 "_id INTEGER PRIMARY KEY," + 1260 "date INTEGER DEFAULT 0," + 1261 "subject TEXT," + 1262 "recipient_ids TEXT," + 1263 "snippet TEXT," + 1264 "snippet_cs INTEGER DEFAULT 0," + 1265 "read INTEGER DEFAULT 1," + 1266 "type INTEGER DEFAULT 0," + 1267 "error INTEGER DEFAULT 0);"); 1268 db.execSQL("INSERT INTO temp_threads SELECT * FROM threads;"); 1269 db.execSQL("DROP TABLE IF EXISTS threads;"); 1270 db.execSQL("ALTER TABLE temp_threads RENAME TO threads;"); 1271 } 1272 1273 private void upgradeDatabaseToVersion31(SQLiteDatabase db) { 1274 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete"); 1275 1276 // Update threads table whenever a message in sms is deleted 1277 // (Usually an abandoned draft.) 1278 db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " + 1279 "AFTER DELETE ON sms " + 1280 "BEGIN " + 1281 " UPDATE threads SET " + 1282 " date = (strftime('%s','now') * 1000) " + 1283 " WHERE threads._id = old.thread_id; " + 1284 " UPDATE threads SET" + 1285 " snippet = (SELECT snippet FROM" + 1286 " (SELECT date * 1000 AS date, sub AS snippet," + 1287 " sub_cs AS snippet_cs FROM pdu" + 1288 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1289 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1290 " WHERE threads._id = old.thread_id; " + 1291 " UPDATE threads SET" + 1292 " snippet_cs = (SELECT snippet_cs FROM" + 1293 " (SELECT date * 1000 AS date, sub AS snippet," + 1294 " sub_cs AS snippet_cs FROM pdu" + 1295 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1296 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1297 " WHERE threads._id = old.thread_id; " + 1298 "END;"); 1299 1300 // Update threads table whenever a message in pdu is deleted 1301 db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " + 1302 "AFTER DELETE ON pdu " + 1303 "BEGIN " + 1304 " UPDATE threads SET " + 1305 " date = (strftime('%s','now') * 1000)" + 1306 " WHERE threads._id = old.thread_id;" + 1307 " UPDATE threads SET" + 1308 " snippet = (SELECT snippet FROM" + 1309 " (SELECT date * 1000 AS date, sub AS snippet," + 1310 " sub_cs AS snippet_cs FROM pdu" + 1311 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1312 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1313 " WHERE threads._id = old.thread_id; " + 1314 " UPDATE threads SET" + 1315 " snippet_cs = (SELECT snippet_cs FROM" + 1316 " (SELECT date * 1000 AS date, sub AS snippet," + 1317 " sub_cs AS snippet_cs FROM pdu" + 1318 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1319 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1320 " WHERE threads._id = old.thread_id; " + 1321 "END;"); 1322 } 1323 1324 private void upgradeDatabaseToVersion32(SQLiteDatabase db) { 1325 db.execSQL("CREATE TABLE IF NOT EXISTS rate (sent_time INTEGER);"); 1326 } 1327 1328 private void upgradeDatabaseToVersion33(SQLiteDatabase db) { 1329 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_update"); 1330 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete"); 1331 1332 db.execSQL("CREATE TRIGGER update_threads_error_on_update_mms " + 1333 " AFTER UPDATE OF err_type ON pending_msgs " + 1334 " WHEN (OLD.err_type < 10 AND NEW.err_type >= 10)" + 1335 " OR (OLD.err_type >= 10 AND NEW.err_type < 10) " + 1336 "BEGIN" + 1337 " UPDATE threads SET error = " + 1338 " CASE" + 1339 " WHEN NEW.err_type >= 10 THEN error + 1" + 1340 " ELSE error - 1" + 1341 " END " + 1342 " WHERE _id =" + 1343 " (SELECT DISTINCT thread_id" + 1344 " FROM pdu" + 1345 " WHERE _id = NEW.msg_id); " + 1346 "END;"); 1347 1348 db.execSQL("CREATE TRIGGER update_threads_error_on_delete_mms " + 1349 " BEFORE DELETE ON pdu" + 1350 " WHEN OLD._id IN (SELECT DISTINCT msg_id" + 1351 " FROM pending_msgs" + 1352 " WHERE err_type >= 10) " + 1353 "BEGIN " + 1354 " UPDATE threads SET error = error - 1" + 1355 " WHERE _id = OLD.thread_id; " + 1356 "END;"); 1357 1358 db.execSQL("CREATE TRIGGER update_threads_error_on_update_sms " + 1359 " AFTER UPDATE OF type ON sms" + 1360 " WHEN (OLD.type != 5 AND NEW.type = 5)" + 1361 " OR (OLD.type = 5 AND NEW.type != 5) " + 1362 "BEGIN " + 1363 " UPDATE threads SET error = " + 1364 " CASE" + 1365 " WHEN NEW.type = 5 THEN error + 1" + 1366 " ELSE error - 1" + 1367 " END " + 1368 " WHERE _id = NEW.thread_id; " + 1369 "END;"); 1370 1371 db.execSQL("CREATE TRIGGER update_threads_error_on_delete_sms " + 1372 " AFTER DELETE ON sms" + 1373 " WHEN (OLD.type = 5) " + 1374 "BEGIN " + 1375 " UPDATE threads SET error = error - 1" + 1376 " WHERE _id = OLD.thread_id; " + 1377 "END;"); 1378 } 1379 1380 private void upgradeDatabaseToVersion34(SQLiteDatabase db) { 1381 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert"); 1382 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update"); 1383 1384 db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " + 1385 "BEGIN" + 1386 " UPDATE threads SET" + 1387 " date = (strftime('%s','now') * 1000), " + 1388 " snippet = new.body," + 1389 " snippet_cs = 0" + 1390 " WHERE threads._id = new.thread_id; " + 1391 " UPDATE threads SET read = " + 1392 " CASE (SELECT COUNT(*)" + 1393 " FROM sms" + 1394 " WHERE read = 0" + 1395 " AND thread_id = threads._id)" + 1396 " WHEN 0 THEN 1" + 1397 " ELSE 0" + 1398 " END" + 1399 " WHERE threads._id = new.thread_id; " + 1400 "END;"); 1401 1402 db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" + 1403 " UPDATE OF date, body, msg_box" + 1404 " ON sms " + 1405 "BEGIN" + 1406 " UPDATE threads SET" + 1407 " date = (strftime('%s','now') * 1000), " + 1408 " snippet = new.body," + 1409 " snippet_cs = 0" + 1410 " WHERE threads._id = new.thread_id; " + 1411 " UPDATE threads SET read = " + 1412 " CASE (SELECT COUNT(*)" + 1413 " FROM sms" + 1414 " WHERE read = 0" + 1415 " AND thread_id = threads._id)" + 1416 " WHEN 0 THEN 1" + 1417 " ELSE 0" + 1418 " END" + 1419 " WHERE threads._id = new.thread_id; " + 1420 "END;"); 1421 } 1422 1423 private void upgradeDatabaseToVersion35(SQLiteDatabase db) { 1424 db.execSQL("CREATE TABLE temp_threads (" + 1425 "_id INTEGER PRIMARY KEY," + 1426 "date INTEGER DEFAULT 0," + 1427 "message_count INTEGER DEFAULT 0," + 1428 "recipient_ids TEXT," + 1429 "snippet TEXT," + 1430 "snippet_cs INTEGER DEFAULT 0," + 1431 "read INTEGER DEFAULT 1," + 1432 "type INTEGER DEFAULT 0," + 1433 "error INTEGER DEFAULT 0);"); 1434 db.execSQL("INSERT INTO temp_threads " + 1435 "SELECT _id, date, 0 AS message_count, recipient_ids," + 1436 " snippet, snippet_cs, read, type, error " + 1437 "FROM threads;"); 1438 db.execSQL("DROP TABLE IF EXISTS threads;"); 1439 db.execSQL("ALTER TABLE temp_threads RENAME TO threads;"); 1440 1441 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 1442 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert"); 1443 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete"); 1444 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_delete"); 1445 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update"); 1446 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 1447 1448 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " + 1449 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1450 "BEGIN" + 1451 " UPDATE threads SET" + 1452 " date = (strftime('%s','now') * 1000), " + 1453 " snippet = new.sub, " + 1454 " snippet_cs = new.sub_cs" + 1455 " WHERE threads._id = new.thread_id; " + 1456 " UPDATE threads SET message_count = " + 1457 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1458 " ON threads._id = thread_id" + 1459 " WHERE thread_id = new.thread_id" + 1460 " AND sms.type != 3) + " + 1461 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1462 " ON threads._id = thread_id" + 1463 " WHERE thread_id = new.thread_id" + 1464 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1465 " AND msg_box != 3) " + 1466 " WHERE threads._id = new.thread_id; " + 1467 " UPDATE threads SET read = " + 1468 " CASE (SELECT COUNT(*)" + 1469 " FROM pdu" + 1470 " WHERE read = 0 AND thread_id = threads._id)" + 1471 " WHEN 0 THEN 1 ELSE 0" + 1472 " END" + 1473 " WHERE threads._id = new.thread_id; " + 1474 "END;"); 1475 1476 db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " + 1477 "BEGIN" + 1478 " UPDATE threads SET" + 1479 " date = (strftime('%s','now') * 1000), " + 1480 " snippet = new.body," + 1481 " snippet_cs = 0" + 1482 " WHERE threads._id = new.thread_id; " + 1483 " UPDATE threads SET message_count = " + 1484 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1485 " ON threads._id = thread_id" + 1486 " WHERE thread_id = new.thread_id" + 1487 " AND sms.type != 3) + " + 1488 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1489 " ON threads._id = thread_id" + 1490 " WHERE thread_id = new.thread_id" + 1491 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1492 " AND msg_box != 3) " + 1493 " WHERE threads._id = new.thread_id; " + 1494 " UPDATE threads SET read = " + 1495 " CASE (SELECT COUNT(*)" + 1496 " FROM sms" + 1497 " WHERE read = 0" + 1498 " AND thread_id = threads._id)" + 1499 " WHEN 0 THEN 1" + 1500 " ELSE 0" + 1501 " END" + 1502 " WHERE threads._id = new.thread_id; " + 1503 "END;"); 1504 1505 db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " + 1506 "AFTER DELETE ON sms " + 1507 "BEGIN " + 1508 " UPDATE threads SET " + 1509 " date = (strftime('%s','now') * 1000) " + 1510 " WHERE threads._id = old.thread_id; " + 1511 " UPDATE threads SET message_count = " + 1512 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1513 " ON threads._id = thread_id" + 1514 " WHERE thread_id = old.thread_id" + 1515 " AND sms.type != 3) + " + 1516 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1517 " ON threads._id = thread_id" + 1518 " WHERE thread_id = old.thread_id" + 1519 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1520 " AND msg_box != 3) " + 1521 " WHERE threads._id = old.thread_id; " + 1522 " UPDATE threads SET" + 1523 " snippet = (SELECT snippet FROM" + 1524 " (SELECT date * 1000 AS date, sub AS snippet," + 1525 " sub_cs AS snippet_cs FROM pdu" + 1526 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1527 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1528 " WHERE threads._id = old.thread_id; " + 1529 " UPDATE threads SET" + 1530 " snippet_cs = (SELECT snippet_cs FROM" + 1531 " (SELECT date * 1000 AS date, sub AS snippet," + 1532 " sub_cs AS snippet_cs FROM pdu" + 1533 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1534 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1535 " WHERE threads._id = old.thread_id; " + 1536 "END;"); 1537 1538 db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " + 1539 "AFTER DELETE ON pdu " + 1540 "BEGIN " + 1541 " UPDATE threads SET " + 1542 " date = (strftime('%s','now') * 1000)" + 1543 " WHERE threads._id = old.thread_id;" + 1544 " UPDATE threads SET message_count = " + 1545 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1546 " ON threads._id = thread_id" + 1547 " WHERE thread_id = old.thread_id" + 1548 " AND sms.type != 3) + " + 1549 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1550 " ON threads._id = thread_id" + 1551 " WHERE thread_id = old.thread_id" + 1552 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1553 " AND msg_box != 3) " + 1554 " WHERE threads._id = old.thread_id; " + 1555 " UPDATE threads SET" + 1556 " snippet = (SELECT snippet FROM" + 1557 " (SELECT date * 1000 AS date, sub AS snippet," + 1558 " sub_cs AS snippet_cs FROM pdu" + 1559 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1560 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1561 " WHERE threads._id = old.thread_id; " + 1562 " UPDATE threads SET" + 1563 " snippet_cs = (SELECT snippet_cs FROM" + 1564 " (SELECT date * 1000 AS date, sub AS snippet," + 1565 " sub_cs AS snippet_cs FROM pdu" + 1566 " UNION SELECT date, body AS snippet, NULL AS snippet_cs" + 1567 " FROM sms) ORDER BY date DESC LIMIT 1) " + 1568 " WHERE threads._id = old.thread_id; " + 1569 "END;"); 1570 1571 db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" + 1572 " UPDATE OF date, body, type" + 1573 " ON sms " + 1574 "BEGIN" + 1575 " UPDATE threads SET" + 1576 " date = (strftime('%s','now') * 1000), " + 1577 " snippet = new.body," + 1578 " snippet_cs = 0" + 1579 " WHERE threads._id = new.thread_id; " + 1580 " UPDATE threads SET message_count = " + 1581 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1582 " ON threads._id = thread_id" + 1583 " WHERE thread_id = new.thread_id" + 1584 " AND sms.type != 3) + " + 1585 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1586 " ON threads._id = thread_id" + 1587 " WHERE thread_id = new.thread_id" + 1588 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1589 " AND msg_box != 3) " + 1590 " WHERE threads._id = new.thread_id; " + 1591 " UPDATE threads SET read = " + 1592 " CASE (SELECT COUNT(*)" + 1593 " FROM sms" + 1594 " WHERE read = 0" + 1595 " AND thread_id = threads._id)" + 1596 " WHEN 0 THEN 1" + 1597 " ELSE 0" + 1598 " END" + 1599 " WHERE threads._id = new.thread_id; " + 1600 "END;"); 1601 1602 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 1603 " UPDATE OF date, sub, msg_box ON pdu " + 1604 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1605 "BEGIN" + 1606 " UPDATE threads SET" + 1607 " date = (strftime('%s','now') * 1000), " + 1608 " snippet = new.sub, " + 1609 " snippet_cs = new.sub_cs" + 1610 " WHERE threads._id = new.thread_id; " + 1611 " UPDATE threads SET message_count = " + 1612 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1613 " ON threads._id = thread_id" + 1614 " WHERE thread_id = new.thread_id" + 1615 " AND sms.type != 3) + " + 1616 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1617 " ON threads._id = thread_id" + 1618 " WHERE thread_id = new.thread_id" + 1619 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1620 " AND msg_box != 3) " + 1621 " WHERE threads._id = new.thread_id; " + 1622 " UPDATE threads SET read = " + 1623 " CASE (SELECT COUNT(*)" + 1624 " FROM pdu" + 1625 " WHERE read = 0 AND thread_id = threads._id)" + 1626 " WHEN 0 THEN 1 ELSE 0" + 1627 " END" + 1628 " WHERE threads._id = new.thread_id; " + 1629 "END;"); 1630 } 1631 1632 private void upgradeDatabaseToVersion36(SQLiteDatabase db) { 1633 db.execSQL("CREATE TABLE IF NOT EXISTS drm (_id INTEGER PRIMARY KEY, _data TEXT);"); 1634 db.execSQL("CREATE TRIGGER IF NOT EXISTS drm_file_cleanup DELETE ON drm " + 1635 "BEGIN SELECT _DELETE_FILE(old._data); END;"); 1636 } 1637 1638 private void upgradeDatabaseToVersion37(SQLiteDatabase db) { 1639 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete"); 1640 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_delete"); 1641 1642 db.execSQL("CREATE TRIGGER sms_update_thread_on_delete " + 1643 "AFTER DELETE ON sms " + 1644 "BEGIN " + 1645 " UPDATE threads SET " + 1646 " date = (strftime('%s','now') * 1000) " + 1647 " WHERE threads._id = old.thread_id; " + 1648 " UPDATE threads SET message_count = " + 1649 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1650 " ON threads._id = thread_id" + 1651 " WHERE thread_id = old.thread_id" + 1652 " AND sms.type != 3) + " + 1653 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1654 " ON threads._id = thread_id" + 1655 " WHERE thread_id = old.thread_id" + 1656 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1657 " AND msg_box != 3) " + 1658 " WHERE threads._id = old.thread_id; " + 1659 " UPDATE threads SET snippet = " + 1660 " (SELECT snippet FROM" + 1661 " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" + 1662 " UNION SELECT date, body AS snippet, thread_id FROM sms)" + 1663 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 1664 " WHERE threads._id = OLD.thread_id; " + 1665 " UPDATE threads SET snippet_cs = " + 1666 " (SELECT snippet_cs FROM" + 1667 " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" + 1668 " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" + 1669 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 1670 " WHERE threads._id = OLD.thread_id; " + 1671 "END;"); 1672 1673 db.execSQL("CREATE TRIGGER pdu_update_thread_on_delete " + 1674 "AFTER DELETE ON pdu " + 1675 "BEGIN " + 1676 " UPDATE threads SET " + 1677 " date = (strftime('%s','now') * 1000)" + 1678 " WHERE threads._id = old.thread_id;" + 1679 " UPDATE threads SET message_count = " + 1680 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1681 " ON threads._id = thread_id" + 1682 " WHERE thread_id = old.thread_id" + 1683 " AND sms.type != 3) + " + 1684 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1685 " ON threads._id = thread_id" + 1686 " WHERE thread_id = old.thread_id" + 1687 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1688 " AND msg_box != 3) " + 1689 " WHERE threads._id = old.thread_id; " + 1690 " UPDATE threads SET snippet = " + 1691 " (SELECT snippet FROM" + 1692 " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" + 1693 " UNION SELECT date, body AS snippet, thread_id FROM sms)" + 1694 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 1695 " WHERE threads._id = OLD.thread_id; " + 1696 " UPDATE threads SET snippet_cs = " + 1697 " (SELECT snippet_cs FROM" + 1698 " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" + 1699 " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" + 1700 " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + 1701 " WHERE threads._id = OLD.thread_id; " + 1702 "END;"); 1703 1704 db.execSQL("CREATE TABLE temp_part (" + 1705 "_id INTEGER PRIMARY KEY," + 1706 "mid INTEGER," + 1707 "seq INTEGER DEFAULT 0," + 1708 "ct TEXT," + 1709 "name TEXT," + 1710 "chset INTEGER," + 1711 "cd TEXT," + 1712 "fn TEXT," + 1713 "cid TEXT," + 1714 "cl TEXT," + 1715 "ctt_s INTEGER," + 1716 "ctt_t TEXT," + 1717 "_data TEXT);"); 1718 db.execSQL("INSERT INTO temp_part SELECT * FROM part;"); 1719 db.execSQL("UPDATE temp_part SET seq='0';"); 1720 db.execSQL("UPDATE temp_part SET seq='-1' WHERE ct='application/smil';"); 1721 db.execSQL("DROP TABLE IF EXISTS part;"); 1722 db.execSQL("ALTER TABLE temp_part RENAME TO part;"); 1723 } 1724 1725 private void upgradeDatabaseToVersion38(SQLiteDatabase db) { 1726 db.execSQL("DROP TRIGGER IF EXISTS part_file_cleanup;"); 1727 db.execSQL("DROP TRIGGER IF EXISTS drm_file_cleanup;"); 1728 } 1729 1730 private void upgradeDatabaseToVersion39(SQLiteDatabase db) { 1731 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert"); 1732 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update"); 1733 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 1734 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 1735 1736 db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " + 1737 "BEGIN" + 1738 " UPDATE threads SET" + 1739 " date = (strftime('%s','now') * 1000), " + 1740 " snippet = new.body," + 1741 " snippet_cs = 0" + 1742 " WHERE threads._id = new.thread_id; " + 1743 " UPDATE threads SET message_count = " + 1744 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1745 " ON threads._id = thread_id" + 1746 " WHERE thread_id = new.thread_id" + 1747 " AND sms.type != 3) + " + 1748 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1749 " ON threads._id = thread_id" + 1750 " WHERE thread_id = new.thread_id" + 1751 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1752 " AND msg_box != 3 " + 1753 " AND pdu.m_id is NULL) + " + 1754 " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " + 1755 " ON threads._id = thread_id" + 1756 " WHERE thread_id = new.thread_id" + 1757 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1758 " AND msg_box != 3 " + 1759 " AND pdu.m_id is not NULL) " + 1760 " WHERE threads._id = new.thread_id; " + 1761 " UPDATE threads SET read = " + 1762 " CASE (SELECT COUNT(*)" + 1763 " FROM sms" + 1764 " WHERE read = 0" + 1765 " AND thread_id = threads._id)" + 1766 " WHEN 0 THEN 1" + 1767 " ELSE 0" + 1768 " END" + 1769 " WHERE threads._id = new.thread_id; " + 1770 "END;"); 1771 1772 db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" + 1773 " UPDATE OF date, body, type" + 1774 " ON sms " + 1775 "BEGIN" + 1776 " UPDATE threads SET" + 1777 " date = (strftime('%s','now') * 1000), " + 1778 " snippet = new.body," + 1779 " snippet_cs = 0" + 1780 " WHERE threads._id = new.thread_id; " + 1781 " UPDATE threads SET message_count = " + 1782 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1783 " ON threads._id = thread_id" + 1784 " WHERE thread_id = new.thread_id" + 1785 " AND sms.type != 3) + " + 1786 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1787 " ON threads._id = thread_id" + 1788 " WHERE thread_id = new.thread_id" + 1789 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1790 " AND msg_box != 3 " + 1791 " AND pdu.m_id is NULL) + " + 1792 " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " + 1793 " ON threads._id = thread_id" + 1794 " WHERE thread_id = new.thread_id" + 1795 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1796 " AND msg_box != 3 " + 1797 " AND pdu.m_id is not NULL) " + 1798 " WHERE threads._id = new.thread_id; " + 1799 " UPDATE threads SET read = " + 1800 " CASE (SELECT COUNT(*)" + 1801 " FROM sms" + 1802 " WHERE read = 0" + 1803 " AND thread_id = threads._id)" + 1804 " WHEN 0 THEN 1" + 1805 " ELSE 0" + 1806 " END" + 1807 " WHERE threads._id = new.thread_id; " + 1808 "END;"); 1809 1810 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " + 1811 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1812 "BEGIN" + 1813 " UPDATE threads SET" + 1814 " date = (strftime('%s','now') * 1000), " + 1815 " snippet = new.sub, " + 1816 " snippet_cs = new.sub_cs" + 1817 " WHERE threads._id = new.thread_id; " + 1818 " UPDATE threads SET message_count = " + 1819 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1820 " ON threads._id = thread_id" + 1821 " WHERE thread_id = new.thread_id" + 1822 " AND sms.type != 3) + " + 1823 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1824 " ON threads._id = thread_id" + 1825 " WHERE thread_id = new.thread_id" + 1826 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1827 " AND msg_box != 3 " + 1828 " AND pdu.m_id is NULL) + " + 1829 " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " + 1830 " ON threads._id = thread_id" + 1831 " WHERE thread_id = new.thread_id" + 1832 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1833 " AND msg_box != 3 " + 1834 " AND pdu.m_id is not NULL) " + 1835 " WHERE threads._id = new.thread_id; " + 1836 " UPDATE threads SET read = " + 1837 " CASE (SELECT COUNT(*)" + 1838 " FROM pdu" + 1839 " WHERE read = 0 AND thread_id = threads._id)" + 1840 " WHEN 0 THEN 1 ELSE 0" + 1841 " END" + 1842 " WHERE threads._id = new.thread_id; " + 1843 "END;"); 1844 1845 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 1846 " UPDATE OF date, sub, msg_box ON pdu " + 1847 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1848 "BEGIN" + 1849 " UPDATE threads SET" + 1850 " date = (strftime('%s','now') * 1000), " + 1851 " snippet = new.sub, " + 1852 " snippet_cs = new.sub_cs" + 1853 " WHERE threads._id = new.thread_id; " + 1854 " UPDATE threads SET message_count = " + 1855 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1856 " ON threads._id = thread_id" + 1857 " WHERE thread_id = new.thread_id" + 1858 " AND sms.type != 3) + " + 1859 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1860 " ON threads._id = thread_id" + 1861 " WHERE thread_id = new.thread_id" + 1862 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1863 " AND msg_box != 3 " + 1864 " AND pdu.m_id is NULL) + " + 1865 " (SELECT COUNT(DISTINCT pdu.m_id) FROM pdu LEFT JOIN threads " + 1866 " ON threads._id = thread_id" + 1867 " WHERE thread_id = new.thread_id" + 1868 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1869 " AND msg_box != 3 " + 1870 " AND pdu.m_id is not NULL) " + 1871 " WHERE threads._id = new.thread_id; " + 1872 " UPDATE threads SET read = " + 1873 " CASE (SELECT COUNT(*)" + 1874 " FROM pdu" + 1875 " WHERE read = 0 AND thread_id = threads._id)" + 1876 " WHEN 0 THEN 1 ELSE 0" + 1877 " END" + 1878 " WHERE threads._id = new.thread_id; " + 1879 "END;"); 1880 } 1881 1882 private void upgradeDatabaseToVersion40(SQLiteDatabase db) { 1883 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_insert"); 1884 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_date_subject_on_update"); 1885 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_on_insert"); 1886 db.execSQL("DROP TRIGGER IF EXISTS pdu_update_thread_date_subject_on_update"); 1887 1888 db.execSQL("CREATE TRIGGER sms_update_thread_on_insert AFTER INSERT ON sms " + 1889 "BEGIN" + 1890 " UPDATE threads SET" + 1891 " date = (strftime('%s','now') * 1000), " + 1892 " snippet = new.body," + 1893 " snippet_cs = 0" + 1894 " WHERE threads._id = new.thread_id; " + 1895 " UPDATE threads SET message_count = " + 1896 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1897 " ON threads._id = thread_id" + 1898 " WHERE thread_id = new.thread_id" + 1899 " AND sms.type != 3) + " + 1900 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1901 " ON threads._id = thread_id" + 1902 " WHERE thread_id = new.thread_id" + 1903 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1904 " AND msg_box != 3) " + 1905 " WHERE threads._id = new.thread_id; " + 1906 " UPDATE threads SET read = " + 1907 " CASE (SELECT COUNT(*)" + 1908 " FROM sms" + 1909 " WHERE read = 0" + 1910 " AND thread_id = threads._id)" + 1911 " WHEN 0 THEN 1" + 1912 " ELSE 0" + 1913 " END" + 1914 " WHERE threads._id = new.thread_id; " + 1915 "END;"); 1916 1917 db.execSQL("CREATE TRIGGER sms_update_thread_date_subject_on_update AFTER" + 1918 " UPDATE OF date, body, type" + 1919 " ON sms " + 1920 "BEGIN" + 1921 " UPDATE threads SET" + 1922 " date = (strftime('%s','now') * 1000), " + 1923 " snippet = new.body," + 1924 " snippet_cs = 0" + 1925 " WHERE threads._id = new.thread_id; " + 1926 " UPDATE threads SET message_count = " + 1927 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1928 " ON threads._id = thread_id" + 1929 " WHERE thread_id = new.thread_id" + 1930 " AND sms.type != 3) + " + 1931 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1932 " ON threads._id = thread_id" + 1933 " WHERE thread_id = new.thread_id" + 1934 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1935 " AND msg_box != 3) " + 1936 " WHERE threads._id = new.thread_id; " + 1937 " UPDATE threads SET read = " + 1938 " CASE (SELECT COUNT(*)" + 1939 " FROM sms" + 1940 " WHERE read = 0" + 1941 " AND thread_id = threads._id)" + 1942 " WHEN 0 THEN 1" + 1943 " ELSE 0" + 1944 " END" + 1945 " WHERE threads._id = new.thread_id; " + 1946 "END;"); 1947 1948 db.execSQL("CREATE TRIGGER pdu_update_thread_on_insert AFTER INSERT ON pdu " + 1949 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1950 "BEGIN" + 1951 " UPDATE threads SET" + 1952 " date = (strftime('%s','now') * 1000), " + 1953 " snippet = new.sub, " + 1954 " snippet_cs = new.sub_cs" + 1955 " WHERE threads._id = new.thread_id; " + 1956 " UPDATE threads SET message_count = " + 1957 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1958 " ON threads._id = thread_id" + 1959 " WHERE thread_id = new.thread_id" + 1960 " AND sms.type != 3) + " + 1961 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1962 " ON threads._id = thread_id" + 1963 " WHERE thread_id = new.thread_id" + 1964 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1965 " AND msg_box != 3) " + 1966 " WHERE threads._id = new.thread_id; " + 1967 " UPDATE threads SET read = " + 1968 " CASE (SELECT COUNT(*)" + 1969 " FROM pdu" + 1970 " WHERE read = 0 AND thread_id = threads._id)" + 1971 " WHEN 0 THEN 1 ELSE 0" + 1972 " END" + 1973 " WHERE threads._id = new.thread_id; " + 1974 "END;"); 1975 1976 db.execSQL("CREATE TRIGGER pdu_update_thread_date_subject_on_update AFTER" + 1977 " UPDATE OF date, sub, msg_box ON pdu " + 1978 " WHEN new.m_type=132 OR new.m_type=130 OR new.m_type=128 " + 1979 "BEGIN" + 1980 " UPDATE threads SET" + 1981 " date = (strftime('%s','now') * 1000), " + 1982 " snippet = new.sub, " + 1983 " snippet_cs = new.sub_cs" + 1984 " WHERE threads._id = new.thread_id; " + 1985 " UPDATE threads SET message_count = " + 1986 " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + 1987 " ON threads._id = thread_id" + 1988 " WHERE thread_id = new.thread_id" + 1989 " AND sms.type != 3) + " + 1990 " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + 1991 " ON threads._id = thread_id" + 1992 " WHERE thread_id = new.thread_id" + 1993 " AND (m_type=132 OR m_type=130 OR m_type=128)" + 1994 " AND msg_box != 3) " + 1995 " WHERE threads._id = new.thread_id; " + 1996 " UPDATE threads SET read = " + 1997 " CASE (SELECT COUNT(*)" + 1998 " FROM pdu" + 1999 " WHERE read = 0 AND thread_id = threads._id)" + 2000 " WHEN 0 THEN 1 ELSE 0" + 2001 " END" + 2002 " WHERE threads._id = new.thread_id; " + 2003 "END;"); 2004 } 2005 2006 private void upgradeDatabaseToVersion41(SQLiteDatabase db) { 2007 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_move_mms"); 2008 db.execSQL("CREATE TRIGGER update_threads_error_on_move_mms " + 2009 " BEFORE UPDATE OF msg_box ON pdu " + 2010 " WHEN (OLD.msg_box = 4 AND NEW.msg_box != 4) " + 2011 " AND (OLD._id IN (SELECT DISTINCT msg_id" + 2012 " FROM pending_msgs" + 2013 " WHERE err_type >= 10)) " + 2014 "BEGIN " + 2015 " UPDATE threads SET error = error - 1" + 2016 " WHERE _id = OLD.thread_id; " + 2017 "END;"); 2018 } 2019 2020 private void upgradeDatabaseToVersion42(SQLiteDatabase db) { 2021 db.execSQL("DROP TRIGGER IF EXISTS sms_update_thread_on_delete"); 2022 db.execSQL("DROP TRIGGER IF EXISTS delete_obsolete_threads_sms"); 2023 db.execSQL("DROP TRIGGER IF EXISTS update_threads_error_on_delete_sms"); 2024 } 2025} 2026