转载请注明出处:http://blog.csdn.net/droyon/article/details/8724403
维护短彩信很长时间了,终于想写点什么了,那就从数据库开始吧!不当之处,欢迎指正。
关于LEFT_JOIN,INNER_JOIN等数据库知识,大家可以访问W3SCHOOL。
MmsSmsDatabaseHelper.java
1、首先看一下私有静态常量。这些静态常量在构建数据库触发器,构建数据表时会用到。
private static final String SMS_UPDATE_THREAD_READ_BODY = " UPDATE threads SET read = " + " CASE (SELECT COUNT(*)" + " FROM sms" + " WHERE " + Sms.READ + " = 0" + " AND " + Sms.THREAD_ID + " = threads._id)" + " WHEN 0 THEN 1" + " ELSE 0" + " END" + " WHERE threads._id = new." + Sms.THREAD_ID + "; ";大体是这样,里面内嵌了一个函数,函数内容是,首先查询sms数据表中Sms.THREAD_ID的值为threads._id的所有行,再次找出这些行中Sms.READ的值为0的行,统计其行数目。如果行数目为0,则输出1,否则输出0.将输出的值赋给threads数据表_id值为new.Sms.THREAD_ID所对应的行中的read字段。
说白了就是检查短信数据库中是否存在未读短信。
2、
private static final String UPDATE_THREAD_COUNT_ON_NEW = " UPDATE threads SET message_count = " + " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + " ON threads._id = " + Sms.THREAD_ID + " WHERE " + Sms.THREAD_ID + " = new.thread_id" + " AND sms." + Sms.TYPE + " != 3) + " + " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + " ON threads._id = " + Mms.THREAD_ID + " WHERE " + Mms.THREAD_ID + " = new.thread_id" + " AND (m_type=132 OR m_type=130 OR m_type=128)" + " AND " + Mms.MESSAGE_BOX + " != 3) " + " WHERE threads._id = new.thread_id; ";
说白了,就是将短信和彩信中信息的数据加在一起,存到threads数据表的message_count字段中。
3、
private static final String UPDATE_THREAD_COUNT_ON_OLD = " UPDATE threads SET message_count = " + " (SELECT COUNT(sms._id) FROM sms LEFT JOIN threads " + " ON threads._id = " + Sms.THREAD_ID + " WHERE " + Sms.THREAD_ID + " = old.thread_id" + " AND sms." + Sms.TYPE + " != 3) + " + " (SELECT COUNT(pdu._id) FROM pdu LEFT JOIN threads " + " ON threads._id = " + Mms.THREAD_ID + " WHERE " + Mms.THREAD_ID + " = old.thread_id" + " AND (m_type=132 OR m_type=130 OR m_type=128)" + " AND " + Mms.MESSAGE_BOX + " != 3) " + " WHERE threads._id = old.thread_id; ";和上面基本类似,不同在最后的where判断条件上
WHERE threads._id = new.thread_id;
WHERE threads._id = old.thread_id;
一个new,一个old很能说明问题,也就是说,这两个常量,一个用在处理新插入信息,一个处理旧的信息。
4、
private static final String SMS_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE = "BEGIN" + " UPDATE threads SET" + " date = (strftime('%s','now') * 1000), " + " snippet = new." + Sms.BODY + ", " + " snippet_cs = 0" + " WHERE threads._id = new." + Sms.THREAD_ID + "; " + UPDATE_THREAD_COUNT_ON_NEW + SMS_UPDATE_THREAD_READ_BODY + "END;";
这个常量用在处理那些新更新的数据,更新threads数据表的date字段、snippet字段(信息会话列表中,显示最新信息的部分提示),snippet_cs字段。然后使用我们前面介绍的两个静态常量。
说白了,在更新sms数据表时,触发更新threads数据表。
5、
private static final String PDU_UPDATE_THREAD_CONSTRAINTS = " WHEN new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + " OR new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND + " OR new." + Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_SEND_REQ + " ";这个静态常量字符串的意思是说,信息类型是发送的彩信或者接收的彩信类型,或者接收的彩信、但数据未下载的信息三种类型。
6、
private static final String PDU_UPDATE_THREAD_READ_BODY = " UPDATE threads SET read = " + " CASE (SELECT COUNT(*)" + " FROM " + MmsProvider.TABLE_PDU + " WHERE " + Mms.READ + " = 0" + " AND " + Mms.THREAD_ID + " = threads._id " + " AND (m_type=132 OR m_type=130 OR m_type=128)) " + " WHEN 0 THEN 1" + " ELSE 0" + " END" + " WHERE threads._id = new." + Mms.THREAD_ID + "; ";和短信一样,计算彩信中是否存在未读信息,如果存在在threads数据表中置标志为。检索的彩信仅仅是发送或者接收也就是5中所描述的三种彩信。
7、
private static final String PDU_UPDATE_THREAD_DATE_SNIPPET_COUNT_ON_UPDATE = "BEGIN" + " UPDATE threads SET" + " date = (strftime('%s','now') * 1000), " + " snippet = new." + Mms.SUBJECT + ", " + " snippet_cs = new." + Mms.SUBJECT_CHARSET + " WHERE threads._id = new." + Mms.THREAD_ID + "; " + UPDATE_THREAD_COUNT_ON_NEW + PDU_UPDATE_THREAD_READ_BODY + "END;";和短信一样,在更新pdu表时,触发更新threads表,其中更新date,snippet,snippet_cs字段,同时用到了前面定义的静态常量。
8、
private static final String UPDATE_THREAD_SNIPPET_SNIPPET_CS_ON_DELETE = " UPDATE threads SET snippet = " + " (SELECT snippet FROM" + " (SELECT date * 1000 AS date, sub AS snippet, thread_id FROM pdu" + " UNION SELECT date, body AS snippet, thread_id FROM sms)" + " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + " WHERE threads._id = OLD.thread_id; " + " UPDATE threads SET snippet_cs = " + " (SELECT snippet_cs FROM" + " (SELECT date * 1000 AS date, sub_cs AS snippet_cs, thread_id FROM pdu" + " UNION SELECT date, 0 AS snippet_cs, thread_id FROM sms)" + " WHERE thread_id = OLD.thread_id ORDER BY date DESC LIMIT 1) " + " WHERE threads._id = OLD.thread_id; ";在彩信或者短信数据库删除信息条目时,更新会话信息数据库threads中的snippet以及snippet_cs字段。
9、
private static final String PART_UPDATE_THREADS_ON_INSERT_TRIGGER = "CREATE TRIGGER update_threads_on_insert_part " + " AFTER INSERT ON part " + " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " + " BEGIN " + " UPDATE threads SET has_attachment=1 WHERE _id IN " + " (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " + " WHERE part._id=new._id LIMIT 1); " + " END";这个常量字符串是用于创建触发器,在向part表内插入一条信息时,并且其CONTENT_TYPE(ct)不等于“text/plain”或者“application/smil”时,开始更新会话表threads,设置表内字段has_attachment为1,如果thread_id存在。
10、
private static final String PART_UPDATE_THREADS_ON_UPDATE_TRIGGER = "CREATE TRIGGER update_threads_on_update_part " + " AFTER UPDATE of " + Part.MSG_ID + " ON part " + " WHEN new.ct != 'text/plain' AND new.ct != 'application/smil' " + " BEGIN " + " UPDATE threads SET has_attachment=1 WHERE _id IN " + " (SELECT pdu.thread_id FROM part JOIN pdu ON pdu._id=part.mid " + " WHERE part._id=new._id LIMIT 1); " + " END";这个常量字段用于创建触发器,内容是:当更新了part数据表中的Part.MSG_ID字段时,并且CONTENT_TYPE不等于text/plain或者application/smil时,开始更新数据库threads数据表,设置表内字段has_attachment = 1,并且当_id存在时。
11、
private static final String PART_UPDATE_THREADS_ON_DELETE_TRIGGER = "CREATE TRIGGER update_threads_on_delete_part " + " AFTER DELETE ON part " + " WHEN old.ct != 'text/plain' AND old.ct != 'application/smil' " + " BEGIN " + " UPDATE threads SET has_attachment = " + " CASE " + " (SELECT COUNT(*) FROM part JOIN pdu " + " WHERE pdu.thread_id = threads._id " + " AND part.ct != 'text/plain' AND part.ct != 'application/smil' " + " AND part.mid = pdu._id)" + " WHEN 0 THEN 0 " + " ELSE 1 " + " END; " + " END";用户创建触发器,在删除part表内的数据时,如果ct也就是CONTENT_TYPE不等于text/plain或者application/smail时,开始更新threads数据表,它没有where限制,也就是设置表内 所有数据的has_attachment字段等于下面函数的输出值。
函数作用:查询part表内特定的part.mid所对应的行的数量,如果为0,输出0,如果不为0,那么输出1.
12、
private static final String PDU_UPDATE_THREADS_ON_UPDATE_TRIGGER = "CREATE TRIGGER update_threads_on_update_pdu " + " AFTER UPDATE of thread_id ON pdu " + " BEGIN " + " UPDATE threads SET has_attachment=1 WHERE _id IN " + " (SELECT pdu.thread_id FROM part JOIN pdu " + " WHERE part.ct != 'text/plain' AND part.ct != 'application/smil' " + " AND part.mid = pdu._id);" + " END";创建一个触发器,在更新了pdu数据表内的thread_id字段,开始更新thread数据表,设置has_attchment字段等于1,并且特定的thread_id存在,这个特定thread_id来自于更新的pdu表行中的_id所对应的thread_id.
这是数据库设计会用的静态常量字符串,后面会介绍数据库创建等。