Skip to content

Commit c3da381

Browse files
committed
change entries getter
1 parent 3e32d5a commit c3da381

File tree

11 files changed

+96
-109
lines changed

11 files changed

+96
-109
lines changed

tagstudio/src/core/library/alchemy/library.py

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -217,33 +217,28 @@ def entries_count(self) -> int:
217217
with Session(self.engine) as session:
218218
return session.scalar(select(func.count(Entry.id)))
219219

220-
@property
221-
def _entries(self) -> Iterator[Entry]:
220+
def get_entries(self, with_joins: bool = False) -> Iterator[Entry]:
222221
"""Load entries without joins."""
223222
with Session(self.engine) as session:
224-
entries = session.execute(select(Entry).distinct()).scalars() # .unique()
225-
for entry in entries:
226-
yield entry
227-
session.expunge(entry)
228-
229-
@property
230-
def _entries_full(self) -> Iterator[Entry]:
231-
"""Load entries with joins."""
232-
with Session(self.engine) as session:
233-
stmt = (
234-
select(Entry)
235-
.outerjoin(Entry.text_fields)
236-
.outerjoin(Entry.datetime_fields)
237-
.outerjoin(Entry.tag_box_fields)
238-
.options(
239-
contains_eager(Entry.text_fields),
240-
contains_eager(Entry.datetime_fields),
241-
contains_eager(Entry.tag_box_fields).selectinload(TagBoxField.tags),
223+
stmt = select(Entry)
224+
if with_joins:
225+
stmt = (
226+
stmt.outerjoin(Entry.text_fields)
227+
.outerjoin(Entry.datetime_fields)
228+
.outerjoin(Entry.tag_box_fields)
229+
.options(
230+
contains_eager(Entry.text_fields),
231+
contains_eager(Entry.datetime_fields),
232+
contains_eager(Entry.tag_box_fields).selectinload(
233+
TagBoxField.tags
234+
),
235+
)
242236
)
243-
.distinct()
244-
)
237+
stmt = stmt.distinct()
245238

246-
entries = session.execute(stmt).scalars().unique() # .all()
239+
entries = session.execute(stmt).scalars()
240+
if with_joins:
241+
entries = entries.unique()
247242

248243
for entry in entries:
249244
yield entry

tagstudio/src/core/utils/missing_files.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def refresh_missing_files(self) -> Iterator[int]:
2929
"""Track the number of Entries that point to an invalid file path."""
3030
logger.info("refresh_missing_files running")
3131
self.missing_files = []
32-
for i, entry in enumerate(self.library._entries):
32+
for i, entry in enumerate(self.library.get_entries()):
3333
full_path = self.library.library_dir / entry.path
3434
if not full_path.exists() or not full_path.is_file():
3535
self.missing_files.append(entry)

tagstudio/src/qt/modals/folders_to_tags.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def add_tag_to_tree(items: list[Tag]):
6868
reversed_tag = reverse_tag(library, tag, None)
6969
add_tag_to_tree(reversed_tag)
7070

71-
for entry in library._entries:
71+
for entry in library.get_entries():
7272
folders = entry.path.parts[1:-1]
7373
if not folders:
7474
continue
@@ -121,7 +121,7 @@ def _add_folders_to_tree(items: typing.Sequence[str]) -> BranchData:
121121
reversed_tag = reverse_tag(library, tag, None)
122122
add_tag_to_tree(reversed_tag)
123123

124-
for entry in library._entries:
124+
for entry in library.get_entries():
125125
folders = entry.path.parts[1:-1]
126126
if not folders:
127127
continue

tagstudio/tests/conftest.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ def library(request):
7575
yield lib
7676

7777

78+
@pytest.fixture
79+
def entry(library):
80+
yield next(library.get_entries())
81+
82+
83+
@pytest.fixture
84+
def entry_full(library):
85+
yield next(library.get_entries(with_joins=True))
86+
87+
7888
@pytest.fixture
7989
def qt_driver(qtbot, library):
8090
with TemporaryDirectory() as tmp_dir:
@@ -97,7 +107,7 @@ class Args:
97107
driver.lib = library
98108
# TODO - downsize this method and use it
99109
# driver.start()
100-
driver.frame_content = list(library._entries)
110+
driver.frame_content = list(library.get_entries())
101111
yield driver
102112

103113

tagstudio/tests/macros/test_sidecar.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,18 @@
99

1010

1111
@pytest.mark.parametrize("library", [TemporaryDirectory()], indirect=True)
12-
def test_sidecar_macro(qt_driver, library, cwd):
13-
entry = next(library._entries_full)
14-
entry.path = Path("newgrounds/foo.txt")
12+
def test_sidecar_macro(qt_driver, library, cwd, entry_full):
13+
entry_full.path = Path("newgrounds/foo.txt")
1514

1615
fixture = cwd / "fixtures/sidecar_newgrounds.json"
17-
dst = library.library_dir / "newgrounds" / (entry.path.stem + ".json")
16+
dst = library.library_dir / "newgrounds" / (entry_full.path.stem + ".json")
1817
dst.parent.mkdir()
1918
shutil.copy(fixture, dst)
2019

21-
qt_driver.frame_content = [entry]
20+
qt_driver.frame_content = [entry_full]
2221
qt_driver.run_macro(MacroID.SIDECAR, 0)
2322

24-
entry = next(library._entries_full)
23+
entry = next(library.get_entries(with_joins=True))
2524
new_fields = (
2625
(_FieldID.DESCRIPTION.name, "NG description"),
2726
(_FieldID.ARTIST.name, "NG artist"),

tagstudio/tests/qt/test_driver.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@ def test_update_thumbs(qt_driver):
2828
assert thumb.isVisible() == (idx == 0)
2929

3030

31-
def test_select_item_bridge(qt_driver):
31+
def test_select_item_bridge(qt_driver, entry):
3232
# mock some props since we're not running `start()`
3333
qt_driver.autofill_action = Mock()
3434
qt_driver.sort_fields_action = Mock()
3535

36-
entry = next(qt_driver.lib._entries)
37-
3836
# set the content manually
3937
qt_driver.frame_content = [entry] * 3
4038

tagstudio/tests/qt/test_item_thumb.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55

66

77
@pytest.mark.parametrize("new_value", (True, False))
8-
def test_badge_visual_state(library, qt_driver, new_value):
9-
entry = next(qt_driver.lib._entries)
10-
8+
def test_badge_visual_state(library, qt_driver, entry, new_value):
119
thumb = ItemThumb(ItemType.ENTRY, qt_driver.lib, qt_driver, (100, 100), 0)
1210

1311
qt_driver.frame_content = [entry]

tagstudio/tests/qt/test_preview_panel.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
def test_update_widgets_not_selected(qt_driver, library):
8-
qt_driver.frame_content = list(library._entries)
8+
qt_driver.frame_content = list(library.get_entries())
99
qt_driver.selected = []
1010

1111
panel = PreviewPanel(library, qt_driver)
@@ -16,7 +16,7 @@ def test_update_widgets_not_selected(qt_driver, library):
1616

1717

1818
def test_update_widgets_single_selected(qt_driver, library):
19-
qt_driver.frame_content = list(library._entries)
19+
qt_driver.frame_content = list(library.get_entries())
2020
qt_driver.selected = [0]
2121

2222
panel = PreviewPanel(library, qt_driver)
@@ -34,7 +34,7 @@ def test_update_widgets_multiple_selected(qt_driver, library):
3434
library.add_entries([entry])
3535
assert library.entries_count == 3
3636

37-
qt_driver.frame_content = list(library._entries)
37+
qt_driver.frame_content = list(library.get_entries())
3838
qt_driver.selected = [0, 1, 2]
3939

4040
panel = PreviewPanel(library, qt_driver)
@@ -50,13 +50,12 @@ def test_update_widgets_multiple_selected(qt_driver, library):
5050
}
5151

5252

53-
def test_write_container_text_line(qt_driver, library):
53+
def test_write_container_text_line(qt_driver, entry_full, library):
5454
# Given
5555
panel = PreviewPanel(library, qt_driver)
56-
entry = next(library._entries_full)
5756

58-
field = entry.text_fields[0]
59-
assert len(entry.text_fields) == 1
57+
field = entry_full.text_fields[0]
58+
assert len(entry_full.text_fields) == 1
6059
assert field.type.type == FieldTypeEnum.TEXT_LINE
6160
assert field.type.name == "Title"
6261

@@ -77,42 +76,42 @@ def test_write_container_text_line(qt_driver, library):
7776
modal.save_button.click()
7877

7978
# Then reload entry
80-
entry = next(library._entries_full)
79+
entry_full = next(library.get_entries(with_joins=True))
8180
# the value was updated
82-
assert entry.text_fields[0].value == "bar"
81+
assert entry_full.text_fields[0].value == "bar"
8382

8483

8584
def test_remove_field(qt_driver, library):
8685
# Given
8786
panel = PreviewPanel(library, qt_driver)
88-
entries = list(library._entries_full)
87+
entries = list(library.get_entries(with_joins=True))
8988
qt_driver.frame_content = entries
9089
panel.selected = [1]
9190

9291
field = entries[1].text_fields[0]
9392
panel.write_container(0, field)
9493
panel.remove_field(field)
9594

96-
entries = list(library._entries_full)
95+
entries = list(library.get_entries(with_joins=True))
9796
assert not entries[1].text_fields
9897

9998

10099
def test_update_field(qt_driver, library):
101100
panel = PreviewPanel(library, qt_driver)
102101

103-
qt_driver.frame_content = list(library._entries)[:2]
102+
qt_driver.frame_content = list(library.get_entries())[:2]
104103
qt_driver.selected = [0, 1]
105104
panel.selected = [0, 1]
106105

107106
field = [
108107
x
109-
for x in next(library._entries_full).text_fields
108+
for x in next(library.get_entries(with_joins=True)).text_fields
110109
if x.type.type == FieldTypeEnum.TEXT_LINE
111110
][0]
112111

113112
panel.update_field(field, "meow")
114113

115-
for entry in list(library._entries_full)[:2]:
114+
for entry in library.get_entries(with_joins=True):
116115
field = [
117116
x for x in entry.text_fields if x.type.type == FieldTypeEnum.TEXT_LINE
118117
][0]

tagstudio/tests/qt/test_tag_widget.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from unittest.mock import patch
22

3-
from src.core.library import Entry
43
from src.core.library.alchemy.fields import _FieldID
54
from src.qt.widgets.tag import TagWidget
65
from src.qt.widgets.tag_box import TagBoxWidget
@@ -9,7 +8,7 @@
98

109
def test_tag_widget(qtbot, library, qt_driver):
1110
# given
12-
entry = next(library._entries_full)
11+
entry = next(library.get_entries(with_joins=True))
1312
field = entry.tag_box_fields[0]
1413

1514
tag_widget = TagBoxWidget(field, "title", qt_driver)
@@ -26,7 +25,7 @@ def test_tag_widget(qtbot, library, qt_driver):
2625

2726
def test_tag_widget_add_existing_raises(qtbot, library, qt_driver):
2827
# Given
29-
entry = next(library._entries_full)
28+
entry = next(library.get_entries(with_joins=True))
3029
tag_field = [f for f in entry.tag_box_fields if f.type_key == _FieldID.TAGS.name][0]
3130

3231
assert len(entry.tags) == 1
@@ -46,7 +45,7 @@ def test_tag_widget_add_existing_raises(qtbot, library, qt_driver):
4645

4746
def test_tag_widget_add_new_pass(qtbot, library, qt_driver, generate_tag):
4847
# Given
49-
entry = next(library._entries_full)
48+
entry = next(library.get_entries(with_joins=True))
5049
field = entry.tag_box_fields[0]
5150

5251
tag = generate_tag(name="new_tag")
@@ -65,14 +64,14 @@ def test_tag_widget_add_new_pass(qtbot, library, qt_driver, generate_tag):
6564
assert not mocked.emit.called
6665

6766

68-
def test_tag_widget_remove(qtbot, qt_driver):
69-
entry: Entry = next(qt_driver.lib._entries_full)
70-
71-
tag = list(entry.tags)[0]
67+
def test_tag_widget_remove(qtbot, qt_driver, library, entry_full):
68+
tag = list(entry_full.tags)[0]
7269
assert tag
7370

74-
assert entry.tag_box_fields
75-
tag_field = [f for f in entry.tag_box_fields if f.type_key == _FieldID.TAGS.name][0]
71+
assert entry_full.tag_box_fields
72+
tag_field = [
73+
f for f in entry_full.tag_box_fields if f.type_key == _FieldID.TAGS.name
74+
][0]
7675

7776
tag_widget = TagBoxWidget(tag_field, "title", qt_driver)
7877
tag_widget.driver.selected = [0]
@@ -84,19 +83,19 @@ def test_tag_widget_remove(qtbot, qt_driver):
8483

8584
tag_widget.remove_button.clicked.emit()
8685

87-
entry: Entry = next(qt_driver.lib._entries_full)
86+
entry = next(qt_driver.lib.get_entries(with_joins=True))
8887
assert not entry.tag_box_fields[0].tags
8988

9089

91-
def test_tag_widget_edit(qtbot, qt_driver):
90+
def test_tag_widget_edit(qtbot, qt_driver, library, entry_full):
9291
# Given
93-
entry: Entry = next(qt_driver.lib._entries_full)
94-
95-
tag = list(entry.tags)[0]
92+
tag = list(entry_full.tags)[0]
9693
assert tag
9794

98-
assert entry.tag_box_fields
99-
tag_field = [f for f in entry.tag_box_fields if f.type_key == _FieldID.TAGS.name][0]
95+
assert entry_full.tag_box_fields
96+
tag_field = [
97+
f for f in entry_full.tag_box_fields if f.type_key == _FieldID.TAGS.name
98+
][0]
10099

101100
tag_box_widget = TagBoxWidget(tag_field, "title", qt_driver)
102101
tag_box_widget.driver.selected = [0]

tagstudio/tests/test_folders_tags.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33

44
def test_folders_to_tags(library):
55
folders_to_tags(library)
6-
entry = [x for x in library._entries_full if "bar.md" in str(x.path)][0]
6+
entry = [
7+
x for x in library.get_entries(with_joins=True) if "bar.md" in str(x.path)
8+
][0]
79
assert {x.name for x in entry.tags} == {"two", "bar"}

0 commit comments

Comments
 (0)