use of net.sqlcipher.database.SQLiteConstraintException in project Zom-Android by zom.
the class ImpsProvider method seedInitialPresenceByAccount.
/**
* make sure the presence for all contacts of a given account is set to
* offline, and each contact has a presence row associated with it. However,
* this method does not remove presences for which the corresponding
* contacts no longer exist. That's probably ok since presence is kept in
* memory, so it won't stay around for too long. Here is the algorithm.
*
* 1. for all presence that have a corresponding contact, make it OFFLINE.
* This is one sqlite call. 2. query for all the contacts that don't have a
* presence, and add a presence row for them.
*
* TODO simplify the presence management! The desire is to have a presence
* row for each TODO contact in the database, so later we can just call
* update() on the presence rows TODO instead of checking for the existence
* of presence first. The assumption is we get TODO presence updates much
* more frequently. However, the logic to maintain that goal is TODO overly
* complicated. One possible solution is to use insert_or_replace the
* presence rows TODO when updating the presence. That way we don't always
* need to maintain an empty presence TODO row for each contact.
*
* @param account the account of the contacts for which we want to create
* seed presence rows.
*/
private void seedInitialPresenceByAccount(long account) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_CONTACTS);
qb.setProjectionMap(sContactsProjectionMap);
mQueryContactIdSelectionArgs1[0] = String.valueOf(account);
final SQLiteDatabase db = getDBHelper().getWritableDatabase();
db.beginTransaction();
Cursor c = null;
try {
ContentValues presenceValues = new ContentValues();
presenceValues.put(Imps.Presence.PRESENCE_STATUS, Imps.Presence.OFFLINE);
presenceValues.put(Imps.Presence.PRESENCE_CUSTOM_STATUS, "");
// update all the presence for the account so they are offline
StringBuilder buf = new StringBuilder();
buf.append(Imps.Presence.CONTACT_ID);
buf.append(" in (select ");
buf.append(Imps.Contacts._ID);
buf.append(" from ");
buf.append(TABLE_CONTACTS);
buf.append(" where ");
buf.append(Imps.Contacts.ACCOUNT);
buf.append("=?) ");
String selection = buf.toString();
log("seedInitialPresence: reset presence selection=" + selection);
int count = db.update(TABLE_PRESENCE, presenceValues, selection, mQueryContactIdSelectionArgs1);
log("seedInitialPresence: reset " + count + " presence rows to OFFLINE");
// for in-memory presence table, add a presence row for each contact that
// doesn't have a presence. in-memory presence table isn't reliable, and goes away
// when device reboot or IMProvider process dies, so we can't rely on each contact
// have a corresponding presence.
{
log("seedInitialPresence: contacts_with_no_presence_selection => " + CONTACTS_WITH_NO_PRESENCE_SELECTION);
}
c = qb.query(db, CONTACT_ID_PROJECTION, CONTACTS_WITH_NO_PRESENCE_SELECTION, mQueryContactIdSelectionArgs1, null, null, null, null);
log("seedInitialPresence: found " + c.getCount() + " contacts w/o presence");
count = 0;
while (c.moveToNext()) {
long id = c.getLong(CONTACT_ID_COLUMN);
presenceValues.put(Imps.Presence.CONTACT_ID, id);
try {
if (db.insert(TABLE_PRESENCE, null, presenceValues) > 0) {
count++;
}
} catch (SQLiteConstraintException ex) {
// we could possibly catch this exception, since there could be a presence
// row with the same contact_id. That's fine, just ignore the error
log("seedInitialPresence: insert presence for contact_id " + id + " failed, caught " + ex);
}
}
log("seedInitialPresence: added " + count + " new presence rows");
db.setTransactionSuccessful();
} finally {
if (c != null) {
c.close();
}
db.endTransaction();
}
}
Aggregations