Difference between revisions of "Server Protocol"
Line 206: | Line 206: | ||
|} | |} | ||
− | + | As can be seen in the table, all results end with a single {{Code|\0}} byte, which indicates that the process was successful. If an error occurs, an additional byte {{Code|\1}} is sent, which is then followed by the {{Code|error message}}. | |
==Example== | ==Example== |
Revision as of 14:16, 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. A detailed example demonstrates how a concrete byte exchange can look like.
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. |
As can be seen in the table, all results end with a single \0
byte, which indicates that the process was successful. If an error occurs, an additional byte \1
is sent, which is then 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'
. The query is then evaluated, 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 sends user name "jack":
6A 61 63 6B 00
- Client sends hashed password/timestamp combination
md5(md5("topsecret") + "1369578179679") = "66442c0e3b5af8b9324f7e31b7f5cca8":36 36 34 ... 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 a response (which is equal to an empty info string) 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)