Difference between revisions of "Store Module"

From BaseX Documentation
Jump to navigation Jump to search
m (Text replacement - "</syntaxhighlight>" to "</pre>")
 
(10 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
In addition, custom stores can be read and written. Custom stores have filenames with the pattern {{Code|store-NAME.basex}}. The implicit write of the standard store at shutdown time will be disabled if a custom store is used.
 
In addition, custom stores can be read and written. Custom stores have filenames with the pattern {{Code|store-NAME.basex}}. The implicit write of the standard store at shutdown time will be disabled if a custom store is used.
  
Functions of this module are non-deterministic and side-effecting: Updates will immediately be visible, and a repeated call of the same function may yield different results if the contents of the store have changed.
+
Functions of this module are nondeterministic and side-effecting: Updates will immediately be visible, and a repeated call of the same function may yield different results if the contents of the store have changed.
  
 
=Conventions=
 
=Conventions=
Line 17: Line 17:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:get|$key as xs:string|item()*}}<br/ >
+
|<pre>store:get(
 +
  $key as xs:string
 +
) as item()*</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 28: Line 30:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:put|$key as xs:string, $value as item()*|empty-sequence()}}<br/ >
+
|<pre>store:put(
 +
  $key   as xs:string,
 +
  $value as item()*
 +
) as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 42: Line 47:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:get-or-put|$key as xs:string, $put as function() as item()*|item()*}}<br/ >
+
|<pre>store:get-or-put(
 +
  $key as xs:string,
 +
  $put as function(*)
 +
) as item()*</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 53: Line 61:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:remove|$key as xs:string|empty-sequence()}}<br/ >
+
|<pre>store:remove(
 +
  $key as xs:string
 +
) as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 64: Line 74:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:keys||xs:string*}}
+
|<pre>store:keys() as xs:string*</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 75: Line 85:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:clear||empty-sequence()}}<br/ >
+
|<pre>store:clear() as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 88: Line 98:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:read||empty-sequence()}}<br/ >{{Func|store:read|$name as xs:string|empty-sequence()}}
+
|<pre>store:read(
 +
  $name as xs:string?  := ()
 +
) as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 102: Line 114:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:write||empty-sequence()}}<br/ >{{Func|store:write|$name as xs:string|empty-sequence()}}
+
|<pre>store:write(
 +
  $name as xs:string?  := ()
 +
) as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 116: Line 130:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:list||xs:string*}}
+
|<pre>store:list() as xs:string*</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 127: Line 141:
 
