Changes

Jump to navigation Jump to search
111 bytes removed ,  16:30, 29 June 2023
* 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 username and password as arguments.
* 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 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|replaceput()}} and {{Code|storeputbinary()}} method methods pass on input streams to the corresponding database commands. The input can be a UTF-8 encoded XML document, a binary resource, or any other data (such as JSON or CSV) that can be successfully converted to a resource by the server.
* To speed up execution, an output stream can be specified by some clients; this way, all results will be directed to that output stream.
===Conventions===
* <code>\xxx</code>: single byte.* <code>{...}</code>: utf8 strings or raw data, suffixed with a <code>\000</code> byte. To avoid confusion with this end-of-string byte, all transferred <code>\000</code> and <code>\FF</code> bytes that occur in raw data will be are prefixed with by an additional <code>\FF</code>byte.
===Authentication===
# Client connects to server socket
# Server sends a '''realm''' and '''nonce''', separated by a colon: <code>{realm:nonce}</code>
# Client sends the '''user nameusername''' and a hash value. The hash is composed of the md5 hash of## the md5 hash of the '''user nameusername''', '''realm''', and '''password''' (all separated by a colon), and
## the '''nonce''': <code>{username} {md5(md5(username:realm:password) + nonce)}</code>
# Server replies with <code>\000</code> (success) or <code>\101</code> (error)
====CRAM-MD5====
CRAM-MD5 was discarded, because unsalted md5 hashes could can easily be uncoveredusing rainbow tables. However, most client bindings still provide support forthe outdated handshaking, as it only slightly differs from the new protocol:
# Client connects to server socket
# Server sends a '''nonce''' (timestamp): <code>{nonce}</code>
# Client sends the '''user nameusername''' and a hash value. The hash is composed of the md5 hash of
## the md5 of the '''password''' and
## the '''nonce''': <code>{username} {md5(md5(password) + nonce)}</code>
# Server replies with <code>\000</code> (success) or <code>\101</code> (error)
Clients can easily be implemented It is possible to support both support {{Code|digest}} and {{Code|cram-md5}} authenticationin clients: If the first server response contains no colon, {{Code|cram-md5}} 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 {name} 09 {path} {input}</code>| <code>{info} \000</code>| Adds a new resource document to the opened database.
|-
| WATCHPUT| <code>\10 0C {namepath} {input}</code>| <code>{info} \000</code>| Registers the client for Puts (adds or replaces) an XML document resource in the specified eventopened database.
|-
| UNWATCHPUTBINARY| <code>\11 {name}</code>| <code>{info} \0</code>| Unregisters the client.|-| REPLACE| <code>\12 {path} {input}</code>| <code>{info} \0</code>| Replaces a resource with the specified input.|-| STORE| <code>\13 0D {path} {input}</code>| <code>{info} \000</code>| Stores Puts (adds or replaces) 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 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 [[Options#SERIALIZER{{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 contains 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 DataMetadata|XDM Meta DataMetadata]]. 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====
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 examples for 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==
In the following example, a client registers a new session and executes the [[Commands#INFO{{Command|INFO]] }} database command. Next, it creates a new query instance for the XQuery expression {{Code|1, 2+'3'}}. The query is then evaluated, 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 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 username "jack": {{Code|6A 61 63 6B 00 ►}}
* '''Client''' sends hash: md5(md5("jack:BaseX:topsecret") + "1369578179679") = "ca664a31f8deda9b71ea3e79347f6666": {{Code|63 61 36 ... 00 ►}}
* '''Server''' replies with success code: {{Code|◄ 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}}
===Session===
* Create and return session with host, port, user name username 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>
* Add a document to the current database from an input stream:<br/><code>void add(String path, InputStream input)</code>
* Replace Put a document with the specified input stream:<br/><code>void replaceput(String path, InputStream input)</code> * Store raw data at the specified path:<br/><code>void store(String path, InputStream input)</code> * Watch the specified event:<br/><code>void watch(String name, Event notifier)</code>
* Unwatch Put a binary resource at the specified eventpath:<br/><code>void unwatchputBinary(String namepath, InputStream input)</code>
* Return process information:<br/><code>String info()</code>
=Changelog=
 
;Version 8.2
 
* Removed: {{Code|WATCH}} and {{Code|UNWATCH}} command
;Version 8.0
</div>
[[Category:Developer]]
[[Category:Server]]
[[Category:API]]
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu