Skip to content

Commit 50e7430

Browse files
committed
fixes
1 parent 76b4835 commit 50e7430

File tree

1 file changed

+76
-47
lines changed

1 file changed

+76
-47
lines changed

pysimplesql/pysimplesql.py

+76-47
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,9 @@
168168
DELETE_RETURNED: int = 2 # A result was found
169169
DELETE_ABORTED: int = 4 # The search was aborted, likely during a callback
170170
DELETE_RECURSION_LIMIT_ERROR: int = 8 # We hit max nested levels
171-
DELETE_CASCADE_RECURSION_LIMIT: int = (
172-
15 # Mysql sets this as 15 when using foreign key CASCADE DELETE
173-
)
171+
172+
# Mysql sets this as 15 when using foreign key CASCADE DELETE
173+
DELETE_CASCADE_RECURSION_LIMIT: int = 15
174174

175175
# -------
176176
# Sorting
@@ -987,7 +987,7 @@ def requery(
987987
not len(self.frm[parent_table].rows.index)
988988
or Relationship.parent_virtual(self.table, self.frm)
989989
):
990-
self.rows = pd.DataFrame([]) # purge rows
990+
self.rows = pd.DataFrame(columns=self.rows.columns) # purge rows
991991
if update_elements:
992992
self.frm.update_elements(self.key)
993993
if requery_dependents:
@@ -1008,9 +1008,15 @@ def requery(
10081008
rows = self.driver.execute(query)
10091009
self.rows = rows
10101010

1011-
# now we can restore the sort order
1012-
self.load_sort_settings(sort_settings)
1013-
self.sort(self.table)
1011+
if len(self.rows.index):
1012+
# if "sort_order" not in self.rows.attrs:
1013+
# # Store the sort order as a dictionary in the attrs of the DataFrame
1014+
# sort_order = self.rows[self.pk_column].to_list()
1015+
# self.rows.attrs["sort_order"] = {self.pk_column: sort_order}
1016+
1017+
# now we can restore the sort order
1018+
self.load_sort_settings(sort_settings)
1019+
self.sort(self.table)
10141020

10151021
# Perform transform one row at a time
10161022
if self.transform is not None:
@@ -1022,8 +1028,9 @@ def requery(
10221028
# can have an equal comparison. Not the prettiest solution. Will look into
10231029
# this more on the PySimpleGUI end and make a follow-up ticket.
10241030

1025-
# Note on the below. Without rows.loc[:,:], the .applymap would return an entirely new DataFrame, and not
1026-
# a ResultSet. TODO: Move this into it's own ResultSet method?
1031+
# Note on the below. Without rows.loc[:,:], the .applymap would return an
1032+
# entirely new DataFrame, and not a ResultSet. TODO: Move this into it's own
1033+
# ResultSet method?
10271034
self.rows.loc[:, :] = self.rows.applymap(
10281035
lambda x: x.rstrip() if isinstance(x, str) else x
10291036
)
@@ -1369,7 +1376,7 @@ def set_by_pk(
13691376
omit_elements = []
13701377
# don't update self/dependents if we are going to below anyway
13711378
self.prompt_save(update_elements=False)
1372-
1379+
13731380
self.current_index = self.rows.index[self.rows[self.pk_column] == pk].tolist()[
13741381
0
13751382
]
@@ -1683,7 +1690,7 @@ def save_record(
16831690
else:
16841691
result = self.driver.save_record(self, changed_row)
16851692

1686-
if result.exception is not None:
1693+
if not isinstance(result, pd.DataFrame) and result.exception is not None:
16871694
self.frm.popup.ok(
16881695
lang.dataset_save_fail_title,
16891696
lang.dataset_save_fail.format_map(
@@ -1708,7 +1715,7 @@ def save_record(
17081715

17091716
# If child changes parent, move index back and requery/requery_dependents
17101717
if (
1711-
cascade_fk_changed and not current_row.virtual
1718+
cascade_fk_changed and not self.row_is_virtual()
17121719
): # Virtual rows already requery, and have no dependents.
17131720
self.frm[self.table].requery(select_first=False) # keep spot in table
17141721
self.frm[self.table].requery_dependents()
@@ -1829,18 +1836,22 @@ def delete_record(
18291836

18301837
# Delete child records first!
18311838
result = self.driver.delete_record(self, True)
1832-
if result == DELETE_RECURSION_LIMIT_ERROR:
1833-
self.frm.popup.ok(
1834-
lang.delete_failed_title,
1835-
lang.delete_failed.format_map(
1836-
LangFormat(exception=lang.delete_recursion_limit_error)
1837-
),
1838-
)
1839-
elif result.exception is not None:
1840-
self.frm.popup.ok(
1841-
lang.delete_failed_title,
1842-
lang.delete_failed.format_map(LangFormat(exception=result.exception)),
1843-
)
1839+
1840+
if not isinstance(result, pd.DataFrame):
1841+
if result == DELETE_RECURSION_LIMIT_ERROR:
1842+
self.frm.popup.ok(
1843+
lang.delete_failed_title,
1844+
lang.delete_failed.format_map(
1845+
LangFormat(exception=lang.delete_recursion_limit_error)
1846+
),
1847+
)
1848+
elif result.exception is not None:
1849+
self.frm.popup.ok(
1850+
lang.delete_failed_title,
1851+
lang.delete_failed.format_map(
1852+
LangFormat(exception=result.exception)
1853+
),
1854+
)
18441855

18451856
# callback
18461857
if "after_delete" in self.callbacks:
@@ -1990,7 +2001,9 @@ def row_is_virtual(self, index: int = None) -> bool:
19902001
"""
19912002
if index is None:
19922003
index = self.current_index
1993-
return self.rows.attrs["virtual"][index]
2004+
if self.rows is not None and len(self.rows.index):
2005+
return self.rows.attrs["virtual"][index]
2006+
return False
19942007

19952008
def table_values(
19962009
self, columns: List[str] = None, mark_virtual: bool = False
@@ -2291,12 +2304,15 @@ def sort(self, table: str) -> None:
22912304
self.sort_reset()
22922305
else:
22932306
print(
2294-
f"Sort column is not None. Sorting by column {self.rows.attrs['sort_column']}"
2307+
f"Sort column is not None. "
2308+
f"Sorting by column {self.rows.attrs['sort_column']}"
22952309
)
22962310
self.sort_by_column(
22972311
self.rows.attrs["sort_column"], table, self.rows.attrs["sort_reverse"]
22982312
)
2299-
self.set_by_pk(pk)
2313+
self.set_by_pk(
2314+
pk, update_elements=False, requery_dependents=False, skip_prompt_save=True
2315+
)
23002316

23012317
def sort_cycle(self, column: str, table: str) -> int:
23022318
"""
@@ -2333,7 +2349,11 @@ def insert_row(self, row: dict, idx: int = None) -> None:
23332349
:returns: None
23342350
"""
23352351
row_series = pd.Series(row)
2336-
self.rows.append(row_series, ignore_index=True)
2352+
attrs = self.rows.attrs.copy()
2353+
self.rows = pd.concat([self.rows, row_series.to_frame().T], ignore_index=True)
2354+
self.rows.attrs = attrs.copy()
2355+
# not quite working, but closer
2356+
# just need to update attrs with new index
23372357
return
23382358
if idx is None:
23392359
idx = len(self.rows.index)
@@ -3244,22 +3264,23 @@ def update_elements(
32443264
for data_key in self.datasets:
32453265
if target_data_key is not None and data_key != target_data_key:
32463266
continue
3267+
32473268
# disable mapped elements for this table if
32483269
# there are no records in this table or edit protect mode
3249-
disable = len(self[data_key].rows) == 0 or self._edit_protect
3270+
disable = len(self[data_key].rows.index) == 0 or self._edit_protect
32503271
self.update_element_states(data_key, disable)
32513272

32523273
for m in (m for m in self.event_map if m["table"] == self[data_key].table):
32533274
# Disable delete and mapped elements for this table if there are no
32543275
# records in this table or edit protect mode
32553276
if ":table_delete" in m["event"]:
3256-
disable = len(self[data_key].rows) == 0 or self._edit_protect
3277+
disable = len(self[data_key].rows.index) == 0 or self._edit_protect
32573278
win[m["event"]].update(disabled=disable)
32583279

32593280
# Disable duplicate if no rows, edit protect, or current row virtual
32603281
elif ":table_duplicate" in m["event"]:
32613282
disable = (
3262-
len(self[data_key].rows) == 0
3283+
len(self[data_key].rows.index) == 0
32633284
or self._edit_protect
32643285
or self[data_key]
32653286
.get_current_row()
@@ -3271,15 +3292,16 @@ def update_elements(
32713292
# Disable first/prev if only 1 row, or first row
32723293
elif ":table_first" in m["event"] or ":table_previous" in m["event"]:
32733294
disable = (
3274-
len(self[data_key].rows) < 2
3295+
len(self[data_key].rows.index) < 2
32753296
or self[data_key].current_index == 0
32763297
)
32773298
win[m["event"]].update(disabled=disable)
32783299

32793300
# Disable next/last if only 1 row, or last row
32803301
elif ":table_next" in m["event"] or ":table_last" in m["event"]:
3281-
disable = len(self[data_key].rows) < 2 or (
3282-
self[data_key].current_index == len(self[data_key].rows) - 1
3302+
disable = len(self[data_key].rows.index) < 2 or (
3303+
self[data_key].current_index
3304+
== len(self[data_key].rows.index) - 1
32833305
)
32843306
win[m["event"]].update(disabled=disable)
32853307

@@ -3289,7 +3311,7 @@ def update_elements(
32893311
parent = Relationship.get_parent(data_key)
32903312
if parent is not None:
32913313
disable = (
3292-
len(self[parent].rows) == 0
3314+
len(self[parent].rows.index) == 0
32933315
or self._edit_protect
32943316
or Relationship.parent_virtual(data_key, self)
32953317
)
@@ -3299,7 +3321,7 @@ def update_elements(
32993321

33003322
# Disable db_save when needed
33013323
elif ":db_save" in m["event"] or ":save_table" in m["event"]:
3302-
disable = len(self[data_key].rows) == 0 or self._edit_protect
3324+
disable = len(self[data_key].rows.index) == 0 or self._edit_protect
33033325
win[m["event"]].update(disabled=disable)
33043326

33053327
# Enable/Disable quick edit buttons
@@ -3819,7 +3841,8 @@ def update_table_element(
38193841
# update element
38203842
element.update(values=values, select_rows=select_rows)
38213843
# set vertical scroll bar to follow selected element
3822-
if vscroll_position:
3844+
# call even for 0.0, so that a 'reset sort' repositions vscroll to top.
3845+
if vscroll_position is not None:
38233846
element.set_vscroll_position(vscroll_position)
38243847
window.refresh() # Event handled and bypassed
38253848
# Enable handling for "<<TreeviewSelect>>" event
@@ -5268,14 +5291,18 @@ def __init__(
52685291
def __call__(self, column):
52695292
# store the pk:
52705293
pk = self.frm[self.data_key].get_current_pk()
5271-
sort_order = self.frm[self.data_key].sort_cycle(column, self.data_key)
5272-
# We only need to update the selectors not all elements,
5273-
# so first set by the primary key, then update_selectors()
5274-
self.frm[self.data_key].set_by_pk(
5275-
pk, update_elements=False, requery_dependents=False, skip_prompt_save=True
5276-
)
5277-
self.frm.update_selectors(self.data_key)
5278-
self.table_heading.update_headings(self.element, column, sort_order)
5294+
if len(self.frm[data_key].rows.index):
5295+
sort_order = self.frm[self.data_key].sort_cycle(column, self.data_key)
5296+
# We only need to update the selectors not all elements,
5297+
# so first set by the primary key, then update_selectors()
5298+
self.frm[self.data_key].set_by_pk(
5299+
pk,
5300+
update_elements=False,
5301+
requery_dependents=False,
5302+
skip_prompt_save=True,
5303+
)
5304+
self.frm.update_selectors(self.data_key)
5305+
self.table_heading.update_headings(self.element, column, sort_order)
52795306

52805307

52815308
# ======================================================================================
@@ -6041,9 +6068,11 @@ def set(
60416068
df.attrs["lastrowid"] = lastrowid
60426069
df.attrs["exception"] = exception
60436070
df.attrs["column_info"] = column_info
6071+
6072+
# Store virtual flags for each row
60446073
df.attrs["virtual"] = pd.Series(
6045-
[False] * len(df.index), index=df.index
6046-
) # Store virtual flags for each row
6074+
[False] * len(df.index), index=df.index, dtype="int64"
6075+
)
60476076
return df
60486077

60496078

0 commit comments

Comments
 (0)