diff --git a/CHANGELOG.md b/CHANGELOG.md index b2cb3685684fa3eeda24a13ba72e38bc6bf9aa22..d09fad76f5704db24b60a6dfd1d23cd4599f6488 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### -* `apiutils.merge_entities` now has a `merge_id_with_resolved_entity` keyword +* `utils.merge_entities` now has a `merge_id_with_resolved_entity` keyword which allows to identify property values with each other in case that one is an id and the other is an Entity with this id. Default is ``False``, so no change to the default behavior. +* apiutils.escape_quoted_text for escaping text in queries. ### Changed ### diff --git a/src/linkahead/utils/escape.py b/src/linkahead/utils/escape.py new file mode 100644 index 0000000000000000000000000000000000000000..d6b206fc458b7ba002603fafe51c3a7835202920 --- /dev/null +++ b/src/linkahead/utils/escape.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# +# This file is a part of the LinkAhead Project. +# +# Copyright (C) 2024 Henrik tom Wörden <h.tomwoerden@indiscale.com> +# Copyright (C) 2024 IndiScale GmbH <info@indiscale.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +# + + +def escape_quoted_text(text: str) -> str: + """The characters ``\\`` and ``*`` need to be escaped if used in quoted expressions in the query + language. + + This function return the given string where the characters ``\\`` and ``*`` are escaped by + a ``\\``. + + Parameters + ---------- + text : str + The text to be escaped + + Returns + ------- + str + The escaped text + """ + return text.replace('\\', r'\\').replace('*', r'\*') diff --git a/src/linkahead/utils/get_entity.py b/src/linkahead/utils/get_entity.py index ea9f3228bfc32f223979846623fccdec45752e5d..9fee45826b46c5a5ec9ca8c1e0bec134f5d7ce77 100644 --- a/src/linkahead/utils/get_entity.py +++ b/src/linkahead/utils/get_entity.py @@ -22,7 +22,9 @@ """Convenience functions to retrieve a specific entity.""" from typing import Union -from ..common.models import execute_query, Entity + +from ..common.models import Entity, execute_query +from .escape import escape_quoted_text def get_entity_by_name(name: str) -> Entity: @@ -30,6 +32,7 @@ def get_entity_by_name(name: str) -> Entity: Submits the query "FIND ENTITY WITH name='{name}'". """ + name = escape_quoted_text(name) return execute_query(f"FIND ENTITY WITH name='{name}'", unique=True) diff --git a/unittests/test_apiutils.py b/unittests/test_apiutils.py index 549312c367eea90eac79a9bbb4898cde76f8e8ac..3ed719f7b00a4c5bf25583ac6729738d3d872f57 100644 --- a/unittests/test_apiutils.py +++ b/unittests/test_apiutils.py @@ -26,13 +26,12 @@ # A. Schlemmer, 02/2018 -import pytest import linkahead as db import linkahead.apiutils -from linkahead.apiutils import (apply_to_ids, compare_entities, create_id_query, - empty_diff, EntityMergeConflictError, - resolve_reference, merge_entities) - +import pytest +from linkahead.apiutils import (EntityMergeConflictError, apply_to_ids, + compare_entities, create_id_query, empty_diff, + merge_entities, resolve_reference) from linkahead.common.models import SPECIAL_ATTRIBUTES diff --git a/unittests/test_utils.py b/unittests/test_utils.py index 3d8e2896247f66c98f1461c1a1e91baca5f01cb6..4fb223f7c71cd2ed2871016e776a5a25e5bc9001 100644 --- a/unittests/test_utils.py +++ b/unittests/test_utils.py @@ -23,8 +23,10 @@ # """Tests for linkahead.common.utils.""" from __future__ import unicode_literals -from lxml.etree import Element + from linkahead.common.utils import xml2str +from linkahead.utils.escape import escape_quoted_text +from lxml.etree import Element def test_xml2str(): @@ -32,3 +34,10 @@ def test_xml2str(): element = Element(name) serialized = xml2str(element) assert serialized == "<Björn/>\n" + + +def test_escape_quoted_text(): + assert escape_quoted_text("bla") == "bla" + assert escape_quoted_text("bl\\a") == "bl\\\\a" + assert escape_quoted_text("bl*a") == "bl\\*a" + assert escape_quoted_text("bl*ab\\\\lab\\*labla") == "bl\\*ab\\\\\\\\lab\\\\\\*labla"