use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class DbMailItem method readTombstones.
public static TypedIdList readTombstones(Mailbox mbox, long lastSync, boolean equalModSeq) throws ServiceException {
TypedIdList tombstones = new TypedIdList();
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
if (equalModSeq) {
stmt = conn.prepareStatement("SELECT type, ids, sequence FROM " + getTombstoneTableName(mbox) + " WHERE " + IN_THIS_MAILBOX_AND + "sequence >= ? AND ids IS NOT NULL" + " ORDER BY sequence");
} else {
stmt = conn.prepareStatement("SELECT type, ids, sequence FROM " + getTombstoneTableName(mbox) + " WHERE " + IN_THIS_MAILBOX_AND + "sequence > ? AND ids IS NOT NULL" + " ORDER BY sequence");
}
Db.getInstance().enableStreaming(stmt);
int pos = 1;
pos = setMailboxId(stmt, mbox, pos);
stmt.setLong(pos++, lastSync);
rs = stmt.executeQuery();
while (rs.next()) {
MailItem.Type type = MailItem.Type.of(rs.getByte(1));
String row = rs.getString(2);
int modSeq = rs.getInt(3);
if (row == null || row.equals("")) {
continue;
}
// the list of tombstones is comma-delimited
for (String stone : row.split(",")) {
try {
// a tombstone may either be ID or ID:UUID, so parse accordingly
int delimiter = stone.indexOf(':');
if (delimiter == -1) {
tombstones.add(type, Integer.parseInt(stone), null, modSeq);
} else {
tombstones.add(type, Integer.parseInt(stone.substring(0, delimiter)), Strings.emptyToNull(stone.substring(delimiter + 1)), modSeq);
}
} catch (NumberFormatException nfe) {
ZimbraLog.sync.warn("unparseable TOMBSTONE entry: " + stone);
}
}
}
return tombstones;
} catch (SQLException e) {
throw ServiceException.FAILURE("reading tombstones since change: " + lastSync, e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class DbMailItem method listConvItems.
/**
* Return the conversation ids corresponds to messages with given cutoff time.
* @param folder
* @param messageSyncStart
* @param type
* @param descending
* @param older
* @return
* @throws ServiceException
*/
public static TypedIdList listConvItems(Folder folder, long messageSyncStart, MailItem.Type type, boolean descending, boolean older) throws ServiceException {
Mailbox mbox = folder.getMailbox();
assert Db.supports(Db.Capability.ROW_LEVEL_LOCKING) || Thread.holdsLock(mbox);
TypedIdList result = new TypedIdList();
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
if (older) {
stmt = conn.prepareStatement("SELECT parent_id FROM " + getMailItemTableName(folder) + " WHERE " + IN_THIS_MAILBOX_AND + " type = ? AND date < ?" + " ORDER BY date" + (descending ? " DESC" : ""));
} else {
stmt = conn.prepareStatement("SELECT parent_id FROM " + getMailItemTableName(folder) + " WHERE " + IN_THIS_MAILBOX_AND + " type = ? AND date >= ?" + " ORDER BY date" + (descending ? " DESC" : ""));
}
int pos = 1;
pos = setMailboxId(stmt, mbox, pos);
//message's parent_id is always conversation..
stmt.setByte(pos++, MailItem.Type.MESSAGE.toByte());
stmt.setLong(pos++, messageSyncStart);
rs = stmt.executeQuery();
while (rs.next()) {
int id = rs.getInt(1);
if (id != 0 && !result.contains(id)) {
result.add(MailItem.Type.CONVERSATION, id, "");
}
}
return result;
} catch (SQLException e) {
throw ServiceException.FAILURE("fetching item list for folder " + folder.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class DbMailItem method populateWithResultSetData.
/**
* @param visible
* @param modified
* @param missed
* @param stmt
* @return
* @throws SQLException
* @throws ServiceException
*/
private static Pair<List<Integer>, TypedIdList> populateWithResultSetData(Set<Integer> visible, PreparedStatement stmt, int lastDeleteSync) throws SQLException, ServiceException {
List<Integer> modified = new ArrayList<Integer>();
TypedIdList missed = new TypedIdList();
ResultSet rs = null;
try {
rs = stmt.executeQuery();
while (rs.next()) {
if (visible == null || visible.contains(rs.getInt(3))) {
modified.add(rs.getInt(1));
} else {
int modSeq = rs.getInt(5);
if (modSeq > lastDeleteSync) {
missed.add(MailItem.Type.of(rs.getByte(2)), rs.getInt(1), rs.getString(4), modSeq, rs.getString(6));
}
}
}
} finally {
DbPool.closeResults(rs);
}
return new Pair<List<Integer>, TypedIdList>(modified, missed);
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class DbMailItem method listCalendarItems.
/**
* @param start start time of range, in milliseconds. {@code -1} means to leave the start time unconstrained.
* @param end end time of range, in milliseconds. {@code -1} means to leave the end time unconstrained.
*/
public static TypedIdList listCalendarItems(Mailbox mbox, MailItem.Type type, long start, long end, int folderId, int[] excludeFolderIds) throws ServiceException {
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = calendarItemStatement(conn, "mi.id, mi.type, mi.uuid", mbox, type, start, end, folderId, excludeFolderIds);
rs = stmt.executeQuery();
TypedIdList result = new TypedIdList();
while (rs.next()) {
result.add(MailItem.Type.of(rs.getByte(2)), rs.getInt(1), rs.getString(3));
}
return result;
} catch (SQLException e) {
throw ServiceException.FAILURE("listing calendar items for mailbox " + mbox.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.util.TypedIdList in project zm-mailbox by Zimbra.
the class GalSearchControl method doLocalGalAccountSync.
private void doLocalGalAccountSync(GalSearchResultCallback callback, Mailbox mbox, OperationContext octxt, int changeId, Set<Integer> folderIds, String syncToken, int limit, String filterAttr, String filterValue) throws ServiceException {
ZimbraLog.gal.info("Using limit %d for gal account sync", limit);
Pair<List<Integer>, TypedIdList> changed = mbox.getModifiedItems(octxt, changeId, 0, MailItem.Type.CONTACT, folderIds, -1, limit);
int count = 0;
boolean hasMore = false;
for (int itemId : changed.getFirst()) {
try {
MailItem item = mbox.getItemById(octxt, itemId, MailItem.Type.CONTACT);
if (item instanceof Contact) {
Contact c = (Contact) item;
if (filterAttr != null && !filterValue.equals(c.get(filterAttr))) {
continue;
}
callback.handleContact(c);
count++;
if (count % 100 == 0) {
ZimbraLog.gal.trace("processing #%s", count);
}
changeId = item.getModifiedSequence();
if (count == limit) {
hasMore = true;
break;
}
}
} catch (MailServiceException mse) {
if (MailServiceException.NO_SUCH_ITEM.equals(mse.getId())) {
ZimbraLog.gal.warn("skipping item %d due to no such item; probably deleted during sync", itemId, mse);
} else {
throw mse;
}
}
}
GalSyncToken newToken = new GalSyncToken(syncToken, mbox.getAccountId(), changeId);
ZimbraLog.gal.debug("computing new sync token for %s:%s", mbox.getAccountId(), newToken);
callback.setNewToken(newToken);
callback.setHasMoreResult(hasMore);
}
Aggregations