Skip to content

Commit 076abc7

Browse files
committed
[refactor] Cleanup XQuery compilation and execution calls
1 parent 4ffc982 commit 076abc7

110 files changed

Lines changed: 2999 additions & 3381 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

exist-core/pom.xml

Lines changed: 30 additions & 0 deletions
Large diffs are not rendered by default.

exist-core/src/main/java/org/exist/collections/triggers/XQueryStartupTrigger.java

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import java.util.*;
4949

50+
import com.evolvedbinary.j8fu.function.ConsumerE;
5051
import org.apache.logging.log4j.LogManager;
5152
import org.apache.logging.log4j.Logger;
5253
import org.exist.collections.Collection;
@@ -63,10 +64,9 @@
6364
import org.exist.storage.txn.TransactionManager;
6465
import org.exist.storage.txn.Txn;
6566
import org.exist.xmldb.XmldbURI;
66-
import org.exist.xquery.CompiledXQuery;
67-
import org.exist.xquery.XQuery;
67+
import org.exist.xquery.XPathException;
6868
import org.exist.xquery.XQueryContext;
69-
import org.exist.xquery.value.Sequence;
69+
import org.exist.xquery.XQueryUtil;
7070
import xyz.elemental.mediatype.MediaType;
7171

7272
import static org.exist.util.StringUtil.endsWith;
@@ -267,49 +267,31 @@ private List<String> getParameters(Map<String, List<? extends Object>> params) {
267267
* @param broker eXist database broker
268268
* @param path path to query, formatted as xmldb:exist:///db/...
269269
*/
270-
private void executeQuery(DBBroker broker, String path) {
271-
272-
XQueryContext context = null;
270+
private void executeQuery(final DBBroker broker, final String path) {
273271
try {
274272
// Get path to xquery
275-
Source source = SourceFactory.getSource(broker, null, path, false);
273+
final Source source = SourceFactory.getSource(broker, null, path, false);
276274

277275
if (source == null) {
278-
LOG.info("No XQuery found at '{}'", path);
276+
LOG.warn("No XQuery found at '{}'", path);
279277

280278
} else {
281-
// Setup xquery service
282-
XQuery service = broker.getBrokerPool().getXQueryService();
283-
context = new XQueryContext(broker.getBrokerPool());
284-
285-
// Allow use of modules with relative paths
286-
String moduleLoadPath = substringBeforeLast(path, "/");
287-
context.setModuleLoadPath(moduleLoadPath);
288-
289-
// Compile query
290-
CompiledXQuery compiledQuery = service.compile(context, source);
291-
292-
LOG.info("Starting XQuery at '{}'", path);
279+
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreCompilation = xqueryContext -> {
280+
// Allow use of modules with relative paths
281+
final String moduleLoadPath = substringBeforeLast(path, "/");
282+
xqueryContext.setModuleLoadPath(moduleLoadPath);
283+
};
293284

294-
// Finish preparation
295-
context.prepareForExecution();
285+
LOG.info("Executing XQuery Startup Trigger: {}", path);
296286

297-
// Execute
298-
Sequence result = service.execute(broker, compiledQuery, null);
299-
300-
// Log results
301-
LOG.info("Result XQuery: '{}'", result.getStringValue());
287+
final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, source, false, null, null, setupXqueryContextPreCompilation, null, null);
302288

289+
LOG.info("Executed XQuery Startup Trigger: {} in {}", path, queryResult.executionTime);
303290
}
304291

305-
} catch (Throwable t) {
292+
} catch (final Throwable t) {
306293
// Dirty, catch it all
307294
LOG.error("An error occurred during preparation/execution of the XQuery script {}: {}", path, t.getMessage(), t);
308-
309-
} finally {
310-
if (context != null) {
311-
context.runCleanupTasks();
312-
}
313295
}
314296
}
315297

exist-core/src/main/java/org/exist/collections/triggers/XQueryTrigger.java

Lines changed: 28 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@
5454
import java.util.Properties;
5555
import java.util.Set;
5656

57+
import com.evolvedbinary.j8fu.function.ConsumerE;
5758
import org.apache.logging.log4j.LogManager;
5859
import org.apache.logging.log4j.Logger;
5960
import org.exist.collections.Collection;
6061
import org.exist.dom.persistent.DocumentImpl;
61-
import org.exist.dom.persistent.NodeSet;
6262
import org.exist.dom.QName;
6363
import org.exist.security.PermissionDeniedException;
6464
import org.exist.source.DBSource;
@@ -246,8 +246,8 @@ private Source getQuerySource(final DBBroker broker) {
246246

247247
private void prepare(final TriggerEvent event, final DBBroker broker, final Txn transaction, final XmldbURI src, final XmldbURI dst, final boolean isCollection) throws TriggerException {
248248
//get the query
249-
final Source query = getQuerySource(broker);
250-
if (query == null) {
249+
final Source source = getQuerySource(broker);
250+
if (source == null) {
251251
return;
252252
}
253253

@@ -259,53 +259,27 @@ private void prepare(final TriggerEvent event, final DBBroker broker, final Txn
259259
return;
260260
}
261261

262-
@Nullable CompiledXQuery compiled = null;
263-
@Nullable XQueryContext context = null;
264-
try {
265-
266-
compiled = broker.getBrokerPool().getXQueryPool().borrowCompiledXQuery(broker, query);
267-
if (compiled == null) {
268-
context = new XQueryContext(broker.getBrokerPool());
269-
} else {
270-
context = compiled.getContext();
271-
context.prepareForReuse();
272-
}
262+
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreExecution = xqueryContext -> {
263+
declareExternalVariables(xqueryContext, TriggerPhase.BEFORE, event, src, dst, isCollection);
264+
};
273265

274-
if (compiled == null) {
275-
compiled = service.compile(context, query);
276-
} else {
277-
compiled.getContext().updateContext(context);
278-
context.getWatchDog().reset();
279-
}
280-
281-
declareExternalVariables(context, TriggerPhase.BEFORE, event, src, dst, isCollection);
266+
try {
267+
final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, source, true, null, null, setupXqueryContextPreExecution, null, null);
282268

283-
//execute the XQuery
284-
//TODO : should we provide another contextSet ?
285-
final NodeSet contextSet = NodeSet.EMPTY_SET;
286-
service.execute(broker, compiled, contextSet);
287-
//TODO : should we have a special processing ?
288-
if (LOG.isDebugEnabled()) {
289-
LOG.debug("Trigger fired for prepare");
290-
}
269+
if (LOG.isDebugEnabled()) {
270+
LOG.debug("Trigger fired for prepare in: {}", queryResult.executionTime);
271+
}
291272

292-
} catch (final XPathException | IOException | PermissionDeniedException e) {
293-
TriggerStatePerThread.clear();
294-
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
295-
} finally {
296-
if (context != null) {
297-
context.runCleanupTasks();
298-
}
299-
if (compiled != null) {
300-
broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(query, compiled);
301-
}
302-
}
273+
} catch (final XPathException | IOException | PermissionDeniedException e) {
274+
TriggerStatePerThread.clear();
275+
throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
276+
}
303277
}
304278

305279
private void finish(final TriggerEvent event, final DBBroker broker, final Txn transaction, final XmldbURI src, final XmldbURI dst, final boolean isCollection) {
306280
//get the query
307-
final Source query = getQuerySource(broker);
308-
if (query == null) {
281+
final Source source = getQuerySource(broker);
282+
if (source == null) {
309283
return;
310284
}
311285

@@ -317,47 +291,22 @@ private void finish(final TriggerEvent event, final DBBroker broker, final Txn t
317291
return;
318292
}
319293

320-
@Nullable CompiledXQuery compiled = null;
321-
@Nullable XQueryContext context = null;
322-
try {
323-
compiled = broker.getBrokerPool().getXQueryPool().borrowCompiledXQuery(broker, query);
324-
if (compiled == null) {
325-
context = new XQueryContext(broker.getBrokerPool());
326-
} else {
327-
context = compiled.getContext();
328-
context.prepareForReuse();
329-
}
294+
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreExecution = xqueryContext -> {
295+
declareExternalVariables(xqueryContext, TriggerPhase.AFTER, event, src, dst, isCollection);
296+
};
330297

331-
if (compiled == null) {
332-
compiled = service.compile(context, query);
333-
} else {
334-
compiled.getContext().updateContext(context);
335-
context.getWatchDog().reset();
336-
}
337-
338-
declareExternalVariables(context, TriggerPhase.AFTER, event, src, dst, isCollection);
339-
340-
//execute the XQuery
341-
//TODO : should we provide another contextSet ?
342-
final NodeSet contextSet = NodeSet.EMPTY_SET;
343-
service.execute(broker, compiled, contextSet);
344-
//TODO : should we have a special processing ?
345-
346-
} catch (final XPathException | IOException | PermissionDeniedException e) {
347-
LOG.error("Error during trigger finish", e);
348-
} finally {
349-
if (context != null) {
350-
context.runCleanupTasks();
351-
}
352-
if (compiled != null) {
353-
broker.getBrokerPool().getXQueryPool().returnCompiledXQuery(query, compiled);
354-
}
355-
}
298+
long executionTime = -1;
299+
try {
300+
final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, source, true, null, null, setupXqueryContextPreExecution, null, null);
301+
executionTime = queryResult.executionTime;
302+
} catch (final XPathException | IOException | PermissionDeniedException e) {
303+
LOG.error("Error during trigger finish", e);
304+
}
356305

357306
TriggerStatePerThread.clearIfFinished(TriggerPhase.AFTER);
358307

359308
if (LOG.isDebugEnabled()) {
360-
LOG.debug("Trigger fired for finish");
309+
LOG.debug("Trigger fired for finish in {}", executionTime);
361310
}
362311
}
363312

exist-core/src/main/java/org/exist/http/AuditTrailSessionListener.java

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
*/
4646
package org.exist.http;
4747

48+
import com.evolvedbinary.j8fu.function.ConsumerE;
4849
import org.apache.logging.log4j.LogManager;
4950
import org.apache.logging.log4j.Logger;
5051
import org.exist.dom.persistent.BinaryDocument;
@@ -57,11 +58,10 @@
5758
import org.exist.storage.XQueryPool;
5859
import org.exist.storage.lock.Lock.LockMode;
5960
import org.exist.xmldb.XmldbURI;
60-
import org.exist.xquery.CompiledXQuery;
61-
import org.exist.xquery.XQuery;
61+
import org.exist.xquery.XPathException;
6262
import org.exist.xquery.XQueryContext;
63+
import org.exist.xquery.XQueryUtil;
6364
import org.exist.xquery.value.AnyURIValue;
64-
import org.exist.xquery.value.Sequence;
6565

6666
import javax.servlet.http.HttpSession;
6767
import javax.servlet.http.HttpSessionEvent;
@@ -116,9 +116,7 @@ private void executeXQuery(String xqueryResourcePath) {
116116
if (xqueryResourcePath != null && xqueryResourcePath.length() > 0) {
117117
xqueryResourcePath = xqueryResourcePath.trim();
118118

119-
@Nullable CompiledXQuery compiled = null;
120-
@Nullable XQueryContext context = null;
121-
@Nullable Source source = null;
119+
@Nullable Source source;
122120

123121
try {
124122
final BrokerPool pool = BrokerPool.getInstance();
@@ -146,45 +144,18 @@ private void executeXQuery(String xqueryResourcePath) {
146144
return;
147145
}
148146

149-
final XQuery xquery = pool.getXQueryService();
150-
if (xquery == null) {
151-
LOG.error("broker unable to retrieve XQueryService");
152-
return;
153-
}
154-
155-
compiled = xqpool.borrowCompiledXQuery(broker, source);
156-
if (compiled == null) {
157-
context = new XQueryContext(broker.getBrokerPool());
158-
} else {
159-
context = compiled.getContext();
160-
context.prepareForReuse();
161-
}
162-
context.setStaticallyKnownDocuments(new XmldbURI[]{pathUri});
163-
context.setBaseURI(new AnyURIValue(pathUri.toString()));
164-
165-
if (compiled == null) {
166-
compiled = xquery.compile(context, source);
167-
} else {
168-
compiled.getContext().updateContext(context);
169-
context.getWatchDog().reset();
170-
}
147+
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreCompilation = xqueryContext -> {
148+
xqueryContext.setStaticallyKnownDocuments(new XmldbURI[]{pathUri});
149+
xqueryContext.setBaseURI(new AnyURIValue(pathUri.toString()));
150+
};
171151

172152
final Properties outputProperties = new Properties();
153+
final XQueryUtil.QueryResult queryResult = XQueryUtil.query(broker, source, true, null, outputProperties, setupXqueryContextPreCompilation, null, null);
173154

174-
final long startTime = System.currentTimeMillis();
175-
final Sequence result = xquery.execute(broker, compiled, null, outputProperties);
176-
final long queryTime = System.currentTimeMillis() - startTime;
177155
if (LOG.isTraceEnabled()) {
178-
LOG.trace("XQuery execution results: {} in {}ms.", result.toString(), queryTime);
156+
LOG.trace("XQuery execution results: {} in {}ms.", queryResult.result.toString(), queryResult.executionTime);
179157
}
180158
}
181-
} finally {
182-
if (context != null) {
183-
context.runCleanupTasks();
184-
}
185-
if (compiled != null && source != null) {
186-
xqpool.returnCompiledXQuery(source, compiled);
187-
}
188159
}
189160

190161
} catch (final Exception e) {

0 commit comments

Comments
 (0)