search work

1.  introduce an FTS3 indexed table called "words"
2.  put all sms messages into the words table (done in the SmsProvider's insert).
3.  put all part messages which are plain text into the words table (done in the MmsProvider's insert).
4.  put triggers on the delete and update for sms and part and update words appropriately.
5.  remove the search recents code (mainly commented out) within the mms app.
6.  implement a suggest provider which queries the words table for matches.
7.  modify the search activity to use the words table rather than a LIKE clause.
8.  modify the search activity to use a regular expression (rather than String.indexOf) for
    generating the snippet and highlighting the appropriate words within the snippet.  NOTE
    that originally I wanted to compute the matching words positions using the sql offsets
    function but it doesn't work within the slightly complicated query which is used for
    doing the search (two joins and a union, etc.)
9.  modify the highlighting code within compose message activity to use regular expressions
    rather than indexof to do the highlighting.
10. what else did I forget?
diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java
index 74c69f1..c0fa0f3 100644
--- a/src/com/android/providers/telephony/MmsProvider.java
+++ b/src/com/android/providers/telephony/MmsProvider.java
@@ -30,6 +30,7 @@
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.provider.BaseColumns;
+import android.provider.Telephony;
 import android.provider.Telephony.Mms;
 import android.provider.Telephony.MmsSms;
 import android.provider.Telephony.Mms.Addr;
@@ -53,6 +54,7 @@
     static final String TABLE_PART = "part";
     static final String TABLE_RATE = "rate";
     static final String TABLE_DRM  = "drm";
+    static final String TABLE_WORDS = "words";
 
     @Override
     public boolean onCreate() {
@@ -367,10 +369,12 @@
             }
 
             String contentType = values.getAsString("ct");
-            
+
             // text/plain and app application/smil store their "data" inline in the
             // table so there's no need to create the file
-            if (!"text/plain".equals(contentType) && !"application/smil".equals(contentType)) {
+            boolean plainText = "text/plain".equals(contentType);
+            boolean smilText = "application/smil".equals(contentType);
+            if (!plainText && !smilText) {
                 // Generate the '_data' field of the part with default
                 // permission settings.
                 String path = getContext().getDir("parts", 0).getPath()
@@ -399,6 +403,26 @@
             }
 
             res = Uri.parse(res + "/part/" + rowId);
+
+            // Don't use a trigger for updating the words table because of a bug
+            // in FTS3.  The bug is such that the call to get the last inserted
+            // row is incorrect.
+            if (plainText) {
+                // Update the words table with a corresponding row.  The words table
+                // allows us to search for words quickly, without scanning the whole
+                // table;
+                ContentValues cv = new ContentValues();
+
+                // we're using the row id of the part table row but we're also using ids
+                // from the sms table so this divides the space into two large chunks.
+                // The row ids from the part table start at 2 << 32.
+                cv.put(Telephony.MmsSms.WordsTable.ID, (2 << 32) + rowId);
+                cv.put(Telephony.MmsSms.WordsTable.INDEXED_TEXT, values.getAsString("text"));
+                cv.put(Telephony.MmsSms.WordsTable.SOURCE_ROW_ID, rowId);
+                cv.put(Telephony.MmsSms.WordsTable.TABLE_ID, 2);
+                db.insert(TABLE_WORDS, Telephony.MmsSms.WordsTable.INDEXED_TEXT, cv);
+            }
+
         } else if (table.equals(TABLE_RATE)) {
             long now = values.getAsLong(Rate.SENT_TIME);
             long oneHourAgo = now - 1000 * 60 * 60;