Search in sources :

Example 1 with Flag

use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.

the class DbTag method alterTag.

public static void alterTag(Tag tag, List<Integer> itemIds, boolean add) throws ServiceException {
    if (itemIds == null || itemIds.isEmpty()) {
        return;
    }
    Mailbox mbox = tag.getMailbox();
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    try {
        boolean isFlag = tag instanceof Flag;
        boolean altersModseq = !isFlag || !((Flag) tag).isSystemFlag();
        String primaryUpdate, sanityCheckAnd;
        if (isFlag) {
            primaryUpdate = "flags = flags" + (add ? " + ?" : " - ?");
            sanityCheckAnd = Db.getInstance().bitAND("flags", "?") + (add ? " = 0" : " <> 0") + " AND ";
        } else {
            if (add) {
                primaryUpdate = "tag_names = CASE WHEN tag_names IS NULL THEN ? ELSE " + Db.getInstance().concat("tag_names", "?") + " END";
                sanityCheckAnd = "(tag_names IS NULL OR tag_names NOT LIKE ?) AND ";
            } else {
                primaryUpdate = "tag_names = CASE tag_names WHEN ? THEN NULL ELSE REPLACE(tag_names, ?, '\0') END";
                sanityCheckAnd = "";
            }
        }
        String updateChangeID = altersModseq ? ", mod_metadata = ?, change_date = ?" : "";
        for (int i = 0; i < itemIds.size(); i += Db.getINClauseBatchSize()) {
            int count = Math.min(Db.getINClauseBatchSize(), itemIds.size() - i);
            stmt = conn.prepareStatement("UPDATE " + DbMailItem.getMailItemTableName(mbox) + " SET " + primaryUpdate + updateChangeID + " WHERE " + DbMailItem.IN_THIS_MAILBOX_AND + sanityCheckAnd + DbUtil.whereIn("id", count));
            int pos = 1;
            // primary update
            if (isFlag) {
                stmt.setLong(pos++, ((Flag) tag).toBitmask());
            } else {
                stmt.setString(pos++, delimitTagName(tag.getName()));
                stmt.setString(pos++, delimitTagName(tag.getName()).substring(add ? 1 : 0));
            }
            // change ID update
            if (altersModseq) {
                stmt.setInt(pos++, mbox.getOperationChangeID());
                stmt.setInt(pos++, mbox.getOperationTimestamp());
            }
            pos = DbMailItem.setMailboxId(stmt, mbox, pos);
            // sanity check
            if (isFlag) {
                stmt.setLong(pos++, ((Flag) tag).toBitmask());
            } else if (add) {
                stmt.setString(pos++, tagLIKEPattern(tag.getName()));
            }
            // item IDs
            for (int index = i; index < i + count; index++) {
                stmt.setInt(pos++, itemIds.get(index));
            }
            stmt.executeUpdate();
            stmt.close();
            stmt = null;
            if (add) {
                addTaggedItemEntries(mbox, tag.getId(), itemIds.subList(i, i + count));
            } else {
                removeTaggedItemEntries(mbox, tag.getId(), itemIds.subList(i, i + count));
            }
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("updating tag data for " + itemIds.size() + " items: " + DbMailItem.getIdListForLogging(itemIds), e);
    } finally {
        DbPool.closeStatement(stmt);
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Flag(com.zimbra.cs.mailbox.Flag) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 2 with Flag

use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.

the class GetTag method handle.

public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
    List<Tag> tags = null;
    try {
        tags = mbox.getTagList(octxt);
    } catch (ServiceException e) {
        // just return no tags in the perm denied case (not considered an error here)...
        if (!e.getCode().equals(ServiceException.PERM_DENIED))
            throw e;
    }
    Element response = zsc.createElement(MailConstants.GET_TAG_RESPONSE);
    if (tags != null) {
        for (Tag tag : tags) {
            if (tag == null || tag instanceof Flag)
                continue;
            ToXML.encodeTag(response, ifmt, octxt, tag);
        }
    }
    return response;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Element(com.zimbra.common.soap.Element) Tag(com.zimbra.cs.mailbox.Tag) Flag(com.zimbra.cs.mailbox.Flag)

Example 3 with Flag

use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.

the class SoapSession method putRefresh.

/**
 * Serializes basic folder/tag structure to a SOAP response header.
 *  <p>
 *  Adds a &lt;refresh> block to the existing &lt;context> element.
 *  This &lt;refresh> block contains the basic folder, tag, and mailbox
 *  size information needed to display and update the web UI's overview
 *  pane.  The &lt;refresh> block is sent when a new session is created.
 *
 *  This API implicitly clears all cached notifications and therefore
 *  should only been used during session creation.
 * @param ctxt  An existing SOAP header <context> element
 * @param zsc   The SOAP request's encapsulated context
 */
public void putRefresh(Element ctxt, ZimbraSoapContext zsc) throws ServiceException {
    Mailbox mbox = this.getMailboxOrNull();
    if (mbox == null) {
        return;
    }
    synchronized (sentChanges) {
        for (QueuedNotifications ntfn : sentChanges) {
            ntfn.clearMailboxChanges();
        }
    }
    Element eRefresh = ctxt.addUniqueElement(ZimbraNamespace.E_REFRESH);
    eRefresh.addAttribute(AccountConstants.E_VERSION, BuildInfo.FULL_VERSION, Element.Disposition.CONTENT);
    OperationContext octxt = DocumentHandler.getOperationContext(zsc, this);
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
    // dump current mailbox status (currently just size)
    ToXML.encodeMailbox(eRefresh, octxt, mbox);
    // dump all tags under a single <tags> parent
    List<Tag> tags = mbox.getTagList(octxt);
    if (tags != null && tags.size() > 0) {
        Element eTags = eRefresh.addUniqueElement(ZimbraNamespace.E_TAGS);
        for (Tag tag : tags) {
            if (tag != null && !(tag instanceof Flag)) {
                ToXML.encodeTag(eTags, ifmt, octxt, tag);
            }
        }
    }
    // first, get the user's folder hierarchy
    FolderNode root = mbox.getFolderTree(octxt, null, false);
    OperationContextData.setNeedGranteeName(octxt, false);
    GetFolder.encodeFolderNode(root, eRefresh, ifmt, octxt);
    // The Boolean of the Pair indicates whether the mountpoint is found to be broken
    Map<ItemId, Pair<Boolean, Element>> mountpoints = new HashMap<ItemId, Pair<Boolean, Element>>();
    // for mountpoints pointing to this host, get the serialized folder subhierarchy
    expandLocalMountpoints(octxt, root, eRefresh.getFactory(), mountpoints);
    // for mountpoints pointing to other hosts, get the folder structure from the remote server
    expandRemoteMountpoints(octxt, zsc, mountpoints);
    // graft in subfolder trees from the other user's mailbox, making sure that mountpoints reflect the counts (etc.) of the target folder
    if (!mountpoints.isEmpty()) {
        transferMountpointContents(eRefresh.getOptionalElement(MailConstants.E_FOLDER), octxt, mountpoints);
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) FolderNode(com.zimbra.cs.mailbox.Mailbox.FolderNode) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) Flag(com.zimbra.cs.mailbox.Flag) ItemId(com.zimbra.cs.service.util.ItemId) Mailbox(com.zimbra.cs.mailbox.Mailbox) Tag(com.zimbra.cs.mailbox.Tag) Pair(com.zimbra.common.util.Pair)

Example 4 with Flag

use of com.zimbra.cs.mailbox.Flag in project zm-mailbox by Zimbra.

the class DbSearch method encodeTag.

private boolean encodeTag(Set<Tag> tags, boolean bool, boolean useJoin, boolean and) {
    if (tags.isEmpty()) {
        return false;
    }
    if (useJoin) {
        assert !dumpster;
        assert bool;
    }
    if (dumpster) {
        // There is no corresponding table to TAGGED_ITEM in dumpster, hence brute-force search.
        int flags = 0;
        for (Tag tag : tags) {
            if (tag instanceof Flag) {
                Flag flag = (Flag) tag;
                if (flag.getId() == Flag.ID_UNREAD) {
                    if (and) {
                        sql.append(" AND ");
                    }
                    sql.append("mi.unread = ?");
                    and = true;
                    params.add(bool ? 1 : 0);
                } else {
                    flags |= flag.toBitmask();
                }
            } else {
                if (and) {
                    sql.append(" AND ");
                }
                and = true;
                sql.append("(mi.tag_names");
                if (!bool) {
                    // Include NULL because LIKE does not match NULL.
                    sql.append(" IS NULL OR mi.tag_names NOT");
                }
                sql.append(" LIKE ?)");
                params.add(DbTag.tagLIKEPattern(tag.getName()));
            }
        }
        if (flags != 0) {
            sql.append(" AND ").append(Db.getInstance().bitAND("mi.flags", "?")).append(" = ?");
            params.add(flags);
            params.add(bool ? flags : 0);
        }
    } else if (bool) {
        // Repeats "EXISTS (SELECT...)" as many times as tags.
        if (useJoin) {
            assert tags.size() == 1;
            Tag tag = tags.iterator().next();
            // AND (mi.id = ti.item_id AND mi.mailbox_id = ti.mailbox_id AND ti.tag_id = -10)
            if (and) {
                sql.append(" AND ");
            }
            sql.append("(mi.id = ti.item_id AND mi.mailbox_id = ti.mailbox_id AND ti.tag_id = ?)");
            params.add(tag.getId());
            and = true;
        } else {
            for (Tag tag : tags) {
                if (and) {
                    sql.append(" AND ");
                }
                sql.append("EXISTS (SELECT * FROM ").append(DbTag.getTaggedItemTableName(mailbox, "ti"));
                and = true;
                sql.append(" WHERE ");
                if (!DebugConfig.disableMailboxGroups) {
                    sql.append("mi.mailbox_id = ti.mailbox_id AND ");
                }
                sql.append("mi.id = ti.item_id AND ti.tag_id = ?)");
                params.add(tag.getId());
            }
        }
    } else {
        // NOT EXISTS (SELECT... WHERE... tag_id IN...)
        if (and) {
            sql.append(" AND ");
        }
        sql.append("NOT EXISTS (SELECT * FROM ").append(DbTag.getTaggedItemTableName(mailbox, "ti"));
        and = true;
        sql.append(" WHERE ");
        if (!DebugConfig.disableMailboxGroups) {
            sql.append("mi.mailbox_id = ti.mailbox_id AND ");
        }
        sql.append("mi.id = ti.item_id AND ").append(DbUtil.whereIn("ti.tag_id", tags.size())).append(')');
        for (Tag tag : tags) {
            params.add(tag.getId());
        }
    }
    return true;
}
Also used : Tag(com.zimbra.cs.mailbox.Tag) Flag(com.zimbra.cs.mailbox.Flag)

Aggregations

Flag (com.zimbra.cs.mailbox.Flag)4 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 Tag (com.zimbra.cs.mailbox.Tag)3 Element (com.zimbra.common.soap.Element)2 OperationContext (com.zimbra.cs.mailbox.OperationContext)2 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)2 ServiceException (com.zimbra.common.service.ServiceException)1 Pair (com.zimbra.common.util.Pair)1 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)1 FolderNode (com.zimbra.cs.mailbox.Mailbox.FolderNode)1 ItemId (com.zimbra.cs.service.util.ItemId)1 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)1 PreparedStatement (java.sql.PreparedStatement)1 SQLException (java.sql.SQLException)1 HashMap (java.util.HashMap)1