Skip to content

Commit 7112636

Browse files
author
stonebig
committed
simplify dbtree code
1 parent 9a06d9e commit 7112636

File tree

1 file changed

+78
-85
lines changed

1 file changed

+78
-85
lines changed

examples/sqlite_py_manager.py

Lines changed: 78 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def create_menu(self):
8686
self.menu_help.add_command(label='about',
8787
command=lambda: messagebox.showinfo(message="""
8888
\nSqlite_py_manager : a graphic SQLite Client in 1 Python file
89-
\nversion 2014-06-09b : 'The magic 8th PEP'
89+
\nversion 2014-06-09c : 'Touch of Zen'
9090
\n(https://github.com/stonebig/baresql/blob/master/examples)"""))
9191

9292
def create_toolbar(self):
@@ -134,9 +134,9 @@ def new_db(self, filename=''):
134134
self.database_file = filename
135135
if os.path.isfile(filename):
136136
if messagebox.askyesno(
137-
message='Confirm Destruction of previous Datas ?',
138-
icon='question', title='Destroying'):
139-
os.remove(filename)
137+
message='Confirm Destruction of previous Datas ?',
138+
icon='question', title='Destroying'):
139+
os.remove(filename)
140140
self.conn = Baresql(self.database_file)
141141
self.actualize_db()
142142

