From 21fa0abd30603e99e8c4a8dec61c40f60c1c824c Mon Sep 17 00:00:00 2001
From: Daniel Salzman <daniel.salzman@nic.cz>
Date: Tue, 25 Oct 2016 15:19:17 +0200
Subject: [PATCH] ctl: purge also zone timers with zone-purge

---
 doc/man/knotc.8in          |  2 +-
 doc/man_knotc.rst          |  2 +-
 src/knot/ctl/commands.c    |  5 ++++-
 src/knot/zone/timers.c     | 34 ++++++++++++++++++++++++++++++++++
 src/knot/zone/timers.h     | 12 ++++++++++++
 src/utils/knotc/commands.c |  2 +-
 6 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/doc/man/knotc.8in b/doc/man/knotc.8in
index d547b97fce..1cad663eec 100644
--- a/doc/man/knotc.8in
+++ b/doc/man/knotc.8in
@@ -135,7 +135,7 @@ requires a ttl value specified.
 Remove zone data within the transaction.
 .TP
 \fBzone\-purge\fP \fIzone\fP\&...
-Purge zone data, zone file, and zone journal.
+Purge zone data, file, journal, and timers.
 .TP
 \fBconf\-init\fP
 Initialize the configuration database. (*)
diff --git a/doc/man_knotc.rst b/doc/man_knotc.rst
index 70baa568ce..75762c4d1c 100644
--- a/doc/man_knotc.rst
+++ b/doc/man_knotc.rst
@@ -112,7 +112,7 @@ Actions
   Remove zone data within the transaction.
 
 **zone-purge** *zone*...
-  Purge zone data, zone file, and zone journal.
+  Purge zone data, file, journal, and timers.
 
 **conf-init**
   Initialize the configuration database. (*)
diff --git a/src/knot/ctl/commands.c b/src/knot/ctl/commands.c
index a6a7e2f023..09e76cf1d3 100644
--- a/src/knot/ctl/commands.c
+++ b/src/knot/ctl/commands.c
@@ -22,6 +22,7 @@
 #include "knot/ctl/commands.h"
 #include "knot/events/handlers.h"
 #include "knot/updates/zone-update.h"
+#include "knot/zone/timers.h"
 #include "libknot/libknot.h"
 #include "libknot/yparser/yptrafo.h"
 #include "contrib/macros.h"
@@ -915,7 +916,9 @@ static int zone_purge(zone_t *zone, ctl_args_t *args)
 	(void)unlink(journalfile);
 	free(journalfile);
 
-	// TODO: Purge the zone timers (after zone events refactoring).
+	// Purge the zone timers.
+	(void)remove_timer_db(args->server->timers_db, args->server->zone_db,
+	                      zone->name);
 
 	return KNOT_EOK;
 }
diff --git a/src/knot/zone/timers.c b/src/knot/zone/timers.c
index 4f88507cf2..e608c42bc9 100644
--- a/src/knot/zone/timers.c
+++ b/src/knot/zone/timers.c
@@ -219,6 +219,40 @@ int write_timer_db(knot_db_t *timer_db, knot_zonedb_t *zone_db)
 	return db_api->txn_commit(&txn);
 }
 
+int remove_timer_db(knot_db_t *timer_db, knot_zonedb_t *zone_db,
+                    const knot_dname_t *zone_name)
+{
+	if (timer_db == NULL) {
+		return KNOT_EOK;
+	}
+
+	if (zone_db == NULL || zone_name == NULL) {
+		return KNOT_EINVAL;
+	}
+
+	const knot_db_api_t *db_api = knot_db_lmdb_api();
+	assert(db_api);
+
+	knot_db_txn_t txn;
+	int ret = db_api->txn_begin(timer_db, &txn, KNOT_DB_SORTED);
+	if (ret != KNOT_EOK) {
+		return ret;
+	}
+
+	knot_db_val_t key = {
+		.data = (void *)zone_name,
+		.len = knot_dname_size(zone_name)
+	};
+
+	ret = db_api->del(&txn, &key);
+	if (ret != KNOT_EOK) {
+		db_api->txn_abort(&txn);
+		return ret;
+	}
+
+	return db_api->txn_commit(&txn);
+}
+
 int sweep_timer_db(knot_db_t *timer_db, knot_zonedb_t *zone_db)
 {
 	if (timer_db == NULL) {
diff --git a/src/knot/zone/timers.h b/src/knot/zone/timers.h
index 988f4f6264..c6c8b80c68 100644
--- a/src/knot/zone/timers.h
+++ b/src/knot/zone/timers.h
@@ -62,6 +62,18 @@ int read_zone_timers(knot_db_t *timer_db, const zone_t *zone, time_t *timers);
  */
 int write_timer_db(knot_db_t *timer_db, knot_zonedb_t *zone_db);
 
+/*!
+ * \brief Removes specific zone timers from timers db.
+ *
+ * \param timer_db   Timer database.
+ * \param zone_db    Zone database.
+ * \param zone_name  Zone name.
+ *
+ * \return KNOT_E*
+ */
+int remove_timer_db(knot_db_t *timer_db, knot_zonedb_t *zone_db,
+                    const knot_dname_t *zone_name);
+
 /*!
  * \brief Removes stale zones info from timers db.
  *
diff --git a/src/utils/knotc/commands.c b/src/utils/knotc/commands.c
index 947108a584..9636d0316f 100644
--- a/src/utils/knotc/commands.c
+++ b/src/utils/knotc/commands.c
@@ -930,7 +930,7 @@ static const cmd_help_t cmd_help_table[] = {
 	{ CMD_ZONE_GET,        "<zone> [<owner> [<type>]]",              "Get zone data within the transaction." },
 	{ CMD_ZONE_SET,        "<zone>  <owner> [<ttl>] <type> <rdata>", "Add zone record within the transaction." },
 	{ CMD_ZONE_UNSET,      "<zone>  <owner> [<type> [<rdata>]]",     "Remove zone data within the transaction." },
-	{ CMD_ZONE_PURGE,      "<zone>...",                              "Purge zone data, zone file, and zone journal." },
+	{ CMD_ZONE_PURGE,      "<zone>...",                              "Purge zone data, file, journal, and timers." },
 	{ "",                  "",                                       "" },
 	{ CMD_CONF_INIT,       "",                                       "Initialize the confdb. (*)" },
 	{ CMD_CONF_CHECK,      "",                                       "Check the server configuration. (*)" },
-- 
GitLab