Search in sources :

Example 6 with TypedIdList

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

the class Mailbox method delete.

/**
     * Delete the <tt>MailItem</tt>s with the given ids.  If there is no <tt>MailItem</tt> for a given id, that id is
     * ignored.  If the id maps to an existing <tt>MailItem</tt> of an incompatible type, however, an error is thrown.
     *
     * @param octxt operation context or {@code null}
     * @param itemIds item ids
     * @param type item type or {@link MailItem.Type#UNKNOWN}
     * @param tcon target constraint or {@code null}
     * @param useEmptyForFolders empty folder {@code true} or {@code false}
     * @param nonExistingItems object of {@link ArrayList} or {@code null}
     */
private void delete(OperationContext octxt, int[] itemIds, MailItem.Type type, TargetConstraint tcon, boolean useEmptyForFolders, List<Integer> nonExistingItems) throws ServiceException {
    DeleteItem redoRecorder = new DeleteItem(mId, itemIds, type, tcon);
    List<Integer> folderIds = Lists.newArrayList();
    boolean success = false;
    try {
        beginTransaction("delete", octxt, redoRecorder);
        setOperationTargetConstraint(tcon);
        for (int id : itemIds) {
            if (id == ID_AUTO_INCREMENT) {
                continue;
            }
            MailItem item;
            try {
                item = getItemById(id, MailItem.Type.UNKNOWN);
            } catch (NoSuchItemException nsie) {
                if (nonExistingItems != null) {
                    nonExistingItems.add(id);
                }
                // trying to delete nonexistent things is A-OK!
                continue;
            }
            // however, trying to delete messages and passing in a folder ID is not OK
            if (!MailItem.isAcceptableType(type, item.getType())) {
                throw MailItem.noSuchItem(id, type);
            } else if (!checkItemChangeID(item) && item instanceof Tag) {
                throw MailServiceException.MODIFY_CONFLICT();
            }
            if (useEmptyForFolders && MailItem.Type.FOLDER.equals(item.getType())) {
                // removed later to allow batching delete of contents in there own transactions
                folderIds.add(id);
            } else {
                // delete the item, but don't write the tombstone until we're finished...
                item.delete(false);
            }
        }
        // deletes have already been collected, so fetch the tombstones and write once
        TypedIdList tombstones = collectPendingTombstones();
        if (tombstones != null && !tombstones.isEmpty()) {
            DbMailItem.writeTombstones(this, tombstones);
        }
        success = true;
    } finally {
        endTransaction(success);
    }
    for (Integer folderId : folderIds) {
        emptyFolder(octxt, folderId, true, /* removeTopLevelFolder */
        true, /* removeSubfolders */
        tcon);
    }
}
Also used : DbMailItem(com.zimbra.cs.db.DbMailItem) DeleteItem(com.zimbra.cs.redolog.op.DeleteItem) AlterItemTag(com.zimbra.cs.redolog.op.AlterItemTag) CreateTag(com.zimbra.cs.redolog.op.CreateTag) DbTag(com.zimbra.cs.db.DbTag) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) RefreshMountpoint(com.zimbra.cs.redolog.op.RefreshMountpoint) TargetConstraint(com.zimbra.cs.mailbox.MailItem.TargetConstraint) CreateMountpoint(com.zimbra.cs.redolog.op.CreateMountpoint)

Example 7 with TypedIdList

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

the class Sync method folderSync.

/**
     * @param calendarStart start time of range, in milliseconds. {@code -1} means to leave the start time unconstrained.
     */