@@ -223,24 +223,25 @@ def actualize_db(self):
223223
# delete existing tree entries before re-creating them
224224
for node in self.db_tree.get_children():
225225
self.db_tree.delete(node)
226-
# create initial node
226+
# create top node
227227
id0 = self.db_tree.insert(
228228
"", 0, "Database",
229229
text=(self.database_file.replace("\\", "/")).split("/")[-1],
230230
values=(self.database_file, ""))
231-
# add master_table, Tables, Views, Trigger, Index
232-
for category in ['master_table', 'table', 'view', 'trigger', 'index',
231+
# add Database Objects, by Category
232+
for categ in ['master_table', 'table', 'view', 'trigger', 'index',
233233
'pydef']:
234-
self.add_thingsnew(id0, category)
235-
# redo for attached databases
236-
for att_db in self.add_thingsnew(id0, 'attached_databases'):
237-
# create initial node for attached table
234+
self.feed_dbtree(id0, categ)
235+
# for attached databases
236+
for att_db in self.feed_dbtree(id0, 'attached_databases'):
237+
# create another top node
238238
id0 = self.db_tree.insert(
239239
"", 'end', att_db + "(Attached)",
240240
text=att_db+" (attached database)", values=(att_db, ""))
241-
# add attached db's master_table, Tables, Views, Trigger, and Index
241+
# add attached Database Objects, by Category
242242
for categ in ['master_table', 'table', 'view', 'trigger', 'index']:
243-
self.add_thingsnew(id0, categ, att_db)
243+
self.feed_dbtree(id0, categ, att_db)
244+
# update time of last refresh
244245
self.db_tree.heading('#0', text=(
245246
datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
246247

@@ -403,7 +404,7 @@ def get_tk_icons(self):
403404
xlzceksqu6ET7JwtLRrhwNt+1HdDUQAAOw==
404405
'''
405406
}
406-
return {k: PhotoImage(data=v) for k, v in icons.items()}
407+
return {k: PhotoImage(data=v) for k, v in icons.items()}
407408

408409
def createToolTip(self, widget, text):
409410
"""create a tooptip box for a widget."""
@@ -439,40 +440,44 @@ def close(event):
439440
widget.bind("<Enter>", enter)
440441
widget.bind("<Leave>", close)
441442

442-
def add_thingsnew(self, root_id, what, attached_db=""):
443-
"""add a sub-tree to database tree pan"""
444-
tables = get_things(self.conn, what, attached_db)
445-
# level 1 : create the "what" node (as not empty)
443+
def feed_dbtree(self, root_id, category, attached_db=""):
444+
"""feed database treeview for category, return list of leaves names"""
446445

447-
def id(t): return ('"%s".' % t.replace('"', '""')) if t != "" else t
448-
attached = id(attached_db)
446+
# prepare re-formatting functions for fields and database names
447+
def f(t): return ('"%s"' % t.replace('"', '""')) if t != "" else t
448+
449+
def db(t): return ('"%s".' % t.replace('"', '""')) if t != "" else t
450+
attached = db(attached_db)
451+
452+
# get Category list of [unique_name, name, definition, sub_category]
453+
tables = get_leaves(self.conn, category, attached_db)
449454
if len(tables) > 0:
455+
# level 1 : create the "category" node (as Category is not empty)
450456
idt = self.db_tree.insert(
451-
root_id, "end",
452-
"%s%s" % (attached, what),
453-
text="%s (%s)" % (what, len(tables)), values=("", ""))
454-
# level 2 : print object creation, and '(Definition)' if Table/View
455-
for tab in tables:
456-
definition = tab[2]
457+
root_id, "end", "%s%s (node)" % (attached, category),
458+
text="%s (%s)" % (category, len(tables)), values=("", ""))
459+
for t_id, t_name, definition, sub_cat in tables:
460+
# level 2 : print object creation, and '(Definition)' if fields
457461
sql3 = ""
458-
if tab[3] != '':
462+
if sub_cat != '':
459463
# it's a table : prepare a Query with names of each column
460-
colnames = [col[1] for col in tab[3]]
461-
columns = [col[0] for col in tab[3]]
464+
sub_c = get_leaves(self.conn, sub_cat, attached_db, t_name)
465+
colnames = [col[1] for col in sub_c]
466+
columns = [col[1] + ' ' + col[2] for col in sub_c]
462467
sql3 = 'select "'+'" , "'.join(colnames)+'" from ' + (
463-
'%s"%s"' % (attached, tab[1]))
468+
'%s%s' % (attached, f(t_name)))
464469
idc = self.db_tree.insert(
465-
idt, "end", "%s%s" % (attached, tab[0]),
466-
text=tab[1], tags=('run',), values=(definition, sql3))
470+
idt, "end", "%s%s" % (attached, t_id),
471+
text=t_name, tags=('run',), values=(definition, sql3))
467472
if sql3 != "":
468473
self.db_tree.insert(
469-
idc, "end", ("%s%s.%s" % (attached, tab[1], -1)),
474+
idc, "end", ("%s%s.%s" % (attached, t_name, -1)),
470475
text=['(Definition)'], tags=('run',),
471476
values=(definition, ""))
472477
# level 3 : Insert a line per column of the Table/View
473-
for c in range(len(columns)):
478+
for c in range(len(sub_c)):
474479
self.db_tree.insert(
475-
idc, "end", ("%s%s.%s" % (attached, tab[1], c)),
480+
idc, "end", "%s%s" % (sub_c[c][0], c),
476481
text=columns[c], tags=('run_up',), values=('', ''))
477482
return [i[1] for i in tables]
478483

@@ -1046,57 +1051,45 @@ def export_csvqr(actions):
10461051
export_csv_dialog(query, "Export Query", actions)
10471052

10481053

1049-
def get_things(conn, what, attached_db="", tbl=""):
1050-
"""'what' objects : [objectCode, objectName, Definition, [Lvl - 1]]"""
1051-
# dico = what : what qry, result id, result text, result crea, 'what' below
1052-
# or what : other 'what' specification to use in thi dictionnary
1053-
dico = {
1054-
'index': 'trigger',
1055-
'trigger': (
1056-
"""SELECT '{0:s}' || name, name, coalesce(sql,'--auto') sql
1057-
FROM {0:s}sqlite_master WHERE type='{1:s}' ORDER BY name""",
1058-
'{0:s}', '{1:s}', '{2:s}', ''),
1059-
'master_table': (
1060-
"""SELECT '{0:s}sqlite_master', 'sqlite_master', '--auto'
1061-
UNION
1062-
SELECT '{0:s}'||name, name, sql FROM {0:s}sqlite_master
1063-
WHERE type='table' AND name LIKE 'sqlite_%'
1064-
ORDER BY name""",
1065-
'{0:s}', '{1:s}', '{2:s}', 'fields'),
1066-
'table': 'view',
1067-
'view': ("""SELECT '{0:s}' || name, name, sql FROM {0:s}sqlite_master
1068-
WHERE type='{1:s}' AND NOT
1069-
(type='table' AND name LIKE 'sqlite_%') ORDER BY name""",
1070-
'{0:s}', '{1:s}', '{2:s}', 'fields'),
1071-
'fields': ("PRAGMA {0:s}TABLE_INFO([{2:s}])",
1072-
'{1:s} {2:s}', '{1:s}', '', ''),
1073-
'attached_databases': ("PRAGMA database_list", '{1:s}', '{1:s}',
1074-
"ATTACH DATABASE '{2:s}' as '{1:s}'", ''),
1075-
'pydef': ("#N/A", '{0:s}', '{0:s}', '{1:s}', '')}
1076-
1077-
def id(t): return ('"%s".' % t.replace('"', '""')) if t != "" else t
1078-
1079-
attached = id(attached_db)
1080-
order = dico[what]
1081-
if isinstance(order, type('e')): # indirection
1082-
order = dico[order]
1083-
Tables = []
1084-
if what == "pydef": # pydef request is not sql
1085-
resu = [[k, v['pydef']] for k, v in conn.conn_def.items()]
1054+
def get_leaves(conn, category, attached_db="", tbl=""):
1055+
"""returns a list of 'category' objects in attached_db
1056+
[objectCode, objectLabel, Definition, 'sub-level']
1057+
"""
1058+
# create formatting shortcuts
1059+
def f(t): return ('"%s"' % t.replace('"', '""')) if t != "" else t
1060+
1061+
def d(t): return ('%s.' % t) if t != "" else t
1062+
1063+
# Initialize datas
1064+
Tables, db, tb = [], d(attached_db), f(tbl)
1065+
1066+
if category == "pydef": # pydef request is not sql, answer is direct
1067+
Tables = [[k, k, v['pydef'], ''] for k, v in conn.conn_def.items()]
1068+
elif category == 'attached_databases':
1069+
# get all attached database, but not the first one ('main')
1070+
resu = list((conn.execute("PRAGMA database_list").fetchall()))[1:]
1071+
for c in resu:
1072+
instruct = "ATTACH DATABASE %s as %s" % (f(c[2]), f(c[1]))
1073+
Tables.append([c[1], c[1], instruct, ''])
1074+
elif category == 'fields':
1075+
resu = conn.execute("PRAGMA %sTABLE_INFO(%s)" % (db, tb)).fetchall()
1076+
Tables = [[db + tb + "." + f(c[1]), c[1], c[2], ''] for c in resu]
1077+
elif category in ('index', 'trigger', 'master_table', 'table', 'view'):
1078+
# others are 1 sql request that generates directly Tables
1079+
if category in ('index', 'trigger'):
1080+
sql = """SELECT '{0}' || name, name, coalesce(sql,'--auto') , ''
1081+
FROM {0}sqlite_master WHERE type='{1}' ORDER BY name"""
1082+
elif category == 'master_table':
1083+
sql = """SELECT '{0}sqlite_master', 'sqlite_master', '--auto'
1084+
, 'fields' UNION SELECT '{0}'||name, name, sql, 'fields'
1085+
FROM {0}sqlite_master
1086+
WHERE type='table' AND name LIKE 'sqlite_%' ORDER BY name"""
1087+
elif category in ('table', 'view'):
1088+
sql = """SELECT '{0}' || name, name, sql , 'fields'
1089+
FROM {0}sqlite_master WHERE type = '{1}' AND NOT
1090+
(type='table' AND name LIKE 'sqlite_%') ORDER BY name"""
1091+
Tables = list(conn.execute(sql.format(db, category, tbl)).fetchall())
10861092

1087-
else:
1088-
# others are sql request
1089-
resu = conn.execute(order[0].format(attached, what, tbl)).fetchall()
1090-
# result must be transformed in a list, and attached db 'main' removed
1091-
resu = list(resu) if what != 'attached_databases' else list(resu)[1:]
1092-
# generate tree list for this 'what' category level :
1093-
# [objectCode, objectName, Definition, [Level below] or '']
1094-
for rec in resu:
1095-
result = [order[i].format(*rec) for i in range(1, 5)]
1096-
if result[3] != '':
1097-
resu2 = get_things(conn, result[3], attached_db, result[1])
1098-
result[3] = resu2
1099-
Tables.append(result)
11001093
return Tables
11011094

11021095

0 commit comments

Comments
 (0)