Search in sources :

Example 6 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DataSourceManager method updateSchedule.

/**
     *
     * Updates scheduling data for this <tt>DataSource</tt> both in memory and in the
     * <tt>data_source_task</tt> database table.
     *
     * @param account Account for the DataSource, cannot be null.
     * @param ds The DataSource.  Ignored if cancelSchedule is true.
     * @param dsId zimbraId of the DataSource.
     * @param cancelSchedule cancel scheduling for the DataSource.
     * @throws ServiceException
     */
private static void updateSchedule(Account account, DataSource ds, String dsId, boolean cancelSchedule) throws ServiceException {
    if (!LC.data_source_scheduling_enabled.booleanValue()) {
        return;
    }
    String accountId = account.getId();
    ZimbraLog.datasource.debug("Updating schedule for account %s, data source %s", accountId, dsId);
    int mboxId = MailboxManager.getInstance().lookupMailboxId(account.getId());
    if (mboxId == -1)
        return;
    if (cancelSchedule) {
        ZimbraLog.datasource.info("Data source %s was deleted.  Deleting scheduled task.", dsId);
        ScheduledTaskManager.cancel(DataSourceTask.class.getName(), dsId, mboxId, false);
        DbScheduledTask.deleteTask(DataSourceTask.class.getName(), dsId);
        deleteManaged(accountId, dsId);
        return;
    }
    if (!ds.isEnabled()) {
        ZimbraLog.datasource.info("Data source %s is disabled.  Deleting scheduled task.", dsId);
        ScheduledTaskManager.cancel(DataSourceTask.class.getName(), dsId, mboxId, false);
        DbScheduledTask.deleteTask(DataSourceTask.class.getName(), dsId);
        return;
    }
    ZimbraLog.datasource.info("Updating schedule for data source %s", ds.getName());
    DbConnection conn = null;
    try {
        conn = DbPool.getConnection();
        ScheduledTaskManager.cancel(conn, DataSourceTask.class.getName(), ds.getId(), mboxId, false);
        if (ds.isScheduled()) {
            DataSourceTask task = new DataSourceTask(mboxId, accountId, dsId, ds.getPollingInterval());
            ZimbraLog.datasource.debug("Scheduling %s", task);
            ScheduledTaskManager.schedule(conn, task);
        }
        conn.commit();
    } catch (ServiceException e) {
        ZimbraLog.datasource.warn("Unable to schedule data source %s", ds.getName(), e);
        DbPool.quietRollback(conn);
    } finally {
        DbPool.quietClose(conn);
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 7 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DbMailItem method getById.

public static List<UnderlyingData> getById(Mailbox mbox, Collection<Integer> ids, MailItem.Type type) throws ServiceException {
    if (Mailbox.isCachedType(type)) {
        throw ServiceException.INVALID_REQUEST("folders and tags must be retrieved from cache", null);
    }
    List<UnderlyingData> result = new ArrayList<UnderlyingData>();
    if (ids.isEmpty()) {
        return result;
    }
    List<UnderlyingData> conversations = new ArrayList<UnderlyingData>();
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    ResultSet rs = null;
    Iterator<Integer> it = ids.iterator();
    for (int i = 0; i < ids.size(); i += Db.getINClauseBatchSize()) {
        try {
            int count = Math.min(Db.getINClauseBatchSize(), ids.size() - i);
            stmt = conn.prepareStatement("SELECT " + DB_FIELDS + " FROM " + getMailItemTableName(mbox, "mi") + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("id", count));
            int pos = 1;
            pos = setMailboxId(stmt, mbox, pos);
            for (int index = i; index < i + count; index++) {
                stmt.setInt(pos++, it.next());
            }
            rs = stmt.executeQuery();
            while (rs.next()) {
                UnderlyingData data = constructItem(rs);
                MailItem.Type resultType = MailItem.Type.of(data.type);
                if (!MailItem.isAcceptableType(type, resultType)) {
                    throw MailItem.noSuchItem(data.id, type);
                } else if (Mailbox.isCachedType(resultType)) {
                    throw ServiceException.INVALID_REQUEST("folders and tags must be retrieved from cache", null);
                }
                if (resultType == MailItem.Type.CONVERSATION) {
                    conversations.add(data);
                }
                result.add(data);
            }
        } catch (SQLException e) {
            throw ServiceException.FAILURE("fetching " + ids.size() + " items: " + getIdListForLogging(ids), e);
        } finally {
            DbPool.closeResults(rs);
            DbPool.closeStatement(stmt);
        }
    }
    if (!conversations.isEmpty()) {
        completeConversations(mbox, conn, conversations);
    }
    return result;
}
Also used : MailItem(com.zimbra.cs.mailbox.MailItem) 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)

Example 8 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DbMailItem method persistCounts.

public static void persistCounts(MailItem item, Metadata metadata) throws ServiceException {
    Mailbox mbox = item.getMailbox();
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    try {
        stmt = conn.prepareStatement("UPDATE " + getMailItemTableName(item) + " SET size = ?, unread = ?, metadata = ?, mod_metadata = ?, change_date = ?, mod_content = ?" + " WHERE " + IN_THIS_MAILBOX_AND + "id = ?");
        int pos = 1;
        stmt.setLong(pos++, item.getSize());
        stmt.setInt(pos++, item.getUnreadCount());
        stmt.setString(pos++, checkMetadataLength(metadata.toString()));
        stmt.setInt(pos++, item.getModifiedSequence());
        if (item.getChangeDate() > 0) {
            stmt.setInt(pos++, (int) (item.getChangeDate() / 1000));
        } else {
            stmt.setNull(pos++, Types.INTEGER);
        }
        stmt.setInt(pos++, item.getSavedSequence());
        pos = setMailboxId(stmt, mbox, pos);
        stmt.setInt(pos++, item.getId());
        stmt.executeUpdate();
    } catch (SQLException e) {
        throw ServiceException.FAILURE("writing metadata for mailbox " + item.getMailboxId() + ", item " + item.getId(), e);
    } finally {
        DbPool.closeStatement(stmt);
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 9 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DbMailItem method checkNamingConstraint.

private static void checkNamingConstraint(Mailbox mbox, int folderId, String name, int modifiedItemId) throws ServiceException {
    if (name == null || name.equals("")) {
        return;
    }
    if (Db.supports(Db.Capability.UNIQUE_NAME_INDEX) && !Db.supports(Db.Capability.CASE_SENSITIVE_COMPARISON)) {
        return;
    }
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        stmt = conn.prepareStatement("SELECT COUNT(*) FROM " + getMailItemTableName(mbox) + " WHERE " + IN_THIS_MAILBOX_AND + "folder_id = ? AND id <> ? AND " + Db.equalsSTRING("name"));
        int pos = 1;
        pos = setMailboxId(stmt, mbox, pos);
        stmt.setInt(pos++, folderId);
        stmt.setInt(pos++, modifiedItemId);
        stmt.setString(pos++, StringUtil.trimTrailingSpaces(name));
        rs = stmt.executeQuery();
        if (!rs.next() || rs.getInt(1) > 0) {
            throw MailServiceException.ALREADY_EXISTS(name);
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("checking for naming conflicts", e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.closeStatement(stmt);
    }
}
Also used : SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 10 with DbConnection

use of com.zimbra.cs.db.DbPool.DbConnection in project zm-mailbox by Zimbra.

the class DbMailItem method markDeletionTargets.

/**
     * Updates all affected conversations when a <code>List</code> of <code>MailItem</code>s
     * is deleted.  Updates each conversation's message count and nulls out
     * metadata so that the sender list is recalculated the next time the conversation
     * is instantiated.
     *
     * @param mbox the mailbox
     * @param ids of the items being deleted
     * @return the ids of any conversation that were purged as a result of this operation
     */
public static List<Integer> markDeletionTargets(Mailbox mbox, List<Integer> ids, Set<Integer> candidates) throws ServiceException {
    if (ids == null) {
        return null;
    }
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        String table = getMailItemTableName(mbox);
        if (Db.supports(Db.Capability.MULTITABLE_UPDATE)) {
            for (int i = 0; i < ids.size(); i += Db.getINClauseBatchSize()) {
                int count = Math.min(Db.getINClauseBatchSize(), ids.size() - i);
                stmt = conn.prepareStatement("UPDATE " + table + ", " + "(SELECT parent_id pid, COUNT(*) count FROM " + getMailItemTableName(mbox) + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("id", count) + " AND parent_id IS NOT NULL GROUP BY parent_id) AS x" + " SET size = size - count, metadata = NULL, mod_metadata = ?, change_date = ?" + " WHERE " + IN_THIS_MAILBOX_AND + "id = pid AND type = " + MailItem.Type.CONVERSATION.toByte());
                int pos = 1;
                pos = setMailboxId(stmt, mbox, pos);
                for (int index = i; index < i + count; index++) {
                    stmt.setInt(pos++, ids.get(index));
                }
                stmt.setInt(pos++, mbox.getOperationChangeID());
                stmt.setInt(pos++, mbox.getOperationTimestamp());
                pos = setMailboxId(stmt, mbox, pos);
                stmt.executeUpdate();
                stmt.close();
            }
        } else {
            stmt = conn.prepareStatement("SELECT parent_id, COUNT(*) FROM " + getMailItemTableName(mbox) + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("id", ids.size()) + " AND parent_id IS NOT NULL" + " GROUP BY parent_id");
            int pos = 1;
            pos = setMailboxId(stmt, mbox, pos);
            for (int id : ids) {
                stmt.setInt(pos++, id);
            }
            rs = stmt.executeQuery();
            Map<Integer, List<Integer>> counts = new HashMap<Integer, List<Integer>>();
            while (rs.next()) {
                int convId = rs.getInt(1), count = rs.getInt(2);
                List<Integer> targets = counts.get(count);
                if (targets == null) {
                    counts.put(count, targets = new ArrayList<Integer>());
                }
                targets.add(convId);
            }
            rs.close();
            stmt.close();
            for (Map.Entry<Integer, List<Integer>> update : counts.entrySet()) {
                stmt = conn.prepareStatement("UPDATE " + getMailItemTableName(mbox) + " SET size = size - ?, metadata = NULL, mod_metadata = ?, change_date = ?" + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("id", update.getValue().size()) + " AND type = " + MailItem.Type.CONVERSATION.toByte());
                pos = 1;
                stmt.setInt(pos++, update.getKey());
                stmt.setInt(pos++, mbox.getOperationChangeID());
                stmt.setInt(pos++, mbox.getOperationTimestamp());
                pos = setMailboxId(stmt, mbox, pos);
                for (int convId : update.getValue()) {
                    stmt.setInt(pos++, convId);
                }
                stmt.executeUpdate();
                stmt.close();
            }
        }
    } catch (SQLException e) {
        throw ServiceException.FAILURE("marking deletions for conversations touching " + ids.size() + " items: " + getIdListForLogging(ids), e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.closeStatement(stmt);
    }
    return getPurgedConversations(mbox, candidates);
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) DbConnection(com.zimbra.cs.db.DbPool.DbConnection) ResultSet(java.sql.ResultSet) List(java.util.List) ArrayList(java.util.ArrayList) TypedIdList(com.zimbra.cs.mailbox.util.TypedIdList) Map(java.util.Map) EnumMap(java.util.EnumMap) HashMap(java.util.HashMap)

Aggregations

DbConnection (com.zimbra.cs.db.DbPool.DbConnection)218 PreparedStatement (java.sql.PreparedStatement)165 SQLException (java.sql.SQLException)162 ResultSet (java.sql.ResultSet)85 Mailbox (com.zimbra.cs.mailbox.Mailbox)71 ArrayList (java.util.ArrayList)36 ServiceException (com.zimbra.common.service.ServiceException)23 UnderlyingData (com.zimbra.cs.mailbox.MailItem.UnderlyingData)18 HashMap (java.util.HashMap)10 Metadata (com.zimbra.cs.mailbox.Metadata)9 IOException (java.io.IOException)9 MailItem (com.zimbra.cs.mailbox.MailItem)8 TypedIdList (com.zimbra.cs.mailbox.util.TypedIdList)8 AccountServiceException (com.zimbra.cs.account.AccountServiceException)7 Folder (com.zimbra.cs.mailbox.Folder)7 List (java.util.List)6 DbVolume (com.zimbra.cs.db.DbVolume)5 PendingDelete (com.zimbra.cs.mailbox.MailItem.PendingDelete)5 VirtualConversation (com.zimbra.cs.mailbox.VirtualConversation)5 CreateVolume (com.zimbra.cs.redolog.op.CreateVolume)5