mirror of
https://github.com/moparisthebest/xeps
synced 2024-11-22 09:12:19 -05:00
fc8efac7b1
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@590 4b5297f7-1745-476d-ba37-a9c6900126ab
796 lines
29 KiB
XML
796 lines
29 KiB
XML
<?xml version='1.0' encoding='UTF-8'?>
|
|
<!DOCTYPE xep SYSTEM 'xep.dtd' [
|
|
<!ENTITY % ents SYSTEM "xep.ent">
|
|
%ents;
|
|
]>
|
|
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
|
|
<xep>
|
|
<header>
|
|
<title>Jabber Database Access</title>
|
|
<abstract>Expose RDBM systems directly to the jabber network</abstract>
|
|
&LEGALNOTICE;
|
|
<number>0043</number>
|
|
<status>Retracted</status>
|
|
<type>Standards Track</type>
|
|
<sig>Standards</sig>
|
|
<author>
|
|
<firstname>Justin</firstname>
|
|
<surname>Kirby</surname>
|
|
<email>justin@openaether.org</email>
|
|
<jid>zion@openaether.org</jid>
|
|
</author>
|
|
<revision>
|
|
<version>0.2</version>
|
|
<date>2003-10-20</date>
|
|
<initials>psa</initials>
|
|
<remark>At the request of the author, changed status to Retracted; interested parties should refer to <<link url="http://www.openaether.org/projects/jabber_database.html">http://www.openaether.org/projects/jabber_database.html</link>> for further information.</remark>
|
|
</revision>
|
|
<revision>
|
|
<version>0.1</version>
|
|
<date>2002-08-21</date>
|
|
<initials>jk</initials>
|
|
<remark>Initial public release</remark>
|
|
</revision>
|
|
</header>
|
|
<section1 topic='Introduction'>
|
|
<p>Accessing a RDBMS in a generic fashion is a complex and difficult
|
|
task. Consequently, this will not be an attempt to XMLize a generic
|
|
Database API or query language. Instead, it will providing a
|
|
simple mechanism for a JID to read/write data that it has access to
|
|
and specifying a model for those schemas to use in xml.</p>
|
|
|
|
<p>This document has two aims.</p>
|
|
|
|
<ol>
|
|
<li>Be able to request the available schemas</li>
|
|
<li>Perform near SQL-like data manipulation</li>
|
|
</ol>
|
|
|
|
<p>Although designed for use with an RDBMS this document is not
|
|
restricted to such uses. It may be used with any data storage
|
|
system that can be broken down to a simple table, column/row
|
|
format. for example comma delimited files.</p>
|
|
</section1>
|
|
<section1 topic='Prerequisites'>
|
|
<p>To understand the following sections of this document the reader
|
|
must be aware of the following.</p>
|
|
|
|
<section2 topic='Namespace'>
|
|
<p>The current namespace of <link>http://openaether.org/projects/jabber_database.html</link>
|
|
will be used until this becomes a jep. Once officially accepted as
|
|
a jep and approved as final by the council, it will become
|
|
<link>http://www.xmpp.org/extensions/xep-0043.html</link>.</p>
|
|
</section2>
|
|
<section2 topic='Elements'>
|
|
<ul>
|
|
<li>version - specify the version of the protocol that the client/server supports</li>
|
|
<li>database - specify the database/catalog has the following attributes:
|
|
<ul>
|
|
<li>name - name of the database/catalog</li>
|
|
<li>sql - embed native SQL queries directly</li>
|
|
<li>table - the element scopes the children into the table. has the following attributes:
|
|
<ul>
|
|
<li>name - name of the table</li>
|
|
<li>permission - what the user can do with the data</li>
|
|
<li>col - describes the column. has the following attributes
|
|
<ul>
|
|
<li>name - name of the column</li>
|
|
<li>type - SQL99 datatype of the column</li>
|
|
<li>size - size of the datatype if required</li>
|
|
<li>op - comparison operator, used only if child of where element</li>
|
|
</ul>
|
|
</li>
|
|
<li>where - scopes col elements into a 'sql-like' where clause
|
|
<ul>
|
|
<li>col - see above</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>proc - element scopes the children into a procedure has the following attributes:
|
|
<ul>
|
|
<li>name - name of the sproc</li>
|
|
<li>permission - what the user can do with the data</li>
|
|
<li>col - see above</li>
|
|
<li>result - indicated return value by running the procedure (restricted to integer)</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</section2>
|
|
<section2 topic='Data Types'>
|
|
<p>There are a limited subset of data types available:</p>
|
|
<ul>
|
|
<li>bit - a single 'bit', usually used to represent boolean values</li>
|
|
<li>tinyint - signed 8bit integer, has a range from -128 to +127</li>
|
|
<li>integer - signed 32bit integer, has a range from -2147483648 to +2147483647</li>
|
|
<li>utinyint - unsigned 8bit integer, has a range from 0 to +255</li>
|
|
<li>uinteger - usigned 32bit integer, has a range from 0 to +4294967296</li>
|
|
<li>float - allowed values are -3.402823466E+38 to
|
|
-1.175494351E-38, 0, and 1.175494351E-38 to 3.402823466E+38 (can NOT be unsigned)</li>
|
|
<li>numeric - unlimited size (some databases constrain this though)</li>
|
|
<li>date - resolution is one day. acceptable ranges vary (TODO: constrain minimal range to something)</li>
|
|
<li>datetime - a date and time combination (often has range dependencies)</li>
|
|
<li>timestamp - a datetime used most often to record events</li>
|
|
<li>time - a time in the format HH:MM:SS (TODO: specify valid range)</li>
|
|
<li>char - an unsigned byte representing a single character (ASCII)</li>
|
|
<li>vchar - a variable width char</li>
|
|
<li>text - an extremely large chunk of text</li>
|
|
<li>blob - an extremely large chunk of binary data (encode in MIME)</li>
|
|
</ul>
|
|
</section2>
|
|
<section2 topic='Assumed Database Setup'>
|
|
<p>All SQL/RDBMS units will be scoped in the xml hierarchy:</p>
|
|
|
|
<code>
|
|
<database>
|
|
<table>
|
|
<col/>
|
|
</table>
|
|
</database>
|
|
</code>
|
|
|
|
<p>All examples will assume the existence of the following rdbms setup. A
|
|
database named 'testdb' with tables created with following SQL
|
|
script:</p>
|
|
|
|
<code>
|
|
create table tbl_one
|
|
(
|
|
a_int int,
|
|
a_float float,
|
|
a_char char(10)
|
|
)
|
|
create table tbl_two
|
|
(
|
|
a_date datetime,
|
|
a_numeric numeric(9,3)
|
|
)
|
|
</code>
|
|
</section2>
|
|
</section1>
|
|
<section1 topic='Usage'>
|
|
<section2 topic='Requesting Schemas'>
|
|
<example caption='A simple schema request'>
|
|
<iq id="001" to="db.host" type="get">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>This is a simple request to discover what tables/procedures
|
|
exist on the database testdb. And what permissions are available
|
|
to the user. All schema requests will respond within the scope that
|
|
was asked for. This is to prevent unnecessary data from flooding
|
|
the network. So the response for the above request would look
|
|
something like:</p>
|
|
|
|
<example caption='Response to a schema request'>
|
|
<iq id="001" type="result" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one" permission="both"/>
|
|
<table name="tbl_two" permission="read"/>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>The response is scoped to only the 'children' of the request.
|
|
Since the request was for the testdb database, only the tables
|
|
within that database were returned in the result. The reason for
|
|
the limitation is to prevent excessively large packets from filling
|
|
the network from large schemas.</p>
|
|
|
|
<p>The response indicates that the user has both read and write
|
|
permissions on the table 'tbl_one' and only read permissions on
|
|
the table 'tbl_two'. Consequently, the user may only perform get
|
|
requests on 'tbl_two'.</p>
|
|
|
|
<example caption='Request detailed table schema'>
|
|
<iq id="002" type="get" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one"/>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>The response would look like:</p>
|
|
|
|
<example caption='Response to detailed request'>
|
|
<iq id="002" type="result" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one" permission="both">
|
|
<col name="a_int" type="int"/>
|
|
<col name="a_float" type="float"/>
|
|
<col name="a_char" type="char" size="10"/>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>The schema response for tbl_one is quite intuitive. Three
|
|
columns exist, one called a_int of type int (integer), another
|
|
a_float of type float and a third called a_char of type char
|
|
with a size of ten characters.</p>
|
|
|
|
|
|
</section2>
|
|
|
|
<section2 topic='Manipulating Data'>
|
|
|
|
<p>Manipulation of data (select, insert, update, delete) will
|
|
definitely not be elegant or easy. SQL allows for some fairly
|
|
complex queries on any fully functional RDBMS. Consequently,
|
|
the data manipulation will be relatively limited since it is
|
|
not a goal to translate SQL into xml.</p>
|
|
|
|
<section3 topic='Selects'>
|
|
<p>To indicate a select like query, specify an <iq> of
|
|
type get. The table that the query is to be performed against
|
|
must be specified. The columns that are to be returned in
|
|
the result set must be scoped within the relative table.
|
|
Any attribute on the <col> element besides name will be
|
|
ignored. e.g. it is not required nor recommended to specify
|
|
the data types or the sizes while performing a get.</p>
|
|
|
|
<example caption='Basic select'>
|
|
<iq id="003" type="get" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_int"/>
|
|
<col name="a_float"/>
|
|
<col name="a_char"/>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
|
|
SQL Syntax:
|
|
select a_int, a_float, a_char
|
|
from tbl_one
|
|
</example>
|
|
|
|
<p>It is also possible to specify a limit on the number of rows
|
|
returned in the result set by specifying a value for the limit
|
|
attribute.</p>
|
|
|
|
<example caption='Basic select with limit'>
|
|
<iq id="003" type="get" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one" limit="2">
|
|
<col name="a_int"/>
|
|
<col name="a_float"/>
|
|
<col name="a_char"/>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>In this case a limit of two rows will be returned in the result set.</p>
|
|
|
|
<p> The result set which is returned will contain all the rows
|
|
that met the criteria of the select. There is no schema
|
|
information beyond the column names included in the result set.
|
|
Each 'row' in the result set is scoped within the corresponding
|
|
<table> element. This allows for queries on multiple
|
|
tables to be used in one <iq> packet.</p>
|
|
|
|
<example caption='Response to basic select'>
|
|
<iq id="003" type="result" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_int">1234</col>
|
|
<col name="a_float">123.45</col>
|
|
<col name="a_char">onetwothre</col>
|
|
</table>
|
|
<table name="tbl_one">
|
|
<col name="a_int">2345</col>
|
|
<col name="a_float">234.56</col>
|
|
<col name="a_char">twothreefo</col>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
</section3>
|
|
|
|
<section3 topic='Constraining Result Sets'>
|
|
<p>It would be impractical to request the entire contents of the
|
|
table every time you needed one row or a subset of the data. You
|
|
can constrain the result set by specifying a where clause.</p>
|
|
|
|
<example caption='Select with constraints'>
|
|
<iq id="004" type="get" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_int"/>
|
|
<col name="a_float"/>
|
|
<col name="a_char"/>
|
|
<where>
|
|
<col name="a_int" op="eq">1234</col>
|
|
<col name="a_float" op="lt" conj="and">200.00</col>
|
|
</where>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
|
|
SQL Syntax:
|
|
select a_int, a_float, a_char from tbl_one
|
|
where a_int = 1234 and a_float < 200.00
|
|
</example>
|
|
|
|
<p>Attributes only used in the <col> element within a
|
|
<where> element are the op (for operator) and conj for
|
|
(conjunction). The op is used for comparison operators such
|
|
as <, >, =, <>, <=, >=</p>
|
|
|
|
<ul>
|
|
<li>eq - equivalent =</li>
|
|
<li>neq - not-equivalent <></li>
|
|
<li>lt - less than <</li>
|
|
<li>gt - greater than ></li>
|
|
<li>let - less than or equivalent <=</li>
|
|
<li>get - greater than or equivalent >=</li>
|
|
<li>null - IS NULL (the column is null in the database sense of the word)</li>
|
|
</ul>
|
|
|
|
<p>The conjuction attribute is used to combined constraints in the where clause</p>
|
|
|
|
<ul>
|
|
<li>not - to negate a result</li>
|
|
<li>or - logical OR ||</li>
|
|
<li>and - logical AND &&</li>
|
|
</ul>
|
|
|
|
<p><strong>Result</strong></p>
|
|
|
|
<example caption='Response to select with constraints'>
|
|
<iq id="003" type="result" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_int">1234</col>
|
|
<col name="a_float">123.45</col>
|
|
<col name="a_char">onetwothre</col>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
</section3>
|
|
|
|
<section3 topic='Inserts'>
|
|
<p>Inserting or altering the stored data in anyway requires
|
|
setting the type attribute to a value of set. This indicates
|
|
that the user wants to perform a 'insert/update'. The
|
|
differentiating factor between an insert and an update operation
|
|
is whether a <where> element is used. If there is no
|
|
<where> element then it must be interpreted as an insert.
|
|
If a <where> element does exist, then it must be
|
|
interpreted as an update.</p>
|
|
|
|
<example caption='Inserting data'>
|
|
<iq id="004" type="set" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_int">3456</col>
|
|
<col name="a_float">345.67</col>
|
|
<col name="a_char">threefour</col>
|
|
</table>
|
|
<table name="tbl_two">
|
|
<col name="a_date">02/16/2002</col>
|
|
<col name="a_numeric">123456789123.123</col>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
|
|
SQL syntax:
|
|
insert tbl_one (a_int, a_float,a_char)VALUES(3456, 345.67, 'threefour')
|
|
insert tbl_two (a_date, a_numeric) VALUES('02/16/2002', 123456789123.123)
|
|
</example>
|
|
|
|
<p><strong>Result</strong></p>
|
|
|
|
<p> If there is no result set for the query, as in an update,
|
|
insert, delete, then the response must indicate success or
|
|
failure within the <table> element scope. An empty
|
|
<table> element indicates success, and a <table>
|
|
element containing an <error> element indicates a failure.</p>
|
|
|
|
<example caption='Response to data insert'>
|
|
<iq id="004" type="result" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one"/>
|
|
<table name="tbl_two">
|
|
<error code="380">permission denied on table</error>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p> The insert into tbl_one succeeded since the response has an
|
|
empty <table> element. However, the insert into tbl_two
|
|
failed with a permission denied error. Which is indicated with a
|
|
non-empty <table> element.</p>
|
|
</section3>
|
|
|
|
<section3 topic='Updates'>
|
|
|
|
<p> As stated previously, if the type attribute has a value of
|
|
set and a <where> element exists, then it must be interpreted as an update.</p>
|
|
|
|
<example caption='Updating'>
|
|
<iq id="005" type="set" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<col name="a_char">aaaaaaaaaa</col>
|
|
<where>
|
|
<col name=c"a_int">1234</col>
|
|
</where>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
|
|
SQL Syntax:
|
|
update tbl_one
|
|
set a_char = 'aaaaaaaaaa'
|
|
where a_int = 1234
|
|
</example>
|
|
|
|
<p><strong>Result</strong></p>
|
|
|
|
<p> Again, if there is no result set returned by the query, then
|
|
success or failure must be indicated.</p>
|
|
|
|
<example caption='Response to update'>
|
|
<iq id="005" type="result" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one"/>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
</section3>
|
|
|
|
<section3 topic='Deletes'>
|
|
|
|
<p> If the type attribute has a value of set and there are no
|
|
<col> elements scoped within the <table> element,
|
|
then the query must be interpreted as a delete.</p>
|
|
|
|
<example caption='Simple delete'>
|
|
<iq id="006" type="set" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one">
|
|
<where>
|
|
<col name="a_int" op="eq">1234</col>
|
|
</where>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
|
|
SQL Syntax:
|
|
delete from tbl_one where a_int = 1234
|
|
</example>
|
|
|
|
<p><strong>Result</strong></p>
|
|
|
|
<p>Again, if a result set is not generated by a query, then
|
|
success or failure must be indicated by the <table> element</p>
|
|
|
|
<example caption='Response to delete'>
|
|
<iq id="006" type="result" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one"/>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
</section3>
|
|
</section2>
|
|
<section2 topic='Procedures'>
|
|
|
|
<p> Procedures, or stored procedures <note>Apparently procedures
|
|
are not as common in RDBMS as I thought. Postgres and MySQL have
|
|
functions, but not procedures. So until I, or someone else,
|
|
researches this issue this feature is on hold.</note>
|
|
, are often handy to make frequently used sql queries execute faster.
|
|
These are simply queries stored in a precompiled form and given a
|
|
name with a list of parameters. Each RDBMS handles procedures
|
|
differently, but the common characteristics are that they are
|
|
stored server side and have in/out parameters.</p>
|
|
|
|
<p> The <proc> element will be used to indicate a procedure.
|
|
It has similar characteristics to the <table> element. The
|
|
core differences are that the <col> elements have permissions
|
|
and a <result> element can be used to indicate the value
|
|
returned by the procedure.</p>
|
|
|
|
<p> The permission attribute on a <col> element is used to
|
|
indicate whether the parameter is in (read), out (write) or in/out (both). </p>
|
|
|
|
<p> The only result set acceptable from a procedure is that of the
|
|
parameters or <col> element. If the procedure produces a
|
|
result set outside of the parameters this should be ignored.</p>
|
|
|
|
</section2>
|
|
<section2 topic='Errors'>
|
|
|
|
<p> The server must be able to let the client know when an error
|
|
occurs, instead of just being silent.</p>
|
|
|
|
<table caption='Error Codes'>
|
|
<tr>
|
|
<th>Code</th>
|
|
<th>Message</th>
|
|
<th>Description</th>
|
|
</tr>
|
|
<tr>
|
|
<td>399</td>
|
|
<td>Invalid Database Name</td>
|
|
<td>Returned when the client has requested information from a
|
|
database which does not exist according to the component.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>398</td>
|
|
<td>Invalid Table Name</td>
|
|
<td>Returned when the client has requested information from a
|
|
table/procedure which does not exist according to the component.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>397</td>
|
|
<td>Invalid Column Name</td>
|
|
<td>Returned when the client has requested information from a
|
|
column which does not exist according to the component.</td>
|
|
</tr>
|
|
<tr>
|
|
<td>380</td>
|
|
<td>Permission Denied on Table</td>
|
|
<td>Returned when the requested action is not allowed for the
|
|
user on the table</td>
|
|
</tr>
|
|
<tr>
|
|
<td>401</td>
|
|
<td>Access Denied</td>
|
|
<td>Returned when the user does not have permission to use the
|
|
component.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>If the user requests an action on a table which they do not have
|
|
permission to do the following should be returned</p>
|
|
|
|
<example caption='Permission denied error'>
|
|
<iq id="004" type="error" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_two">
|
|
<error code="380">permission denied on table</error>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p>If the user is not allowed to access the component the following should be returned</p>
|
|
|
|
<example caption='General access denied'>
|
|
<iq id="004" type="error" from="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<error code="401">Access Denied</error>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
</section2>
|
|
<section2 topic='Optional Features'>
|
|
<p> There are requirements which can be provided by other jabber
|
|
components/namespaces, namely the jabber:iq:browse namespace
|
|
in-place of Version Negotiation. Due to the inherent limitations
|
|
of the above data retrieval mechanisms more sophisticated querying
|
|
techniques might be desired. The <query> element will extend
|
|
the functionality </p>
|
|
|
|
<section3 topic='Embedded SQL'>
|
|
<p> The abilities described in the Basics section are just that,
|
|
basic. To provide more flexibility and allow for the full power
|
|
of SQL without xmlifying everything, a <sql> element may
|
|
be implemented to provide this feature.</p>
|
|
|
|
<p> The <sql> element must be scoped within the <database> element.</p>
|
|
|
|
<example caption='Embedded sql query'>
|
|
<iq id="007" type="get" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<sql> select a_int, a_float from tbl_one </sql>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p><strong>Result</strong></p>
|
|
|
|
<example caption='Response to embedded query'>
|
|
<iq id="007" type="result" to="db.host">
|
|
<database
|
|
name="testdb"
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
<table name="tbl_one" permission="both">
|
|
<col name="a_int" type="integer"/>
|
|
<col name="a_float" type="float"/>
|
|
</table>
|
|
<table name="tbl_one">
|
|
<col name="a_int">1234</col>
|
|
<col name="a_float">123.45</col>
|
|
</table>
|
|
<table name="tbl_one">
|
|
<col name="a_int">2345</col>
|
|
<col name="a_float">234.56</col>
|
|
</table>
|
|
</database>
|
|
</iq>
|
|
</example>
|
|
|
|
<p> Since SQL is so flexible, the result set schema is not known
|
|
until it is returned as a result of the query. Consequently, it
|
|
must be sent as the first 'row' of the returned result. Each
|
|
following row will be the actual data queried for.</p>
|
|
|
|
<p> If multiple tables are used within one SQL statement, then
|
|
then name attribute within the <table> element can not be
|
|
accurately denoted with a single table name. The best way to deal
|
|
with this situation is to simply use a unique identifier within
|
|
the scope of the <database> element. This will allow for
|
|
multiple <sql> results to be scoped within the same result.</p>
|
|
|
|
</section3>
|
|
<section3 topic='Version Negotiation'>
|
|
|
|
<p>It is expected that this protocol will grow and be extended
|
|
to meet various demands. Therefore, version
|
|
negotiation<note>Version Negotiation is being killed since browsing, feature
|
|
negotiation, or disco will be able to perform this function,
|
|
however it might be useful as an optional feature for clients
|
|
that don't implement these yet, especially considering none
|
|
of these have been standardized.</note> will be
|
|
incorporated up front.</p>
|
|
|
|
<p>When the connection initiator, client end-user or
|
|
server/transport, starts a session, it must first send
|
|
the version number it expects to use, otherwise, behavior
|
|
is undefined.</p>
|
|
|
|
<code>
|
|
<iq id="000" type="get" to="db.host">
|
|
<database
|
|
xmlns="http://openaether.org/projects/jabber_database.html">
|
|
<version>0.1</version>
|
|
</database>
|
|
</iq>
|
|
</code>
|
|
|
|
<p>Three responses are possible from the server.</p>
|
|
<ol>
|
|
<li>
|
|
<p>It supports that version number and responds with:</p>
|
|
<code>
|
|
<iq id="000" type="result" from="db.host">
|
|
<database
|
|
xmlns="http://openaether.org/projects/jabber_database.html">
|
|
<version>0.1</version>
|
|
</database>
|
|
</iq>
|
|
</code>
|
|
<p>The type of 'result' indicates that the version request was
|
|
successful and if the client is satisfied with the version number,
|
|
may continue with schema requests or whatever.</p></li>
|
|
|
|
<li><p>It does not support that version number and responds with:</p>
|
|
<code>
|
|
<iq id="000" type="error" from="db.host">
|
|
<database
|
|
xmlns="http://openaether.org/projects/jabber_database.html"/>
|
|
</iq>
|
|
</code>
|
|
<p>The type of 'error' indicates a failure in conforming to the
|
|
desired version number. The server may optionally send an
|
|
alternative option.</p>
|
|
<code>
|
|
<iq id="000" type="error" from="db.host">
|
|
<database
|
|
xmlns="http://openaether.org/projects/jabber_database.html">
|
|
<version>0.2</version>
|
|
</database>
|
|
</iq>
|
|
</code></li>
|
|
<li>If the server has no idea what the client is talking
|
|
about it should send the appropriate Jabber error code.</li>
|
|
</ol>
|
|
</section3>
|
|
</section2>
|
|
</section1>
|
|
|
|
<section1 topic='Limitations'>
|
|
<ol>
|
|
<li>No joins, roll ups, cubes</li>
|
|
<li>Views are not differentiated from tables</li>
|
|
<li>provides basic sql-like functionality only</li>
|
|
<li>Utilizes <em>lowest common denominator</em> approach</li>
|
|
</ol>
|
|
</section1>
|
|
|
|
<section1 topic='Todos'>
|
|
<ul>
|
|
<li>define procedures; what they are and how they work</li>
|
|
<li>determine value of adding administration features</li>
|
|
</ul>
|
|
</section1>
|
|
|
|
<section1 topic='Thanks'>
|
|
<p>Thanks to Russell Davis (ukscone) for fine tuning the layout and wording of this jep. It would probably have been unreadable if it wasn't for him.</p>
|
|
</section1>
|
|
|
|
<section1 topic='DTD and Schema'>
|
|
<section2 topic='DTD'>
|
|
<code>
|
|
<!ELEMENT version (#PCDATA)>
|
|
<!ELEMENT error (#PCDATA)>
|
|
<!ELEMENT sql(#PCDATA)>
|
|
<!ELEMENT database (table | sproc | sql | error)*>
|
|
<!ELEMENT table (col | where | error)*>
|
|
<!ELEMENT where (col+)>
|
|
<!ELEMENT col (#PCDATA)>
|
|
<!ELEMENT proc(col | result | error)*>
|
|
<!ELEMENT result (#PCDATA)>
|
|
<!ATTLIST error code CDATA #IMPLIED>
|
|
<!ATTLIST database name CDATA #IMPLIED>
|
|
<!ATTLIST table
|
|
name CDATA #IMPLIED
|
|
permission (read | write | both) #IMPLIED
|
|
limit CDATA #IMPLIED
|
|
>
|
|
<!ATTLIST proc name CDATA #IMPLIED>
|
|
<!ATTLIST col
|
|
name CDATA #IMPLIED
|
|
size CDATA #IMPLIED
|
|
op (eq | neq | lt | gt | let | get | null) #IMPLIED
|
|
conj (not | or | and ) #IMPLIED
|
|
permission (read | write | both) #IMPLIED
|
|
type (bit | tinyint | integer | utinyint | uinteger |
|
|
float | numeric | date | datetime | timestamp |
|
|
time | char | vchar | text | blob) #IMPLIED
|
|
>
|
|
</code>
|
|
</section2>
|
|
<section2 topic='Schema'>
|
|
<p><strong>Anyone care to do this?</strong></p>
|
|
</section2>
|
|
</section1>
|
|
</xep>
|