private static boolean folderSync(Element response, OperationContext octxt, ItemIdFormatter ifmt, Mailbox mbox, Folder folder, Set<Folder> visible, long calendarStart, long messageSyncStart, SyncPhase phase) throws ServiceException {
    if (folder == null)
        return false;
    if (visible != null && visible.isEmpty())
        return false;
    boolean isVisible = visible == null || visible.remove(folder);
    // short-circuit if we know that this won't be in the output
    List<Folder> subfolders = folder.getSubfolders(null);
    if (!isVisible && subfolders.isEmpty())
        return false;
    // write this folder's data to the response
    boolean initial = phase == SyncPhase.INITIAL;
    Element f = ToXML.encodeFolder(response, ifmt, octxt, folder, Change.ALL_FIELDS);
    if (initial && isVisible && folder.getType() == MailItem.Type.FOLDER) {
        // we're in the middle of an initial sync, so serialize the item ids
        if (folder.getId() == Mailbox.ID_FOLDER_TAGS) {
            initialTagSync(f, octxt, ifmt, mbox);
        } else {
            TypedIdList idlist = mbox.getItemIds(octxt, folder.getId());
            initialMsgSync(f, idlist, octxt, mbox, folder, messageSyncStart);
            initialItemSync(f, MailConstants.E_CHAT, idlist.getIds(MailItem.Type.CHAT));
            initialItemSync(f, MailConstants.E_CONTACT, idlist.getIds(MailItem.Type.CONTACT));
            initialItemSync(f, MailConstants.E_NOTE, idlist.getIds(MailItem.Type.NOTE));
            initialCalendarSync(f, idlist, octxt, mbox, folder, calendarStart);
            initialItemSync(f, MailConstants.E_DOC, idlist.getIds(MailItem.Type.DOCUMENT));
            initialItemSync(f, MailConstants.E_WIKIWORD, idlist.getIds(MailItem.Type.WIKI));
            initialCovSync(f, idlist, octxt, mbox, folder, messageSyncStart);
        }
    }
    if (isVisible && visible != null && visible.isEmpty())
        return true;
    // write the subfolders' data to the response
    for (Folder subfolder : subfolders) {
        if (subfolder != null) {
            isVisible |= folderSync(f, octxt, ifmt, mbox, subfolder, visible, calendarStart, messageSyncStart, phase);
        }
    }
    // if this folder and all its subfolders are not visible (oops!), remove them from the response
    if (!isVisible) {
        f.detach();
    }
    return isVisible;
}
Also used : Element(com.zimbra.common.soap.Element) Folder(com.zimbra.cs.mailbox.Folder) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList)

Example 8 with TypedIdList

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

the class PagedDeleteTest method testRemoveBeforeCutoff.

@Test
public void testRemoveBeforeCutoff() {
    TypedIdList tombstone = new TypedIdList();
    tombstone.add(Type.MESSAGE, 3, "", 100);
    tombstone.add(Type.MESSAGE, 4, "", 101);
    tombstone.add(Type.APPOINTMENT, 1, "", 101);
    tombstone.add(Type.APPOINTMENT, 5, "", 100);
    tombstone.add(Type.APPOINTMENT, 9, "", 103);
    tombstone.add(Type.MESSAGE, 2, "", 99);
    tombstone.add(Type.MESSAGE, 22, "", 105);
    tombstone.add(Type.MESSAGE, 24, "", 103);
    PagedDelete pgDelete = new PagedDelete(tombstone, true);
    pgDelete.removeBeforeCutoff(4, 101);
    Collection<Integer> ids = pgDelete.getAllIds();
    Assert.assertEquals(4, ids.size());
    pgDelete.trimDeletesTillPageLimit(3);
    ids = pgDelete.getAllIds();
    Assert.assertEquals(3, ids.size());
    Assert.assertTrue(ids.contains(4));
    Assert.assertTrue(ids.contains(9));
    Assert.assertTrue(ids.contains(24));
    Assert.assertTrue(pgDelete.isDeleteOverFlow());
    Assert.assertEquals(pgDelete.getCutOffModsequnce(), 105);
    Assert.assertEquals(pgDelete.getLastItemId(), 22);
    Multimap<Type, Integer> ids2Type = pgDelete.getTypedItemIds();
    Assert.assertEquals(3, ids2Type.size());
    Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 4));
    Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 9));
    Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 24));
}
Also used : Type(com.zimbra.cs.mailbox.MailItem.Type) PagedDelete(com.zimbra.cs.mailbox.util.PagedDelete) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) Test(org.junit.Test)

Example 9 with TypedIdList

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

the class PagedDeleteTest method testTrimDeletesTillPageLimit.

@Test
public void testTrimDeletesTillPageLimit() {
    TypedIdList tombstone = new TypedIdList();
    tombstone.add(Type.MESSAGE, 3, "", 100);
    tombstone.add(Type.MESSAGE, 4, "", 101);
    tombstone.add(Type.MESSAGE, 1, "", 101);
    tombstone.add(Type.MESSAGE, 5, "", 100);
    tombstone.add(Type.MESSAGE, 9, "", 103);
    PagedDelete pgDelete = new PagedDelete(tombstone, false);
    pgDelete.trimDeletesTillPageLimit(3);
    Collection<Integer> ids = pgDelete.getAllIds();
    Assert.assertEquals(3, ids.size());
    Assert.assertTrue(ids.contains(3));
    Assert.assertTrue(ids.contains(5));
    Assert.assertTrue(ids.contains(1));
    Assert.assertTrue(pgDelete.isDeleteOverFlow());
    Assert.assertTrue(pgDelete.getCutOffModsequnce() == 101);
    Assert.assertTrue(pgDelete.getLastItemId() == 4);
}
Also used : PagedDelete(com.zimbra.cs.mailbox.util.PagedDelete) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) Test(org.junit.Test)

Example 10 with TypedIdList

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

the class PagedDeleteTest method testTypedDeletesTillPageLimit.

@Test
public void testTypedDeletesTillPageLimit() {
    TypedIdList tombstone = new TypedIdList();
    tombstone.add(Type.MESSAGE, 3, "", 100);
    tombstone.add(Type.MESSAGE, 4, "", 101);
    tombstone.add(Type.APPOINTMENT, 1, "", 101);
    tombstone.add(Type.APPOINTMENT, 5, "", 100);
    tombstone.add(Type.MESSAGE, 9, "", 103);
    PagedDelete pgDelete = new PagedDelete(tombstone, true);
    pgDelete.trimDeletesTillPageLimit(3);
    Collection<Integer> ids = pgDelete.getAllIds();
    Assert.assertEquals(3, ids.size());
    Assert.assertTrue(ids.contains(3));
    Assert.assertTrue(ids.contains(5));
    Assert.assertTrue(ids.contains(1));
    Assert.assertTrue(pgDelete.isDeleteOverFlow());
    Assert.assertTrue(pgDelete.getCutOffModsequnce() == 101);
    Assert.assertTrue(pgDelete.getLastItemId() == 4);
    Multimap<Type, Integer> ids2Type = pgDelete.getTypedItemIds();
    Assert.assertEquals(3, ids2Type.size());
    Assert.assertTrue(ids2Type.containsEntry(Type.MESSAGE, 3));
    Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 5));
    Assert.assertTrue(ids2Type.containsEntry(Type.APPOINTMENT, 1));
}
Also used : Type(com.zimbra.cs.mailbox.MailItem.Type) PagedDelete(com.zimbra.cs.mailbox.util.PagedDelete) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) Test(org.junit.Test)

Aggregations

TypedIdList (com.zimbra.cs.mailbox.util.TypedIdList)25 ResultSet (java.sql.ResultSet)7 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)6 PreparedStatement (java.sql.PreparedStatement)6 SQLException (java.sql.SQLException)6 Test (org.junit.Test)6 MailItem (com.zimbra.cs.mailbox.MailItem)5 PagedDelete (com.zimbra.cs.mailbox.util.PagedDelete)5 ZFolder (com.zimbra.client.ZFolder)4 CreateFolder (com.zimbra.cs.redolog.op.CreateFolder)4 ArrayList (java.util.ArrayList)4 List (java.util.List)4 Pair (com.zimbra.common.util.Pair)3 Folder (com.zimbra.cs.mailbox.Folder)3 Type (com.zimbra.cs.mailbox.MailItem.Type)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 Element (com.zimbra.common.soap.Element)2 DbTag (com.zimbra.cs.db.DbTag)2 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)2 AlterItemTag (com.zimbra.cs.redolog.op.AlterItemTag)2