Changes

Jump to navigation Jump to search
405 bytes added ,  15:30, 10 April 2019
no edit summary
* Most clients are accompanied by some example files, which demonstrate how database commands can be executed or how queries can be evaluated.
==Constructors and FunctionsTransfer Protocol==
<All [[Clients]] use the following client/div>server protocol to communicate with the server.<div style="float:left; width:48%;">===Session===The description of the protocol is helpful if you want to implement your own client.
* Create and return session with host, port, user name and password:<br/><code>Session(String host, int port, String name, String password)</code>===Conventions===
* Execute <code>\xx</code>: single byte.* <code>{...}</code>: utf8 strings or raw data, suffixed with a command <code>\00</code> byte. To avoid confusion with this end-of-string byte, all transfered <code>\00</code> and return the result:<brcode>\FF</code>bytes are prefixed by an additional <code>String execute(String command)\FF</code>byte.
* Return a query instance for the specified query:<br/><code>Query query(String query)</code>===Authentication===
* Create a database from an input stream:<br/><code>void create(String name, InputStream input)</code>====Digest====
* Add a document to the current database from an input streamDigest authentication is used since Version 8.0:<br/><code>void add(String path, InputStream input)</code>
* Replace # Client connects to server socket# Server sends a document with '''realm''' and '''nonce''', separated by a colon: <code>{realm:nonce}</code># Client sends the '''user name''' and a hash value. The hash is composed of the md5 hash of## the md5 hash of the '''user name''', '''realm''', and '''password''' (all separated by a colon), and## the specified input stream'''nonce''':<brcode>{username} {md5(md5(username:realm:password) + nonce)}</code># Server replies with <code>\00</code>void replace(String path, InputStream inputsuccess)or <code>\01</code>(error)
* Store raw data at the specified path:<br/><code>void store(String path, InputStream input)</code>====CRAM-MD5====
* Watch CRAM-MD5 was discarded, because unsalted md5 hashes could easily be uncoveredusing rainbow tables. However, most client bindings still provide support forthe specified eventoutdated handshaking, as it only slightly differs from the new protocol:<br/><code>void watch(String name, Event notifier)</code>
* Unwatch the specified event# Client connects to server socket# Server sends a '''nonce''' (timestamp):<br/><code>void unwatch(String name){nonce}</code># Client sends the '''user name''' and a hash value. The hash is composed of the md5 hash of## the md5 of the '''password''' and* Return process information## the '''nonce''':<br/><code>String info{username} {md5(md5(password) + nonce)}</code> * Close the session:# Server replies with <br/code>\00</code>void close(success)or </code> \01</divcode><div style="float:left; width:4%;">&nbsp;</div><div style="float:left; width:48%;">===Query===(error)
* Create query instance with session and query:<br/><code>Query(Session session, String query)</code> * Bind an external variable:<br/><code>void bind(String name, String value, String type)</code><br/>The type can be an empty string. * Bind the context item:<br/><code>void context(String value, String type)</code><br/>The type Clients can easily be an empty string. * Execute the query and return the result:<br/><code>String execute()</code> * Iterator: check if a query returns more items:<br/><code>boolean more()</code> * Iterator: return the next item:<br/><code>String next()</code> * Return query information:<br/><code>String info()</code> * Return serialization parameters:<br/><code>String options()</code> * Return if the query may perform updates:<br/><code>boolean updating()</code> * Close the query:<br/><code>void close()</code></div> <div style="float:left; width:100%;"> ==Transfer Protocol== All [[Clients]] use the following client/server protocol implemented to communicate with the server.The description of the protocol is helpful if you want to implement your own client. ===General Syntax=== * <code>\x</code>: single byte.* <code>both support {{...Code|digest}}</code>: utf8 strings or raw data, suffixed with a <code>\0</code> byte. To avoid confusion with this end-of-string byte, all <code>\0</code> and <code>\FF</code> bytes that occur in raw data will be prefixed with <code>\FF</code>. ===Authentication (via [http://tools.ietf.org/html/rfc2195 {{Code|cram-md5])=== # Client connects to server socket# Server sends timestamp (string representation of the current time in milliseconds):<br/><code>{timestamp}</code># Client sends username and hashed password/timestamp} authentication:<br/><code>If the first server response contains no colon, {username} {Code|cram-md5(md5(password) + timestamp)}</code># Server replies with <code>\0</code> (success) or <code>\1</code> (error)} should be chosen.
===Command Protocol===
| COMMAND
| <code>{command}</code>
| <code>{result} {info} \000</code>
| Executes a database command.
|-
| QUERY
| <code>\0 00 {query}</code>| <code>{id} \000</code>
| Creates a new query instance and returns its id.
|-
| CREATE
| <code>\8 08 {name} {input}</code>| <code>{info} \000</code>
| Creates a new database with the specified input (may be empty).
|-
| ADD
| <code>\9 09 {name} {path} {input}</code>| <code>{info} \000</code>
| Adds a new resource to the opened database.
|-
| WATCH
| <code>\10 {name}</code>
| <code>{info} \0</code>
| Registers the client for the specified event.
|-
| UNWATCH
| <code>\11 {name}</code>
| <code>{info} \0</code>
| Unregisters the client.
|-
| REPLACE
| <code>\12 0C {path} {input}</code>| <code>{info} \000</code>
| Replaces a resource with the specified input.
|-
| STORE
| <code>\13 0D {path} {input}</code>| <code>{info} \000</code>
| Stores a binary resource in the opened database.
|-
| ↯ error
| <code></code>
| <code>{</code>''partial result''<code>} {error} \101</code>
| Error feedback.
|}
|-
| CLOSE
| <code>\2 02 {id}</code>| <code>\0 00 \000</code>
| Closes and unregisters the query with the specified id.
|-
| BIND
| <code>\3 03 {id} {name} {value} {type}</code>| <code>\0 00 \000</code>
| Binds a value to a variable. The type will be ignored if the string is empty.
|-
| RESULTS
| <code>\4 04 {id}</code>| <code>\x xx {item} ... \x xx {item} \000</code>| Returns all resulting items as strings, prefixed by a single byte ({{Code|\xxx}}) that represents the [[Server Protocol: Types|Type ID]]. This command is called by the {{Code|more()}} function of a client implementation.
|-
| EXECUTE
| <code>\5 05 {id}</code>| <code>{result} \000</code>| Executes the query and returns all results the result as a single string.
|-
| INFO
| <code>\6 06 {id}</code>| <code>{result} \000</code>
| Returns a string with query compilation and profiling info.
|-
| OPTIONS
| <code>\7 07 {id}</code>| <code>{result} \000</code>| Returns a string with all query serialization parameters, which can e.g. be assigned to the {{Option|SERIALIZER}} option.
|-
| CONTEXT
| <code>\14 0E {id} {value} {type}</code>| <code>\0 00 \000</code>
| Binds a value to the context. The type will be ignored if the string is empty.
|-
| UPDATING
| <code>\30 1E {id}</code>| <code>{result} \000</code>| Returns {{Code|true}} if the query may perform updatescontains updating expressions; {{Code|false}} otherwise.
|-
| FULL
| <code>\31 1F {id}</code>| <code>''XDM'' {item} ... ''XDM'' {item} \000</code>
| Returns all resulting items as strings, prefixed by the [[Server Protocol: Types#XDM Meta Data|XDM Meta Data]]. This command is e. g. used by the [[Developing|XQJ API]].
|}
As can be seen in the table, all results end with a single {{Code|\000}} byte, which indicates that the process was successful. If an error occurs, an additional byte {{Code|\101}} is sent, which is then followed by the {{Code|error}} message string.
====Binding Sequences====
{{Mark|Since Version 8.0}}, also Also sequences can be bound to variables and the context:
* {{Code|empty-sequence()}} must be supplied as type if an empty sequence is to be bound.
* Multiple items are supplied via the <code>{value}</code> argument and separated with {{Code|\101}} bytes.* Item types are specified by appending {{Code|\202}} and the type in its string representation to an item. If no item type is specified, the general type is used.
Some examplesfor the <code>{value}</code> argument:
* the two integers {{Code|123}} and {{Code|789}} are encoded as {{Code|123}}, {{Code|\101}}, {{Code|789}} and {{Code|\000}} ({{Code|xs:integer}} may be specified via the <code>{type}</code> argument).* the two items {{Code|xs:integer(123)}} and {{Code|xs:string('ABC')}} are encoded as {{Code|123}}, {{Code|\202}}, {{Code|xs:integer}}, {{Code|\101}}, {{Code|ABC}}, {{Code|\202}}, {{Code|xs:string}} and {{Code|\000}}.
==Example==
* '''Client''' connects to the database server socket
* '''Server''' sends realm and timestamp "BaseX:1369578179679": {{Code|◄ 42 61 73 65 58 3A 31 33 36 39 35 37 38 31 37 39 36 37 39 00}}
* '''Client''' sends user name "jack": {{Code|6A 61 63 6B 00 ►}}
* '''Client''' additionally sends hashed password/timestamp combinationhash: md5(md5("jack:BaseX:topsecret") + "1369578179679") = "66442c0e3b5af8b9324f7e31b7f5cca8ca664a31f8deda9b71ea3e79347f6666": {{Code|63 61 36 36 34 ... 00 ►}}
* '''Server''' replies with success code: {{Code|◄ 00}}
* '''Client''' sends the "INFO" command: {{Code|49 4E 46 4F 00 ►}}
* '''Client''' requests the query results via the RESULTS protocol command and its query id: {{Code|04 31 00 ►}}
* '''Server''' returns the first result ("1", type xs:integer): {{Code|◄ 52 31 00}}
* '''Server''' sends a single "{{Code|\0" 00}} byte instead of a new result, which indicates that no more results can be expected: {{Code|◄ 00}}* '''Server''' sends the error code "{{Code|\1" 01}} and the error message ("Stopped at..."): {{Code|◄ 01 53 74 6f ... 00}}
* '''Client''' closes the query instance: {{Code|02 31 00 ►}}
* '''Server''' sends a response (which is equal to an empty info string) and success code: {{Code|◄ 00 00}}
* '''Client''' closes the socket connection
==Existing ClientsConstructors and Functions== Most language bindings provide the following constructors and functions: </div><div style="float:left; width:48%;">===Session=== * Create and return session with host, port, user name and password:<br/><code>Session(String host, int port, String name, String password)</code> * Execute a command and return the result:<br/><code>String execute(String command)</code> * 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 input)</code> * Add a document to the current database from an input stream:<br/><code>void add(String path, InputStream input)</code> * Replace a document with the specified input stream:<br/><code>void replace(String path, InputStream input)</code> * Store raw data at the specified path:<br/><code>void store(String path, InputStream input)</code> * Return process information:<br/><code>String info()</code> * Close the session:<br/><code>void close()</code> </div><div style="float:left; width:4%;">&nbsp;</div><div style="float:left; width:48%;">===Query=== * Create query instance with session and query:<br/><code>Query(Session session, String query)</code> * Bind an external variable:<br/><code>void bind(String name, String value, String type)</code><br/>The type can be an empty string. * Bind the context item:<br/><code>void context(String value, String type)</code><br/>The type can be an empty string.
* [httpsExecute the query and return the result:<br/><code>String execute()</github.comcode> * Iterator: check if a query returns more items:<br/BaseXdb><code>boolean more()</basex-examplescode> * Iterator: return the next item:<br/blob><code>String next()</mastercode> * Return query information:<br/src><code>String info()</main/java/org/basex/examples/api/BaseXClient.java Java client]code> * [httpsReturn serialization parameters:<br/><code>String options()</github.com/BaseXdb/basex-api/blob/master/src/main/c%23/BaseXClient.cs C# client]code> * [httpsReturn if the query may perform updates:<br/><code>boolean updating()</github.com/BaseXdb/basex-api/blob/master/src/main/python/BaseXClient.py Python client]code> * [httpsClose the query:<br/><code>void close()</github.com/BaseXdb/basex-api/blob/master/srccode></main/perl/BaseXClient.pm Perl client]div>* more client implementations are listed on the [[Clients]] page.<div style="float:left; width:100%;">
=Changelog=
 
;Version 8.2
 
* Removed: {{Code|WATCH}} and {{Code|UNWATCH}} command
;Version 8.0
* Updated: cram-md5 replaced with digest authentication
* Updated: {{Code|BIND}} command: support more than one item
</div>
[[Category:Developer]]
[[Category:Server]]
[[Category:API]]
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu