Skip to content

Commit 52faf52

Browse files
committed
[refactor] Remove polution of XML:DB API into the Query Engine
1 parent d26adcc commit 52faf52

13 files changed

Lines changed: 232 additions & 197 deletions

File tree

exist-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,7 @@
12531253
<include>src/test/java/org/exist/xquery/CardinalityTest.java</include>
12541254
<include>src/test/java/org/exist/xquery/CleanupTest.java</include>
12551255
<include>src/main/java/org/exist/xquery/CombiningExpression.java</include>
1256+
<include>src/main/java/org/exist/xquery/CompiledXQuery.java</include>
12561257
<include>src/test/java/org/exist/xquery/ConstructedNodesRecoveryTest.java</include>
12571258
<include>src/test/java/org/exist/xquery/ConstructedNodesTest.java</include>
12581259
<include>src/main/java/org/exist/xquery/Context.java</include>
@@ -1470,6 +1471,7 @@
14701471
<include>src/test/java/org/exist/xquery/functions/util/Base64FunctionsTest.java</include>
14711472
<include>src/test/java/org/exist/xquery/functions/util/BaseConverterTest.java</include>
14721473
<include>src/main/java/org/exist/xquery/functions/util/BuiltinFunctions.java</include>
1474+
<include>src/main/java/org/exist/xquery/functions/util/CollectionName.java</include>
14731475
<include>src/main/java/org/exist/xquery/functions/util/DescribeFunction.java</include>
14741476
<include>src/test/java/org/exist/xquery/functions/util/EvalTest.java</include>
14751477
<include>src/test/java/org/exist/xquery/functions/util/ExpandTest.java</include>
@@ -2085,6 +2087,7 @@
20852087
<exclude>src/test/java/org/exist/xmldb/IndexingTest.java</exclude>
20862088
<exclude>src/main/java/org/exist/xmldb/LocalBinaryResource.java</exclude>
20872089
<exclude>src/main/java/org/exist/xmldb/LocalCollection.java</exclude>
2090+
<exclude>src/main/java/org/exist/xmldb/LocalCompiledExpression.java</exclude>
20882091
<exclude>src/main/java/org/exist/xmldb/LocalResourceSet.java</exclude>
20892092
<exclude>src/main/java/org/exist/xmldb/LocalRestoreService.java</exclude>
20902093
<exclude>src/main/java/org/exist/xmldb/LocalXMLResource.java</exclude>
@@ -2161,6 +2164,7 @@
21612164
<exclude>src/test/java/org/exist/xquery/CastExpressionTest.java</exclude>
21622165
<exclude>src/test/java/org/exist/xquery/CleanupTest.java</exclude>
21632166
<exclude>src/main/java/org/exist/xquery/CombiningExpression.java</exclude>
2167+
<exclude>src/main/java/org/exist/xquery/CompiledXQuery.java</exclude>
21642168
<exclude>src/test/java/org/exist/xquery/ConstructedNodesRecoveryTest.java</exclude>
21652169
<exclude>src/test/java/org/exist/xquery/ConstructedNodesTest.java</exclude>
21662170
<exclude>src/main/java/org/exist/xquery/Context.java</exclude>
@@ -2403,6 +2407,7 @@
24032407
<exclude>src/test/java/org/exist/xquery/functions/util/Base64FunctionsTest.java</exclude>
24042408
<exclude>src/test/java/org/exist/xquery/functions/util/BaseConverterTest.java</exclude>
24052409
<exclude>src/main/java/org/exist/xquery/functions/util/BuiltinFunctions.java</exclude>
2410+
<exclude>src/main/java/org/exist/xquery/functions/util/CollectionName.java</exclude>
24062411
<exclude>src/main/java/org/exist/xquery/functions/util/DescribeFunction.java</exclude>
24072412
<exclude>src/main/java/org/exist/xquery/functions/util/Eval.java</exclude>
24082413
<exclude>src/test/java/org/exist/xquery/functions/util/EvalTest.java</exclude>
@@ -2684,6 +2689,7 @@ The original license statement is also included below.]]></preamble>
26842689
<include>src/main/java/org/exist/security/internal/aider/ImmutableUnixStylePermissionAider.java</include>
26852690
<include>src/main/java/org/exist/source/DbStoreSource.java</include>
26862691
<include>src/main/java/org/exist/source/DbUriSource.java</include>
2692+
<include>src/main/java/org/exist/xmldb/LocalCompiledExpression.java</include>
26872693
<include>src/test/java/org/exist/xquery/RunningXQueryRestTest.java</include>
26882694
<include>src/test/java/org/exist/xquery/RunningXQueryTest.java</include>
26892695
<include>src/test/java/org/exist/xquery/RunningXQueryXmlDbTest.java</include>

exist-core/src/main/java/org/exist/xmldb/LocalCollection.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ public org.xmldb.api.base.Collection getParentCollection() throws XMLDBException
323323
});
324324
}
325325

326-
public String getPath() throws XMLDBException {
326+
String getPath() {
327327
return path.toString();
328328
}
329329

@@ -765,13 +765,8 @@ public XmldbURI getURI() {
765765
//No port ;-)
766766
//No context ;-)
767767
//accessor.append(getContext());
768-
try {
769-
//TODO : cache it when constructed
770-
return XmldbURI.create(accessor.toString(), getPath());
771-
} catch(final XMLDBException e) {
772-
//TODO : should never happen
773-
return null;
774-
}
768+
769+
return XmldbURI.create(accessor.toString(), getPath());
775770
}
776771

777772
/**
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (C) 2014, Evolved Binary Ltd
3+
*
4+
* This file was originally ported from FusionDB to Elemental by
5+
* Evolved Binary, for the benefit of the Elemental Open Source community.
6+
* Only the ported code as it appears in this file, at the time that
7+
* it was contributed to Elemental, was re-licensed under The GNU
8+
* Lesser General Public License v2.1 only for use in Elemental.
9+
*
10+
* This license grant applies only to a snapshot of the code as it
11+
* appeared when ported, it does not offer or infer any rights to either
12+
* updates of this source code or access to the original source code.
13+
*
14+
* The GNU Lesser General Public License v2.1 only license follows.
15+
*
16+
* =====================================================================
17+
*
18+
* Elemental
19+
* Copyright (C) 2024, Evolved Binary Ltd
20+
*
21+
* admin@evolvedbinary.com
22+
* https://www.evolvedbinary.com | https://www.elemental.xyz
23+
*
24+
* This library is free software; you can redistribute it and/or
25+
* modify it under the terms of the GNU Lesser General Public
26+
* License as published by the Free Software Foundation; version 2.1.
27+
*
28+
* This library is distributed in the hope that it will be useful,
29+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
30+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
31+
* Lesser General Public License for more details.
32+
*
33+
* You should have received a copy of the GNU Lesser General Public
34+
* License along with this library; if not, write to the Free Software
35+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36+
*/
37+
package org.exist.xmldb;
38+
39+
import org.exist.xquery.XQueryUtil;
40+
import org.xmldb.api.base.CompiledExpression;
41+
42+
/**
43+
* XML:DB Local Compiled Expression wrapper for a compiled XQuery.
44+
*
45+
* @author <a href="mailto:adam@evolvedbinary.com">Adam Retter</a>
46+
*/
47+
public class LocalCompiledExpression implements CompiledExpression, AutoCloseable {
48+
49+
private final XQueryUtil.CompilationResult compilationResult;
50+
51+
public LocalCompiledExpression(final XQueryUtil.CompilationResult compilationResult) {
52+
this.compilationResult = compilationResult;
53+
}
54+
55+
/**
56+
* Get the underlying compilation result.
57+
*
58+
* @return the underlying compilation result.
59+
*/
60+
public XQueryUtil.CompilationResult getCompilationResult() {
61+
return compilationResult;
62+
}
63+
64+
@Override
65+
public void reset() {
66+
compilationResult.reset();
67+
}
68+
69+
@Override
70+
public void close() {
71+
compilationResult.close();
72+
}
73+
}

exist-core/src/main/java/org/exist/xmldb/LocalXPathQueryService.java

Lines changed: 40 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.exist.source.DbStoreSource;
5959
import org.exist.source.FileSource;
6060
import org.exist.source.Source;
61+
import org.exist.source.StringSource;
6162
import org.exist.storage.BrokerPool;
6263
import org.exist.storage.DBBroker;
6364
import org.exist.storage.lock.Lock.LockMode;
@@ -66,9 +67,7 @@
6667
import org.exist.storage.txn.Txn;
6768
import org.exist.util.LockException;
6869
import org.exist.xmldb.function.LocalXmldbFunction;
69-
import org.exist.xquery.CompiledXQuery;
7070
import org.exist.xquery.XPathException;
71-
import org.exist.xquery.XQuery;
7271
import org.exist.xquery.XQueryContext;
7372
import org.exist.xquery.XQueryUtil;
7473
import org.exist.xquery.value.AnyURIValue;
@@ -216,34 +215,27 @@ public EXistResourceSet execute(final XMLResource res, final CompiledExpression
216215
}
217216

218217
private EXistResourceSet execute(final DBBroker broker, final Txn transaction, XmldbURI[] docs, final Sequence contextSet, final CompiledExpression expression, final String sortExpr) throws XMLDBException {
219-
final CompiledXQuery expr = (CompiledXQuery) expression;
220-
final XQueryContext context = expr.getContext();
218+
if (!(expression instanceof LocalCompiledExpression)) {
219+
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "LocalXPathQueryService#execute requires a LocalCompiledExpression");
220+
}
221+
final LocalCompiledExpression localCompiledExpression = (LocalCompiledExpression) expression;
222+
final XQueryUtil.CompilationResult compilationResult = localCompiledExpression.getCompilationResult();
221223

222-
boolean queryResultOwnershipTransferred = false;
223-
@Nullable XQueryUtil.QueryResult queryResult = null;
224-
try {
225-
context.setStaticallyKnownDocuments(docs);
224+
final ConsumerE<XQueryContext, XPathException> preExecutionContext = xqueryContext -> {
225+
xqueryContext.setStaticallyKnownDocuments(docs);
226226
if (lockedDocuments != null) {
227-
context.setProtectedDocs(lockedDocuments);
228-
}
229-
setupContext(null, context);
230-
declareVariables(context);
231-
232-
final XQuery xquery = brokerPool.getXQueryService();
233-
234-
final long executionStarted = System.currentTimeMillis();
235-
@Nullable final Sequence result = xquery.execute(broker, expr, null, contextSet, properties, true);
236-
final long executionFinished = System.currentTimeMillis();
237-
238-
if (LOG.isTraceEnabled()) {
239-
LOG.trace("Query took {} ms.", executionFinished - executionStarted);
240-
}
241-
242-
if (result == null) {
243-
return null;
227+
xqueryContext.setProtectedDocs(lockedDocuments);
244228
}
229+
setupContext(compilationResult.source, xqueryContext);
230+
declareVariables(xqueryContext);
231+
};
245232

246-
queryResult = new XQueryUtil.QueryResult(expr.getSource(), null, expr, context, -1, executionFinished - executionStarted, result);
233+
boolean queryResultOwnershipTransferred = false;
234+
@Nullable XQueryUtil.QueryResult queryResult = null;
235+
try {
236+
// TODO(AR) does reset context need to be called on the result? it was previously (note the 'true' param) -> xquery.execute(broker, expr, null, contextSet, properties, true);
237+
// NOTE(AR) queryResult takes ownership of compilationResult
238+
queryResult = XQueryUtil.execute(broker, compilationResult, contextSet, properties, preExecutionContext, null);
247239

248240
final Properties resourceSetProperties = new Properties(properties);
249241
resourceSetProperties.setProperty(EXistOutputKeys.XDM_SERIALIZATION, "yes");
@@ -259,11 +251,11 @@ private EXistResourceSet execute(final DBBroker broker, final Txn transaction, X
259251

260252
} finally {
261253
if (!queryResultOwnershipTransferred) {
262-
// NOTE(AR) we are returning null or an exception was raised, and so we still own the queryResult and we must therefore close it
254+
// NOTE(AR) we are returning null or an exception was raised, and so we still own the queryResult or compilationResult and we must therefore close it
263255
if (queryResult != null) {
264256
queryResult.close();
265257
} else {
266-
context.runCleanupTasks();
258+
compilationResult.close();
267259
}
268260
}
269261
}
@@ -306,11 +298,7 @@ private EXistResourceSet execute(final DBBroker broker, final Txn transaction, f
306298

307299
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreCompilation = xqueryContext -> {
308300
xqueryContext.setStaticallyKnownDocuments(docs);
309-
try {
310-
setupContext(source, xqueryContext);
311-
} catch (final XMLDBException e) {
312-
throw new XPathException(e);
313-
}
301+
setupContext(source, xqueryContext);
314302
};
315303

316304
final ConsumerE<XQueryContext, XPathException> setupXqueryContextPreExecution = this::declareVariables;
@@ -374,20 +362,22 @@ public CompiledExpression compileAndCheck(final String query) throws XMLDBExcept
374362
}
375363

376364
private Either<XPathException, CompiledExpression> compileAndCheck(final DBBroker broker, final Txn transaction, final String query) throws XMLDBException {
377-
final long start = System.currentTimeMillis();
378-
final XQuery xquery = broker.getBrokerPool().getXQueryService();
379-
final XQueryContext context = new XQueryContext(broker.getBrokerPool());
365+
366+
final Source source = new StringSource(query);
367+
368+
final ConsumerE<XQueryContext, XPathException> preCompilationContext = xqueryContext -> setupContext(source, xqueryContext);
380369

381370
try {
382-
setupContext(null, context);
383-
final CompiledExpression expr = xquery.compile(context, query);
384-
if(LOG.isDebugEnabled()) {
385-
LOG.debug("compilation took {}", System.currentTimeMillis() - start);
371+
final XQueryUtil.CompilationResult compilationResult = XQueryUtil.compile(broker, source, false, true, preCompilationContext);
372+
if (LOG.isDebugEnabled()) {
373+
LOG.debug("Compilation took {}ms", compilationResult.compilationTime);
386374
}
387-
return Either.Right(expr);
375+
376+
final CompiledExpression compiledExpression = new LocalCompiledExpression(compilationResult);
377+
return Either.Right(compiledExpression);
388378
} catch (final PermissionDeniedException e) {
389379
throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, e.getMessage(), e);
390-
} catch(final IllegalArgumentException e) {
380+
} catch(final IOException e) {
391381
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage(), e);
392382
} catch(final XPathException e) {
393383
return Either.Left(e);
@@ -406,14 +396,10 @@ public EXistResourceSet queryResource(final String resource, final String query)
406396
});
407397
}
408398

409-
protected void setupContext(final Source source, final XQueryContext context) throws XMLDBException, XPathException {
410-
try {
411-
context.setBaseURI(new AnyURIValue(properties.getProperty("base-uri", collection.getPath())));
412-
} catch(final XPathException e) {
413-
throw new XMLDBException(ErrorCodes.INVALID_URI,"Invalid base uri",e);
414-
}
399+
protected void setupContext(final Source source, final XQueryContext context) throws XPathException {
400+
context.setBaseURI(new AnyURIValue(properties.getProperty("base-uri", collection.getPath())));
415401

416-
if(moduleLoadPath != null) {
402+
if (moduleLoadPath != null) {
417403
context.setModuleLoadPath(moduleLoadPath);
418404
} else if (source != null) {
419405
String modulePath = null;
@@ -561,7 +547,10 @@ public void setModuleLoadPath(final String path) {
561547

562548
@Override
563549
public void dump(final CompiledExpression expression, final Writer writer) throws XMLDBException {
564-
final CompiledXQuery expr = (CompiledXQuery)expression;
565-
expr.dump(writer);
550+
if (!(expression instanceof LocalCompiledExpression)) {
551+
throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "LocalXPathQueryService#dump requires a LocalCompiledExpression");
552+
}
553+
final LocalCompiledExpression localCompiledExpression = (LocalCompiledExpression) expression;
554+
localCompiledExpression.getCompilationResult().dump(writer);
566555
}
567556
}

exist-core/src/main/java/org/exist/xquery/CompiledXQuery.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
* admin@evolvedbinary.com
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -26,13 +50,11 @@
2650
import org.exist.source.Source;
2751
import org.exist.xquery.value.Item;
2852
import org.exist.xquery.value.Sequence;
29-
import org.xmldb.api.base.CompiledExpression;
30-
3153

3254
/**
3355
* @author wolf
3456
*/
35-
public interface CompiledXQuery extends CompiledExpression {
57+
public interface CompiledXQuery {
3658

3759
/**
3860
* Reset the compiled expression tree. Discard all

exist-core/src/main/java/org/exist/xquery/PathExpr.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.exist.dom.persistent.VirtualNodeSet;
5252
import org.exist.xquery.util.ExpressionDumper;
5353
import org.exist.xquery.value.*;
54-
import org.xmldb.api.base.CompiledExpression;
5554

5655
import java.io.Writer;
5756
import java.util.ArrayList;
@@ -66,8 +65,7 @@
6665
* @author perig
6766
* @author ljo
6867
*/
69-
public class PathExpr extends AbstractExpression implements CompiledXQuery,
70-
CompiledExpression, RewritableExpression {
68+
public class PathExpr extends AbstractExpression implements CompiledXQuery, RewritableExpression {
7169

7270
protected final static Logger LOG = LogManager.getLogger(PathExpr.class);
7371

exist-core/src/main/java/org/exist/xquery/UserDefinedFunction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,12 @@ public List<ClosureVariable> getClosureVariables() {
315315
return closureVariables;
316316
}
317317

318-
protected Sequence[] getCurrentArguments() {
318+
/**
319+
* Get the current arguments to the user defined function.
320+
*
321+
* @return the current arguments.
322+
*/
323+
public Sequence[] getCurrentArguments() {
319324
return currentArguments;
320325
}
321326
}

0 commit comments

Comments
 (0)