package de.thedevstack.conversationsplus.persistance.db.access; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.enums.FileStatus; import de.thedevstack.conversationsplus.persistance.db.migrations.FileParamsBodyToDatabaseFieldsMigration; import eu.siacs.conversations.entities.Message; /** * */ public class MessageDatabaseAccess extends AbstractDatabaseAccess { // since cplus db version 1 public static final String TABLE_NAME_ADDITIONAL_PARAMETERS = "message_parameters"; private static final String COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD = "httpupload"; private static final String COLUMN_NAME_MSG_PARAMS_MSGUUID = "message_uuid"; private static final String COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION = "treatasdownloadable_decision"; // since cplus db version 3 private static final String COLUMN_NAME_MSG_PARAMS_FILE_SIZE = "file_size"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_TYPE = "file_type"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_WIDTH = "file_width"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT = "file_height"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_STATUS = "file_status"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_NAME = "file_name"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_PATH = "file_path"; private static final String COLUMN_NAME_MSG_PARAMS_FILE_URL = "file_url"; private static final String TABLE_ADDITIONAL_PARAMETERS_CREATE_V1 = "CREATE TABLE " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + " (" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + " TEXT, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD + " INTEGER DEFAULT 0, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION + " TEXT DEFAULT 'NOT_DECIDED', " + "FOREIGN KEY(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") REFERENCES " + Message.TABLENAME + "(" + Message.UUID + ") ON DELETE CASCADE)"; private static final String TABLE_ADDITIONAL_PARAMETERS_CREATE = "CREATE TABLE " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + " (" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + " TEXT, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD + " INTEGER DEFAULT 0, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION + " TEXT DEFAULT 'NOT_DECIDED', " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_TYPE + " TEXT DEFAULT NULL, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE + " INTEGER DEFAULT 0, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT + " INTEGER DEFAULT 0, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH + " INTEGER DEFAULT 0, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS + " TEXT DEFAULT 'UNDEFINED', " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_NAME + " TEXT DEFAULT NULL, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH + " TEXT DEFAULT NULL, " + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL + " TEXT DEFAULT NULL, " + "FOREIGN KEY(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") REFERENCES " + Message.TABLENAME + "(" + Message.UUID + ") ON DELETE CASCADE)"; public static void updateMessageParameters(SQLiteDatabase db, Message message, String uuid) { String[] args = {uuid}; db.update(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, MessageDatabaseAccess.getAdditionalParametersContentValues(message), MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", args); } public static ContentValues getAdditionalParametersContentValues(Message message) { ContentValues additionalParameters = new ContentValues(); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID, message.getUuid()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD, message.isHttpUploaded() ? 1 : 0); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION, message.treatAsDownloadable().name()); if (null != message.getFileParams()) { FileParams fileParams = message.getFileParams(); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_TYPE, fileParams.getMimeType()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE, fileParams.getSize()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT, fileParams.getHeight()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH, fileParams.getWidth()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH, fileParams.getPath()); additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_URL, fileParams.getUrl()); if (null != fileParams.getFileStatus()) { additionalParameters.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS, fileParams.getFileStatus().name()); } } return additionalParameters; } private static void populateMessageParametersFromCursor(Cursor cursor, Message message) { boolean isHttpUploaded = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_HTTPUPLOAD) == 1; message.setHttpUploaded(isHttpUploaded); String downloadable = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_TREATASDOWNLOADABLE_DECISION); Message.Decision treatAsDownloadable = Message.Decision.NOT_DECIDED; try { treatAsDownloadable = Message.Decision.valueOf(downloadable); } catch (IllegalArgumentException e) { // Should only happen if the database is corrupted, but to be on the save side catch it here Logging.e("db.msg", "Unknown Decision for treatAsDownloadable found: '" + downloadable + "'"); } message.setTreatAsDownloadable(treatAsDownloadable); if (message.hasFileAttached()) { FileParams fileParams = new FileParams(message.getBody()); String fileType = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_TYPE); fileParams.setMimeType(fileType); String name = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_NAME); fileParams.setName(name); String path = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_PATH); fileParams.setPath(path); String url = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_URL); fileParams.setUrl(url); long fileSize = CursorHelper.getLong(cursor, COLUMN_NAME_MSG_PARAMS_FILE_SIZE); fileParams.setSize(fileSize); int imageHeight = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT); fileParams.setHeight(imageHeight); int imageWidth = CursorHelper.getInt(cursor, COLUMN_NAME_MSG_PARAMS_FILE_WIDTH); fileParams.setWidth(imageWidth); String status = CursorHelper.getString(cursor, COLUMN_NAME_MSG_PARAMS_FILE_STATUS); if (null != status && !status.isEmpty()) { FileStatus fileStatus = FileStatus.UNDEFINED; try { fileStatus = FileStatus.valueOf(status); } catch (IllegalArgumentException e) { // Should only happen if the database is corrupted, but to be on the save side catch it here Logging.e("db.msg", "Unknown FileStatus for fileParams.fileStatus found: '" + status + "'"); } fileParams.setFileStatus(fileStatus); } message.setFileParams(fileParams); } } public static void populateMessageParameters(SQLiteDatabase db, Message message) { Cursor paramsCursor = db.query(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, null, MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", new String[] {message.getUuid()}, null, null, null, null); paramsCursor.moveToNext(); MessageDatabaseAccess.populateMessageParametersFromCursor(paramsCursor, message); paramsCursor.close(); } public static void upgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 1 && newVersion >= 1) { Logging.d("db.upgrade.cplus", "Creating additional parameters table for messages."); db.execSQL(MessageDatabaseAccess.TABLE_ADDITIONAL_PARAMETERS_CREATE_V1); db.execSQL("INSERT INTO " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS + "(" + MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + ") " + " SELECT " + Message.UUID + " FROM " + Message.TABLENAME); } if (oldVersion < 3 && newVersion >= 3) { Logging.d("db.upgrade.cplus", "Upgrade " + MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS); String[] columnDefinitions = { MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_TYPE + " TEXT DEFAULT NULL", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE + " INTEGER DEFAULT 0", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT + " INTEGER DEFAULT 0", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH + " INTEGER DEFAULT 0", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_STATUS + " TEXT DEFAULT 'UNDEFINED'", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_NAME + " TEXT DEFAULT NULL", MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_PATH + " TEXT DEFAULT NULL", }; addNewColumns(db, MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, columnDefinitions); Logging.d("db.upgrade.cplus", "Migrate file params from message body to database fields"); Cursor cursor = db.rawQuery("SELECT " + Message.UUID + ", " + Message.BODY + " FROM " + Message.TABLENAME + " WHERE " + Message.TYPE + "=? OR " + Message.TYPE + "=?", new String[] {String.valueOf(Message.TYPE_FILE), String.valueOf(Message.TYPE_IMAGE)}); while (cursor.moveToNext()) { String uuid = CursorHelper.getString(cursor, Message.UUID); String body = CursorHelper.getString(cursor, Message.BODY); FileParams fileParams = FileParamsBodyToDatabaseFieldsMigration.getFileParams(body); String newBody = fileParams.getUrl(); ContentValues values = new ContentValues(); values.put(Message.BODY, newBody); db.update(Message.TABLENAME, values, Message.UUID + "=?", new String[] {uuid}); ContentValues parameterValues = new ContentValues(); parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_SIZE, fileParams.getSize()); parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_HEIGHT, fileParams.getHeight()); parameterValues.put(MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_FILE_WIDTH, fileParams.getWidth()); db.update(MessageDatabaseAccess.TABLE_NAME_ADDITIONAL_PARAMETERS, parameterValues, MessageDatabaseAccess.COLUMN_NAME_MSG_PARAMS_MSGUUID + "=?", new String[] {uuid}); } cursor.close(); } } public static void create(SQLiteDatabase db) { // Create Conversations+ related tables db.execSQL(MessageDatabaseAccess.TABLE_ADDITIONAL_PARAMETERS_CREATE); } }