Search in sources :

Example 16 with UnderlyingData

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();
        }
    }
}
Also used : SQLException(java.sql.SQLException) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 17 with UnderlyingData

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);
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) SQLException(java.sql.SQLException) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) Color(com.zimbra.common.mailbox.Color) ResultSet(java.sql.ResultSet) SecureRandom(java.security.SecureRandom) PreparedStatement(java.sql.PreparedStatement)

Example 18 with UnderlyingData

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;
}
Also used : ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MessagingException(javax.mail.MessagingException) ArchiveInputEntry(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputEntry) GZIPInputStream(java.util.zip.GZIPInputStream) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ArchiveInputStream(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) InputStream(java.io.InputStream) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) IOException(java.io.IOException) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) GZIPInputStream(java.util.zip.GZIPInputStream) BufferStream(com.zimbra.common.util.BufferStream) ZSharedFileInputStream(com.zimbra.common.zmime.ZSharedFileInputStream) TarArchiveInputStream(com.zimbra.cs.service.formatter.TarArchiveInputStream) ArchiveInputStream(com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) FileOutputStream(java.io.FileOutputStream) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream) ItemData(com.zimbra.cs.service.util.ItemData)

Example 19 with UnderlyingData

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);
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) SQLException(java.sql.SQLException) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 20 with UnderlyingData

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);
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) SQLException(java.sql.SQLException) UnderlyingData(com.zimbra.cs.mailbox.MailItem.UnderlyingData) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Aggregations

UnderlyingData (com.zimbra.cs.mailbox.MailItem.UnderlyingData)30 PreparedStatement (java.sql.PreparedStatement)21 SQLException (java.sql.SQLException)21 ResultSet (java.sql.ResultSet)20 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)18 ArrayList (java.util.ArrayList)13 Mailbox (com.zimbra.cs.mailbox.Mailbox)8 Tag (com.zimbra.cs.mailbox.Tag)4 ServiceException (com.zimbra.common.service.ServiceException)3 MailItem (com.zimbra.cs.mailbox.MailItem)3 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 Color (com.zimbra.common.mailbox.Color)2 BufferStream (com.zimbra.common.util.BufferStream)2 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)2 ZSharedFileInputStream (com.zimbra.common.zmime.ZSharedFileInputStream)2 DbMailItem (com.zimbra.cs.db.DbMailItem)2 Folder (com.zimbra.cs.mailbox.Folder)2 ArchiveInputEntry (com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputEntry)2 ArchiveInputStream (com.zimbra.cs.service.formatter.ArchiveFormatter.ArchiveInputStream)2