From 05ede7d899edbf51dc4a0c35460b3cb7abf25cea Mon Sep 17 00:00:00 2001
From: fly <merspieler@airmail.cc>
Date: Fri, 13 Mar 2020 10:54:09 +0100
Subject: [PATCH] Added triggers

Signed-off-by: fly <merspieler@airmail.cc>
---
 init-db.py | 132 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 103 insertions(+), 29 deletions(-)

diff --git a/init-db.py b/init-db.py
index bf0d1cb..298a6e9 100755
--- a/init-db.py
+++ b/init-db.py
@@ -1,9 +1,60 @@
 #! /usr/bin/python3
+# Copyright (C) 2018-2020 Merspieler, merspieler _at_ airmail.cc
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
 import pymysql
+import sys
 from common import norm, get_tile_width, get_tile, get_area_name
 
-# TODO set default to false
-force = True
+dbuser= ""
+dbpw = ""
+force = False
+
+argc = len(sys.argv)
+i = 1
+while i < argc:
+	if sys.argv[i] == "-p" or sys.argv[i] == "--password":
+		i += 1
+		dbpw = int(sys.argv[i])
+	elif sys.argv[i] == "-u" or sys.argv[i] == "--user":
+		i += 1
+		dbuser = sys.argv[i]
+	elif sys.argv[i] == "-f" or sys.argv[i] == "--force":
+		force = True
+	elif sys.argv[i] == "-h" or sys.argv[i] == "--help":
+		print("usage: init-db.py [OPTIONS]")
+		print("Initializes worldbuild status db")
+		print("")
+		print("OPTIONS")
+		print("  -p, --password    Database password")
+		print("  -u, --user        Database user")
+		print("  -f, --force       Recreates everything from scratch")
+		print("  -h, --help        Shows this help and exit")
+		sys.exit(0)
+	else:
+		print("Unknown option " + sys.argv[i])
+		sys.exit(1)
+	i += 1
+
+if dbuser == "":
+	print("ERROR: No database user given")
+	sys.exit(1)
+
+if dbpw == "":
+	print("ERROR: No database password given")
 
 states = [
 	"pending",
@@ -20,10 +71,12 @@ db = pymysql.connect("localhost", dbuser, dbpw, "worldbuild")
 cursor = db.cursor()
 
 if force:
-	cursor.execute("DROP TABLE tile")
-	cursor.execute("DROP TABLE secondLevel")
-	cursor.execute("DROP TABLE topLevel")
-	cursor.execute("DROP TABLE status")
+	cursor.execute("DROP TABLE IF EXISTS tile")
+	cursor.execute("DROP TABLE IF EXISTS secondLevel")
+	cursor.execute("DROP TABLE IF EXISTS topLevel")
+	cursor.execute("DROP TABLE IF EXISTS status")
+	cursor.execute("DROP TRIGGER update_top_level")
+	cursor.execute("DROP TRIGGER update_second_level")
 
 cursor.execute("CREATE TABLE IF NOT EXISTS status (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(15) UNIQUE NOT NULL);")
 cursor.execute("CREATE TABLE IF NOT EXISTS topLevel (id INT PRIMARY KEY AUTO_INCREMENT, name CHAR(7) UNIQUE NOT NULL, status_id INT NOT NULL, FOREIGN KEY (status_id) REFERENCES status(id));")
@@ -89,32 +142,53 @@ while lat < 90:
 
 db.commit()
 
-# TODO create trigger
 # Get states
 #SELECT status.name AS state, COUNT(status.name) AS occ FROM tile INNER JOIN status ON tile.status_id = status.id WHERE tile.parent_id = 400 GROUP BY status.name;
-'''
-DELIMITER //
-CREATE OR REPLACE TRIGGER update_second_level
-AFTER UPDATE ON tile
-FOR EACH ROW
-BEGIN
-	IF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "packaged")) THEN
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "packaged") WHERE id = NEW.parent_id;
-	ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "done")) THEN
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "done") WHERE id = NEW.parent_id;
-	ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "started")) > 0 THEN
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "started") WHERE id = NEW.parent_id;
-	ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "rebuild")) > 0 THEN
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "rebuild") WHERE id = NEW.parent_id;
-	ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "skip")) > 0 THEN
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "skip") WHERE id = NEW.parent_id;
-	ELSE
-		UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "pending") WHERE id = NEW.parent_id;
-	END IF;
-END; //
-DELIMITER ;
 
-'''
+print("Creating triggers")
+
+# Trigger for updating secondLevel on tile update
+sql = ('CREATE OR REPLACE TRIGGER update_second_level '
+'AFTER UPDATE ON tile '
+'FOR EACH ROW '
+'BEGIN '
+	'IF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "packaged")) THEN '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "packaged") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "done")) THEN '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "done") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "started")) > 0 THEN '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "started") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "rebuild")) > 0 THEN '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "rebuild") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM tile WHERE tile.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "skip")) > 0 THEN '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "skip") WHERE id = NEW.parent_id; '
+	'ELSE '
+		'UPDATE secondLevel SET status_id = (SELECT id FROM status WHERE name = "pending") WHERE id = NEW.parent_id; '
+	'END IF; '
+'END; ')
+cursor.execute(sql)
+
+# Trigger for updating topLevel on secondLevel update
+sql = ('CREATE OR REPLACE TRIGGER update_top_level '
+'AFTER UPDATE ON secondLevel '
+'FOR EACH ROW '
+'BEGIN '
+	'IF (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "packaged")) THEN '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "packaged") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id) = (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "done")) THEN '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "done") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "started")) > 0 THEN '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "started") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "rebuild")) > 0 THEN '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "rebuild") WHERE id = NEW.parent_id; '
+	'ELSEIF (SELECT COUNT(status_id) FROM secondLevel WHERE secondLevel.parent_id = NEW.parent_id AND status_id = (SELECT id FROM status WHERE name = "skip")) > 0 THEN '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "skip") WHERE id = NEW.parent_id; '
+	'ELSE '
+		'UPDATE topLevel SET status_id = (SELECT id FROM status WHERE name = "pending") WHERE id = NEW.parent_id; '
+	'END IF; '
+'END; ')
+cursor.execute(sql)
+db.commit()
 
 #except:
 #	db.rollback()