use of org.exist.dom.memtree.MemTreeBuilder in project exist by eXist-db.
the class ExecuteFunctionTest method testMissingParamType.
@Test
public void testMissingParamType() throws SQLException {
// mocks a simple SQL prepared statement with one parameter that lacks a type attribute.
// This should throw an informative error.
XQueryContext context = new XQueryContextStub();
ExecuteFunction execute = new ExecuteFunction(context, signatureByArity(ExecuteFunction.FS_EXECUTE, functionName, 3));
final String sql = "SELECT ?";
// create mock objects
Connection connection = mock(Connection.class);
PreparedStatement preparedStatement = mock(PreparedStatement.class);
Object[] mocks = new Object[] { connection, preparedStatement };
// register mocked connection and prepared statement
final long connId = SQLModule.storeConnection(context, connection);
final long stmtId = SQLModule.storePreparedStatement(context, new PreparedStatementWithSQL(sql, preparedStatement));
// mock behavior
expect(preparedStatement.getConnection()).andReturn(connection);
// no behavior necessary - error should be thrown before first call
replay(mocks);
// execute function
MemTreeBuilder paramBuilder = new MemTreeBuilder(context);
paramBuilder.startDocument();
paramBuilder.startElement(new QName("parameters", SQLModule.NAMESPACE_URI), null);
paramBuilder.startElement(new QName("param", SQLModule.NAMESPACE_URI), null);
paramBuilder.endElement();
paramBuilder.endElement();
paramBuilder.endDocument();
final ElementImpl sqlParams = (ElementImpl) paramBuilder.getDocument().getFirstChild();
try {
execute.eval(new Sequence[] { new IntegerValue(connId), new IntegerValue(stmtId), sqlParams, new BooleanValue(false) }, Sequence.EMPTY_SEQUENCE);
fail("This should have thrown");
} catch (XPathException e) {
assertTrue(e.getMessage().contains("<sql:param> must contain attribute sql:type"));
}
}
use of org.exist.dom.memtree.MemTreeBuilder in project exist by eXist-db.
the class ExecuteFunctionTest method testSQLException.
@Test
public void testSQLException() throws SQLException, XPathException {
// mocks a simple SQL prepared statement with one parameter that fails on execution
// and verifies the error message
// the parameter is filled with an empty sql:param element
XQueryContext context = new XQueryContextStub();
ExecuteFunction execute = new ExecuteFunction(context, signatureByArity(ExecuteFunction.FS_EXECUTE, functionName, 3));
final String sql = "SELECT ?";
final String test_message = "SQL ERROR";
final String test_sqlState = "SQL STATE";
// create mock objects
Connection connection = mock(Connection.class);
PreparedStatement preparedStatement = mock(PreparedStatement.class);
Object[] mocks = new Object[] { connection, preparedStatement };
// register mocked connection and prepared statement
final long connId = SQLModule.storeConnection(context, connection);
final long stmtId = SQLModule.storePreparedStatement(context, new PreparedStatementWithSQL(sql, preparedStatement));
// mock behavior
expect(preparedStatement.getConnection()).andReturn(connection);
preparedStatement.setObject(1, "", Types.VARCHAR);
expect(preparedStatement.execute()).andThrow(new SQLException(test_message, test_sqlState));
replay(mocks);
// execute function
MemTreeBuilder paramBuilder = new MemTreeBuilder(context);
paramBuilder.startDocument();
paramBuilder.startElement(new QName("parameters", SQLModule.NAMESPACE_URI), null);
paramBuilder.startElement(new QName("param", SQLModule.NAMESPACE_URI), null);
paramBuilder.addAttribute(new QName("type", SQLModule.NAMESPACE_URI), "varchar");
paramBuilder.endElement();
paramBuilder.endElement();
paramBuilder.endDocument();
final ElementImpl sqlParams = (ElementImpl) paramBuilder.getDocument().getFirstChild();
Sequence res = execute.eval(new Sequence[] { new IntegerValue(connId), new IntegerValue(stmtId), sqlParams, new BooleanValue(false) }, Sequence.EMPTY_SEQUENCE);
// assert expectations
verify(mocks);
assertEquals(1, res.getItemCount());
assertEquals(Type.ELEMENT, res.getItemType());
Node root = ((NodeValue) res.itemAt(0)).getNode();
assertEquals("sql:exception", root.getNodeName());
assertEquals(6, root.getChildNodes().getLength());
Node node = root.getFirstChild();
Node state = node;
assertEquals("sql:state", state.getNodeName());
assertEquals(test_sqlState, state.getTextContent());
node = node.getNextSibling();
Node message = node;
assertEquals("sql:message", message.getNodeName());
assertEquals(test_message, message.getTextContent());
node = node.getNextSibling();
Node stackTrace = node;
assertEquals("sql:stack-trace", stackTrace.getNodeName());
node = node.getNextSibling();
Node sqlErr = node;
assertEquals("sql:sql", sqlErr.getNodeName());
assertEquals(sql, sqlErr.getTextContent());
node = node.getNextSibling();
Node parameters = node;
assertEquals("sql:parameters", parameters.getNodeName());
Node param1 = parameters.getFirstChild();
assertEquals("sql:param", param1.getNodeName());
assertEquals("varchar", param1.getAttributes().getNamedItemNS(SQLModule.NAMESPACE_URI, "type").getTextContent());
assertEquals("", param1.getTextContent());
node = node.getNextSibling();
Node xquery = node;
assertEquals("sql:xquery", xquery.getNodeName());
}
use of org.exist.dom.memtree.MemTreeBuilder in project exist by eXist-db.
the class ContentReceiver method startElement.
@Override
public void startElement(QName qname, AttrList attribs) throws SAXException {
// Calculate path to current element
currentElementPath.addComponent(qname);
// Current path matches wanted path
if (matches(currentElementPath)) {
if (sendDataToCB) {
// Data is already sent to callback, ignore
} else {
// New element match, new data
// Save reference to current path
startElementPath = new NodePath(currentElementPath);
// Store old fragment in stack
context.pushDocumentContext();
// Create new receiver
MemTreeBuilder memBuilder = context.getDocumentBuilder();
docBuilderReceiver = new DocumentBuilderReceiver(memBuilder);
// Switch on retrievel
sendDataToCB = true;
}
}
if (sendDataToCB) {
docBuilderReceiver.startElement(qname, attribs);
}
}
use of org.exist.dom.memtree.MemTreeBuilder in project exist by eXist-db.
the class ContentFunctions method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// is argument the empty sequence?
if (args[0].isEmpty()) {
return Sequence.EMPTY_SEQUENCE;
}
ContentExtraction ce = new ContentExtraction();
if (isCalledAs("stream-content")) {
/* binary content */
BinaryValue binary = (BinaryValue) args[0].itemAt(0);
/* callback function */
FunctionReference ref = (FunctionReference) args[2].itemAt(0);
Map<String, String> mappings = new HashMap<>();
if (args[3].hasOne()) {
NodeValue namespaces = (NodeValue) args[3].itemAt(0);
parseMappings(namespaces, mappings);
}
return streamContent(ce, binary, args[1], ref, mappings, args[4]);
} else {
try {
if (isCalledAs("get-metadata")) {
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
builder.startDocument();
builder.startElement(new QName("html", XHTML_NS), null);
builder.startElement(new QName("head", XHTML_NS), null);
final QName qnMeta = new QName("meta", XHTML_NS);
final Metadata metadata = ce.extractMetadata((BinaryValue) args[0].itemAt(0));
for (final String name : metadata.names()) {
for (final String value : metadata.getValues(name)) {
final AttributesImpl attributes = new AttributesImpl();
attributes.addAttribute("", "name", "name", "string", name);
attributes.addAttribute("", "content", "content", "string", value);
builder.startElement(qnMeta, attributes);
builder.endElement();
}
}
builder.endElement();
builder.endElement();
builder.endDocument();
return builder.getDocument();
} finally {
context.popDocumentContext();
}
} else {
final DocumentBuilderReceiver builder = new DocumentBuilderReceiver();
builder.setSuppressWhitespace(false);
final Metadata metadata = ce.extractContentAndMetadata((BinaryValue) args[0].itemAt(0), (ContentHandler) builder);
return (NodeValue) builder.getDocument();
}
} catch (IOException | SAXException | ContentExtractionException ex) {
LOG.error(ex.getMessage(), ex);
throw new XPathException(this, ex.getMessage(), ex);
}
}
}
use of org.exist.dom.memtree.MemTreeBuilder in project exist by eXist-db.
the class FnImport method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (!context.getSubject().hasDbaRole()) {
throw (new XPathException(this, "Permission denied, calling user '" + context.getSubject().getName() + "' must be a DBA to kill a running xquery"));
}
final String dirOrFile = args[0].getStringValue();
String adminPass = null;
if (args[1].hasOne()) {
adminPass = args[1].getStringValue();
}
String adminPassAfter = null;
if (args[2].hasOne()) {
adminPassAfter = args[2].getStringValue();
}
MemTreeBuilder builder = null;
context.pushDocumentContext();
try {
if (NAME.equals(getName())) {
builder = context.getDocumentBuilder();
builder.startDocument();
builder.startElement(IMPORT_ELEMENT, null);
}
try {
final SystemImport restore = new SystemImport(context.getDatabase());
final RestoreListener listener = new XMLRestoreListener(builder);
restore.restore(org.exist.security.SecurityManager.DBA_USER, adminPass, adminPassAfter, Paths.get(dirOrFile), listener);
} catch (final Exception e) {
throw new XPathException(this, "restore failed with exception: " + e.getMessage(), e);
}
if (builder == null) {
return Sequence.EMPTY_SEQUENCE;
} else {
builder.endElement();
builder.endDocument();
return (NodeValue) builder.getDocument().getDocumentElement();
}
} finally {
if (builder != null) {
context.popDocumentContext();
}
}
}
Aggregations