@ -16,11 +16,13 @@
* /
* /
package org.thoughtcrime.securesms.database ;
package org.thoughtcrime.securesms.database ;
import android.annotation.TargetApi ;
import android.content.Context ;
import android.content.Context ;
import android.database.Cursor ;
import android.database.Cursor ;
import android.database.sqlite.SQLiteDatabase ;
import android.database.sqlite.SQLiteDatabase ;
import android.database.sqlite.SQLiteOpenHelper ;
import android.database.sqlite.SQLiteOpenHelper ;
import android.database.sqlite.SQLiteQueryBuilder ;
import android.database.sqlite.SQLiteQueryBuilder ;
import android.os.Build ;
import android.support.annotation.NonNull ;
import android.support.annotation.NonNull ;
import android.support.annotation.Nullable ;
import android.support.annotation.Nullable ;
import android.util.Log ;
import android.util.Log ;
@ -34,33 +36,44 @@ import java.util.Set;
public class MmsSmsDatabase extends Database {
public class MmsSmsDatabase extends Database {
private static final String TAG = MmsSmsDatabase . class . getSimpleName ( ) ;
public static final String TRANSPORT = "transport_type" ;
public static final String TRANSPORT = "transport_type" ;
public static final String MMS_TRANSPORT = "mms" ;
public static final String MMS_TRANSPORT = "mms" ;
public static final String SMS_TRANSPORT = "sms" ;
public static final String SMS_TRANSPORT = "sms" ;
private static final String [ ] PROJECTION = { MmsSmsColumns . ID , SmsDatabase . BODY , SmsDatabase . TYPE ,
MmsSmsColumns . THREAD_ID ,
SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT ,
MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . MESSAGE_TYPE , MmsDatabase . MESSAGE_BOX ,
SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY ,
MmsDatabase . STATUS , MmsSmsColumns . RECEIPT_COUNT ,
MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT ,
AttachmentDatabase . ATTACHMENT_ID_ALIAS ,
AttachmentDatabase . UNIQUE_ID ,
AttachmentDatabase . MMS_ID ,
AttachmentDatabase . SIZE ,
AttachmentDatabase . DATA ,
AttachmentDatabase . CONTENT_TYPE ,
AttachmentDatabase . CONTENT_LOCATION ,
AttachmentDatabase . CONTENT_DISPOSITION ,
AttachmentDatabase . NAME ,
AttachmentDatabase . TRANSFER_STATE } ;
public MmsSmsDatabase ( Context context , SQLiteOpenHelper databaseHelper ) {
public MmsSmsDatabase ( Context context , SQLiteOpenHelper databaseHelper ) {
super ( context , databaseHelper ) ;
super ( context , databaseHelper ) ;
}
}
public Cursor getConversation ( long threadId , long limit ) {
public Cursor getConversation ( long threadId , long limit ) {
String [ ] projection = { MmsSmsColumns . ID , SmsDatabase . BODY , SmsDatabase . TYPE ,
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " DESC" ;
MmsSmsColumns . THREAD_ID ,
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId ;
SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT ,
MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . MESSAGE_TYPE , MmsDatabase . MESSAGE_BOX ,
SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY ,
MmsDatabase . STATUS , MmsSmsColumns . RECEIPT_COUNT ,
MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " DESC" ;
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId ;
Cursor cursor = queryTables ( PROJECTION , selection , order , limit > 0 ? String . valueOf ( limit ) : null ) ;
Cursor cursor = queryTables ( projection , selection , selection , order , null , limit > 0 ? String . valueOf ( limit ) : null ) ;
setNotifyConverationListeners ( cursor , threadId ) ;
setNotifyConverationListeners ( cursor , threadId ) ;
return cursor ;
return cursor ;
@ -71,67 +84,27 @@ public class MmsSmsDatabase extends Database {
}
}
public Cursor getIdentityConflictMessagesForThread ( long threadId ) {
public Cursor getIdentityConflictMessagesForThread ( long threadId ) {
String [ ] projection = { MmsSmsColumns . ID , SmsDatabase . BODY , SmsDatabase . TYPE ,
MmsSmsColumns . THREAD_ID ,
SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT ,
MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . MESSAGE_TYPE , MmsDatabase . MESSAGE_BOX ,
SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY ,
MmsDatabase . STATUS , MmsSmsColumns . RECEIPT_COUNT ,
MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " ASC" ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " ASC" ;
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId + " AND " + MmsSmsColumns . MISMATCHED_IDENTITIES + " IS NOT NULL" ;
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId + " AND " + MmsSmsColumns . MISMATCHED_IDENTITIES + " IS NOT NULL" ;
Cursor cursor = queryTables ( projection, selection , selection , order , null , null ) ;
Cursor cursor = queryTables ( PROJECTION , selection , order , null ) ;
setNotifyConverationListeners ( cursor , threadId ) ;
setNotifyConverationListeners ( cursor , threadId ) ;
return cursor ;
return cursor ;
}
}
public Cursor getConversationSnippet ( long threadId ) {
public Cursor getConversationSnippet ( long threadId ) {
String [ ] projection = { MmsSmsColumns . ID , SmsDatabase . BODY , SmsDatabase . TYPE ,
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " DESC" ;
MmsSmsColumns . THREAD_ID ,
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId ;
SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT ,
MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . MESSAGE_TYPE , MmsDatabase . MESSAGE_BOX ,
SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY ,
MmsDatabase . STATUS , MmsSmsColumns . RECEIPT_COUNT ,
MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " DESC" ;
String selection = MmsSmsColumns . THREAD_ID + " = " + threadId ;
return queryTables ( projection, selection , selection , order , null , "1" ) ;
return queryTables ( PROJECTION , selection , order , "1" ) ;
}
}
public Cursor getUnread ( ) {
public Cursor getUnread ( ) {
String [ ] projection = { MmsSmsColumns . ID , SmsDatabase . BODY , SmsDatabase . READ , SmsDatabase . TYPE ,
SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT , MmsSmsColumns . THREAD_ID ,
SmsDatabase . STATUS ,
MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . MESSAGE_TYPE , MmsDatabase . MESSAGE_BOX ,
MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY ,
MmsDatabase . STATUS , MmsSmsColumns . RECEIPT_COUNT ,
MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " ASC" ;
String order = MmsSmsColumns . NORMALIZED_DATE_RECEIVED + " ASC" ;
String selection = MmsSmsColumns . READ + " = 0" ;
String selection = MmsSmsColumns . READ + " = 0" ;
return queryTables ( projection, selection , selection , order , null , null ) ;
return queryTables ( PROJECTION , selection , order , null ) ;
}
}
public int getConversationCount ( long threadId ) {
public int getConversationCount ( long threadId ) {
@ -146,27 +119,47 @@ public class MmsSmsDatabase extends Database {
DatabaseFactory . getMmsDatabase ( context ) . incrementDeliveryReceiptCount ( address , timestamp ) ;
DatabaseFactory . getMmsDatabase ( context ) . incrementDeliveryReceiptCount ( address , timestamp ) ;
}
}
private Cursor queryTables ( String [ ] projection , String s msSelection, String mmsS election, String order , String groupBy , String limit ) {
private Cursor queryTables ( String [ ] projection , String s election, String order , String limit ) {
String [ ] mmsProjection = { MmsDatabase . DATE_SENT + " AS " + MmsSmsColumns . NORMALIZED_DATE_SENT ,
String [ ] mmsProjection = { MmsDatabase . DATE_SENT + " AS " + MmsSmsColumns . NORMALIZED_DATE_SENT ,
MmsDatabase . DATE_RECEIVED + " AS " + MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsDatabase . DATE_RECEIVED + " AS " + MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsSmsColumns . ID , SmsDatabase . BODY , MmsSmsColumns . READ , MmsSmsColumns . THREAD_ID ,
MmsDatabase . TABLE_NAME + "." + MmsDatabase . ID + " AS " + MmsSmsColumns . ID ,
AttachmentDatabase . TABLE_NAME + "." + AttachmentDatabase . ROW_ID + " AS " + AttachmentDatabase . ATTACHMENT_ID_ALIAS ,
SmsDatabase . BODY , MmsSmsColumns . READ , MmsSmsColumns . THREAD_ID ,
SmsDatabase . TYPE , SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT , MmsDatabase . MESSAGE_TYPE ,
SmsDatabase . TYPE , SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT , MmsDatabase . MESSAGE_TYPE ,
MmsDatabase . MESSAGE_BOX , SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . MESSAGE_BOX , SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY , MmsDatabase . STATUS ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY , MmsDatabase . STATUS ,
MmsSmsColumns . RECEIPT_COUNT , MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsSmsColumns . RECEIPT_COUNT , MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
MmsDatabase . NETWORK_FAILURE , TRANSPORT ,
AttachmentDatabase . UNIQUE_ID ,
AttachmentDatabase . MMS_ID ,
AttachmentDatabase . SIZE ,
AttachmentDatabase . DATA ,
AttachmentDatabase . CONTENT_TYPE ,
AttachmentDatabase . CONTENT_LOCATION ,
AttachmentDatabase . CONTENT_DISPOSITION ,
AttachmentDatabase . NAME ,
AttachmentDatabase . TRANSFER_STATE } ;
String [ ] smsProjection = { SmsDatabase . DATE_SENT + " AS " + MmsSmsColumns . NORMALIZED_DATE_SENT ,
String [ ] smsProjection = { SmsDatabase . DATE_SENT + " AS " + MmsSmsColumns . NORMALIZED_DATE_SENT ,
SmsDatabase . DATE_RECEIVED + " AS " + MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
SmsDatabase . DATE_RECEIVED + " AS " + MmsSmsColumns . NORMALIZED_DATE_RECEIVED ,
MmsSmsColumns . ID , SmsDatabase . BODY , MmsSmsColumns . READ , MmsSmsColumns . THREAD_ID ,
MmsSmsColumns . ID , "NULL AS " + AttachmentDatabase . ATTACHMENT_ID_ALIAS ,
SmsDatabase . BODY , MmsSmsColumns . READ , MmsSmsColumns . THREAD_ID ,
SmsDatabase . TYPE , SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT , MmsDatabase . MESSAGE_TYPE ,
SmsDatabase . TYPE , SmsDatabase . ADDRESS , SmsDatabase . ADDRESS_DEVICE_ID , SmsDatabase . SUBJECT , MmsDatabase . MESSAGE_TYPE ,
MmsDatabase . MESSAGE_BOX , SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . MESSAGE_BOX , SmsDatabase . STATUS , MmsDatabase . PART_COUNT ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . CONTENT_LOCATION , MmsDatabase . TRANSACTION_ID ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY , MmsDatabase . STATUS ,
MmsDatabase . MESSAGE_SIZE , MmsDatabase . EXPIRY , MmsDatabase . STATUS ,
MmsSmsColumns . RECEIPT_COUNT , MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsSmsColumns . RECEIPT_COUNT , MmsSmsColumns . MISMATCHED_IDENTITIES ,
MmsDatabase . NETWORK_FAILURE , TRANSPORT } ;
MmsDatabase . NETWORK_FAILURE , TRANSPORT ,
AttachmentDatabase . UNIQUE_ID ,
AttachmentDatabase . MMS_ID ,
AttachmentDatabase . SIZE ,
AttachmentDatabase . DATA ,
AttachmentDatabase . CONTENT_TYPE ,
AttachmentDatabase . CONTENT_LOCATION ,
AttachmentDatabase . CONTENT_DISPOSITION ,
AttachmentDatabase . NAME ,
AttachmentDatabase . TRANSFER_STATE } ;
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder ( ) ;
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder ( ) ;
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder ( ) ;
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder ( ) ;
@ -174,10 +167,10 @@ public class MmsSmsDatabase extends Database {
mmsQueryBuilder . setDistinct ( true ) ;
mmsQueryBuilder . setDistinct ( true ) ;
smsQueryBuilder . setDistinct ( true ) ;
smsQueryBuilder . setDistinct ( true ) ;
mmsQueryBuilder . setTables ( MmsDatabase . TABLE_NAME ) ;
mmsQueryBuilder . setTables ( MmsDatabase . TABLE_NAME + " LEFT OUTER JOIN " + AttachmentDatabase . TABLE_NAME + " ON (" + MmsDatabase . TABLE_NAME + "." + MmsDatabase . ID + " = " + AttachmentDatabase . TABLE_NAME + "." + AttachmentDatabase . MMS_ID + ")" ) ;
smsQueryBuilder . setTables ( SmsDatabase . TABLE_NAME ) ;
smsQueryBuilder . setTables ( SmsDatabase . TABLE_NAME ) ;
Set < String > mmsColumnsPresent = new HashSet < String > ( ) ;
Set < String > mmsColumnsPresent = new HashSet < > ( ) ;
mmsColumnsPresent . add ( MmsSmsColumns . ID ) ;
mmsColumnsPresent . add ( MmsSmsColumns . ID ) ;
mmsColumnsPresent . add ( MmsSmsColumns . READ ) ;
mmsColumnsPresent . add ( MmsSmsColumns . READ ) ;
mmsColumnsPresent . add ( MmsSmsColumns . THREAD_ID ) ;
mmsColumnsPresent . add ( MmsSmsColumns . THREAD_ID ) ;
@ -198,7 +191,16 @@ public class MmsSmsDatabase extends Database {
mmsColumnsPresent . add ( MmsDatabase . STATUS ) ;
mmsColumnsPresent . add ( MmsDatabase . STATUS ) ;
mmsColumnsPresent . add ( MmsDatabase . NETWORK_FAILURE ) ;
mmsColumnsPresent . add ( MmsDatabase . NETWORK_FAILURE ) ;
Set < String > smsColumnsPresent = new HashSet < String > ( ) ;
mmsColumnsPresent . add ( AttachmentDatabase . ROW_ID ) ;
mmsColumnsPresent . add ( AttachmentDatabase . UNIQUE_ID ) ;
mmsColumnsPresent . add ( AttachmentDatabase . SIZE ) ;
mmsColumnsPresent . add ( AttachmentDatabase . CONTENT_TYPE ) ;
mmsColumnsPresent . add ( AttachmentDatabase . CONTENT_LOCATION ) ;
mmsColumnsPresent . add ( AttachmentDatabase . CONTENT_DISPOSITION ) ;
mmsColumnsPresent . add ( AttachmentDatabase . NAME ) ;
mmsColumnsPresent . add ( AttachmentDatabase . TRANSFER_STATE ) ;
Set < String > smsColumnsPresent = new HashSet < > ( ) ;
smsColumnsPresent . add ( MmsSmsColumns . ID ) ;
smsColumnsPresent . add ( MmsSmsColumns . ID ) ;
smsColumnsPresent . add ( MmsSmsColumns . BODY ) ;
smsColumnsPresent . add ( MmsSmsColumns . BODY ) ;
smsColumnsPresent . add ( MmsSmsColumns . ADDRESS ) ;
smsColumnsPresent . add ( MmsSmsColumns . ADDRESS ) ;
@ -213,16 +215,16 @@ public class MmsSmsDatabase extends Database {
smsColumnsPresent . add ( SmsDatabase . DATE_RECEIVED ) ;
smsColumnsPresent . add ( SmsDatabase . DATE_RECEIVED ) ;
smsColumnsPresent . add ( SmsDatabase . STATUS ) ;
smsColumnsPresent . add ( SmsDatabase . STATUS ) ;
String mmsSubQuery = mmsQueryBuilder . buildUnionSubQuery ( TRANSPORT , mmsProjection , mmsColumnsPresent , 2, MMS_TRANSPORT , mmsS election, null , null , null ) ;
String mmsSubQuery = mmsQueryBuilder . buildUnionSubQuery ( TRANSPORT , mmsProjection , mmsColumnsPresent , 3, MMS_TRANSPORT , s election, null , null , null ) ;
String smsSubQuery = smsQueryBuilder . buildUnionSubQuery ( TRANSPORT , smsProjection , smsColumnsPresent , 2 , SMS_TRANSPORT , s msS election, null , null , null ) ;
String smsSubQuery = smsQueryBuilder . buildUnionSubQuery ( TRANSPORT , smsProjection , smsColumnsPresent , 3 , SMS_TRANSPORT , s election, null , null , null ) ;
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder ( ) ;
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder ( ) ;
String unionQuery = unionQueryBuilder . buildUnionQuery ( new String [ ] { smsSubQuery , mmsSubQuery } , order , null ) ;
String unionQuery = unionQueryBuilder . buildUnionQuery ( new String [ ] { smsSubQuery , mmsSubQuery } , order , limit ) ;
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder ( ) ;
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder ( ) ;
outerQueryBuilder . setTables ( "(" + unionQuery + ")" ) ;
outerQueryBuilder . setTables ( "(" + unionQuery + ")" ) ;
String query = outerQueryBuilder . buildQuery ( projection , null , null , groupBy , null , null , limit ) ;
String query = outerQueryBuilder . buildQuery ( projection , null , null , null , null , null , null ) ;
Log . w ( "MmsSmsDatabase" , "Executing query: " + query ) ;
Log . w ( "MmsSmsDatabase" , "Executing query: " + query ) ;
SQLiteDatabase db = databaseHelper . getReadableDatabase ( ) ;
SQLiteDatabase db = databaseHelper . getReadableDatabase ( ) ;
@ -277,14 +279,15 @@ public class MmsSmsDatabase extends Database {
return getCurrent ( ) ;
return getCurrent ( ) ;
}
}
@TargetApi ( Build . VERSION_CODES . HONEYCOMB )
public MessageRecord getCurrent ( ) {
public MessageRecord getCurrent ( ) {
String type = cursor . getString ( cursor . getColumnIndexOrThrow ( TRANSPORT ) ) ;
String type = cursor . getString ( cursor . getColumnIndexOrThrow ( TRANSPORT ) ) ;
if ( MmsSmsDatabase . MMS_TRANSPORT . equals ( type ) ) {
Log . w ( "MmsSmsDatabase" , "Type: " + type ) ;
return getMmsReader ( ) . getCurrent ( ) ;
} else {
if ( MmsSmsDatabase . MMS_TRANSPORT . equals ( type ) ) return getMmsReader ( ) . getCurrent ( ) ;
return getSmsReader ( ) . getCurrent ( ) ;
else if ( MmsSmsDatabase . SMS_TRANSPORT . equals ( type ) ) return getSmsReader ( ) . getCurrent ( ) ;
}
else throw new AssertionError ( "Bad type: " + type ) ;
}
}
public void close ( ) {
public void close ( ) {