Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/dm_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,78 @@ int db_icheck_mimeparts(gboolean cleanup)
return t;
}

int db_icheck_headernames(gboolean cleanup)
{
Connection_T c; ResultSet_T r; volatile int t = DM_SUCCESS;
GList *ids = NULL;

c = db_con_get();
TRY
r = db_query(c, "SELECT hn.id FROM %sheadername hn LEFT JOIN %sheader h ON hn.id = h.headername_id "
"WHERE h.headername_id IS NULL", DBPFX, DBPFX);
while(db_result_next(r)) {
uint64_t *id = g_new0(uint64_t, 1);
*id = db_result_get_u64(r, 0);
ids = g_list_prepend(ids, id);
}
if (cleanup) {
while(ids) {
db_begin_transaction(c);
db_exec(c, "DELETE FROM %sheadername WHERE id = %" PRIu64 "", DBPFX, *(uint64_t *)ids->data);
db_commit_transaction(c);
if (! g_list_next(ids)) break;
ids = g_list_next(ids);
}
}
t = g_list_length(ids);
g_list_destroy(ids);
CATCH(SQLException)
LOG_SQLERROR;
db_rollback_transaction(c);
t = DM_EQUERY;
FINALLY
db_con_close(c);
END_TRY;

return t;
}

int db_icheck_headervalues(gboolean cleanup)
{
Connection_T c; ResultSet_T r; volatile int t = DM_SUCCESS;
GList *ids = NULL;

c = db_con_get();
TRY
r = db_query(c, "SELECT hv.id FROM %sheadervalue hv LEFT JOIN %sheader h ON hv.id = h.headervalue_id "
"WHERE h.headervalue_id IS NULL", DBPFX, DBPFX);
while(db_result_next(r)) {
uint64_t *id = g_new0(uint64_t, 1);
*id = db_result_get_u64(r, 0);
ids = g_list_prepend(ids, id);
}
if (cleanup) {
while(ids) {
db_begin_transaction(c);
db_exec(c, "DELETE FROM %sheadervalue WHERE id = %" PRIu64 "", DBPFX, *(uint64_t *)ids->data);
db_commit_transaction(c);
if (! g_list_next(ids)) break;
ids = g_list_next(ids);
}
}
t = g_list_length(ids);
g_list_destroy(ids);
CATCH(SQLException)
LOG_SQLERROR;
db_rollback_transaction(c);
t = DM_EQUERY;
FINALLY
db_con_close(c);
END_TRY;

return t;
}

int db_icheck_rfcsize(GList **lost)
{
Connection_T c; ResultSet_T r; volatile int t = DM_SUCCESS;
Expand Down
2 changes: 2 additions & 0 deletions src/dm_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,8 @@ int db_get_mailbox_size(uint64_t mailbox_idnr, int only_deleted, uint64_t * mail
int db_icheck_partlists(gboolean cleanup);
int db_icheck_mimeparts(gboolean cleanup);
int db_icheck_physmessages(gboolean cleanup);
int db_icheck_headernames(gboolean cleanup);
int db_icheck_headervalues(gboolean cleanup);

/**
* \brief check for cached header values
Expand Down
41 changes: 40 additions & 1 deletion src/maintenance.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,8 @@ int do_check_integrity(void)
3. Check for loose physmessages
4. Check for loose partlists
5. Check for loose mimeparts
6. Check for loose headernames
7. Check for loose headervalues
*/

/* part 3 */
Expand Down Expand Up @@ -704,12 +706,49 @@ int do_check_integrity(void)
action, difftime(stop, start));
/* end part 5 */

/* part 6 */
start = stop;
qprintf("\n%s DBMAIL headernames integrity...\n", action);
if ((count = db_icheck_headernames(cleanup)) < 0) {
qerrorf("Failed. An error occurred. Please check log.\n");
serious_errors = 1;
return -1;
}

qprintf("Ok. Found [%ld] unconnected headernames.\n", count);
if (count > 0 && cleanup) {
qerrorf("Ok. Orphaned headernames deleted.\n");
}

time(&stop);
qverbosef("--- %s unconnected headernames took %g seconds\n",
action, difftime(stop, start));
/* end part 6 */

/* part 7 */
start = stop;
qprintf("\n%s DBMAIL headervalues integrity...\n", action);
if ((count = db_icheck_headervalues(cleanup)) < 0) {
qerrorf("Failed. An error occurred. Please check log.\n");
serious_errors = 1;
return -1;
}

qprintf("Ok. Found [%ld] unconnected headervalues.\n", count);
if (count > 0 && cleanup) {
qerrorf("Ok. Orphaned headervalues deleted.\n");
}

time(&stop);
qverbosef("--- %s unconnected headervalues took %g seconds\n",
action, difftime(stop, start));
/* end part 7 */

g_list_destroy(lost);
lost = NULL;

time(&stop);
qverbosef("--- %s block integrity took %g seconds\n", action, difftime(stop, start));
/* end part 6 */

return 0;
}
Expand Down