* @return <b>null</b>
* @throws MessagingException
*/
public Message[] expunge() throws MessagingException {
Statement oStmt = null;
CallableStatement oCall = null;
PreparedStatement oUpdt = null;
PreparedStatement oPart = null;
PreparedStatement oAddr = null;
ResultSet oRSet;
String sSQL;
if (DebugFile.trace) {
DebugFile.writeln("Begin DBFolder.expunge()");
DebugFile.incIdent();
}
// *************************************************************************
// If Folder is not opened is read-write mode then raise an exception
if (0==(iOpenMode&READ_WRITE)) {
if (DebugFile.trace) DebugFile.decIdent();
throw new javax.mail.FolderClosedException(this, "Folder is not open is READ_WRITE mode");
}
if ((0==(iOpenMode&MODE_MBOX)) && (0==(iOpenMode&MODE_BLOB))) {
if (DebugFile.trace) DebugFile.decIdent();
throw new javax.mail.FolderClosedException(this, "Folder is not open in MBOX nor BLOB mode");
}
// ***********************************************
// First delete the empty messages
// (used for clearing drafts that have no contents)
DBSubset oEmptyDrafts = new DBSubset (DB.k_mime_msgs+" m",
"m."+DB.gu_mimemsg,
"m."+DB.gu_category+"=? AND m."+DB.gu_workarea+"=? AND " +
"m." + DB.bo_deleted + "<>1 AND m." + DB.gu_parent_msg + " IS NULL AND " +
DBBind.Functions.LENGTH+"("+DBBind.Functions.ISNULL+"(m."+DB.tx_subject+",''))=0 AND " +
"m."+DB.len_mimemsg + "=0 AND NOT EXISTS (SELECT p." + DB.gu_mimemsg + " FROM " +
DB.k_mime_parts + " p WHERE m." + DB.gu_mimemsg + "=p." + DB.gu_mimemsg + ")" , 10);
int iEmptyDrafts = 0;
JDCConnection oConn = null;
try {
oConn = getConnection();
iEmptyDrafts = oEmptyDrafts.load(oConn, new Object[]{getCategoryGuid(),((DBStore)getStore()).getUser().getString(DB.gu_workarea)});
} catch (SQLException sqle) {
throw new MessagingException(sqle.getMessage(), sqle);
}
if (iEmptyDrafts>0) {
sSQL = "UPDATE " + DB.k_mime_msgs + " SET " + DB.bo_deleted + "=1 WHERE " + DB.gu_mimemsg + "=?";
if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+")");
try {
oUpdt = oConn.prepareStatement(sSQL);
for (int d=0; d<iEmptyDrafts; d++) {
oUpdt.setString(1,oEmptyDrafts.getString(0,d));
oUpdt.executeUpdate();
} // next
oUpdt.close();
} catch (SQLException sqle) {
throw new MessagingException(sqle.getMessage(), sqle);
}
} // fi
// ***********************************************
// Get the list of deleted and not purged messages
MboxFile oMBox = null;
DBSubset oDeleted = new DBSubset(DB.k_mime_msgs,
DB.gu_mimemsg+","+DB.pg_message,
DB.bo_deleted+"=1 AND "+DB.gu_category+"='"+oCatg.getString(DB.gu_category)+"'", 100);
try {
int iDeleted = oDeleted.load(getConnection());
File oFile = getFile();
// *************************************
// Purge deleted messages from MBOX file
if (oFile.exists() && iDeleted>0) {
oMBox = new MboxFile(oFile, MboxFile.READ_WRITE);
int[] msgnums = new int[iDeleted];
for (int m=0; m<iDeleted; m++)
msgnums[m] = oDeleted.getInt(1, m);
oMBox.purge(msgnums);
oMBox.close();
}
// *********************************************************
// Remove from disk the files referenced by deleted messages
oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
if (DebugFile.trace) DebugFile.writeln("Connection.executeQuery(SELECT p." + DB.file_name + " FROM " + DB.k_mime_parts + " p," + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg + "=m."+ DB.gu_mimemsg + " AND m." + DB.id_disposition + "='reference' AND m." + DB.bo_deleted + "=1 AND m." + DB.gu_category +"='"+oCatg.getString(DB.gu_category)+"')");
oRSet = oStmt.executeQuery("SELECT p." + DB.id_part + ",p." + DB.id_type + ",p." + DB.file_name + " FROM " + DB.k_mime_parts + " p," + DB.k_mime_msgs + " m WHERE p." +
DB.gu_mimemsg + "=m."+ DB.gu_mimemsg + " AND m." + DB.id_disposition + "='reference' AND m." +
DB.bo_deleted + "=1 AND m." + DB.gu_category +"='"+oCatg.getString(DB.gu_category)+"'");
while (oRSet.next()) {
if (DebugFile.trace) DebugFile.writeln("processing part "+String.valueOf(oRSet.getInt(1))+" "+oRSet.getString(2));
String sFileName = oRSet.getString(3);
if (!oRSet.wasNull()) {
if (DebugFile.trace) DebugFile.writeln("trying to delete file "+sFileName);
try {
File oRef = new File(sFileName);
if (oRef.exists())
oRef.delete();
else if (DebugFile.trace)
DebugFile.writeln("file "+sFileName+" not found");
}
catch (SecurityException se) {
if (DebugFile.trace) DebugFile.writeln("SecurityException deleting file " + sFileName + " " + se.getMessage());
}
}
} // wend
oRSet.close();
oRSet = null;
oStmt.close();
oStmt = null;
// ****************************************************
// Set Category size to length of MBOX file after purge
oFile = getFile();
oStmt = oConn.createStatement();
oStmt.executeUpdate("UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+String.valueOf(oFile.length())+" WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"'");
oStmt.close();
oStmt=null;
// *********************************************
// Actually delete messages from database tables
if (oConn.getDataBaseProduct()==JDCConnection.DBMS_POSTGRESQL) {
oStmt = oConn.createStatement();
for (int d=0; d<iDeleted; d++)
oStmt.executeQuery("SELECT k_sp_del_mime_msg('" + oDeleted.getString(0,d) + "')");
oStmt.close();
oStmt=null;
}
else {
oCall = oConn.prepareCall("{ call k_sp_del_mime_msg(?) }");
for (int d=0; d<iDeleted; d++) {
oCall.setString(1, oDeleted.getString(0,d));
oCall.execute();
} // next
oCall.close();
oCall=null;
}
if (oFile.exists() && iDeleted>0) {
// ***********************************************************************
// Temporary move all messages at k_mime_msgs, k_mime_parts & k_inet_addrs
// beyond its maximum so they do not clash when progressive identifiers
// are re-assigned
BigDecimal oUnit = new BigDecimal(1);
oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
oRSet = oStmt.executeQuery("SELECT MAX("+DB.pg_message+") FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"'");
oRSet.next();
BigDecimal oMaxPg = oRSet.getBigDecimal(1);
if (oRSet.wasNull()) oMaxPg = new BigDecimal(0);
oRSet.close();
oRSet = null;
oStmt.close();
oStmt = null;
oMaxPg = oMaxPg.add(oUnit);
String sCat = getCategory().getString(DB.gu_category);
oStmt = oConn.createStatement();
oStmt.executeUpdate("UPDATE "+DB.k_mime_msgs+" SET "+DB.pg_message+"="+DB.pg_message+"+"+oMaxPg.toString()+" WHERE "+DB.gu_category+"='"+sCat+"'");
oStmt.close();
oStmt = null;
// *********************************************************************************
// Re-assign ordinal position and byte offset for all messages remaining after purge
DBSubset oMsgSet = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg+","+DB.pg_message, DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"' ORDER BY "+DB.pg_message, 1000);
int iMsgCount = oMsgSet.load(oConn);
oMBox = new MboxFile(oFile, MboxFile.READ_ONLY);
long[] aPositions = oMBox.getMessagePositions();
oMBox.close();
oMaxPg = new BigDecimal(0);
oUpdt = oConn.prepareStatement("UPDATE "+DB.k_mime_msgs+" SET "+DB.pg_message+"=?,"+DB.nu_position+"=? WHERE "+DB.gu_mimemsg+"=?");
oPart = oConn.prepareStatement("UPDATE "+DB.k_mime_parts+" SET "+DB.pg_message+"=? WHERE "+DB.gu_mimemsg+"=?");
oAddr = oConn.prepareStatement("UPDATE "+DB.k_inet_addrs+" SET "+DB.pg_message+"=? WHERE "+DB.gu_mimemsg+"=?");
for (int m=0; m<iMsgCount; m++) {
String sGuMsg = oMsgSet.getString(0,m);
oUpdt.setBigDecimal(1, oMaxPg);
oUpdt.setBigDecimal(2, new BigDecimal(aPositions[m]));
oUpdt.setString(3, sGuMsg);
oUpdt.executeUpdate();
oPart.setBigDecimal(1, oMaxPg);
oPart.setString(2, sGuMsg);
oPart.executeUpdate();
oAddr.setBigDecimal(1, oMaxPg);
oAddr.setString(2, sGuMsg);
oAddr.executeUpdate();
oMaxPg = oMaxPg.add(oUnit);
}
oUpdt.close();
oPart.close();
oAddr.close();
}
oConn.commit();
} catch (SQLException sqle) {
try { if (oMBox!=null) oMBox.close(); } catch (Exception e) {}
try { if (oStmt!=null) oStmt.close(); } catch (Exception e) {}
try { if (oCall!=null) oCall.close(); } catch (Exception e) {}
try { if (oConn!=null) oConn.rollback(); } catch (Exception e) {}
throw new MessagingException (sqle.getMessage(), sqle);
}
catch (IOException sqle) {
try { if (oMBox!=null) oMBox.close(); } catch (Exception e) {}
try { if (oStmt!=null) oStmt.close(); } catch (Exception e) {}
try { if (oCall!=null) oCall.close(); } catch (Exception e) {}
try { if (oConn!=null) oConn.rollback(); } catch (Exception e) {}
throw new MessagingException (sqle.getMessage(), sqle);
}
if (DebugFile.trace) {