use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.
the class DbTag method debugConsistencyCheck.
@VisibleForTesting
public static void debugConsistencyCheck(Mailbox mbox) throws ServiceException {
DbConnection conn = mbox.lock.isWriteLockedByCurrentThread() ? mbox.getOperationConnection() : DbPool.getConnection(mbox);
PreparedStatement stmt = null;
ResultSet rs = null;
try {
Map<Integer, UnderlyingData> tdata = Maps.newHashMap();
// make sure the item counts match the tag totals
stmt = conn.prepareStatement("SELECT " + TAG_FIELDS + " FROM " + getTagTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "id > 0");
DbMailItem.setMailboxId(stmt, mbox, 1);
rs = stmt.executeQuery();
while (rs.next()) {
UnderlyingData data = asUnderlyingData(rs);
tdata.put(data.id, data);
}
DbPool.closeResults(rs);
rs = null;
DbPool.closeStatement(stmt);
stmt = null;
// catch spurious TAGGED_ITEM entries
validateTaggedItem(conn, mbox, tdata);
// make sure the TAGGED_ITEM table is accurate
verifyTaggedItem(conn, mbox, tdata);
// make sure the item counts match the tag totals
verifyTagCounts(conn, mbox, tdata);
} catch (SQLException e) {
throw ServiceException.FAILURE("consistency checking tags/flags for mailbox " + mbox.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
if (!mbox.lock.isWriteLockedByCurrentThread()) {
conn.close();
}
}
}
use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.
the class MailboxUpgrade method createTagRows.
private static Map<Integer, String> createTagRows(DbConnection conn, Mailbox mbox, boolean checkDuplicates) throws ServiceException {
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement("SELECT id, name, mod_metadata, metadata FROM " + DbMailItem.getMailItemTableName(mbox) + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + "type = " + MailItem.Type.TAG.toByte());
DbMailItem.setMailboxId(stmt, mbox, 1);
rs = stmt.executeQuery();
Map<Integer, String> tagNames = Maps.newHashMap();
while (rs.next()) {
UnderlyingData data = new UnderlyingData();
data.id = rs.getInt(1);
data.name = rs.getString(2);
data.modMetadata = rs.getInt(3);
Color color = Color.fromMetadata(new Metadata(rs.getString(4)).getLong(Metadata.FN_COLOR, MailItem.DEFAULT_COLOR));
try {
DbTag.createTag(conn, mbox, data, color.getMappedColor() == MailItem.DEFAULT_COLOR ? null : color, true);
} catch (ServiceException se) {
if (checkDuplicates && se.getCode().equals(MailServiceException.ALREADY_EXISTS)) {
// tag name already exist. append a random number to the tag name.
SecureRandom sr = new SecureRandom();
data.name = data.name + sr.nextInt();
DbTag.createTag(conn, mbox, data, color.getMappedColor() == MailItem.DEFAULT_COLOR ? null : color, true);
} else {
throw se;
}
}
tagNames.put(data.id, data.name);
}
return tagNames;
} catch (SQLException e) {
throw ServiceException.FAILURE("creating TAG rows in mbox " + mbox.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.
the class SpamExtract method extractMessages.
private static List<String> extractMessages(HttpClient hc, GetMethod gm, String path, File outdir, boolean raw) throws HttpException, IOException {
List<String> extractedIds = new ArrayList<String>();
gm.setPath(path);
if (LOG.isDebugEnabled()) {
LOG.debug("Fetching " + path);
}
HttpClientUtil.executeMethod(hc, gm);
if (gm.getStatusCode() != HttpStatus.SC_OK) {
throw new IOException("HTTP GET failed: " + gm.getPath() + ": " + gm.getStatusCode() + ": " + gm.getStatusText());
}
ArchiveInputStream tgzStream = null;
try {
tgzStream = new TarArchiveInputStream(new GZIPInputStream(gm.getResponseBodyAsStream()), Charsets.UTF_8.name());
ArchiveInputEntry entry = null;
while ((entry = tgzStream.getNextEntry()) != null) {
LOG.debug("got entry name %s", entry.getName());
if (entry.getName().endsWith(".meta")) {
ItemData itemData = new ItemData(readArchiveEntry(tgzStream, entry));
UnderlyingData ud = itemData.ud;
//.meta always followed by .eml
entry = tgzStream.getNextEntry();
if (raw) {
// Write the message as-is.
File file = new File(outdir, mOutputPrefix + "-" + mExtractIndex++);
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(file));
byte[] data = readArchiveEntry(tgzStream, entry);
ByteUtil.copy(new ByteArrayInputStream(data), true, os, false);
if (verbose) {
LOG.info("Wrote: " + file);
}
extractedIds.add(ud.id + "");
} catch (java.io.IOException e) {
String fileName = outdir + "/" + mOutputPrefix + "-" + mExtractIndex;
LOG.error("Cannot write to " + fileName, e);
} finally {
if (os != null) {
os.close();
}
}
} else {
// Write the attached message to the output directory.
BufferStream buffer = new BufferStream(entry.getSize(), MAX_BUFFER_SIZE);
buffer.setSequenced(false);
MimeMessage mm = null;
InputStream fis = null;
try {
byte[] data = readArchiveEntry(tgzStream, entry);
ByteUtil.copy(new ByteArrayInputStream(data), true, buffer, false);
if (buffer.isSpooled()) {
fis = new ZSharedFileInputStream(buffer.getFile());
mm = new ZMimeMessage(mJMSession, fis);
} else {
mm = new ZMimeMessage(mJMSession, buffer.getInputStream());
}
writeAttachedMessages(mm, outdir, entry.getName());
extractedIds.add(ud.id + "");
} catch (MessagingException me) {
LOG.warn("exception occurred fetching message", me);
} finally {
ByteUtil.closeStream(fis);
}
}
}
}
} finally {
Closeables.closeQuietly(tgzStream);
}
return extractedIds;
}
use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.
the class DbMailItem method setFolder.
public static void setFolder(List<Message> msgs, Folder folder) throws ServiceException {
if (msgs == null || msgs.isEmpty()) {
return;
}
Mailbox mbox = folder.getMailbox();
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
try {
// commented out because at present messages cannot have names (and thus can't have naming conflicts)
// if (!Db.supports(Db.Capability.UNIQUE_NAME_INDEX) || Db.supports(Db.Capability.CASE_SENSITIVE_COMPARISON)) {
// stmt = conn.prepareStatement("SELECT mi.name" +
// " FROM " + getMailItemTableName(mbox, "mi") + ", " + getMailItemTableName(mbox, "m2") +
// " WHERE mi.id IN " + DbUtil.suitableNumberOfVariables(itemIDs) +
// " AND mi.name IS NOT NULL and m2.name IS NOT NULL" +
// " AND m2.folder_id = ? AND mi.id <> m2.id" +
// " AND " + (Db.supports(Db.Capability.CASE_SENSITIVE_COMPARISON) ? "UPPER(mi.name) = UPPER(m2.name)" : "mi.name = m2.name") +
// " AND mi.mailbox_id = ? AND m2.mailbox_id = ?");
// int pos = 1;
// for (Message msg : msgs)
// stmt.setInt(pos++, msg.getId());
// stmt.setInt(pos++, folder.getId());
// stmt.setInt(pos++, mbox.getId());
// stmt.setInt(pos++, mbox.getId());
// rs = stmt.executeQuery();
// if (rs.next())
// throw MailServiceException.ALREADY_EXISTS(rs.getString(1));
// rs.close();
// stmt.close();
// }
int count = 0;
int batchSize = 500;
String imapRenumber = mbox.isTrackingImap() ? ", imap_id = CASE WHEN imap_id IS NULL THEN NULL ELSE 0 END" : "";
stmt = conn.prepareStatement("UPDATE " + getMailItemTableName(folder) + " SET folder_id = ?, prev_folders=?, mod_metadata = ?, change_date = ?" + imapRenumber + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
int modseq = mbox.getOperationChangeID();
for (int j = 0; j < msgs.size(); j++) {
int pos = 1;
stmt.setInt(pos++, folder.getId());
UnderlyingData ud = msgs.get(j).getUnderlyingData();
// prev folders ordered by modseq ascending, e.g. 100:2;200:101;300:5
if (msgs.get(j).getFolderId() != folder.getId()) {
String prevFolders = ud.getPrevFolders();
if (!StringUtil.isNullOrEmpty(prevFolders)) {
String[] modseq2FolderId = prevFolders.split(";");
int maxCount = mbox.getAccount().getServer().getPrevFoldersToTrackMax();
if (modseq2FolderId.length < maxCount) {
prevFolders += ";" + modseq + ":" + ud.folderId;
} else {
// reached max, get rid of the oldest one
String[] tmp = new String[maxCount];
System.arraycopy(modseq2FolderId, 1, tmp, 0, maxCount - 1);
tmp[maxCount - 1] = modseq + ":" + ud.folderId;
prevFolders = StringUtil.join(";", tmp);
}
} else {
prevFolders = modseq + ":" + ud.folderId;
}
stmt.setString(pos++, prevFolders);
ud.setPrevFolders(prevFolders);
} else {
stmt.setString(pos++, msgs.get(j).getUnderlyingData().getPrevFolders());
}
stmt.setInt(pos++, modseq);
stmt.setInt(pos++, mbox.getOperationTimestamp());
pos = setMailboxId(stmt, mbox, pos);
stmt.setInt(pos++, msgs.get(j).getId());
stmt.addBatch();
if (++count % batchSize == 0) {
stmt.executeBatch();
}
}
stmt.executeBatch();
stmt.close();
stmt = null;
} catch (SQLException e) {
// else
throw ServiceException.FAILURE("writing new folder data for messages", e);
} finally {
DbPool.closeStatement(stmt);
}
}
use of com.zimbra.cs.mailbox.MailItem.UnderlyingData in project zm-mailbox by Zimbra.
the class DbMailItem method getRevisionInfo.
public static List<UnderlyingData> getRevisionInfo(MailItem item, boolean fromDumpster) throws ServiceException {
Mailbox mbox = item.getMailbox();
List<UnderlyingData> dlist = new ArrayList<UnderlyingData>();
if (!item.isTagged(Flag.FlagInfo.VERSIONED)) {
return dlist;
}
DbConnection conn = mbox.getOperationConnection();
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn.prepareStatement("SELECT " + REVISION_FIELDS + " FROM " + getRevisionTableName(mbox, fromDumpster) + " WHERE " + IN_THIS_MAILBOX_AND + "item_id = ?" + " ORDER BY version");
int pos = 1;
pos = setMailboxId(stmt, mbox, pos);
stmt.setInt(pos++, item.getId());
rs = stmt.executeQuery();
while (rs.next()) {
dlist.add(constructRevision(rs, item, fromDumpster));
}
return dlist;
} catch (SQLException e) {
throw ServiceException.FAILURE("getting old revisions for item: " + item.getId(), e);
} finally {
DbPool.closeResults(rs);
DbPool.closeStatement(stmt);
}
}
Aggregations