From 4524a26675bd96a6f6f3c3298a21da048a5ae7fa Mon Sep 17 00:00:00 2001 From: Lazlo Westerhof Date: Wed, 18 Dec 2024 13:07:16 +0100 Subject: [PATCH] Utils: start using the GenQuery2 parser --- util/collection.py | 99 ++++++++++++++++++--------------------------- util/data_object.py | 14 ++++--- 2 files changed, 48 insertions(+), 65 deletions(-) diff --git a/util/collection.py b/util/collection.py index 2ea58e9b1..2d1d3bf85 100644 --- a/util/collection.py +++ b/util/collection.py @@ -3,9 +3,7 @@ __copyright__ = 'Copyright (c) 2019-2024, Utrecht University' __license__ = 'GPLv3, see LICENSE' -import itertools import json -from functools import reduce from typing import Iterable, List, Tuple import genquery @@ -18,9 +16,11 @@ def exists(ctx: rule.Context, path: str) -> bool: """Check if a collection with the given path exists.""" - return len(list(genquery.row_iterator( - "COLL_ID", "COLL_NAME = '{}'".format(path), - genquery.AS_LIST, ctx))) > 0 + return len(list(genquery.Query( + ctx, "COLL_ID", + f"COLL_NAME = '{path}'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) > 0 def owner(ctx: rule.Context, path: str) -> Tuple[str, str] | None: @@ -34,28 +34,20 @@ def owner(ctx: rule.Context, path: str) -> Tuple[str, str] | None: def empty(ctx: rule.Context, path: str) -> bool: """Check if a collection contains any data objects.""" - return (len(list(genquery.row_iterator( - "DATA_ID", - "COLL_NAME = '{}'".format(path), - genquery.AS_LIST, ctx))) == 0 - and len(list(genquery.row_iterator( - "DATA_ID", - "COLL_NAME like '{}/%'".format(path), - genquery.AS_LIST, ctx))) == 0) + return len(list(genquery.row_iterator( + ctx, "DATA_ID", + f"COLL_NAME = '{path}' or COLL_NAME like '{path}/%'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) == 0 def size(ctx: rule.Context, path: str) -> int: """Get a collection's size in bytes.""" - def func(x: int, row: List) -> int: - return x + int(row[1]) - - return reduce(func, - itertools.chain(genquery.row_iterator("DATA_ID, DATA_SIZE", - "COLL_NAME like '{}'".format(path), - genquery.AS_LIST, ctx), - genquery.row_iterator("DATA_ID, DATA_SIZE", - "COLL_NAME like '{}/%'".format(path), - genquery.AS_LIST, ctx)), 0) + return sum(row[1] for row in list(genquery.Query( + ctx, "DATA_ID, DATA_SIZE", + f"COLL_NAME like '{path}' or COLL_NAME like '{path}/%'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) def data_count(ctx: rule.Context, path: str, recursive: bool = True) -> int: @@ -73,11 +65,12 @@ def data_count(ctx: rule.Context, path: str, recursive: bool = True) -> int: def collection_count(ctx: rule.Context, path: str, recursive: bool = True) -> int: """Get a collection's collection count (the amount of collections within a collection).""" - return sum(1 for _ in genquery.row_iterator( - "COLL_ID", - "COLL_NAME like '{}/%'".format(path) if recursive else - "COLL_PARENT_NAME = '{}' AND COLL_NAME like '{}/%'".format(path, path), - genquery.AS_LIST, ctx)) + return sum(1 for _ in list(genquery.Query( + ctx, "COLL_ID", + f"COLL_NAME like '{path}/%'" if recursive else + f"COLL_PARENT_NAME = '{path}' AND COLL_NAME like '{path}/%'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) def subcollections(ctx: rule.Context, path: str, recursive: bool = False) -> Iterable: @@ -96,22 +89,15 @@ def subcollections(ctx: rule.Context, path: str, recursive: bool = False) -> Ite :returns: List of all subcollections in a collection """ # coll+subcoll name -> path - def to_absolute(row: List) -> str: - return '{}/{}'.format(*row) - - q_root = genquery.row_iterator("COLL_PARENT_NAME, COLL_NAME", - "COLL_PARENT_NAME = '{}'".format(path), - genquery.AS_LIST, ctx) - - if not recursive: - return map(to_absolute, q_root) + def to_absolute(row: List[str]) -> str: + return f"{row[0]}/{row[1]}" - # Recursive? Return a generator combining both queries. - q_sub = genquery.row_iterator("COLL_PARENT_NAME, COLL_NAME", - "COLL_PARENT_NAME like '{}/%'".format(path), - genquery.AS_LIST, ctx) - - return map(to_absolute, itertools.chain(q_root, q_sub)) + return map(to_absolute, list(genquery.Query( + ctx, "COLL_PARENT_NAME, COLL_NAME", + f"COLL_PARENT_NAME = '{path}'" if recursive else + f"COLL_PARENT_NAME = '{path}' OR COLL_PARENT_NAME like '{path}/%'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) def data_objects(ctx: rule.Context, path: str, recursive: bool = False) -> Iterable: @@ -130,22 +116,15 @@ def data_objects(ctx: rule.Context, path: str, recursive: bool = False) -> Itera :returns: List of all data objects in a collection """ # coll+data name -> path - def to_absolute(row: List) -> str: - return '{}/{}'.format(*row) - - q_root = genquery.row_iterator("COLL_NAME, DATA_NAME", - "COLL_NAME = '{}'".format(path), - genquery.AS_LIST, ctx) - - if not recursive: - return map(to_absolute, q_root) - - # Recursive? Return a generator combining both queries. - q_sub = genquery.row_iterator("COLL_NAME, DATA_NAME", - "COLL_NAME like '{}/%'".format(path), - genquery.AS_LIST, ctx) + def to_absolute(row: List[str]) -> str: + return f"{row[0]}/{row[1]}" - return map(to_absolute, itertools.chain(q_root, q_sub)) + return map(to_absolute, list(genquery.Query( + ctx, "COLL_NAME, DATA_NAME", + f"COLL_NAME = '{path}'" if recursive else + f"COLL_NAME = '{path}' OR COLL_NAME like '{path}/%'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) def create(ctx: rule.Context, path: str, entire_tree: str = '') -> None: @@ -257,7 +236,7 @@ def id_from_name(ctx: rule.Context, coll_name: str) -> str: :returns: Collection id """ - return genquery.Query(ctx, "COLL_ID", "COLL_NAME = '{}'".format(coll_name)).first() + return genquery.Query(ctx, "COLL_ID", "COLL_NAME = '{coll_name}'", parser=genquery.Parser.GENQUERY2).first() def name_from_id(ctx: rule.Context, coll_id: str) -> str: @@ -268,4 +247,4 @@ def name_from_id(ctx: rule.Context, coll_id: str) -> str: :returns: Collection name """ - return genquery.Query(ctx, "COLL_NAME", "COLL_ID = '{}'".format(coll_id)).first() + return genquery.Query(ctx, "COLL_NAME", "COLL_ID = '{coll_id}'", parser=genquery.Parser.GENQUERY2).first() diff --git a/util/data_object.py b/util/data_object.py index d41225685..8f4b0d3c1 100644 --- a/util/data_object.py +++ b/util/data_object.py @@ -19,10 +19,12 @@ def exists(ctx: rule.Context, path: str) -> bool: """Check if a data object with the given path exists.""" - return len(list(genquery.row_iterator( - "DATA_ID", - "COLL_NAME = '%s' AND DATA_NAME = '%s'" % pathutil.chop(path), - genquery.AS_LIST, ctx))) > 0 + coll_name, data_name = pathutil.chop(path) + return len(list(genquery.Query( + ctx, "DATA_ID", + f"COLL_NAME = '{coll_name}' AND DATA_NAME = '{data_name}'", + output=genquery.AS_LIST, + parser=genquery.Parser.GENQUERY2))) > 0 def get_properties(ctx: rule.Context, data_id: str, resource: str) -> Dict | None: @@ -247,8 +249,10 @@ def id_from_path(ctx: rule.Context, path: str) -> str: :returns: Data object id """ + coll_name, data_name = pathutil.chop(path) return genquery.Query(ctx, "DATA_ID", - "COLL_NAME = '%s' AND DATA_NAME = '%s'" % pathutil.chop(path)).first() + f"COLL_NAME = '{coll_name}' AND DATA_NAME = '{data_name}'", + parser=genquery.Parser.GENQUERY2).first() def decode_checksum(checksum: str) -> str: