Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/rdflib/plugins/stores/regexmatching.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author | guerler |
---|---|
date | Fri, 31 Jul 2020 00:32:28 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:d30785e31577 | 1:56ad4e20f292 |
---|---|
1 """ | |
2 This wrapper intercepts calls through the store interface which make use of | |
3 the REGEXTerm class to represent matches by REGEX instead of literal | |
4 comparison. | |
5 | |
6 Implemented for stores that don't support this and essentially | |
7 provides the support by replacing the REGEXTerms by wildcards (None) and | |
8 matching against the results from the store it's wrapping. | |
9 """ | |
10 | |
11 from rdflib.store import Store | |
12 from rdflib.graph import Graph | |
13 import re | |
14 | |
15 # Store is capable of doing its own REGEX matching | |
16 NATIVE_REGEX = 0 | |
17 # Store uses Python's re module internally for REGEX matching | |
18 PYTHON_REGEX = 1 | |
19 | |
20 | |
21 class REGEXTerm(str): | |
22 """ | |
23 REGEXTerm can be used in any term slot and is interpreted as a request to | |
24 perform a REGEX match (not a string comparison) using the value | |
25 (pre-compiled) for checking rdf:type matches | |
26 """ | |
27 def __init__(self, expr): | |
28 self.compiledExpr = re.compile(expr) | |
29 | |
30 def __reduce__(self): | |
31 return (REGEXTerm, (str(''),)) | |
32 | |
33 | |
34 def regexCompareQuad(quad, regexQuad): | |
35 for index in range(4): | |
36 if isinstance(regexQuad[index], REGEXTerm) and not \ | |
37 regexQuad[index].compiledExpr.match(quad[index]): | |
38 return False | |
39 return True | |
40 | |
41 | |
42 class REGEXMatching(Store): | |
43 def __init__(self, storage): | |
44 self.storage = storage | |
45 self.context_aware = storage.context_aware | |
46 # NOTE: this store can't be formula_aware as it doesn't have enough | |
47 # info to reverse the removal of a quoted statement. | |
48 self.formula_aware = storage.formula_aware | |
49 self.transaction_aware = storage.transaction_aware | |
50 | |
51 def open(self, configuration, create=True): | |
52 return self.storage.open(configuration, create) | |
53 | |
54 def close(self, commit_pending_transaction=False): | |
55 self.storage.close() | |
56 | |
57 def destroy(self, configuration): | |
58 self.storage.destroy(configuration) | |
59 | |
60 def add(self, triple, context, quoted=False): | |
61 (subject, predicate, object_) = triple | |
62 self.storage.add((subject, predicate, object_), context, quoted) | |
63 | |
64 def remove(self, triple, context=None): | |
65 (subject, predicate, object_) = triple | |
66 if isinstance(subject, REGEXTerm) or \ | |
67 isinstance(predicate, REGEXTerm) or \ | |
68 isinstance(object_, REGEXTerm) or \ | |
69 (context is not None | |
70 and isinstance(context.identifier, REGEXTerm)): | |
71 # One or more of the terms is a REGEX expression, so we must | |
72 # replace it / them with wildcard(s)and match after we query. | |
73 s = not isinstance(subject, REGEXTerm) and subject or None | |
74 p = not isinstance(predicate, REGEXTerm) and predicate or None | |
75 o = not isinstance(object_, REGEXTerm) and object_ or None | |
76 c = (context is not None | |
77 and not isinstance(context.identifier, REGEXTerm)) \ | |
78 and context \ | |
79 or None | |
80 | |
81 removeQuadList = [] | |
82 for (s1, p1, o1), cg in self.storage.triples((s, p, o), c): | |
83 for ctx in cg: | |
84 ctx = ctx.identifier | |
85 if regexCompareQuad( | |
86 (s1, p1, o1, ctx), | |
87 (subject, predicate, object_, context | |
88 is not None and context.identifier or context)): | |
89 removeQuadList.append((s1, p1, o1, ctx)) | |
90 for s, p, o, c in removeQuadList: | |
91 self.storage.remove((s, p, o), c and Graph(self, c) or c) | |
92 else: | |
93 self.storage.remove((subject, predicate, object_), context) | |
94 | |
95 def triples(self, triple, context=None): | |
96 (subject, predicate, object_) = triple | |
97 if isinstance(subject, REGEXTerm) or \ | |
98 isinstance(predicate, REGEXTerm) or \ | |
99 isinstance(object_, REGEXTerm) or \ | |
100 (context is not None | |
101 and isinstance(context.identifier, REGEXTerm)): | |
102 # One or more of the terms is a REGEX expression, so we must | |
103 # replace it / them with wildcard(s) and match after we query. | |
104 s = not isinstance(subject, REGEXTerm) and subject or None | |
105 p = not isinstance(predicate, REGEXTerm) and predicate or None | |
106 o = not isinstance(object_, REGEXTerm) and object_ or None | |
107 c = (context is not None | |
108 and not isinstance(context.identifier, REGEXTerm)) \ | |
109 and context \ | |
110 or None | |
111 for (s1, p1, o1), cg in self.storage.triples((s, p, o), c): | |
112 matchingCtxs = [] | |
113 for ctx in cg: | |
114 if c is None: | |
115 if context is None \ | |
116 or context.identifier.compiledExpr.match( | |
117 ctx.identifier): | |
118 matchingCtxs.append(ctx) | |
119 else: | |
120 matchingCtxs.append(ctx) | |
121 if matchingCtxs \ | |
122 and regexCompareQuad((s1, p1, o1, None), | |
123 (subject, predicate, object_, None)): | |
124 yield (s1, p1, o1), (c for c in matchingCtxs) | |
125 else: | |
126 for (s1, p1, o1), cg in self.storage.triples( | |
127 (subject, predicate, object_), context): | |
128 yield (s1, p1, o1), cg | |
129 | |
130 def __len__(self, context=None): | |
131 # NOTE: If the context is a REGEX this could be an expensive | |
132 # proposition | |
133 return self.storage.__len__(context) | |
134 | |
135 def contexts(self, triple=None): | |
136 # NOTE: There is no way to control REGEX matching for this method at | |
137 # this level as it only returns the contexts, not the matching | |
138 # triples. | |
139 for ctx in self.storage.contexts(triple): | |
140 yield ctx | |
141 | |
142 def remove_context(self, identifier): | |
143 self.storage.remove((None, None, None), identifier) | |
144 | |
145 def bind(self, prefix, namespace): | |
146 self.storage.bind(prefix, namespace) | |
147 | |
148 def prefix(self, namespace): | |
149 return self.storage.prefix(namespace) | |
150 | |
151 def namespace(self, prefix): | |
152 return self.storage.namespace(prefix) | |
153 | |
154 def namespaces(self): | |
155 return self.storage.namespaces() | |
156 | |
157 def commit(self): | |
158 self.storage.commit() | |
159 | |
160 def rollback(self): | |
161 self.storage.rollback() |