From 76f5cb8c7e5235106d390431ded6929ecde110ef Mon Sep 17 00:00:00 2001 From: William Moore Date: Tue, 6 Apr 2021 11:33:36 +0100 Subject: [PATCH 1/4] Use opts for limit & offset, same as getObjects() --- src/omero/gateway/__init__.py | 39 +++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/omero/gateway/__init__.py b/src/omero/gateway/__init__.py index 0c39a923e..27b9a5587 100644 --- a/src/omero/gateway/__init__.py +++ b/src/omero/gateway/__init__.py @@ -4183,6 +4183,45 @@ def getObjectsByAnnotations(self, obj_type, annids): for e in q.findAllByQuery(sql, p, self.SERVICE_OPTS): yield wrapper(self, e) + def getObjectsByMapAnnotations(self, obj_type, key=None, value=None, ns=None, + opts={}): + + wrapper = KNOWN_WRAPPERS.get(obj_type.lower(), None) + if not wrapper: + raise AttributeError("Don't know how to handle '%s'" % obj_type) + + params = omero.sys.ParametersI() + clauses = [] + if key is not None: + clauses.append("mv.name = :key") + params.addString("key", key) + if value is not None: + clauses.append("mv.value = :value") + params.addString("value", value) + if ns is not None: + clauses.append("ann.ns = :ns") + params.addString("ns", ns) + + # Parse opts dict to build params + limit = opts.get('limit', 500) + offset = opts.get('offset', 0) + if offset is not None and limit is not None: + params.page(offset, limit) + + # Using projection since can't seem to fetch objects AND filter by mapValue + query = """ + select obj.id, obj.name from + %sAnnotationLink ial + join ial.child ann + join ann.mapValue mv + join ial.parent obj""" % wrapper().OMERO_CLASS + if len(clauses) > 0: + query += " where " + " and ".join(clauses) + result = self.getQueryService().projection(query, params, self.SERVICE_OPTS) + ids = [row[0].val for row in result] + return self.getObjects(obj_type, ids) + + ################ # Enumerations # From 9f016b1e73602ab7bc2796e5e425ce3d11ac2b75 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 7 Apr 2021 22:19:34 +0100 Subject: [PATCH 2/4] Handle no objects found by map annotation --- src/omero/gateway/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/omero/gateway/__init__.py b/src/omero/gateway/__init__.py index 27b9a5587..ecdc2b5b3 100644 --- a/src/omero/gateway/__init__.py +++ b/src/omero/gateway/__init__.py @@ -4219,6 +4219,8 @@ def getObjectsByMapAnnotations(self, obj_type, key=None, value=None, ns=None, query += " where " + " and ".join(clauses) result = self.getQueryService().projection(query, params, self.SERVICE_OPTS) ids = [row[0].val for row in result] + if len(ids) == 0: + return [] return self.getObjects(obj_type, ids) From 8147768f99dd6650df6dbb9fd4d0892ed3fac462 Mon Sep 17 00:00:00 2001 From: William Moore Date: Wed, 7 Apr 2021 23:06:33 +0100 Subject: [PATCH 3/4] Support leading & trailing wildcards --- src/omero/gateway/__init__.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/omero/gateway/__init__.py b/src/omero/gateway/__init__.py index ecdc2b5b3..c0103f5b8 100644 --- a/src/omero/gateway/__init__.py +++ b/src/omero/gateway/__init__.py @@ -4192,12 +4192,24 @@ def getObjectsByMapAnnotations(self, obj_type, key=None, value=None, ns=None, params = omero.sys.ParametersI() clauses = [] - if key is not None: - clauses.append("mv.name = :key") - params.addString("key", key) - if value is not None: - clauses.append("mv.value = :value") - params.addString("value", value) + + def add_param(param, value): + if value is None: + return + # Replace wild-cards with `%%` for `like` search + wild_card = (value[0] == "*" or value[-1] == "*") + if value[0] == "*": + value = "%%" + value[1:] + if value[-1] == "*": + value = value[:-1] + "%%" + like = "like" if wild_card else "=" + clauses.append("mv.%s %s :%s" % (param, like, param)) + params.addString(param, value) + + # Build the query, handling wildcards for key and value + add_param("name", key) + add_param("value", value) + if ns is not None: clauses.append("ann.ns = :ns") params.addString("ns", ns) From d27f2f0013bee7f089ed17bfe0b2e16bd98556fb Mon Sep 17 00:00:00 2001 From: William Moore Date: Fri, 9 Apr 2021 10:16:05 +0100 Subject: [PATCH 4/4] Ensure we query for distinct Images --- src/omero/gateway/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/omero/gateway/__init__.py b/src/omero/gateway/__init__.py index c0103f5b8..27fb5d552 100644 --- a/src/omero/gateway/__init__.py +++ b/src/omero/gateway/__init__.py @@ -4222,7 +4222,7 @@ def add_param(param, value): # Using projection since can't seem to fetch objects AND filter by mapValue query = """ - select obj.id, obj.name from + select distinct obj.id from %sAnnotationLink ial join ial.child ann join ann.mapValue mv