@@ -490,6 +490,32 @@ def get_entries_full(self, entry_ids: list[int] | set[int]) -> Iterator[Entry]:
490490 yield entry
491491 session .expunge (entry )
492492
493+ def get_entry_full_by_path (self , path : Path ) -> Entry | None :
494+ """Get the entry with the corresponding path."""
495+ with Session (self .engine ) as session :
496+ stmt = select (Entry ).where (Entry .path == path )
497+ stmt = (
498+ stmt .outerjoin (Entry .text_fields )
499+ .outerjoin (Entry .datetime_fields )
500+ .options (selectinload (Entry .text_fields ), selectinload (Entry .datetime_fields ))
501+ )
502+ stmt = (
503+ stmt .outerjoin (Entry .tags )
504+ .outerjoin (TagAlias )
505+ .options (
506+ selectinload (Entry .tags ).options (
507+ joinedload (Tag .aliases ),
508+ joinedload (Tag .parent_tags ),
509+ )
510+ )
511+ )
512+ entry = session .scalar (stmt )
513+ if not entry :
514+ return None
515+ session .expunge (entry )
516+ make_transient (entry )
517+ return entry
518+
493519 @property
494520 def entries_count (self ) -> int :
495521 with Session (self .engine ) as session :
@@ -698,7 +724,13 @@ def search_tags(
698724
699725 return res
700726
701- def update_entry_path (self , entry_id : int | Entry , path : Path ) -> None :
727+ def update_entry_path (self , entry_id : int | Entry , path : Path ) -> bool :
728+ """Set the path field of an entry.
729+
730+ Returns True if the action succeeded and False if the path already exists.
731+ """
732+ if self .has_path_entry (path ):
733+ return False
702734 if isinstance (entry_id , Entry ):
703735 entry_id = entry_id .id
704736
@@ -715,6 +747,7 @@ def update_entry_path(self, entry_id: int | Entry, path: Path) -> None:
715747
716748 session .execute (update_stmt )
717749 session .commit ()
750+ return True
718751
719752 def remove_tag (self , tag : Tag ):
720753 with Session (self .engine , expire_on_commit = False ) as session :
@@ -1185,6 +1218,18 @@ def mirror_entry_fields(self, *entries: Entry) -> None:
11851218 value = field .value ,
11861219 )
11871220
1221+ def merge_entries (self , from_entry : Entry , into_entry : Entry ) -> None :
1222+ """Add fields and tags from the first entry to the second, and then delete the first."""
1223+ for field in from_entry .fields :
1224+ self .add_field_to_entry (
1225+ entry_id = into_entry .id ,
1226+ field_id = field .type_key ,
1227+ value = field .value ,
1228+ )
1229+ tag_ids = [tag .id for tag in from_entry .tags ]
1230+ self .add_tags_to_entry (into_entry .id , tag_ids )
1231+ self .remove_entries ([from_entry .id ])
1232+
11881233 @property
11891234 def tag_color_groups (self ) -> dict [str , list [TagColorGroup ]]:
11901235 """Return every TagColorGroup in the library."""
0 commit comments