{| width='100%'
 
{| width='100%'
 
|- valign="top"
 
|- valign="top"
| width='120' | '''Signatures'''
+
| width='120' | '''Signature'''
|{{Func|store:delete|$name as xs:string|empty-sequence()}}
+
|<pre>store:delete(
 +
  $name as xs:string
 +
) as empty-sequence()</pre>
 
|- valign="top"
 
|- valign="top"
 
|'''Summary'''
 
|'''Summary'''
Line 141: Line 157:
 
'''Use Case 1: Create/update a system configuration in a running BaseX server instance:
 
'''Use Case 1: Create/update a system configuration in a running BaseX server instance:
  
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
(: store an integer :)
 
(: store an integer :)
 
store:put('version', 1),
 
store:put('version', 1),
Line 151: Line 167:
 
(: serialize configuration to disk :)
 
(: serialize configuration to disk :)
 
store:write()
 
store:write()
</syntaxhighlight>
+
</pre>
  
 
The configuration can be requested by further operations, e.g. a client request:
 
The configuration can be requested by further operations, e.g. a client request:
  
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
store:get('version')
 
store:get('version')
</syntaxhighlight>
+
</pre>
  
 
The store will still be available if BaseX is restarted until it is cleared.
 
The store will still be available if BaseX is restarted until it is cleared.
Line 163: Line 179:
 
'''Use Case 2: Create index for fast lookup operations in the GUI:
 
'''Use Case 2: Create index for fast lookup operations in the GUI:
  
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
let $map := map:merge(
 
let $map := map:merge(
 
   for $country in db:get('factbook')//country
 
   for $country in db:get('factbook')//country
Line 171: Line 187:
 
)
 
)
 
return store:put('religions', $map)
 
return store:put('religions', $map)
</syntaxhighlight>
+
</pre>
  
 
A subsequent query can be used to access its contents:
 
A subsequent query can be used to access its contents:
  
<syntaxhighlight lang="xquery">
+
<pre lang='xquery'>
 
store:get('religions')?Buddhism
 
store:get('religions')?Buddhism
</syntaxhighlight>
+
</pre>
  
 
Note that the store will eventually be written to disk unless it is invalidated before closing the GUI.
 
Note that the store will eventually be written to disk unless it is invalidated before closing the GUI.

Latest revision as of 18:37, 1 December 2023

This XQuery Module provides functions to organize values in a persistent main-memory key-value store.

The store is useful if data (a system configuration, maps serving as indexes) needs to be repeatedly accessed. The store is persistent: Contents will be written to disk at shutdown time, and the serialized store will be retrieved from disk as soon as the store is used for the first time. The store will be stored in a binary store.basex file in the database directory.

In addition, custom stores can be read and written. Custom stores have filenames with the pattern store-NAME.basex. The implicit write of the standard store at shutdown time will be disabled if a custom store is used.

Functions of this module are nondeterministic and side-effecting: Updates will immediately be visible, and a repeated call of the same function may yield different results if the contents of the store have changed.

Conventions[edit]

All functions and errors in this module are assigned to the http://basex.org/modules/store namespace, which is statically bound to the store prefix.

Key-value operations[edit]

store:get[edit]

Signature
store:get(
  $key  as xs:string
) as item()*
Summary Retrieves an entry from the store with the given $key. If the addressed entry does not exist, an empty sequence is returned.

store:put[edit]

Signature
store:put(
  $key    as xs:string,
  $value  as item()*
) as empty-sequence()
Summary Stores an entry with the given $key and $value in the store:
  • If the value is an empty sequence, the entry is removed.
  • If a value refers to an opened database or is a lazy item, its contents are materialized in main memory.
  • Values with function items are rejected.

store:get-or-put[edit]

Signature
store:get-or-put(
  $key  as xs:string,
  $put  as function(*)
) as item()*
Summary Retrieves an entry from the store with the given $key. The $put function will only be invoked if the entry does not exist, and its result will be stored and returned instead.

store:remove[edit]

Signature
store:remove(
  $key  as xs:string
) as empty-sequence()
Summary Removes an entry with the given $key from the store. No error will be raised if an addressed entry does not exist.

store:keys[edit]

Signature
store:keys() as xs:string*
Summary Lists the names of all keys.

store:clear[edit]

Signature
store:clear() as empty-sequence()
Summary Resets the store by removing all its entries.

Store Operations[edit]

store:read[edit]

Signature
store:read(
  $name  as xs:string?  := ()
) as empty-sequence()
Summary Retrieves the standard store from disk, or a custom store if a $name is supplied.
Errors io: The store could not be read.
name: The specified name is invalid.
not-found: A store with the specified name does not exist.

store:write[edit]

Signature
store:write(
   $name  as xs:string?  := ()
) as empty-sequence()
Summary Writes the standard store to disk, or to a custom store file if a $name is supplied. If the standard store is empty, the store file will be deleted.
Errors io: The store could not be written.
name: The specified name is invalid.

store:list[edit]

Signature
store:list() as xs:string*
Summary Lists the names of all custom stores.

store:delete[edit]

Signature
store:delete(
  $name  as xs:string
) as empty-sequence()
Summary Deletes a custom store from disk.
Errors name: The specified name is invalid.
not-found: A store with the specified name does not exist.

Examples[edit]

Use Case 1: Create/update a system configuration in a running BaseX server instance:

(: store an integer :)
store:put('version', 1),
(: retrieve existing or new value, store an element :)
let $license := store:get-or-put('license', function() { 'free' })
return store:put('info', <info>{ $license = 'free' ?? 'Free' !! 'Professional' } License</info>),
(: store a map :)
store:put('data', map { 'year': 2022 }),
(: serialize configuration to disk :)
store:write()

The configuration can be requested by further operations, e.g. a client request:

store:get('version')

The store will still be available if BaseX is restarted until it is cleared.

Use Case 2: Create index for fast lookup operations in the GUI:

let $map := map:merge(
  for $country in db:get('factbook')//country
  for $religion in $country//religions
  group by $religion
  return map:entry($religion, data($country/@name))
)
return store:put('religions', $map)

A subsequent query can be used to access its contents:

store:get('religions')?Buddhism

Note that the store will eventually be written to disk unless it is invalidated before closing the GUI.

Errors[edit]

Code Description
io The store could not be read or written.
name The specified name is invalid.
not-found A store with the specified name does not exist.

Changelog[edit]

The module was introduced with Version 10.