XStreamDB is a native XML database for storing, retrieving and manipulating XML documents.
This user guide describes the four main components of the XStreamDB package:
This guide also provides introductions to:
This guide does not cover the XdbWeb application - see the ReadMe for a link. XdbWeb is a set of utility servlets that allow you to work with XStreamDB resources using http.
The XStreamDB server is the heart of the XStreamDB system.
The server is started as a process under any operating system that supports Java 1.4.
Client software connects to the server using the XDB client libraries, as defined in the XDB API. The client libraries connect to a server using the host address and port that the server is listening on, as provided or configured by the client software. If a client uses a host name instead of an IP number, then a DNS must be available to resolve name to IP number. The default port for the server is 1223. However, it can be changed manually by editing the XDBServer.prop file located in the Server/conf directory.
More information on Server properties is contained in the "Other" section of the Reference Manual . Detailed installation instructions can be found in the InstallDeploy manual, including a discussion on how to install the server as a Windows service.
The easiest way to start and stop the Server is by using the shortcuts "XStreamDB Server Start" and "XStreamDB Server Stop". In Windows, these shortcuts are found on the Desktop or in the Start menu. The server can also be started or stopped using the runServer command file located in the folder {XStreamDB Home}/Server/bin.
Use the "XStreamDB Server Stop" shortcut or runServer stop on the command line to stop the server. This avoids database recovery when the server is restarted, and ensures that no users have active transactions before shutting down the server. Killing the process from the operating system is also possible. However, database recovery will be invoked the first time a database is accessed after a subsequent start of the XStreamDB server process.
Database recovery can be quite time intensive when indexes exist and have to be rebuilt. Also, any transactions that were in progress when the server was stopped or terminated will be automatically rolled back on startup.
The XStreamDB Explorer is a GUI application for configuring and managing an XStreamDB server, the data it contains (including ancillary objects like schemas, triggers, indexes and modules), the users who have access to it, and setting and enforcing permissions and security. Additionally, the Explorer provides an interface for writing and executing XQuery statements on a server.
Use the Explorer for the following tasks:
Start the Explorer by clicking the "XStreamDB Explorer" shortcut. In Windows, this shortcut icon is on the Windows Desktop or Start menu. Alternatively, run explorer.bat in the folder {XStreamDBHome}/Client/Explorer.
From the Configuration tab you can create and manage XStreamDB objects, manage security, and perform backup and restore:
Databases can be created, modified and deleted from the Configuration tab. A list of databases can be seen by clicking on the DATABASES icon in the left pane of the Configuration tab. If you right click on one of the database names, a context menu will list the available actions for that database. Database actions can include:
To create a new database, right click on the DATABASES icon in the left pane of the Configuration tab to display the context menu, then select New Database . A New Database dialog box opens. Enter the name of the new database, then click OK to create the database. When complete, a new database icon with the new database name will be displayed under the DATABASES icon. Depending upon your permission settings, you may not be allowed to perform this operation.
To delete a database, right click on its Database icon in the left pane of the Configuration tab to display the context menu, then select Delete . A confirmation dialog box opens. Click OK to proceed or Cancel to abort. The selected database and all objects associated with it will be deleted. Depending upon your permission settings, you may not be allowed to perform this operation.
Refresh updates your local view of the database configuration with the most up to date information from the XStreamDB server. To refresh your view, right click on the DATABASES icon in the left pane of the Configuration tab to display the context menu, then select Refresh .
Note : A local Explorer configuration view can become out of date when other users modify the configuration, or when you execute statements (in the Statement tab) like CREATE ROOT to modify the configuration directly. Also, certain parts of the Resource subsystem may also add system roots that are not visible until you do a refresh of DATABASES .
A Root is a named collection of XML documents stored in the database. Roots are typically used to organize groups of related documents. A single database may have as many different Roots as you require in order to manage your documents.
Roots can have two other objects associated with them: Indexes and Schemas. Indexes are used automatically where they exist to speed up data retrieval during queries. Schemas, when associated with a root, restrict the use of that root to documents which conform to the specified schema definition. This provides a first level integrity check on documents that are being inserted or updated.
Right click on a root in the left pane of the Configuration tab to display its context menu.
Choose from the following list, actions you can perform on the selected root:
Indexes and triggers for a root are indicated in the two sub trees below the root name.
Right click on one of these subtree icons to display a context menu with the following actions:
To create a new root in a database, right click on the Database icon in the left pane of the Configuration tab to display the context menu, then select New Root . The new root dialog box will be displayed. Enter the name of the new root, then click OK to physically create the root. When complete, a new root icon with the new root name will be displayed under the selected database. Depending upon your permission settings, you may not be allowed to perform this operation.
To delete a root, right click on its Root icon in the left pane of the Configuration tab to display the context menu, then click Delete Root . A confirmation dialog box opens. Click Yes to delete the selected root and all objects associated with it, or No to abort. Depending upon your permission settings, you may not be allowed to perform this operation.
To associate a schema with a root, right click on the Root icon in the left pane of the Configuration tab to display the context menu, then select Schema . The root properties dialog opens at the Schema tab. The Schema tab displays the full schema path of the currently attached schema (if any) for the selected root, and gives you the choice of either attaching or removing a schema.
If you click Attach Schema , a further dialog (see below) appears, listing all schemas in the XStreamDB Schema Repository in the left pane. Clicking on a schema will list all root elements in that schema in the right pane. Selecting one of the root elements will display the full schema path in the text field at the bottom of the dialog. Click OK to attach the schema to the selected root.
Note: All documents in the root must conform to the selected schema definition in order to successfully complete this operation.
Clicking on Remove Schema causes the schema to no longer be associated with the selected root.
Note: Removing a schema from a root does not delete the schema from the XStreamDB Schema Repository. Refer to Configuring_Schemas for instructions on adding and removing schemas.
If you right click on the desired Root icon in the Configuration tab, the popup menu will have an Add Documents entry. Clicking on Add Documents displays the Open File dialog window, which is used to select the documents, or XML files, you would like to insert into the selected Root. You may select a single document, multiple documents or all documents within a folder. Also, with a folder selection, you have the option to recurse into all subfolders by selecting the checkbox at the bottom of the file dialog.
Note: If you have a resource defined for this root, this dialog does not insert the resource also. This is covered in the section on Working with Resources below.
Indexes are created on roots to improve the performance of the XStreamDB XQuery Engine for queries on documents in those roots. They can be created and deleted, but indexes are never accessed by a client directly. Indexes are used automatically by the XQuery Engine wherever possible. Note: Depending upon your permission settings, you may not be allowed to create and delete indexes.
XStreamDB supports two types of indexes: value and full text. A value index is a simple index based on a particular element or attribute value. The full text index is much broader in scope, as it indexes all element and attribute text. Both types apply to all the documents held under a single root upon which the index is defined.
To create an index on a Root, right click on the Index icon under the selected Root in the left pane of the Configuration tab. Select New Index from the context menu. A sub-menu is displayed with the choice of either Value or Full Text .
Creating a Value Index
To create a value index, select Value to open the new value index dialog.
If a schema has been associated with the selected root, the schema tree for that root will be displayed in the dialog. Clicking on any leaf node within the schema tree will create the XPath expression and display it in the XPath textfield.
Enter the name for the new index and, if no schema tree is displayed, the XPath expression specifying the document node to be indexed. Note: The XPath must end with /data() for it to be considered a valid path for indexing purposes.
Indicate that this index is unique by selecting the Unique Index checkbox.
Click OK to index all the documents held by the associated root according to the Indexing XPath provided.
Creating a Full Text Index
To create a full text index, select Full Text from the sub-menu (shown above). This will immediately create the full text index, with the name BdsFtIdx, on the selected root. Note: A root can only have a single full text index.
To delete an index, right click on the specified Index icon in the left pane of the Configuration tab to display the context menu, then select Delete Index . A confirmation dialog box opens. Click OK to delete the index or Cancel to abort.
A trigger is an XQuery statement that is executed either BEFORE or AFTER a document is INSERTED, UPDATED or DELETED in a Root.
Triggers are often used to maintain referential integrity in the database, or for audit logging. For example, you could create a trigger that automatically validates the contents of a document before it is inserted into a root. A trigger may also execute stored functions contained in a module.
To create a trigger on a Root, right click on the Trigger icon under the selected Root in the left pane of the Configuration tab to display the context menu, then select New Trigger . The new Trigger dialog opens.
Enter the Trigger Name and the XQuery Statement to be executed when the specified action occurs. The new trigger dialog automatically includes an example XQuery statement for the trigger, which you can overright. Also note that the trigger's XQuery statement must use the LET and RETURN syntax as shown in the example.
Enter the Action, Timing, Priority and Prologue.
namespace pre = "http://bluestream.com/myns"
Click OK to create the trigger on the root. Depending upon your permission settings, you may not be allowed to perform this operation.
To delete a trigger, right click on its Trigger icon in the left pane of the Configuration tab to display the context menu, then select Delete Trigger . A confirmation dialog box opens. Click OK to delete the trigger or Cancel to abort. Depending upon your permission settings, you may not be allowed to perform this operation.
A module is either a library module or a main module. A library module is a collection of XQuery functions collected together into a module. A main module is a single XQuery expression. You can create, modify and delete libraries of functions. Depending upon your permission settings, you may not be allowed to perform any of these operations.
To create a module, right click on the MODULES icon under the Server icon in the left pane of the Configuration tab to display the context menu, then select New Module . The new Module dialog opens.
Enter the module definition in the large text box. A module definition consists of text that names the module, defines the namespace, and defines all the functions contained in the module. An example is preloaded in the dialog box as follows:
Example:
Create Module "MyModule"
namespace pre = "http://bluestream.com/myns"
DEFINE FUNCTION square(element $val) returns xsd:decimal
{
$val/data() * $val/data()
}
In this example, the new module name is "MyModule", its namespace is "http://bluestream.com/myns", and one function called "square" is defined. Any number of functions can be contained within a single module.
Click OK to create the new module, or Cancel to abort. When a new module is created, the functions it contains are loaded into cache, and prepared for immediate use.
To view the list of modules, select the MODULES icon in the left pane of the Configuration tab. A table list of the modules is displayed in the right pane.
To delete a module, first click on the MODULES icon in the left pane of the Configuration tab to display the list of modules. Then, right click on the module name you wish to delete from the list of modules in the right pane, displaying the context menu, and select Delete Module . A confirmation dialog box opens. Click Yes to delete the module or No to cancel.
XStreamDB includes a backup and restore feature. The backup format is a zip file containing fully expanded XML and binary files. This feature can be accessed by executing queries using the XStreamDB XQuery Engine or through the Explorer. It is recommended that the scheduled backup feature be used from the Explorer for anyone serious about regular backup. The Explorer can also be used to perform partial or full server backups and partial or full server restores. When you do a full server backup and restore, it includes the schemas, users, permission settings, databases, roots and all resource objects. Note : You must be the administrator to perform any backup or restore operation.
Backup and restore can be performed on the following objects:
To perform a backup, right click on either the server name (for a full server backup), a database icon (for a database backup) or a root icon (for a root backup) and select Backup . A further popup menu will be displayed with a choice of either Backup Now or ScheduleBackup . The screenshot below shows the selection of Backup by right clicking on the server icon called "MyServer".
Immediate Backup
To perform an immediate backup, select Backup Now . A prompt will be displayed where the name of the backup file can be entered. You can alternatively choose to use the default filename, which consists of a filename based on the date and time the backup operation was performed. Note: If the backup file specifies a file that already exists, it is overwritten.
Scheduled Backup
To schedule a backup, select Schedule Backup . A dialog box will be displayed allowing you to schedule a new backup, and edit or delete an existing backup. The screenshot below shows this dialog box with two existing scheduled backups.
To schedule a new backup, click the Add button and a second dialog box will be displayed. From this dialog box, you have a choice between daily or weekly intervals. Make all necessary selections and click OK .
Restoring from a previous backup is done by right clicking on the Server icon within the configuration tab. A dialog (below left) appears that requires a:
Server Restore Dialog
|
Backup Archive to Restore
|
Server Restore Dialog
|
Archive Source List
|
A schema must be created externally before it can be added to the Schemas Repository in XStreamDB. Once the schema has been added to the repository, it can be viewed, deleted or attached to a root. Attaching a schema to a root enforces that all XML documents within that root comply to the grammatical rules of the schema. Note: Depending upon your permission settings, you may not be allowed to perform any operations associated with schemas. In addition, you may not be allowed to view any schemas
If you right click on the SCHEMAS icon, a popup context menu lists the available actions as follows:
Once a schema has been added to the repository, you can delete it by right clicking on the Schema icon and selecting Delete Schema from the popup context menu. To view a schema's global elements and their structure, you can simply click on the Schema icon.
To add a schema to the schemas repository, right click on the Schema icon in the left pane of the Configuration tab, then select Add Schema from the context menu. Select the XML schema or DTD from the file open dialog box, and click OK .
It is recommended that if you are adding a group of related schemas, you create a folder (see below) to contain those schemas. Any schemas imported or included by the schema either directly or indirectly will be added to the schema respository automatically.
To add a schema folder, right click on the SCHEMAS icon or a schemas folder in the left pane of the Configuration tab, displaying the context menu. Select Add Folder to display the add folder dialog. Enter a name for the new folder and click OK to create the new folder under the selected node in the tree, or click Cancel to abort.
Using folders is convenient, and sometimes necessary, when adding industry standard schema file sets such as the OAGIS schemas.
For example: in OAGIS schemas, there are 60 schema files that are linked together (in that they include each other). Since these includes use relative folder references, it is necessary that if you are adding a schema from the BODs directory, you must have already created a BODs directory, since some relative references go up two levels ../../ and then descend into another folder. Included or imported schemas and their folders are created automatically, if necesssary. However, going up two levels from the root of schemas is not possible.
To delete a folder, right click on the folder name and select Delete Folder from the context menu. This will delete the folder, all sub folders and all schemas contained in that subtree.
To delete all schemas in the schema repository, right click on the SCHEMAS icon in the left pane of the Configuration tab to display the context menu, and select Delete All Schemas . A dialog box is displayed to confirm deletion. Click OK to confirm deletion of all schemas and schema folders in the schema repository, or click Cancel to abort. If any of the schemas being deleted are in use (attached to a root), then they cannot be deleted.
To delete a schema, right click on its schema icon in the left pane of the Configuration tab to display the context menu, and select Delete Schema. A dialog box is displayed to confirm deletion. Click OK to confirm or Cancel to abort. If the schema is in use (attached to a root), it cannot be deleted.
It is often necessary to refresh the schema view to see schemas added by other users to the schema repository. To refresh the view of schemas, right click on the SCHEMAS icon in the left pane of the Configuration tab to display the context menu, and select Refresh .
All schemas that are added are automatically made into XStreamDB resources under the "SysData/SysSchema" parent. This allows them to be accessed from the XStreamDB WebDAV driver or XdbWeb.
If you left click on any schema under the SCHEMAS icon, or any schema under any schema folder, it will be displayed in two sections in the right pane of the Configuration tab.
The left section lists all the root elements under the selected schema. By clicking on a root element, it will be displayed in tree format in the right section. The screenshot below shows a display of the "Book.xsd:book" schema.
The XStreamDB security system is concerned with authentication and authorization. Authentication is the validation of a user's credentials before that user can access the XStreamDB server. In the Explorer application, this is evidenced by the user logon dialog which is displayed at the time the Explorer is started. Authorization is established by determining permissions from resource access control lists (ACLs). For a detailed description of the XStreamDB security system, see the Security subsection of the Reference Guide. Note: You must have the required permissions to perform any security operations.
To display users in the XStreamDB server, left click on the USERS icon in the left pane of the Configuration tab. The users will be displayed in a table on the right pane of the Configuration tab.
To create a new user, right click on the USERS icon in the left pane of the Configuration tab, then select New User from the context menu. A dialog box will be displayed. Complete the required information and click OK to continue or Cancel to abort. If Ok was selected, the new user will be displayed in the table on the right pane of the Configuration tab.
To modify a user password, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Change Password . Enter the new password in the fields provided and select OK to continue or Cancel to abort.
To add a user as a member of a group, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Member of . A dialog box will be displayed listing all groups the user is currently a member of.
Selecting the Add button will display a further dialog box listing all groups in the XStreamDB Server.
Select which groups the user is to be made a member of, click Add , then click Ok . This will return you to the original dialog. Select Ok to continue or Cancel to abort.
To delete an existing user, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Delete User . A confirmation dialog box opens. Click Yes to proceed or No to abort.
To display groups in the XStreamDB server, left click on the GROUPS icon in the left pane of the Configuration tab. The groups will be displayed in a table on the right pane of the Configuration tab.
On the Configuration tab, under the Server icon, there is a GROUPS icon. If you click on the Groups icon, the popup menu will include an entry for New Group. Clicking on the New Group menu selection will display a dialog in which the group can be defined as well as the user members of the group.
To add a member to a group, display the groups in the right pane of the Configuration tab, as described above. Right click on the group and select Members . A dialog box (below left) will be displayed listing all members within the selected group. Selecting the Add button will display a further dialog box (below right) listing all users in the XStreamDB Server. Select which users are to be added as members of the group, click Add , then click Ok . This will return you to the original dialog. Select Ok to continue or Cancel to abort.
|
|
To delete an existing group, display the groups in the right pane of the Configuration tab, as described above. Right click on the group and select Delete Group . A confirmation dialog box opens. Click Yes to proceed or No to abort.
Permissions are used to control user access to resources. There are five types of permissions that can be applied to a single resource:
The XStreamDB Explorer allows these permissions to be applied at different levels . Permission settings may be overridden at any lower level. Permission levels currently supported from most broad to most specific are:
The permissions dialog is accessed by right clicking on an object from one of the level categories above, for example Database or Root. From the right click menu select User Permissions or Group Permissions . Next you must select a user or group from the list displayed in the permissions dialog by clicking on their name. This is the user/group for which you are setting permissions. Then you click on the Edit Permissions button to view the permissions matrix for the user/group that you selected.
You can then modify entries in the permission matrix and, when your changes are complete, click on the Apply button. The effect of your permission settings after taking into consideration your current settings and the settings of all containing objects at a higher level, can be seen in the effective Permissions column. For example: for all documents in the Book root, the administrator user has effective Create, Read, Update, Delete and Permitting (CRUDP) permissions. Lack of permission on all of these would be -C-R-U-D-P. Click on the CLOSE button to exit the permissions dialog.
XQuery statements can be executed from a Statement Tab. You can have multiple statement tabs opened at any given time, and they are labelled (by default) "Statement{n}", where {n} is a sequential number. The label may be changed by right-clicking on the tab and selecting "Rename".
From the Statement tab you can:
The Database pane is at the top of the Statement tab on the left side and has the title PathBuilder . This is a list of all available databases for the currently connected Server. Clicking on the plus sign + on the left of a database name will expand the view to include all of the roots defined within the selected database.
The Schema Display is accessed by right clicking on a root in the Database pane and selecting Display Schema from the context menu.
Note: This option is only accessible if a schema has previously been associated with a Root.
The Query Statement pane is located immediately below the Database pane. This is where queries are entered. Once a query is entered in this pane it can be executed by clicking on the Execute Query Button.
The History pane is located immediately below the Query Statement pane. This is where previously executed queries are logged. Once a query is executed, it is saved to a history log, and is displayed at the bottom of the Short Form History windows (left side). If the statement is displayed in red, it indicates that that errors occurred when executing the query. The right side of the history pane is used to display the query in its entirety. Right clicking in either history pane provides a popup menu which allows the selected statement to be placed in the Query pane, ready to be executed.
Note: The Explorer comes pre-configured with a number of queries on the sample databases.
The Results pane is located in the bottom left of the Statement tab. This is where output from the last query executed is displayed. The contents of the resultset XML are shown in a tree control which can be expanded and collapsed by clicking on the plus + and minus - signs to the left of each tree item that contains child items.
Initially, only the first 50 results per query are retrieved. Additional groupings of 50 results can be obtained by clicking on the "play" button at the bottom of the Results pane or fetch all using the "play to end" button. The limit per request is initially set to 50 results. However, this number may be modified directly by typing a new value into the "Select Next" edit box. Multiple retrievals performed in this way, and based on the same original query, are cumulative. Thus, if you retrieve 20 results three times, there will be 60 result entries held in the Results pane.
Note in the above graphic the document nodes, for example: 1-0-0. If you right click on this graphic you can:
The Display pane is located on the bottom right of the Statement tab. This is where the XML is displayed for the currently selected result (in the Results pane to the left) is placed.
Here are some selected queries. Many more can be found in the Quick Statements section of the User Guide. As well, Explorer history is preloaded with quite a few queries.
Sample 1: PersonDB Database
Query
for $doc IN Root("/PersonDB/Person")
where $doc/Person/FirstName = "Frank"
and $doc/Person/City LIKE "P_R%"
return $doc
Result
<Person Id='11' Active='true'> <!--firstname comment--> <?--proc instrn--?> <FirstName> Frank </FirstName> <LastName> Crowe </LastName> <City> Paris </City> <BirthDate> 1960-05-30T05:00:00 </BirthDate> <Age> 67 </Age> <StockValue> 826.8 </StockValue> </Person>
Sample 2: BookDB Database
Query
let $people := count(Root('/PersonDB/Person'))
return <Population>{ $people }</Population>
Result
<Population> 100 </Population>
The XStreamDB Explorer is equipped with an internal XML Editor, which can be used to edit XML documents. It can be accessed:
The Editor has all basic functionality, including automatic tag completion and indentation, and block indentation.
Note: If a schema has been associated with the XStreamDB database root where the XML document is stored, schema validation will be performed at the time the edited XML document is saved back to the XStreamDB server.
XStreamDB Explorer creates a log file each time it is run. These log files are accessible from within Explorer by clicking on the Log Tab.
Once the Log Tab is displayed, clicking on an individual log entry in the left pane causes the log file to be loaded and displayed in the right pane.
From the Resources tab you can:
XStreamDB encompases the notion of categories, and resources within those categories. Resource definition and management involves mapping XStreamDB documents to a structure similar to a file system, which can be addressed via URLs, or can be checked out to folders and files in the operating system. Once resources are defined in XStreamDB, documents can be accessed and edited over the Internet using the fully secure XStreamDB WebDAV Java Web application. More discussion on the WebDAV Web application is contained in the XStreamDB User Guide.
The Resources tab includes a simple resource checkin/checkout facility. Once resources are defined, they can be moved to the file system and back again in a fashion similar to a source control system. For example: Get , Checkout and Checkin are supported.
Below is the resource management tab in the explorer with the /BookDB/Book category selected in the left pane and the contents of that category shown in the right pane.
Often it is convenient to be able to work on documents offline when you are not connected to a network. For this reason, the XStreamDB explorer supports moving resources from the database to the client machine file system and back again. Explorer uses a resource Get, Checkout and Checkin system familiar to people who have used source control systems such as Microsoft SourceSafe or CVS. As well, files can be copied to the resource system using the Add XML Files or Add Binary Files option from the right-click popup menu (see diagram below).
Binary content such as .jpg, .gif, .doc, files, can be added to XStreamDB as resources and subsequently referenced using URLs. Just right click on the category and use the add binary files menu item shown below to add a binary file.
Note: A mime type will be defaulted according to the file extension.
Note the Set Query Filter and Populate By Query menu items above. These are used to populate a category from documents already in the root corresponding to the category. What you enter for Set Query Filter is text that becomes a WHERE clause that will select certain documents.
For example, the $doc/Person/City="Paris" below becomes a WHERE clause in the underlying query that populates this Category. To do the actual populate, you must also select the Populate By Query menu item. As well, your query filter is remembered for further populates.
Advanced Usage
One problem with populate is that meaningful names do not show up for your documents. If you have a meaningful name in the data, then you may want to use a custom query in the statement window to populate. The example below is somewhat complex because it is creating new html resources from XML resources using XSL transformation. The thing to bear in mind, however, is the use of the GetXMLResourceText function since it creates the correct XML document for insertion into SysDocument so you are sure you don't corrupt the resource mechanism offered in XStreamDB. If you do corrupt the mechanism you can recover by deleting the SysDocument and SysCategory roots from your database�this will remove all your resource information but will leave your content in their respective root.
LET $xdoc := Root("/reference/temp")
LET $xslDoc := Root("/reference/publish")[@id = "journalist"]
RETURN
LET $doc := XSLTransform($xslDoc,$xdoc)
LET $docId := INSERT DOCUMENT $doc INTO "/reference/html"
LET $length := TextLength($doc)
LET $res := GetXMLResourceText("/reference/html","reference.htm",$docId,$length)
RETURN
INSERT DOCUMENT $res INTO "/reference/SysDocument"
Key terms and concepts are described here.
| Term | Description |
|---|---|
| Database | The storage medium for collections ("Roots") of documents. A database corresponds to a single file on disk and usually has the extension 'XD'. |
| Document | Well formed XML, whether it resides in the database or is accessed via a URL. May or may not begin with an XML declaration. |
| Index | An efficient lookup mechanism that can be defined over a collection of documents (or Root). |
| Module | A user defined library of stored functions under a common namespace. Stored functions in a module execute faster because they are preloaded, and the query plan is already prepared. |
| Result Set | A database concept that allows effective management of results returned from the XQuery Engine. |
| Root | An abstraction that facilitates the management of collections of documents within the database. |
| Schema | A mechanism that defines what the valid XML form may be for an associated XML file. See W3C Schema for more information. |
| Trigger | An XQuery statement that is executed when a document is inserted, updated or deleted in a Root. |
| Type Checking | Verification of correct type usage in an XQuery statement, either statically, before a query is executed, or dynamically, during the execution of the query. This requires an associated schema or DTD file. |
| Validation | The process of ensuring that a particular XML instance satisfies the definitions and constraints as specified in the associated DTD or Schema file. |
| XPath | The XML Path language as defined by the W3C in this document: W3C XPath . |
| XQuery | The XML Query language as defined by the W3C in this document: W3C XQuery . |
WebDAV (Web-based Distributed Authoring and Versioning) is a protocol for accessing and manipulating files and folders in remote systems as Internet resources referenced by URIs. Documents in XStreamDB can be exposed as Internet resources and accessed using a WebDAV client.
Examples of WebDAV clients include Web browsers, operating system file explorers (e.g. Windows, MacOS), and collaborative authoring applications.
For more information on WebDAV, visit www.webdav.org .
Before resources can be accessed via WebDAV they must be defined. Resources can be defined using the API, the scripting tool, or most easily using the XStreamDB Explorer .
The Resources tab above shows a set of XML resources on the right that are contained in the /BookDB/Book category. For example, the Graph_Representations_of_Structures.xml document would be served up under the XDB WebDAV Web application using the resource {scheme}:{host}/BookDB/Book/Graph_Representations_of_Structures.xml, where scheme is http and host is, for example, //www.bluestream.com .
Example editor applications used with XStreamDB resources and the WebDAV Web application are XMLSpy, from Altova, and XMetaL from Blast Radius. XMLSpy is more of an XML workbench; whereas, XMetaL is an XML editor that has richer visual editing capabilities.
As well as editors accessing the database, browsers can access resources directly.
Start up XMLSpy and do the following:
If documents you edit in XMLSpy from WebDAV use relative URIs like /SysData/SysSchema/myschema.xsd then those will also be retrieved by XMLSpy from the XStreamDB server since schemas in XStreamDB are also resources.
This explanation is based on Windows 2000 Professional.
Note: In order to Edit files in a Windows Web Folder it is necessary to have the Editor WebDAV enabled. XMetaL 4.0 is such and editor and others are becoming available. Other Windows applications tend to only allow read access or sometimes no access to the file being accessed.
Here are a few tips and Traps regarding using WebDAV.
At Bluestream we found that designating all external URIs to resources as having /xdbres/ as a prefix was useful because it allows resource accessing technology to be plugged into other Web applications. In order to get this to work with WebDAV you would have to mount the WebDAV Web application war file at /xdbres not at the ROOT as it ships. This applies to XdbWeb as well. XdbWeb is similar to WebDAV except it is for accessing and tranforming resources. We have found that mounting the XdbWeb application at {host}/xdbres/...resourceId is useful. Obviously, both WebDAV and XdbWeb cannot be on the same server at {host}/xdbres.
XStreamDB has a Client-Server architecture, so most client API calls are serviced remotely at the server with any results being returned to the client once the server completes the call.
The XStreamDB client API is broken down into two "sub-APIs". The first, and most important, is the JDBC like Statement functionality API. The second "sub-API" contains system configuration functionality.
The primary interfaces required when using the Statement API are:
All processing is performed by executing XQuery statements that run on the Server. In XStreamDB, there are two flavours of XQuery statements, the XStatement and the XPreparedStatement. The diagram below illustrates the relationships between the primary objects within the Client API.
The Database System Object manager (interface: DSObjectMgr) provides read-only access to database system objects and their properties.
As well, some update capability is provided especially with respect to the SchemaMgr and the ResourceMgr.
The diagram below illustrates how the DSObjectMgr interface is obtained from a connection and what the key objects are once that DSObjectMgr is obtained. Note that the DatabaseTree is a tree that contains not only the Database object but collections of all the sub objects to a database.
Use of the XStreamDB Client API must always follow a proper init, process, shutdown cycle. The code fragment below illustrates this concept. Note that it is recommeded to always place the call to shutdown() in a finally clause to ensure it is invoked at termination.
try
{
SystemManager.
init()
;
// processing code goes here
...
}
catch(throwable t)
{
// handle error cases here
}
finally
{
SystemManager.
shutdown()
;
}
The first step towards running a query is to obtain a Server object. This is done by using the getServer() method on the SystemManager object as shown below.
Server srv = SystemManager.
getServer
("MyServer");
The parameter to getServer() is the 'name' of the server that is defined in the XDBClientConfig.xml file in the Client/conf directory. A simple example of this client configuration file is shown here.
<?xml version="1.0" ?>
<XDBClientConfig>
<Servers>
<Server
name="
MyServer
"
host="
localhost
"
port="
1223
" />
</Servers>
<InstallType type="ClientServer" />
</XDBClientConfig>
Note: The 'host' and the 'port' entries will likely need to be changed to suit your installation environment. The example shown here defines a Server ("localhost") that is running on the same computer as the Client application. It is also using the default port ("1223") for XStreamDB Server. This port number may be changed as necessary, but the ports used by Client and Server must always match.
Note: In a WebApplication is is advisable to make a Server object a static singleton since connection pools are held for a server. Otherwise, connection pooling will not be in effect reducing performance.
Once a Server object has been obtained, the next step is to open a connection through which the Client can communicate with the Server. It may be helpful if you think of the Server object as a proxy for the XStreamDB Server process which may be physically running on a machine in another building or another city.
The Server object acts as a stand-in for the remote Server process. The Server object still requires a connection to the remote Server because it is the remote Server who actually does the heavy work of processing the XQuery statement and formulating results.
To open a connection requires that the Client be authenticated to the Server. In other words, only Users known to the Server are permitted access. Obtain a valid User name and password and then use the following code fragment to create a connection to your XStreamDB Server.
Note it is recommended that XConnections be closed when they are no longer required. This ensures that connections are properly shutdown and that resources are freed for reuse.
// use user + password that is valid on your Server
AuthenticationInfo ai = new
SimpleAuthInfo
("fred", "mypassword");
try
{
XConnection
xc = srv.
getConnection
(ai);
// use the connection to execute some queries...
...
xc.
close
();
}
catch(Throwable t)
{
// handle error
}
Notice that the getConnection() method returns an XConnection object. It is this object that allows you to execute statements against the Server.
The code fragment below illustrates the use of transactions to wrap statement execution. This allows changes to the database to be deferred until their outcome is known to be successful. No alteration of the database occurs until the commitTransaction() method is invoked. If the server throws an XDBException for any reason then the transaction in progress is rolled back. However, you may need to rollback the transaction yourself should your own methods fail unexpectedly. For example, if myOtherOperation() below fail and throw an exception, that exception will be handled in the catch (Throwable t) java code and the connection's transaction is rolled back using "rollbackTransaction().
AuthenticationInfo ai = new SimpleAuthInfo("fred", "mypassword");
try
{
XConnection xc = srv.getConnection(ai);
xc.
beginTransaction
();
XStatement stmt = xc.createStatment(...);
xc.execute(stmt, ...);
myOtherOperation();
xc.
commitTransaction
();
}
catch(XDBException xdbEx)
{
// do nothing since XStreamDB server will automatically rollback these
}
catch (Throwable t)
{
if (xc.isTransactionActive())
xc.
rollbackTransaction
();
}
Once an XConnection has been opened, XStatements can be created quite simply as shown below.
XConnection xc = ...
XStatement
xqStmt = xc.
createStatement
();
Now everything is in place to execute an XQuery statement. At this point, we must associate the XQuery statement we wish to execute with the XStatement object as is demonstrated below. A simple query is: Root('MyDB:MyRoot') which returns all of the documents held under the root specified.
try
{
XConnection xc = ... xc.beginTransaction();
XStatement xqStmt = xc.createStatement();
String myQuery = "Root('/MyDB/MyRoot')";
XResultSet
rs =
xqStmt.
execute
(myQuery,
XStatement.SF_DEFAULT
);
// extract the results from the XResultSet
...
xc.commitTransaction();
}
catch(...)
{
}
Notice the second parameter to the execute() function, XStatement.SF_DEFAULT . This flag tells the Server how the result set should be setup. The table below describes the most common XStatement flag values and when to use them.
| Flag Name | Description |
|---|---|
| SF_TRAVERSE_ALL |
This option causes all the results to be traversed automatically and thus there is no ResultSet returned. This is useful for DML statements, such as CREATE DATABASE, DROP ROOT etc. which typically would not return a result in any case. If you know in advance that your query will not yield any results, or if you do not care to retrieve them use this flag. If you do not use this flag you MUST traverse your results until false is returned, otherwise your statement will not be fully executed. |
| SF_DEFAULT |
This option configures the result set to that each result can be retrieved individually. This allows results to be incrementally retrieved as required. This is commonly used when the total number of results is unknown and you want to retrieve only a few results (perhaps 20) at a time for display purposes. This is a very flexible approach that permits the query to be aborted part way through if it is no longer required. A query may be aborted by invoking close() on the XStatement object. |
An executed statement returns an XResultSet that represents all the results from the query. The code fragment below illustrate how to retrieve each result individually.
Some working code samples can be found in the Client/samples/console directory. Most of the code fragments in this document were based on Query.java .
try
{
XStatement xqStmt = xc.createStatement();
String myQuery = "Root('/MyDB/MyRoot')";
XResultSet
rs =
xqStmt.
execute
(myQuery,
XStatement.SF_DEFAULT
);
if (rs != null)
{
FlexStringBuffer fsbTemp = new FlexStringBuffer();
rs.
beforeFirst
();
int i = 1;
while (rs.
nextValue
())
{
fsbTemp.setLength(0);
rs.
fsbGet
(fsbTemp, false /*append*/);
if (fsbTemp.length() > 0)
{
System.out.println(String.valueOf(i)+". "+fsbTemp);
}
i++;
}
}
// release the statement once it is no longer required
xqStmt.
close
();
}
catch(...)
{
}
Statements are text blocks which are passed to the XStreamDB server for execution. Most statements will be standard XQuery statements but some will use XStreamDB XQuery extensions.
An XStreamDB server hosts one or more databases. Each database is composed of any number of user definable roots. A Root is a collection of documents, similar to a table in a relational database. Within each root can be zero or more documents. A document must be well formed XML but can optionally contain the XML prolog, XML version, and DOCTYPE directives. There is no reason, however, why you can't store fragments of XML in XStreamDB as documents, as long as these fragments are well formed.
A few simple starting examples.
This is one of the simplest queries possible in XQuery. Any XQuery expression is a valid XQuery statement. In this case, "2" is a valid primitive expression which evaluates to 2.
Query:
2
Result:
2
This query shows simple arithmetic with parenthesis. Note that the output of this query is not well-formed XML. The XQuery data model allows the output of a query to be not well-formed XML.
Query:
(1+1)*25
Result:
50
These examples show document access from a root.
An XML document is modelled in XQuery as a tree consisting of a single document node, with a root element child and then that root element has subsequent child elements as necessary. This query returns all the root elements in the root BookDB/Book.
Query:
Root("/BookDB/Book")/book
Result:
<book year = '1994'>
<!--this is the 1st book-->
<title>
TCP/IP Illustrated
</title>
<author>
<last>
Stevens
</last>
XPath expressions are crucial to XQuery
An XPath expression is a type of XQuery expression. XPath expressions allow you to select values by specifying their "path" within a document or set of documents. This query shows the selection of the city elements in all the documents in the root Person.
Query:
Root("/PersonDB/Person")/Person/City
Result:
<City>
Paris
</City>
<City>
London
</City>
<City>
New York
</City>
As well as selecting path values, you can specify predicates (conditions) within XPath. This query returns only those Persons who live in "Paris". Note in the query below that what gets returned is the path expression to the left of the '[' bracket. This bracket can be placed anywhere in the path.
Query:
Root("/PersonDB/Person")/Person[City = "Paris"]
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
XPath expressions can also access attribute values. The expression below accesses the year attribute in the book element. Note: XQuery uses the abbreviated XPath syntax. In the unabbreviated syntax the expression below would read Root('/BookDB/Book')/child:book/attribute:@year.
Query:
Root('/BookDB/Book')/book/@year
Result:
year='1994' year='1992' year='1999' year='2000'
FLWOR (flower) stands for for, let, where, order by and return. The FLWOR expression is one of the main constructs introduced by XQuery. Each of the for, let, where, order by and return parts are "clauses" and are not complete expressions in themselves.
This query returns all the Persons who live in Paris. This query is identical in meaning to the previous XPath example: Root("/PersonDB/Person")/Person[City = "Paris"]. Note: the for below is similar to for loops in other languages. for $d in Root("/PersonDB/Person") can be read as, for each document in root Person, execute the rest of the FLWR expression, binding $d to each document in Person.
Query:
for $d in Root("/PersonDB/Person")
where $d/Person/City = "Paris"
return $d
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
The let clause in FLWR can be used for a number of reasons. This query shows let being used for a simple variable assignment. This query returns the FirstName of all the persons living in Paris. let is typically used in more complex queries - see Advanced FLWR queries.
Query:
for $d in Root("/PersonDB/Person")
let $fn := $d/Person/FirstName/text()
where $d/Person/City = "Paris"
return $fn
Result:
John Frank George Russ Paul Leif Michael Jim Peter
Predicates are a way of restricting the set of data.
As shown in previous queries, it is possible to restrict the sequence of data returned by a FLWR statement by using a where clause, or in the case of XPath a predicate within square brackets. This query further shows the use of predicates. This query returns all the persons with first name John that live in Paris.
Query:
for $d in Root("/PersonDB/Person")
where $d/Person/FirstName = "John"
and $d/Person/City = "Paris"
return $d
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
This query shows the use of not, which is a function and has the effect of converting true to false and false to true. This query returns all the cities with people named John, but not those in Paris.
Query:
for $d in Root("/PersonDB/Person")
where $d/Person/FirstName = "John"
and not($d/Person/City = "Paris")
return $d//City/text()
Result:
London New York Toronto Sydney Vancouver Spuzzum Okotoks Calgary Medicine Hat
When XQuery is parsed the parser is either in Tag state or XQuery state. The allowable grammar for each of these states is different.
This query shows the use of element constructors in XQuery. In this query the entire output of root /PersonDB/Person is placed in the <Result> tag. Note: The left angle bracket "<" causes a shift of the XQuery parser into tag state and it is only through the use of left curly "{" that you can shift back into XQuery expression state.
Query:
<Result>
{Root("/PersonDB/Person")/Person}
</Result>
Result:
<Result>
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
This query shows the use of element constructors in XQuery. In this query the entire output of root /PersonDB/Person is placed in the <Result> tag. Note: The left angle bracket "<" causes a shift of the XQuery parser into tag state and it is only through the use of left curly "{" that you can shift back into XQuery expression state.
Query:
for $p in Root("/PersonDB/Person")/Person
order by $p/FirstName
return $p/FirstName/data()
Result:
Frank Frank Frank Frank Frank Frank Frank Frank Frank
Give me a list of distinct cities where persons live.
Query:
for $c in distinct(
Root("/PersonDB/Person")/Person/City/text())
return $c
Result:
Calgary London Medicine Hat New York Okotoks Paris Spuzzum Sydney Toronto
Search on words.
This query shows the full contents of the books root.
Query:
Root('/BookDB/Book')
Result:
<book year = '1994'>
<!--this is the 1st book-->
<title>
TCP/IP Illustrated
</title>
<author>
<last>
Stevens
</last>
This query returns only those books with the word Unix in its title. Note, the first part of the match expression is the source to search on. The second part of the match is the using clause which specifies the type of match, either contains, proximity or has phrase. In the example below we use the contains clause.
Query:
for $d in Root('/BookDB/Book')
where match $d using [/book/title contains "Unix"]
return $d
Result:
<book year = '1992'>
<!--this is another book-->
<title>
Advanced Programming in the Unix environment
</title>
<author>
<last>
Stevens
</last>
This query returns only those books with the word good and discussion in its review. Note the words discussion and good are spaced separated. What this means is "discussion" and "good" must occur in any order.
Query:
for $d in Root('/BookDB/Book')
where match $d using [/book/review contains "discussion good"]
return $d
Result:
<book>
<!--this is another book-->
<title>
Data on the Web
</title>
<price>
34.95
</price>
<review>
This query will return all documents that contain the word "data" in any path "//*". Each document will be scored according to how relevant it is to the word "data" If data is not contained in the document it will be given a score of zero and the where $score > 0 clause will filter it out. As well, the results are ordered by score descending to produce a "google" style results page. It is expected that a result is further selected by the user with a subsequent GetDocument(-- docid--) kind of query. SNote the words discussion and good are spaced separated. What this means is "discussion" AND "good" must occur in any order.
Query:
for $doc in Root("/BookDB/Book")
let $score := score $doc using [//* contains "data"]
where $score > 0
order by $score descending
return
<hit
title='{$doc/book/title}'
id='{GetDocId($doc)}'
score='{$score}'>
</hit>
Result:
<hit title = 'Data on the Web' id = '1$BookDB:Book$2-14-0' score = '0.65036345'> </hit> <hit title = 'Data on the Web' id = '1$BookDB:Book$2-13-0' score = '0.65036345'> </hit> <hit title = ' Data on the Web' id = '1$BookDB:Book$2-4-0' score = '0.38411513'> </hit> <hit title = 'Data on the Web' id = '1$BookDB:Book$2-12-0' score = '0.38411513'> </hit> <hit title = 'Data on the Web' id = '1$BookDB:Book$2-3-0' score = '0.38411513'>
text() and data() are primitive value accessors.
Sometimes you want to return an element tag and its value, othertimes you want to return the text of the tag. Using the text() accessor allows you to extract the text from the tag. This query will return the city text. Note: you can also use data() to extract the value of city. data() is a typed accessor, but it has the same effect as text() in most cases.
Query:
for $d in Root('/PersonDB/Person')
return $d/Person/City/text()
Result:
Paris London New York Toronto Sydney Vancouver Spuzzum Okotoks Calgary
Data definition covers creation of databases and roots as well as permission setting and schema association with a root. User definition, permission reading and schema add and access is not handled in statements but through the ServerConfigMgr part of the client API. SetDescription
Sometimes you want to return an element tag and its value, othertimes you want to return the text of the tag. Using the text() accessor allows you to extract the text from the tag. This query will return the city text. Note: you can also use data() to extract the value of city. data() is a typed accessor, but it has the same effect as text() in most cases.
Database create.
Query:
create database "/TestDB"
Root create.
Query:
create root "/TestDB/TestRoot"
Drop database.
Query:
drop database "/TestDB"
Node update allows you to update any node within an XQuery variable. Through node update any XQuery variable can be updated by inserting, replacing and deleting elements, attributes and simple values. Often, in practice, this node update is used in conjunction with root update shown below to update the database. Node update can, however be used to simply change the results of the query as shown in these examples here.
Insert a company tag under each Person from Paris.
Query:
for $d in Root("/PersonDB/Person")
let $newdoc :=
update $d using insert value <Company>Ford</Company> into $d/Person
where $d/Person/City = "Paris"
return $newdoc
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
All of the people in Toronto have moved to Vancouver. For those persons with city Toronto, change the value to Vancouver.
Query:
for $d in Root("/PersonDB/Person")
let $newdoc :=
update $d using replace value $d/Person/City/text() with "Vancouver"
where $d/Person/City = "Paris"
return $newdoc
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
Similarily to the above query except we construct a new <City> tag wrapper.
Query:
for $d in Root("/PersonDB/Person")
let $newdoc :=
update $d using replace value $d/Person/City with <City>Vancouver</City>
where $d/Person/City = "Paris"
return $newdoc
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
Take the values from the FirstName and LastName and put them into a new tag called <Name>, replacing FirstName and LastName in the process. Note the use of the delete tag below.
Query:
for $d in Root("/PersonDB/Person")
let $name :=
($d/Person/FirstName/text()," ",$d/Person/LastName/text())
let $nd1 :=
update $d using
replace value $d/Person/FirstName with (<Name>{$name}</Name>)
let $newdoc := update $nd1 using delete value $nd1/Person/LastName
where $d/Person/City = "Paris"
return $newdoc
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<Name>
John Doe
</Name>
<City>
Paris
</City>
Root editing covers the insertion, replacing and deletion of documents in a root. Used in conjunction with tree editing and other features of XQuery, tree editing can be quite powerful.
Create a temporary database.
Query:
create database "/EditDB"
Create a temporary root for persons.
Query:
create root "/EditDB/EditPerson"
Copy person root. Note the use of the insert document expression.
Query:
for $d in Root("/PersonDB/Person")
return
insert document $d into "/EditDB/EditPerson"
Result:
1$EditDB:EditPerson$1-0-0 1$EditDB:EditPerson$1-1-0 1$EditDB:EditPerson$1-2-0 1$EditDB:EditPerson$1-3-0 1$EditDB:EditPerson$1-4-0 1$EditDB:EditPerson$1-5-0 1$EditDB:EditPerson$1-6-0 1$EditDB:EditPerson$1-7-0 1$EditDB:EditPerson$1-8-0
Insert a company tag under each Person from Paris and replace each document in the database with this change.
Query:
for $d in Root("/EditDB/EditPerson")
let $newdoc :=
update $d using
insert value <Company>Ford</Company> into $d/Person
where $d/Person/City = "Paris"
return
replace document GetDocumentId($d) with $newdoc
Result:
1$EditDB:EditPerson$1-0-0 1$EditDB:EditPerson$1-10-0 1$EditDB:EditPerson$1-20-0 1$EditDB:EditPerson$1-30-0 1$EditDB:EditPerson$1-40-0 1$EditDB:EditPerson$1-50-0 1$EditDB:EditPerson$1-60-0 1$EditDB:EditPerson$1-70-0 1$EditDB:EditPerson$1-80-0
Query to ensure that the update was complete.
Query:
for $d in Root("/EditDB/EditPerson")
where $d/Person/City = "Paris"
return $d
Result:
<Person Id = '1' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
Query persons in Toronto.
Query:
for $d in Root("/EditDB/EditPerson")
where $d/Person/City = "Toronto"
return $d
Result:
<Person Id = '4' Active = 'true'>
<!--firstname comment-->
<?proc instrn ?>
<FirstName>
John
</FirstName>
<LastName>
Doe
</LastName>
Delete all the persons from Toronto.
Query:
for $d in Root("/EditDB/EditPerson")
where $d/Person/City = "Toronto"
return delete document GetDocumentId($d)
Result:
Query persons in Toronto.
Query:
for $d in Root("/EditDB/EditPerson")
where $d/Person/City = "Toronto"
return $d
Cleanup database.
Query:
drop database "/EditDB"
Functions modules allow you to define one or more query functions and store them in the database for future use. This allows for the modularization of queries as well as the sharing of queries across projects. Stored functions are pre-compiled to avoid the need to re-compile them every time they are invoked, making them faster than externally provided standard queries.
Create a module with 2 functions.
Query:
create module "TwoFunc"
define function AddOne(xsd:integer $baseNum) returns xsd:integer
{
$baseNum+1
}
define function AddFour(xsd:integer $baseNum) returns xsd:integer
{
4+$baseNum
}
Result:
Use the functions.
Query:
import module namespace pre = "TwoFunc" let $sum := pre:AddOne(1) + pre:AddFour(12) return $sum
Result:
18
Drop function module.
Query:
drop module "TwoFunc"
Result:
Drop function module.
Query:
let $i := "2"
let $min := "10"
let $max := "25"
return
if ($i >= $min and $i <= $max )
then ("yes") else "no"
Result:
yes
XStreamDb supports numeric and string constants and support casting to the built in XStreamDb data types. As well, if W3C schema is provided for the root with data types then XStreamDb will use those data types as necessary
String compare: note string compare, not numeric.
Query:
let $i := "2"
let $min := "10"
let $max := "25"
return
if ($i >= $min and $i <= $max )
then ("yes") else "no"
Result:
yes
Cast to make comparison of strings numeric.
Query:
let $i := "2"
let $min := "10"
let $max := "25"
return
if ($i >= cast as long ($min) and $i <= cast as long ($max) )
then ("yes") else "no"
Result:
no
Numeric constants cause numeric compare.
Query:
let $i := 2
let $min := 10
let $max := 25
return
if ($i >= $min and $i <= $max ) then
("yes") else "no"
Result:
no
XStreamDB is an ideal application to use for providing documentation or other content in a Web environment. Since it is 100% Java and communicates via sockets, it fits perfectly into a networked environment, such as the Web. At its simplest, the Web is an excellent display medium. The scenario described