2020-03-12 06:29:04 +00:00
#! /usr/bin/python3
2020-03-13 09:54:09 +00:00
# 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.
2020-03-12 06:29:04 +00:00
import pymysql
2020-03-13 09:54:09 +00:00
import sys
2020-03-12 06:29:04 +00:00
from common import norm , get_tile_width , get_tile , get_area_name
2020-03-13 09:54:09 +00:00
dbuser = " "
dbpw = " "
2021-03-03 20:29:14 +00:00
dbname = " worldbuild "
2021-09-30 07:15:32 +00:00
dbhost = " localhost "
2020-03-13 09:54:09 +00:00
force = False
2021-09-30 07:15:32 +00:00
use_sqlfile = True
2020-03-13 09:54:09 +00:00
argc = len ( sys . argv )
i = 1
while i < argc :
if sys . argv [ i ] == " -p " or sys . argv [ i ] == " --password " :
i + = 1
2020-03-17 17:44:28 +00:00
dbpw = sys . argv [ i ]
2020-03-13 09:54:09 +00:00
elif sys . argv [ i ] == " -u " or sys . argv [ i ] == " --user " :
i + = 1
dbuser = sys . argv [ i ]
2021-03-03 20:29:14 +00:00
elif sys . argv [ i ] == " -d " or sys . argv [ i ] == " --database " :
i + = 1
dbname = sys . argv [ i ]
2021-09-30 07:15:32 +00:00
elif sys . argv [ i ] == " -h " or sys . argv [ i ] == " --host " :
i + = 1
dbhost = sys . argv [ i ]
2020-03-13 09:54:09 +00:00
elif sys . argv [ i ] == " -f " or sys . argv [ i ] == " --force " :
force = True
2021-09-30 07:15:32 +00:00
elif sys . argv [ i ] == " -N " or sys . argv [ i ] == " --no-sql " :
force = True
2020-03-13 09:54:09 +00:00
elif sys . argv [ i ] == " -h " or sys . argv [ i ] == " --help " :
print ( " usage: init-db.py [OPTIONS] " )
print ( " Initializes worldbuild status db " )
print ( " " )
print ( " OPTIONS " )
2021-03-03 20:29:14 +00:00
print ( " -d, --database Database to be initialised. Default: worldbuild " )
2020-03-13 09:54:09 +00:00
print ( " -p, --password Database password " )
print ( " -u, --user Database user " )
2021-09-30 07:15:32 +00:00
print ( " -h, --host Database host " )
2020-03-13 09:54:09 +00:00
print ( " -f, --force Recreates everything from scratch " )
2021-09-30 07:15:32 +00:00
print ( " -N, --no-sql Don ' t use the sql file and create the structure from scratch " )
print ( " Only recommended when underlaying tiling structure was changed " )
2020-03-13 09:54:09 +00:00
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 " )
2020-03-13 13:07:44 +00:00
sys . exit ( 1 )
2020-03-12 06:29:04 +00:00
#try:
2021-09-30 07:15:32 +00:00
if use_sqlfile :
else :
states = [
" pending " ,
" started " ,
" done " ,
" packaged " ,
" skip " ,
" rebuild "
]
db = pymysql . connect ( dbhost , dbuser , dbpw , dbname )
cursor = db . cursor ( )
if force :
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 IF EXISTS update_top_level " )
cursor . execute ( " DROP TRIGGER IF EXISTS update_second_level " )
cursor . execute ( " CREATE TABLE IF NOT EXISTS status (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(15) UNIQUE NOT NULL, color VARCHAR(20)); " )
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)); " )
cursor . execute ( " CREATE TABLE IF NOT EXISTS secondLevel (id INT PRIMARY KEY AUTO_INCREMENT, name CHAR(7) UNIQUE NOT NULL, status_id INT NOT NULL, parent_id INT NOT NULL, FOREIGN KEY (status_id) REFERENCES status(id), FOREIGN KEY (parent_id) REFERENCES topLevel(id)); " )
cursor . execute ( " CREATE TABLE IF NOT EXISTS tile (id INT PRIMARY KEY AUTO_INCREMENT, status_id INT NOT NULL, parent_id INT NOT NULL, FOREIGN KEY (status_id) REFERENCES status(id), FOREIGN KEY (parent_id) REFERENCES secondLevel(id)); " )
cursor . execute ( " CREATE INDEX IF NOT EXISTS tile_index on tile(status_id, parent_id); " )
for state in states :
sql = " INSERT INTO status(name) VALUES ( ' " + state + " ' ) "
2020-03-12 06:29:04 +00:00
cursor . execute ( sql )
2021-09-30 07:15:32 +00:00
sql = " SELECT id FROM status WHERE name= ' pending ' "
cursor . execute ( sql )
result = cursor . fetchall ( )
for row in result :
sid = str ( row [ 0 ] )
print ( " Creating tile groups " )
ii = - 9
while ii < 9 :
i = ii * 10
jj = - 18
while jj < 18 :
j = jj * 10
major = get_area_name ( i , j )
sql = " INSERT INTO topLevel (name, status_id) VALUES ( ' " + major + " ' , " + sid + " ); "
cursor . execute ( sql )
sql = " SELECT id FROM topLevel WHERE name= ' " + major + " ' "
cursor . execute ( sql )
result = cursor . fetchall ( )
for row in result :
major_id = str ( row [ 0 ] )
for k in range ( 0 , 10 ) :
iii = i
for l in range ( 0 , 10 ) :
minor = get_area_name ( iii , j )
sql = " INSERT INTO secondLevel (parent_id, name, status_id) VALUES ( " + major_id + " , ' " + minor + " ' , " + sid + " ) "
cursor . execute ( sql )
iii + = 1
j + = 1
jj + = 1
ii + = 1
print ( " Creating tiles " )
lat = - 83
while lat < 83 :
lon = - 180
while lon < 180 :
tile = get_tile ( lat , lon )
parent = get_area_name ( lat , lon )
sql = " SELECT id FROM secondLevel WHERE name= ' " + parent + " ' "
cursor . execute ( sql )
result = cursor . fetchall ( )
for row in result :
pid = row [ 0 ]
sql = " INSERT INTO tile (id, parent_id, status_id) VALUES ( " + str ( tile ) + " , " + str ( pid ) + " , " + sid + " ) "
cursor . execute ( sql )
lon + = get_tile_width ( lat )
lat + = 0.125
sql = " CREATE TABLE `auth` (`id` int(11) NOT NULL AUTO_INCREMENT, `token` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `token` (`token`)) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 "
cursor . execute ( sql )
2020-03-12 06:29:04 +00:00
2021-09-30 07:15:32 +00:00
db . commit ( )
2020-03-13 09:54:09 +00:00
2021-09-30 07:15:32 +00:00
# Always create triggers via script cause there can be a user name conflict on import.
2020-03-13 09:54:09 +00:00
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 '
2021-09-30 07:15:32 +00:00
' BEGIN UPDATE secondLevel SET status_id = (SELECT status_id FROM tile JOIN status ON status_id = status.id WHERE tile.parent_id = NEW.parent_id ORDER BY priority ASC LIMIT 1) WHERE id = NEW.parent_id; END ' )
2020-03-13 09:54:09 +00:00
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 '
2021-09-30 07:15:32 +00:00
' BEGIN UPDATE topLevel SET status_id = (SELECT status_id FROM secondLevel JOIN status ON status_id = status.id WHERE secondLevel.parent_id = NEW.parent_id ORDER BY priority ASC LIMIT 1) WHERE id = NEW.parent_id; END ' )
2021-03-03 20:29:14 +00:00
cursor . execute ( sql )
2020-03-13 09:54:09 +00:00
db . commit ( )
2020-03-12 06:29:04 +00:00
#except:
# print("Failed to setup database...")
2021-09-30 07:15:32 +00:00
# db.rollback()
2020-03-12 06:29:04 +00:00
#finally:
db . close ( )