DELIMITER $$
CREATE OR REPLACE DEFINER=`vn`@`localhost` PROCEDURE `bs`.`nightTask_launchAll`()
BEGIN
/**
 * Runs all nightly tasks.
 */
	DECLARE vDone BOOL;
	DECLARE vError VARCHAR(255);
	DECLARE vErrorCode VARCHAR(255);
	DECLARE vSchema VARCHAR(255);
	DECLARE vProcedure VARCHAR(255);
	DECLARE vLogMail VARCHAR(255);
	DECLARE vNightTaskFk INT;

	DECLARE vQueue CURSOR FOR
		SELECT id, `schema`, `procedure` 
			FROM nightTask 
			WHERE finished <= util.VN_CURDATE()
				OR finished IS NULL
			ORDER BY `order`;

	DECLARE CONTINUE HANDLER FOR NOT FOUND
		SET vDone = TRUE;

	SET max_sp_recursion_depth = 3;

	SELECT logMail INTO vLogMail
		FROM nightTaskConfig LIMIT 1;

	OPEN vQueue;
	l: LOOP
		SET vDone = FALSE;
		FETCH vQueue INTO vNightTaskFk, vSchema, vProcedure;

		IF vDone THEN
			LEAVE l;
		END IF;

		UPDATE nightTask
			SET `started` = util.VN_NOW(),
				`finished` = NULL,
				`error` = NULL,
				`errorCode` = NULL
			WHERE id = vNightTaskFk;

		SET vError = NULL;
		CALL nightTask_launchTask(
			vSchema,
			vProcedure,
			vError,
			vErrorCode
		);

		IF vError IS NOT NULL THEN
			IF vLogMail IS NOT NULL THEN
				CALL vn.mail_insert(
					vLogMail,
					NULL,
					CONCAT('Nightly task failed (', vSchema, '.', vProcedure, ')'),
					CONCAT(
						'[', vErrorCode, '] ', vError, CHAR(13, 10), -- Line break
						'See ', SCHEMA(), '.nightTask table for more info.'
					)
				);
			END IF;

			UPDATE nightTask
				SET `error` = vError,
					`errorCode` = vErrorCode
				WHERE id = vNightTaskFk;
		ELSE
			UPDATE nightTask
				SET finished = util.VN_NOW(),
					lastFinished = util.VN_NOW()
				WHERE id = vNightTaskFk;
		END IF;
	END LOOP;
	CLOSE vQueue;
END$$
DELIMITER ;
