Skip to content

Commit 3749664

Browse files
committed
minor cleanups while I try to get query_progress over the line
1 parent 7c80d48 commit 3749664

File tree

4 files changed

+41
-80
lines changed

4 files changed

+41
-80
lines changed

countess/core/pipeline.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,10 @@ def poll_percent(self):
173173
if self.status == PipelineNodeStatus.DONE:
174174
return 100
175175
elif self.status == PipelineNodeStatus.WORK:
176-
return self.plugin.query_progress(self.cursor)
176+
qp = self.plugin.query_progress(self.cursor)
177+
return qp if qp > 0 else 0
177178
else:
178-
return 0
179+
return -1
179180

180181
def run(self, ddbc, row_limit: Optional[int] = None):
181182
if not self.plugin:

countess/gui/main.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -252,24 +252,28 @@ def config_change_callback(self, *_):
252252
def config_change_task_callback(self):
253253
"""Called when the user makes a change and had paused for a bit"""
254254
self.config_change_task = None
255-
logger.debug("config_change_task_callback")
256-
257255
self.node.stop()
256+
self.config_change_start()
257+
258+
def choose_plugin(self, plugin_class):
259+
self.node.plugin = plugin_class()
260+
self.config_change_start()
261+
262+
def config_change_start(self):
263+
self.node.is_dirty = True
258264
self.node.start(self.ddbc, preview_row_limit)
259265
self.config_change_poll_callback()
260266

261267
def config_change_poll_callback(self):
262268
percent = self.node.poll_percent()
263269
if percent < 0:
264270
logger.info("%s: 0/0", self.node.name)
265-
elif percent < 100:
271+
elif 0 <= percent < 100:
266272
logger.info("%s: %d%%", self.node.name, percent)
267-
else:
273+
self.frame.after(50, self.config_change_poll_callback)
274+
elif percent == 100:
268275
logger.info("%s: 100%%", self.node.name)
269276
self.config_change_poll_done()
270-
return
271-
272-
self.frame.after(50, self.config_change_poll_callback)
273277

274278
def config_change_poll_done(self):
275279
self.node.wait()
@@ -285,14 +289,6 @@ def config_change_poll_done(self):
285289
self.config_canvas.yview_moveto(pos1)
286290
self.config_scrollbar.set(pos1, pos2)
287291

288-
def choose_plugin(self, plugin_class):
289-
self.node.plugin = plugin_class()
290-
# self.node.prerun()
291-
self.node.is_dirty = True
292-
self.node.run(self.ddbc, preview_row_limit)
293-
self.show_config_subframe()
294-
self.change_callback(self.node)
295-
296292
def destroy(self):
297293
if self.config_change_task:
298294
self.frame.after_cancel(self.config_change_task)
@@ -302,13 +298,13 @@ def destroy(self):
302298
class SplashWrapper:
303299
def __init__(self, tk_parent):
304300
self.frame = tk.Frame(tk_parent)
305-
self.frame.configure(cursor = 'heart')
301+
self.frame.configure(cursor="heart")
306302

307303
font = ("TkHeadingFont", 16, "bold")
308-
subframe = tk.Frame(self.frame, highlightbackground='black', highlightthickness=1)
309-
subframe.grid(padx=10,pady=10)
310-
self.frame.columnconfigure(0,weight=1)
311-
self.frame.rowconfigure(0,weight=1)
304+
subframe = tk.Frame(self.frame, highlightbackground="black", highlightthickness=1)
305+
subframe.grid(padx=10, pady=10)
306+
self.frame.columnconfigure(0, weight=1)
307+
self.frame.rowconfigure(0, weight=1)
312308
tk.Label(subframe, image=get_icon(tk_parent, "countess")).grid(padx=10, pady=10)
313309
tk.Label(subframe, text=f"CountESS {VERSION}", font=font).grid(padx=10, pady=10)
314310

countess/gui/tabular.py

Lines changed: 21 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import io
22
import logging
3-
import threading
43
import tkinter as tk
54
from functools import partial
65
from math import ceil, floor, isinf, isnan
@@ -15,7 +14,6 @@
1514
duckdb_dtype_is_numeric,
1615
duckdb_dtype_to_datatype_choice,
1716
duckdb_escape_identifier,
18-
duckdb_escape_literal,
1917
)
2018

2119
logger = logging.getLogger(__name__)
@@ -239,71 +237,37 @@ def set_sort_order(self, column_num: int, descending: Optional[bool] = None):
239237
self.sort_ascending = not descending
240238
self.sort_by_col = column_num
241239

242-
# Include all column names for a stable sort order.
240+
# Create an index for whatever column we're sorting by, followed by
241+
# all other column names for a stable sort order.
242+
243243
column_name = self.table.columns[column_num]
244244
escaped_column_names = [
245245
duckdb_escape_identifier(c) for c in [column_name] + [c for c in self.table.columns if c != column_name]
246246
]
247247

248-
# We add an index for whatever column we're sorting by,
249-
# if it doesn't already exist.
250-
# XXX could do this in a thread?
251-
index_name = f"{self.table.alias}__{column_name}__idx"
252-
index_identifier = duckdb_escape_identifier(index_name)
253-
index_literal = duckdb_escape_literal(index_name)
248+
index_identifier = f"{self.table.alias}_{column_num}_idx"
254249

255-
def _create_index_continue():
256-
direction = "ASC" if self.sort_ascending else "DESC"
257-
self.table_order = ",".join(f"{c} {direction}" for c in escaped_column_names)
250+
# XXX I did have some code here which built the index in a separate thread / cursor but it
251+
# was mad with race conditions so I've scrapped it for now and the GUI will just have to
252+
# awkwardly pause.
258253

259-
logger.debug("TabularDataFrame set_sort_order %s %s", column_name, self.table_order)
254+
sql = (
255+
f"CREATE INDEX IF NOT EXISTS {index_identifier} ON {self.table.alias} ("
256+
+ ",".join(escaped_column_names)
257+
+ ")"
258+
)
259+
self.ddbc.sql(sql)
260260

261-
for n, label in enumerate(self.labels):
262-
icon = "sort_un" if n != column_num else "sort_up" if self.sort_ascending else "sort_dn"
263-
label.configure(image=get_icon(self, icon))
261+
direction = "ASC" if self.sort_ascending else "DESC"
262+
self.table_order = ",".join(f"{c} {direction}" for c in escaped_column_names)
264263

265-
self.refresh()
264+
logger.debug("TabularDataFrame set_sort_order %s %s", column_name, self.table_order)
266265

267-
# XXX workaround for https://github.com/duckdb/duckdb/issues/16086
268-
if not self.ddbc.sql(f"select 1 from duckdb_indexes() where index_name = {index_literal}"):
269-
cursor = self.ddbc.cursor()
270-
cursor.sql("set enable_progress_bar_print=false")
271-
cursor.sql("set progress_bar_time=0")
272-
273-
if self._set_sort_order_thread and self._set_sort_order_thread.is_alive():
274-
logger.debug("TabularDataFrame set_sort_order thread already running")
275-
self._set_sort_order_thread.join()
276-
277-
def _create_index_thread():
278-
sql = (
279-
f"CREATE INDEX IF NOT EXISTS {index_identifier} ON {self.table.alias} ("
280-
+ ",".join(escaped_column_names)
281-
+ ")"
282-
)
283-
logger.debug("TabularDataFrame set_sort_order index sql %s", sql)
284-
cursor.sql(sql)
285-
286-
self._set_sort_order_thread = threading.Thread(target=_create_index_thread)
287-
self._set_sort_order_thread.start()
288-
289-
def _create_index_monitor():
290-
if self._set_sort_order_thread.is_alive():
291-
try:
292-
qp = cursor.query_progress()
293-
except AttributeError:
294-
qp = 50
295-
296-
if qp >= 0:
297-
logger.info("Indexing: %d%%", qp)
298-
self.after(50, _create_index_monitor)
299-
else:
300-
self._set_sort_order_thread.join()
301-
logger.info("Indexing: 100%")
302-
_create_index_continue()
303-
304-
self.after(50, _create_index_monitor)
305-
else:
306-
_create_index_continue()
266+
for n, label in enumerate(self.labels):
267+
icon = "sort_un" if n != column_num else "sort_up" if self.sort_ascending else "sort_dn"
268+
label.configure(image=get_icon(self, icon))
269+
270+
self.refresh()
307271

308272
def _label_button_1(self, num, event):
309273
"""Click on column labels to set sort order"""

countess/plugins/variant.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def sql(self, table_name: str, columns: Iterable[str]) -> Optional[str]:
203203
prefix_aa = duckdb_escape_literal((self.prefix_aa.value + ":" if self.prefix_aa else "") + "p.")
204204
prefix_nt = duckdb_escape_literal((self.prefix_nt.value + ":" if self.prefix_nt else "") + "c.")
205205

206-
columns = ' '.join(duckdb_escape_identifier(c) + "," for c in columns if c != self.variant_out.value)
206+
columns = " ".join(duckdb_escape_identifier(c) + "," for c in columns if c != self.variant_out.value)
207207

208208
# XXX handle other short forms like _synNNNX>Y or whatever
209209
return rf"""

0 commit comments

Comments
 (0)