> The XQuery Processor
XQuery is no exception to this rule. Zorba provides XQuery debugging capabilities through tree medias: a high level C++ API to embed and build front-end XQuery debuggers, a command-line tool called XQDB and the XQuery Development Toolkit project, an Eclipse plugin that supports XQuery.
zorba -c -q -f query.xq
With the port option (-p or --ports), you can specify the ports of the debugger server. By default it is 8000 for requests and 9000 for events. If you are using a firewall, you need to have these ports unblocked.
zorba -p 1111:2222 -c -q query.xq -f
Once XQDB is started, you can use the debugger client commands. There are basically divided in 3 categories: execution commands, breakpoints commands and data commands. Use help to get an overview.
(xqdb) help
List of available commands:
Execution commands:
run -- Run the query.
stop -- Stop the query execution.
quit -- Quit Zorba debugger.
continue -- Resume the query execution.
status -- Display the status of the query.
Breakpoint commands:
break -- Set a breakpoint at the specified file and line.
watch -- Add watchpoint to the query
list -- Display the executed query line.
clear -- Clear breakpoints.
Data commands:
vars -- List all variables that are in scope.
eval -- Evaluate an xquery expression and print its result.
Zorba debugger:
version -- Display the version of Zorba engine and its debugger
help -- This help.
$ zorba -c -f -q test_query.xq
You can use list all to print the query:
(xqdb) list all
1 <html>
2 <head>
3 <body>
4 {
5 for $act in <doc>
6 <ACT>
7 <TITLE>T</TITLE>
8 <SPEAKER>S1</SPEAKER>
9 <SPEAKER>S2</SPEAKER>
10 </ACT>
11 </doc>
12 let $speakers := distinct-values($act//SPEAKER)
13 return
14
15 <h1>{$act/TITLE/text()}</h1>
16 <ul>
17 {
18 for $speaker in $speakers
19 return <li>{ $speaker }</li>
20 }
21 </ul>
22
23 }
24 </body>
25 </html>
26
Now we would like to set breakpoints in the query. In Zorba, the following expressions are breakable: For, Let and Return clauses; function calls and If/Else expressions. In the query above, we can set breakpoints at lines 5, 12, 13, 18 and 19:
Use b or break to set any of these breakpoints. For example,
(xqdb) b 19
Set breakpoint at line 19.
And r or run the query:
(xqdb) r
Launch the query
19 return <li>{ $speaker }</li>
The query suspended at line 19. If you are lost, you can use the list command to see the neighboring lines. The expression at which the query has suspended is printed in bold face.
(xqdb) list
16 <ul>
17 {
18 for $speaker in $speakers
19 return <li>{ $speaker }</li>
20 }
21 </ul>
Let's list all variables that are in scope with the vars command:
(xqdb) vars
Global variables:
Local variables:
$act [XS_UNTYPED]
$speaker [XS_UNTYPED]
$speakers [XS_UNTYPED]
You can use the print command to fetch the value of any of these variables. Note that you can execute arbitrary XQuery expressions having the in-scope variables being bound.
(xqdb) p $act
<ACT><TITLE>T</TITLE><SPEAKER>S1</SPEAKER><SPEAKER>S2</SPEAKER></ACT>
(xqdb) p $act/TITLE/text()
T
Now, we would like to remove the breakpoint and set a watchpoint whenever $speaker is equal to S2, i.e. the execution of the query only suspends if the boolean effective value of the condition evalutes to true.
(xqdb) l b
List of breakpoints and watchpoints:
id:1 line:16
(xqdb) delete 1
Breakpoint 1 has been cleared.
(xqdb) w $speaker=S2
Set watchpoint: $speaker=S2
If you rerun the query, it will again break at line 16. However it will break only once, the single time where $speaker is equal to S2:
(xqdb) r
The query being debugged has already started.
Reload query and start it from beginning? (y or n)
y
Launch the query
19 return <li>{ $speaker }</li>
(xqdb) p $speaker
S2
(xqdb) list mymodule.xq
1 module namespace shopping = "http://www.zorba-xquery.com/shopping";
2
3 declare function shopping:discount($price as xs:decimal?, $discount as xs:decimal?) as xs:decimal?
4 {
5 let $disc := ($price*$discount) div 100
6 return ($price - $disc)
7 };
8
(xqdb) b mymodule.xq:5
(xqdb) r
let $disc:= ($price*$discount) div 100