nitb/ctrl: Implement creating and deleting subscribers

Sadly there is no proper foreign key relationship on the tables
that related to the Subscriber. This means we can't use a DELETE
with Cascade and need to delete everything by hand. To make things
worse maybe the SMS/Paging code is still using the subscriber
making the operation more dangerous. I had added NULL checks for
sender_id/receiver_id at 30C3 so we should not crash in this
situation.

Fixes: SYS#274
diff --git a/openbsc/src/libmsc/db.c b/openbsc/src/libmsc/db.c
index 4e6ffc3..a21258d 100644
--- a/openbsc/src/libmsc/db.c
+++ b/openbsc/src/libmsc/db.c
@@ -815,6 +815,93 @@
 	return 0;
 }
 
+int db_subscriber_delete(struct gsm_subscriber *subscr)
+{
+	dbi_result result;
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM AuthKeys WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete Authkeys for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM AuthLastTuples WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete AuthLastTuples for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM AuthToken WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete AuthToken for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM EquipmentWatch WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete EquipmentWatch for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM SMS WHERE sender_id=%llu OR receiver_id=%llu",
+			subscr->id, subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete SMS for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM VLR WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete VLR for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM ApduBlobs WHERE subscriber_id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete ApduBlobs for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	result = dbi_conn_queryf(conn,
+			"DELETE FROM Subscriber WHERE id=%llu",
+			subscr->id);
+	if (!result) {
+		LOGP(DDB, LOGL_ERROR,
+			"Failed to delete Subscriber for %llu\n", subscr->id);
+		return -1;
+	}
+	dbi_result_free(result);
+
+	return 0;
+}
+
 int db_sync_equipment(struct gsm_equipment *equip)
 {
 	dbi_result result;