Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading of repository modules via fn:load-xquery-module #2353

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.*;
import java.util.List;

import org.basex.core.*;
import org.basex.io.*;
import org.basex.query.*;
import org.basex.query.ann.*;
Expand Down Expand Up @@ -50,7 +51,12 @@ public XQMap item(final QueryContext qc, final InputInfo ii) throws QueryExcepti
locs = opt.get(LOCATION_HINTS);
} else {
final byte[] loc = qc.modDeclared.get(modUri);
locs = loc == null ? new String[0] : new String[] {Token.string(loc)};
if(loc != null) {
locs = new String[] { Token.string(loc) };
} else {
final String path = repoFilePath(modUri, qc.context);
locs = path == null ? new String[0] : new String[] { path };
}
}
if(locs.length == 0) throw MODULE_NOT_FOUND_X.get(info, modUri);
for(final String loc : locs) srcs.add(ii.sc().resolve(loc, ii.path()));
Expand Down Expand Up @@ -144,7 +150,14 @@ public XQMap item(final QueryContext qc, final InputInfo ii) throws QueryExcepti
final MapBuilder variables = new MapBuilder();
for(final StaticVar var : mqc.vars) {
if(!var.anns.contains(Annotation.PRIVATE) && Token.eq(var.sc.module.uri(), modUri)) {
variables.put(var.name, var.value(mqc));
try {
variables.put(var.name, var.value(mqc));
} catch (QueryException ex) {
throw ex;
} catch (Exception ex) {
Util.debug(ex);
throw VAREMPTY_X.get(info, var.name());
}
}
}

Expand All @@ -154,6 +167,23 @@ public XQMap item(final QueryContext qc, final InputInfo ii) throws QueryExcepti
return result.map();
}

/**
* Return the repository file path of the XQuery module with the given module URI, or
* {@code null}, if there is no such module in the repository.
* @param modUri module URI
* @param context database context
* @return the file path of the XQuery module in the repository (maybe {@code null})
*/
private String repoFilePath(final byte[] modUri, final Context context) {
final String path = Strings.uri2path(Token.string(modUri));
final String repoPath = context.soptions.get(StaticOptions.REPOPATH);
for(final String suffix : IO.XQSUFFIXES) {
final IOFile file = new IOFile(repoPath, path + suffix);
if(file.exists()) return file.path();
}
return null;
}

/**
* Options for fn:load-xquery-module.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public boolean visit(final ASTVisitor visitor) {
* Returns the name of the variable.
* @return name
*/
private String name() {
public String name() {
return Strings.concat(Token.cpToken('$'), name.string());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,11 @@ public final class FnModuleTest extends SandboxTest {
/** Test method. */
@Test public void loadXQueryModule() {
final Function func = LOAD_XQUERY_MODULE;
final String module = "src/test/resources/hello.xqm";
query(_REPO_INSTALL.args(module));

query(func.args("world", " {'variables': {QName('world', 'ext'): 42}}")
+ "?variables(QName('world', 'ext'))", 42);
query("let $expr := '2 + 2'\n"
+ "let $module := `xquery version '4.0'; \n"
+ " module namespace dyn='http://example.com/dyn';\n"
Expand All @@ -1477,6 +1482,7 @@ public final class FnModuleTest extends SandboxTest {
error(func.args("x", " {'content': 'module namespace y = \"y\";'}"), MODULE_FOUND_OTHER_X);
error(func.args("x.xq", " { 'content': 'declare function local:f() {}; ()' }"),
MODULE_FOUND_MAIN_X);
error(func.args("world"), VAREMPTY_X);
}

/** Test method. */
Expand Down