Difference between revisions of "Server Protocol"
Line 12: | Line 12: | ||
* The {{Code|execute()}} method is called to launch a database command. It returns the result or throws an exception with the received error message. | * The {{Code|execute()}} method is called to launch a database command. It returns the result or throws an exception with the received error message. | ||
− | * The {{Code|query()}} method creates a query instance. Variables and the context item can be bound to that | + | * The {{Code|query()}} method creates a query instance. Variables and the context item can be bound to that instance, and the result can either be requested via {{Code|execute()}}, or in an iterative manner with the {{Code|more()}} and {{Code|next()}} functions. If an error occurs, an exception will be thrown. |
* The {{Code|create()}}, {{Code|add()}}, {{Code|replace()}} and {{Code|store()}} method pass on input streams to the corresponding database commands. | * The {{Code|create()}}, {{Code|add()}}, {{Code|replace()}} and {{Code|store()}} method pass on input streams to the corresponding database commands. | ||
Line 30: | Line 30: | ||
* Execute a command and return the result:<br/><code>String execute(String command)</code> | * Execute a command and return the result:<br/><code>String execute(String command)</code> | ||
− | * Return a query | + | * Return a query instance for the specified query:<br/><code>Query query(String query)</code> |
* Create a database from an input stream:<br/><code>void create(String name, InputStream in)</code> | * Create a database from an input stream:<br/><code>void create(String name, InputStream in)</code> | ||
Line 52: | Line 52: | ||
===Query=== | ===Query=== | ||
− | * Create query | + | * Create query instance with session and query:<br/><code>Query(Session s, String query)</code> |
* Bind an external variable:<br/><code>void bind(String name, String value, String type). The type can be an empty string.</code> | * Bind an external variable:<br/><code>void bind(String name, String value, String type). The type can be an empty string.</code> | ||
Line 173: | Line 173: | ||
| <code>\4 {id}</code> | | <code>\4 {id}</code> | ||
| <code>\x {item} ... \x {item} \0</code> | | <code>\x {item} ... \x {item} \0</code> | ||
− | | Returns | + | | Returns the single items as strings, prefixed by a single byte ({{Code|\x}}) that represents the [[Server Protocol: Types|Type ID]]. This command is called by the {{Code|more()}} function of a client implementation. |
|- | |- | ||
| EXECUTE | | EXECUTE | ||
| <code>\5 {id}</code> | | <code>\5 {id}</code> | ||
| <code>{result} \0</code> | | <code>{result} \0</code> | ||
− | | Executes the query and returns all results as a | + | | Executes the query and returns all results as a single string. |
|- | |- | ||
| INFO | | INFO | ||
Line 206: | Line 206: | ||
|} | |} | ||
− | All results end with a single {{Code|\0}} byte, which indicates that the process was successful. If an error occurs, a byte {{Code|\1}} is sent | + | All results end with a single {{Code|\0}} byte, which indicates that the process was successful. If an error occurs, a byte {{Code|\1}} is additionally sent, followed by the {{Code|error message}}. |
===Example=== | ===Example=== | ||
− | In the following example, a client registers a new session and | + | In the following example, a client registers a new session and executes the [[Commands#INFO|INFO]] database command. Next, it creates a new query instance for the XQuery expression {{Code|1, 2+'3'}}, which receives the id {{Code|1}}. The query is then evaluated via the {{Code|RESULTS}} command, and the server returns the result of the first subexpression {{Code|1}} and an error for the second sub expression. Finally, the query instance and client session are closed. |
− | + | # Client connects to the database server socket | |
+ | # Server sends timestamp "1369578179679": {{Code|31 33 36 39 35 37 38 31 37 39 36 37 39 00}} | ||
+ | # Client send user name and hashed password/timestamp "user", md5(md5("topsecret") + "1369578179679") = "66442c0e3b5af8b9324f7e31b7f5cca8": {{Code|75 73 65 72 00 36 36 ... 00}} | ||
+ | # Server replies with success code: {{Code|00}} | ||
+ | # Client sends the "INFO" command: {{Code|49 4E 46 4F 00}} | ||
+ | # Server responds with the result "General Information...": {{Code|47 65 6e 65 ... 00}} | ||
+ | # Server additionally sends an (empty) info string: {{Code|00}} | ||
+ | # Client creates a new query instance for the XQuery "1, 2+'3'": {{Code|00 31 2C 20 32 2B 27 33 27 00}} | ||
+ | # Server returns query id string "1" and a success code: {{Code|31 00 00}} | ||
+ | # Client requests the query results via the RESULTS protocol command "\4" and the query id "1": {{Code|04 31 00}} | ||
+ | # Server returns the first result ("1", type xs:integer): {{Code|52 31 00}} | ||
+ | # Instead of a second result, a single "\0" byte is returned, which indicates that no more results can be expected: {{Code|00}} | ||
+ | # Next, server returns the error code "\1" and the error message ("Stopped at..."): {{Code|01 53 74 6f ... 00}} | ||
+ | # Client closes the query instance: {{Code|02 31 00}} | ||
+ | # Server sends the response and success code: {{Code|00 00}} | ||
+ | # Client closes the socket connection | ||
==Existing Clients== | ==Existing Clients== | ||
Line 220: | Line 235: | ||
* [https://github.com/BaseXdb/basex-api/blob/master/src/main/python/BaseXClient.py Python client] | * [https://github.com/BaseXdb/basex-api/blob/master/src/main/python/BaseXClient.py Python client] | ||
* [https://github.com/BaseXdb/basex-api/blob/master/src/main/perl/BaseXClient.pm Perl client] | * [https://github.com/BaseXdb/basex-api/blob/master/src/main/perl/BaseXClient.pm Perl client] | ||
+ | * more client implementations are listed on the [[Clients]] page. | ||
=Changelog= | =Changelog= |
Revision as of 14:09, 26 May 2013
This page presents the classes and functions of the BaseX Clients, and the underlying protocol, which is utilized for communicating with the database server.
Contents
Workflow
- All clients are based on the client/server architecture. Hence, a BaseX database server must be started first.
- Each client provides a session class or script with methods to connect to and communicate with the database server. A socket connection will be established by the constructor, which expects a host, port, user name and password as arguments.
- The
execute()
method is called to launch a database command. It returns the result or throws an exception with the received error message.
- The
query()
method creates a query instance. Variables and the context item can be bound to that instance, and the result can either be requested viaexecute()
, or in an iterative manner with themore()
andnext()
functions. If an error occurs, an exception will be thrown.
- The
create()
,add()
,replace()
andstore()
method pass on input streams to the corresponding database commands.
- To speed up execution, an output stream can be specified by some clients; this way, all results will be directed to that output stream.
- Most clients are accompanied by some example files, which demonstrate how database commands can be executed or how queries can be evaluated.
Constructors and Functions
Session
- Create and return session with host, port, user name and password:
Session(String host, int port, String name, String password)
- Execute a command and return the result:
String execute(String command)
- Return a query instance for the specified query:
Query query(String query)
- Create a database from an input stream:
void create(String name, InputStream in)
- Add a document to the current database from an input stream:
void add(String path, InputStream in)
- Replace a document with the specified input stream:
void replace(String path, InputStream in)
- Store raw data at the specified path:
void store(String path, InputStream in)
- Watch the specified event:
void watch(String name, Event notifier)
- Unwatch the specified event:
void unwatch(String name)
- Return process information:
String info()
- Close the session:
void close()
Query
- Create query instance with session and query:
Query(Session s, String query)
- Bind an external variable:
void bind(String name, String value, String type). The type can be an empty string.
- Bind the context item:
void context(String value, String type). The type can be an empty string.
- Execute the query and return the result:
String execute()
- Iterator: check if a query returns more items:
boolean more()
- Iterator: return the next item:
String next()
- Return query information:
String info()
- Return serialization parameters:
String options()
- Return if the query may perform updates:
boolean updating()
- Close the query:
void close()
Transfer Protocol
All Clients use the following client/server protocol to communicate with the server. The description of the protocol is helpful if you want to implement your own client.
General Syntax
\x
: single byte.{...}
: utf8 strings or raw data, suffixed with a\0
byte. To avoid confusion with the suffix byte, all\0
and\FF
bytes that occur in raw data will be prefixed with\FF
.
Authentication (via cram-md5)
- Client connects to server socket
- Server sends timestamp (string representation of the current time in milliseconds):
{timestamp}
- Client sends username and hashed password/timestamp:
{username} {md5(md5(password) + timestamp)}
- Server replies with
\0
(success) or\1
(error)
Command Protocol
The following byte sequences are sent and received from the client (please note that a specific client may not support all of the presented commands):
Command | Client Request | Server Response | Description |
---|---|---|---|
COMMAND | {command}
|
{result} {info} \0
|
Executes a database command. |
QUERY | \0 {query}
|
{id} \0
|
Creates a new query instance and returns its id. |
CREATE | \8 {name} {input}
|
{info} \0
|
Creates a new database with the specified input (may be empty). |
ADD | \9 {name} {path} {input}
|
{info} \0
|
Adds a new resource to the opened database. |
WATCH | \10 {name}
|
{info} \0
|
Registers the client for the specified event. |
UNWATCH | \11 {name}
|
{info} \0
|
Unregisters the client. |
REPLACE | \12 {path} {input}
|
{info} \0
|
Replaces a resource with the specified input. |
STORE | \13 {path} {input}
|
{info} \0
|
Stores a binary resource in the opened database. |
↯ error |
|
{ partial result} {error} \1
|
Error feedback. |
Query Command Protocol
Queries are referenced via an id
, which has been returned by the QUERY
command (see above).
Query Command | Client Request | Server Response | Description |
---|---|---|---|
CLOSE | \2 {id}
|
\0 \0
|
Closes and unregisters the query with the specified id. |
BIND | \3 {id} {name} {value} {type}
|
\0 \0
|
Binds a value to a variable. An empty string can be specified as data type. |
RESULTS | \4 {id}
|
\x {item} ... \x {item} \0
|
Returns the single items as strings, prefixed by a single byte (\x ) that represents the Type ID. This command is called by the more() function of a client implementation.
|
EXECUTE | \5 {id}
|
{result} \0
|
Executes the query and returns all results as a single string. |
INFO | \6 {id}
|
{result} \0
|
Returns a string with query compilation and profiling info. |
OPTIONS | \7 {id}
|
{result} \0
|
Returns a string with all query serialization parameters. |
CONTEXT | \14 {id} {value} {type}
|
\0 \0
|
Binds a value to the context item. An empty string can be specified as data type. |
UPDATING | \30 {id}
|
{result} \0
|
Returns true if the query may perform updates; false otherwise.
|
FULL | \31 {id}
|
XDM {item} ... XDM {item} \0
|
Returns all resulting items as strings, prefixed by the XDM Meta Data. This command is e. g. used by the XQJ API. |
All results end with a single \0
byte, which indicates that the process was successful. If an error occurs, a byte \1
is additionally sent, followed by the error message
.
Example
In the following example, a client registers a new session and executes the INFO database command. Next, it creates a new query instance for the XQuery expression 1, 2+'3'
, which receives the id 1
. The query is then evaluated via the RESULTS
command, and the server returns the result of the first subexpression 1
and an error for the second sub expression. Finally, the query instance and client session are closed.
- Client connects to the database server socket
- Server sends timestamp "1369578179679":
31 33 36 39 35 37 38 31 37 39 36 37 39 00
- Client send user name and hashed password/timestamp "user", md5(md5("topsecret") + "1369578179679") = "66442c0e3b5af8b9324f7e31b7f5cca8":
75 73 65 72 00 36 36 ... 00
- Server replies with success code:
00
- Client sends the "INFO" command:
49 4E 46 4F 00
- Server responds with the result "General Information...":
47 65 6e 65 ... 00
- Server additionally sends an (empty) info string:
00
- Client creates a new query instance for the XQuery "1, 2+'3'":
00 31 2C 20 32 2B 27 33 27 00
- Server returns query id string "1" and a success code:
31 00 00
- Client requests the query results via the RESULTS protocol command "\4" and the query id "1":
04 31 00
- Server returns the first result ("1", type xs:integer):
52 31 00
- Instead of a second result, a single "\0" byte is returned, which indicates that no more results can be expected:
00
- Next, server returns the error code "\1" and the error message ("Stopped at..."):
01 53 74 6f ... 00
- Client closes the query instance:
02 31 00
- Server sends the response and success code:
00 00
- Client closes the socket connection
Existing Clients
- Java client
- C# client
- Python client
- Perl client
- more client implementations are listed on the Clients page.
Changelog
- Version 7.2
- Added: Query Commands CONTEXT, UPDATING and FULL
- Added: Client function
context(String value, String type)