-
Notifications
You must be signed in to change notification settings - Fork 4
/
by_uuid.clj
96 lines (85 loc) · 4.53 KB
/
by_uuid.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
(ns clj-jargon.by-uuid
(:require [clojure.string :as string]
[clojure.tools.logging :as log]
[slingshot.slingshot :refer [throw+]]
[clojure-commons.error-codes :as error]
[clj-jargon.metadata :as meta]
[otel.otel :as otel])
(:import [clojure.lang IPersistentMap IPersistentVector]
[java.util UUID]
[org.irods.jargon.core.pub IRODSGenQueryExecutor]
[org.irods.jargon.core.query
IRODSGenQueryBuilder
IRODSQueryResultRow
QueryConditionOperators
RodsGenQueryEnum]))
(def ^String uuid-attr
"This is the iRODS metadata attribute that holds the UUID."
"ipc_UUID")
(defn ^String get-path
"Returns the path of an entity given its UUID.
Parameters:
cm - an open jargon context
uuid - the UUID of the entity
Returns:
If found, it returns the path of the entity."
[^IPersistentMap cm ^UUID uuid]
(let [results (meta/list-everything-with-attr-value cm uuid-attr uuid)]
(when-not (empty? results)
(when (> (count results) 1)
(log/error "Too many results for" uuid ":" (count results))
(log/debug "Results for" uuid ":" results)
(throw+ {:error_code error/ERR_TOO_MANY_RESULTS
:count (count results)
:uuid uuid}))
(first results))))
(defn- build-file-uuid-query
"Builds the general query for mapping multiple UUIDs to their respective file paths. UUIDs that do not refer to
files will be excluded from the result."
[uuids]
(as-> (IRODSGenQueryBuilder. true nil) builder
(.addSelectAsGenQueryValue builder RodsGenQueryEnum/COL_META_DATA_ATTR_VALUE)
(.addSelectAsGenQueryValue builder RodsGenQueryEnum/COL_COLL_NAME)
(.addSelectAsGenQueryValue builder RodsGenQueryEnum/COL_DATA_NAME)
(.addConditionAsGenQueryField builder
RodsGenQueryEnum/COL_META_DATA_ATTR_NAME
QueryConditionOperators/EQUAL uuid-attr)
(.addConditionAsMultiValueCondition builder
RodsGenQueryEnum/COL_META_DATA_ATTR_VALUE
QueryConditionOperators/IN
(mapv str uuids))
(.exportIRODSQueryFromBuilder builder meta/max-gen-query-results)))
(defn- build-collection-uuid-query
"Builds the general query for mapping multiple UUIDs to their respective collection paths. UUIDs that do not refer
to colletions will be excluded from the result."
[uuids]
(as-> (IRODSGenQueryBuilder. true nil) builder
(.addSelectAsGenQueryValue builder RodsGenQueryEnum/COL_META_COLL_ATTR_VALUE)
(.addSelectAsGenQueryValue builder RodsGenQueryEnum/COL_COLL_NAME)
(.addConditionAsGenQueryField builder
RodsGenQueryEnum/COL_META_COLL_ATTR_NAME
QueryConditionOperators/EQUAL uuid-attr)
(.addConditionAsMultiValueCondition builder
RodsGenQueryEnum/COL_META_COLL_ATTR_VALUE
QueryConditionOperators/IN
(mapv str uuids))
(.exportIRODSQueryFromBuilder builder meta/max-gen-query-results)))
(defn ^IPersistentMap get-paths
"Returns a map from UUID to their corresponding entity path for a given collection of UUIDs.
Parameters:
cm - an open jargon context
uuids - a collection of UUIDs
Returns: A map from UUID to the path of the associated entity. UUIDs that could not be found will be missing from the
resulting map. Note: this function will not detect the case where the same UUID is associated with multiple entities
in the data store. If the same UUID ever becomes associated with multiple entities, whichever entity is found last
will be included in the results."
[{^IRODSGenQueryExecutor executor :executor} uuids]
(otel/with-span [s ["get-paths" {:attributes {"uuids" (str uuids)}}]]
(let [partitions (partition-all 500 uuids)
get-values (fn [^IRODSQueryResultRow row] (.getColumnsAsList row))
format (juxt first (comp (partial string/join "/") rest))
run-query (fn [build-query uuids]
(mapv (comp format get-values)
(.getResults (.executeIRODSQueryAndCloseResult executor (build-query uuids) 0))))]
(into {} (concat (mapcat (partial run-query build-collection-uuid-query) partitions)
(mapcat (partial run-query build-file-uuid-query) partitions))))))