Can't query baseX using an Xquery with "&" - character-encoding

I'm trying to use the baseX REST API with python's requests post method, using a saved .xq file which contains a query with an &.
When running this saved query directly on baseX, there's no problem.
The request as presented in the response also includes the & as it is and not as an &, but I still get the following error (response code is 400):
" Stopped at C:/Program Files (x86)/BaseX/webapp, 37/37:\n[XPST0003] Invalid entity: '&&", "||", "!")) the...'.' "
The relevant part of the request's body is:
<rest:query xmlns:rest="http://basex.org/rest"> <rest:text>declare function local:enrich_node($attr, $supertype) {
$attr, attribute {"supertype"} {$supertype}
};
declare function local:enrich($n as node()) as node() {
typeswitch($n)
...
case $e as element(operator)
return
...
else if ($e/text()=("&&", "||", "!")) then
element {name($e)}
{local:enrich_node($e/#*, "boolop"), for $c in $e/(* | text())
return local:enrich($c) }
else
...
};
declare variable $assign_id as xs:string external;
declare variable $submission_id as xs:string external;
for $node in db:open($assign_id, $submission_id)
return local:enrich($node)</rest:text><variable name="assign_id" value="val1"/><variable name="submission_id" value="val2"/></rest:query>
When I remove the && part from the query it works.
I tried to look for relevant questions but didn't find anything, other then a suggestion to "escape" it with another & which I tried but then the returned error was with 4 &s.
Any ideas?

As the content of rest:text has to be evaluated as XQuery code but should not be parsed as XML it should help to wrap the XQuery code inside of rest:text in a CDATA section.

Related

Invalid coercion: () as xs:string in xdmp:xslt-eval

I am making use of MarkLogic's ability to call XQuery functions in the XSL transform.
Let's say I have an XQuery library with a function whose signature looks like the following. This is for illustrative purposes only.
declare function my-func:ex-join($first as xs:string, $last as xs:string) as xs:string
{
fn:concat($first, '-', $last)
}
From XQuery, I can call this function with empty sequence as parameters, with no issues, i.e.
ex-join((), '1244')
The function will just return an empty sequence, but I don't get any errors. If I try to all this function from with in my XSL transform,as in:
<xsl:value-of select="my-func:ex-join(//node/value/text(), 'something')"/>
If the /node/value does not exist, and an empty sequence is passed in, I get the coercion error.
Does anyone have suggestions to work around the coercion problem, outside of checking the values in XSL prior to the select? These are auto-generated XSL templates, which would mean a lot of coded checks.
Thanks,
-tj
Attempts to invoke that function in XQuery would fail too. It is probably due to function mapping that you don't notice this though. Put the following at the top of your XQuery code:
declare option xdmp:mapping "false";
Next to this, you only need to change the signature of your function to accept empty-sequences. Replace as xs:string with as xs:string?:
declare function my-func:ex-join($first as xs:string?, $last as xs:string?) as xs:string
fn:concat will accept empty sequences as arguments, so no further changes required to make it work..
HTH!

Lua script for scan with 'match' and 'count' constraints

I am using Jedis. I need a Lua script to scan for a pattern with a specified limit. I don't know how to pass the parameters inside Lua script.
Sample Code:
String script="return {redis.call('SCAN',KEYS[1],'COUNT',KEYS[2],'MATCH',KEYS[3]}";
List<String> response = (List<String>)jedis.eval(script,cursor,COUNT,pattern);
How do I pass these parameters to the script?
Your code has several points to fix.
In scan command, 'match' parameter should be placed prior to 'count'.
You should only use KEYS when it is a place for Redis key. Other things should be represented to ARGV.
You forgot to specify key count while calling Jedis.eval().
So, fixed version of your code is,
String script="return {redis.call('SCAN',ARGV[1],'MATCH',ARGV[2],'COUNT',ARGV[3])}";
List<String> response = (List<String>)jedis.eval(script, 0, cursor, pattern, COUNT);
But I agree Itamar to use Jedis.scan() instead.
Hope this helps.

Using resumable.js from Dart

I am trying to use resumable.js from Dart with this code:
var rs = new JS.JsObject(JS.context['Resumable'], [new JS.JsObject.jsify({
'target':context.server+'/upload'
})]);
files.forEach((file) {
rs.callMethod("addFile",[file]);
});
files variable is defined as List<File> (dart.html.File). When I check properties of rs object with these two lines:
JS.context["console"].callMethod("log",[rs['opts']]);
JS.context["console"].callMethod("log",[rs['files']]);
I find that rs.opts are initialized correctly, but rs.files always contains instances of ResumableFile with length 1. I guess that it is because method addFile expects parameter to be instance of Javascript File but it gets instanceof dart:html.File.
Do you have any idea how to convert dart:html.File to Javascript File or how to pass argument to resumable.js?
I know that I can alternatively use methods assignBrowse and assignDrop, but I would like to stick to my solution.
You have to use JsObject.fromBrowserObject to get the underlying js object.
files.forEach((file) {
rs.callMethod("addFile",[new JsObject.fromBrowserObject(file)]);
});

Unable to bind parameter in Insight.Database

I am trying to bind a parameter to a SQL query in my repository but having an error
public IList<Movie> FindMovieById(int movieId)
{
return Database.Connection().QuerySql<Movie>("select * from myDB.movies where ID=?", new { movieId });
}
I get an OleDb exception.
SQL0313: Number of host variables not valid.
Cause . . . . . : The number of host variables or entries in an SQLDA or descriptor area specified in either an EXECUTE or OPEN statement is not the same as the number of parameter markers specified in the prepared SQL statement S000001. If the statement name is *N, the number of host variables or entries in a SQLDA or descriptor area was specified in an OPEN statement and is not the same as the number of host variables specified in the DECLARE CURSOR statement for cursor C000001. Recovery . . . : Change the number of host variables specified in the USING clause or the number of entries in the SQLDA or descriptor area to equal the number of parameter markers in the prepared SQL statement or the number of host variables in the DECLARE CURSOR statement. Precompile the program again.
I have used ? for parameter binding as OleDb has positional parameters which are denoted by '?' rather the '#parameterName'.
Any help is appreciated.
Using Insight.Database can you try this?
return Database.Connection().QuerySql<Movie>(
"select * from myDB.movies where ID=#movieId",
new { movieId = movieId });
In order for Insight to map queries to objects, it binds parameters by name, not by position.
Your parameter object can be an anonymous type. If you specify:
new { movieId }
I believe the compiler will generate a property with the name "MovieID"
In that case, your parameter should be called #movieId.
If your database doesn't support named parameters, please open an issue up on github and I can take a look at it.
https://github.com/jonwagner/Insight.Database/issues

how to to find a string in groovy list

question from a groovy newbie:
sql is initiated as follows
final Binding binding = new Binding();
binding.setProperty("sql", sql);
final groovy.sql.Sql sql = Sql.newInstance(dbConfig.getUrl(), dbConfig.getUserName(), dbConfig.getPasswd(),"oracle.jdbc.OracleDriver");
I am running a query in groovy like this
def listOfRows = sql.rows (select column1 from table1);
listOfRows when printed shows contents like [[column1_name:value1], [column1_name:value2], [column1_name:value3]]
I want to check if value2 (a String) exists in the returned list of values from the above query.
I have tried doing listOfRows.contains('value2') and listOfRows.find('value2'),
it complains that the method does not exist for lists..
what's the best way of doing this ?
EDITED: I have corrected the list of printed values. What's being returned is List<GroovyResultSet>
and I have also added the definition of sql.
I would suggest you to take a look at groovy documentation, and particularly to collections documentation (both tutorial and JDK/GDK).
in that case, the most specifically adapted solution would be to use Collection#find() ... with something like
listOfRows.find { it.contains(':value2') }
Which can be translated into human-readable
find the first element in this collection which string contains ":value2".
You probably want
listOfRows.column1.contains( 'value2' )
You are probably invoking this method which takes a GString (note that GString != String) as an argument. According to this question, a string in single quotes is a standard java string, and a string in double quotes is a templatable string.
'hello' //java.lang.String
"hello" //groovy.lang.GString
Try this:
listOfRows.contains("value2")
what i ended up doing is following :
iterate the listOfRows, get all the values for column1 from each GroovyResultSet into a listOfValues ,then check for my values in that list.
def listOfValues=[];
listOfRows.collect(listOfValues){it.getAt('column1')};
if(listOfValues.size()==3){
println('success');
}

Resources