eXist-db / exist

eXist Native XML Database and Application Platform
https://exist-db.org
GNU Lesser General Public License v2.1
430 stars 180 forks source link

Can't set external variable of a scheduled job #1841

Open ptrckb opened 6 years ago

ptrckb commented 6 years ago

Overriding an external variable with a default value does not work when scheduling a script.

Starting the following job (/db/apps/job.xql):

xquery version "3.1";

declare variable $local:var external := 'NOK';

util:log('warn', $local:var)

with:

xquery version "3.1";

let $params := <parameters>
    <param name="var" value="OK"/>
</parameters>
let $resource := '/db/apps/job.xql'
let $name := 'job'
return scheduler:schedule-xquery-periodic-job($resource, 0, $name, $params, 0, 0)

prints 'NOK' to the log.

If the variable has no default specified (changing the third line of /db/apps/job.xql), it outputs the value passed when scheduling the job.

Tested with current eXist develop (3996133151ad5a0948a2f6fe0966e5791671d49a) on Linux with Java 1.8.0.

dizzzz commented 6 years ago

Please could you fill-in the issue template for each issue you file? That makes the discussion much easier for us. Sorry to bother you with this, but we ask this for a good reason.

ptrckb commented 6 years ago

Thank you for reporting your issue!

To be able to better understand you problem or suggestion, please add as much information as possible to this ticket. When there is no or just little information, it will be too difficult to work on it (and hence we will not be able to solve it)

Please fill in the following sections:

What is the problem

Describe exactly what you see (e.g. an output of an XQuery)

A external variable in a scheduled script can not be overridden.

What did you expect

Describe what you expected to happen. Add for example a reference to a specification.

The variable take the value that is passed as job parameter (scheduler:schedule-xquery-periodic-job).

Describe how to reproduce or add a test

Describe how we can can reproduce the problem.

The best way is to provide a 'self containing' test, a test that can be run without dependancies. The XQSuite - Annotation-based Test Framework for XQuery makes it very easy for you to create tests. These tests can be executed from the eXide editor (XQuery - Run as Test)

Scheduling the following job (/db/apps/job.xql):

xquery version "3.1";

declare variable $local:var external := 'NOK';

util:log('warn', $local:var)

with:

xquery version "3.1";

let $params := <parameters>
    <param name="var" value="OK"/>
</parameters>
let $resource := '/db/apps/job.xql'
let $name := 'job'
return scheduler:schedule-xquery-periodic-job($resource, 0, $name, $params, 0, 0)

prints 'NOK' to the log when I expected it to print 'OK'.

Context information

Please always add the following information

duncdrum commented 6 years ago

@dizzzz bug no bug? reproducible?

dizzzz commented 6 years ago

Good question. No idea for now...

amclark42 commented 2 years ago

I ran into this, too. My setup:

Here’s a Test Suite which demonstrates the problem:

xquery version "3.1";

  module namespace t="http://exist-db.org/xquery/test";
  declare namespace test="http://exist-db.org/xquery/xqsuite";
(:  NAMESPACES  :)
  declare namespace scheduler="http://exist-db.org/xquery/scheduler";
  declare namespace util="http://exist-db.org/xquery/util";
  declare namespace xdb="http://exist-db.org/xquery/xmldb";

(:~
  Try to set an external variable of a scheduled XQuery job.

  @author Ash Clark
  2022
 :)

(:  VARIABLES  :)
  declare variable $t:job-name := 'test-with-param';
  declare variable $t:xquery := 
    "xquery version '3.1';
    declare namespace xdb='http://exist-db.org/xquery/xmldb';
    declare variable $local:addressee external := 'world';
    xdb:store('/db/test', 'msg.xml', <msg>Hello, <name>{$local:addressee}</name>!</msg>)
    ";

(:  FUNCTIONS  :)

  declare
    %test:setUp
  function t:setup() {
    let $testCol := xdb:create-collection("/db", "test")
    return xdb:store("/db/test", "set-message.xq", $t:xquery)
  };

  declare
    %test:tearDown
  function t:tearDown() {
    xdb:remove("/db/test"),
    scheduler:delete-scheduled-job($t:job-name)
  };

  declare
    %test:name("XQuery job was scheduled, with parameters set")
    %test:assertTrue
  function t:A_job-scheduled() as xs:boolean {
    scheduler:schedule-xquery-periodic-job(
        '/db/test/set-message.xq', 
        0,                  (: time between job execution :)
        $t:job-name,
        <parameters>
          <param name="addressee" value="eXist"/>
        </parameters>,
        0,                  (: delay before running :)
        0                   (: times to repeat :)
      )
  };

  declare
    %test:name("XQuery job was completed")
    %test:assertTrue
  function t:B_message-written() as xs:boolean {
    util:wait(500),
    doc-available('/db/test/msg.xml')
  };

  declare
    %test:name("XQuery job used externally-set parameter")
    %test:assertExists
    %test:assertEquals("eXist")
  function t:C_get-addressee-name() as xs:string? {
    doc('/db/test/msg.xml')/msg/name/normalize-space()
  };