Programming in Lua¶
Programming YottaDB in Lua is provided by lua-yottadb, developed by Mitchell and sponsored by the University of Antwerp. We acknowledge their contribution and thank them for the value it adds to the YottaDB community.
lua-yottadb wraps the YottaDB Simple API to provide a Lua API.
Installation¶
The YottaDB Lua API requires a minimum YottaDB release of r1.32 and is tested with a minimum Lua version of 5.3.
If a different version of Lua is being used make sure to either modify the Makefile or pass CFLAGS=-I/path/to/lua
to make
, since the Makefile assumes that the Lua headers are installed at /usr/include/lua5.3
.
$ sudo apt install lua5.4
$ sudo apt install liblua5.4-dev
$ git clone https://github.com/anet-be/lua-yottadb.git
$ cd lua-yottadb
$ sed -i 's/5.3/5.4/g' Makefile
$ sudo make install
$ make test
$
Lua API¶
Lua Wrapper Functions¶
data()¶
As a wrapper for ydb_data_s(), data()
provides information about whether or not a global or local variable node has data and/or subtree.
data(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
integer
Following are the possible return values:
0.0 : there is neither a value nor a subtree; undefined variable node
1.0 : there is a value but no subtree
10.0 : there is no value but there is a subtree
11.0 : there are both a value and a subtree
Example:
> ydb = require('yottadb')
> ydb.data('^Population')
10.0
> ydb.data('^Population', {'USA'})
11.0
To better understand the structure of the Population global variable node refer to the Concepts section. The Population
global variable has been set as follows:
ydb.set('^Population', {'Belgium'}, 1367000)
ydb.set('^Population', {'Thailand'}, 8414000)
ydb.set('^Population', {'USA'}, 325737000)
ydb.set('^Population', {'USA', '17900802'}, 3929326)
ydb.set('^Population', {'USA', '18000804'}, 5308483)
delete_node()¶
As a wrapper for the C function ydb_delete_s(), delete_node()
deletes a global or local variable node.
delete_node(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Example:
> ydb = require('yottadb')
> ydb.set('^Population', {'Belgium'}, 1367000)
> ydb.delete_node('^Population', {'Belgium'})
> ydb.get('^Population', {'Belgium'})
nil
delete_tree()¶
As a wrapper for the C function ydb_delete_s(), delete_tree()
deletes the entire global or local variable node tree.
delete_tree(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Example:
> ydb = require('yottadb')
> ydb.get('^Population', {'USA'})
325737000
> ydb.get('^Population', {'USA', '17900802'})
3929326
> ydb.get('^Population', {'USA', '18000804'})
5308483
> ydb.delete_tree('^Population', {'USA'})
> ydb.data('^Population', {'USA'})
0.0
get()¶
As a wrapper for the C function ydb_get_s(), get()
returns the value of a global or local variable node or an intrinsic variable.
get(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
string or nil
The return value is nil
if the variable node does not exist.
Example:
> ydb = require('yottadb')
> ydb.get('^Population')
nil
> ydb.get('^Population', {'Belgium'})
1367000
> ydb.get('$zgbldir')
/home/ydbuser/.yottadb/r1.34_x86_64/g/yottadb.gld
incr()¶
As a wrapper for the C function ydb_incr_s(), increment()
increments the value in a global or local variable node.
incr(varname, subsarray, increment)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
increment : Optional string or number amount to increment by
The default value of increment
parameter is one.
Return value:
incremented value
Example:
> ydb = require('yottadb')
> ydb.get('num')
4
> ydb.incr('num', 3)
7
> ydb.incr('num')
8
lock()¶
As a wrapper for the C function ydb_lock_s(), lock()
releases any locks held by the process and attempts to acquire all the requested locks.
lock(keys, timeout)
Parameters:
keys : Optional list of variable nodes {varname[, subs]} to lock
timeout : Optional timeout in seconds to wait for the lock
The default value of timeout
parameter is zero.
If keys
is omitted then lock()
just releases all the locks. The keys
parameter refers to the YottaDB key object. For more information on the key object refer key() API function.
lock_decr()¶
As a wrapper for C function ydb_lock_decr_s, lock_decr()
decrements the count of the specified lock held by the process, releasing it if the count goes to zero or ignoring the invocation if the process does not hold the lock.
lock_decr(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
lock_incr()¶
As a wrapper for the C function ydb_lock_incr_s(), lock_incr()
attempts to acquire the requested lock without releasing any locks, incrementing the count if already held.
lock_incr(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
timeout : Optional timeout in seconds to wait for the lock
node_next()¶
As a wrapper for the C function ydb_node_next_s(), node_next()
returns the next global or local variable node.
node_next(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
list or nil
The return value is nil
if there is no next node.
Example:
> ydb = require('yottadb')
> print(table.concat(ydb.node_next('^Population'), ', '))
Belgium
> print(table.concat(ydb.node_next('^Population', {'Belgium'}), ', '))
Thailand
> print(table.concat(ydb.node_next('^Population', {'Thailand'}), ', '))
USA
> print(table.concat(ydb.node_next('^Population', {'USA'}), ', '))
USA, 17900802
> print(table.concat(ydb.node_next('^Population', {'USA', '17900802'}), ', '))
USA, 18000804
Note
- The format used above to print the next node will give an error if there is no next node, i.e., the value returned is
nil
. This case will have to be handled gracefully. The following code snippet is one way to handlenil
as the return value: local ydb = require('yottadb') next = ydb.node_next('^Population', {'USA', '18000804'}) if next ~= nil then print(table.concat(next, ', ')) else print(next) end
node_previous()¶
As a wrapper for the C function ydb_node_previous_s(), node_previous()
returns the previous global or local variable node.
node_previous(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
list or nil
The return value is nil
if there is no previous node.
Example:
> ydb = require('yottadb')
> print(table.concat(ydb.node_previous('^Population', {'USA', '18000804'}), ', '))
USA, 17900802
> print(table.concat(ydb.node_previous('^Population', {'USA', '17900802'}), ', '))
USA
> print(table.concat(ydb.node_previous('^Population', {'USA'}), ', '))
Thailand
> print(table.concat(ydb.node_previous('^Population', {'Thailand'}), ', '))
Belgium
Note
The note on handling nil return values in node_next()
applies to node_previous()
as well.
set()¶
As a wrapper for the C function ydb_set_s(), set()
sets the value of the global variable node, local variable node or intrinsic special variable.
set(varname, subsarray, value)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
value : String value to set, if number is provided it is converted to a string
Example:
> ydb = require('yottadb')
> ydb.set('^Population', {'Belgium'}, 1367000)
> ydb.set('^Population', {'Thailand'}, 8414000)
> ydb.set('^Population', {'USA'}, 325737000)
> ydb.set('^Population', {'USA', '17900802'}, 3929326)
> ydb.set('^Population', {'USA', '18000804'}, 5308483)
str2zwr()¶
As a wrapper for the C function ydb_str2zwr_s(), str2zwr()
returns the zwrite formatted version of the string provided.
strzwr(s)
Parameters:
s: String to format
Return value:
zwrite formatted string
Example:
> ydb=require('yottadb')
> str='The quick brown dog\b\b\bfox jumps over the lazy fox\b\b\bdog.'
> print(str)
The quick brown fox jumps over the lazy dog.
> ydb.str2zwr(str)
"The quick brown dog"_$C(8,8,8)_"fox jumps over the lazy fox"_$C(8,8,8)_"dog."
In the above example the escape sequence b
(backspace) is used.
subscript_next()¶
As a wrapper for the C function ydb_subscript_next_s(), subscript_next()
returns the next subscript, at the same level, of a global or local variable node.
subscript_next(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
string (subscript name) or nil
The return value is nil
if there is no next subscript.
Example:
> ydb=require('yottadb')
> ydb.subscript_next('^Population', {''})
Belgium
> ydb.subscript_next('^Population', {'Belgium'})
Thailand
> ydb.subscript_next('^Population', {'Thailand'})
USA
subscript_previous()¶
As a wrapper for the C function ydb_subscript_previous_s(), subscript_previous()
returns the previous subscript, at the same level, of a global or local variable node.
subscript_previous(varname, subsarray)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
Return value:
string (subscript name) or nil
The return value is nil
if there is no previous subscript.
Example:
> ydb=require('yottadb')
> ydb.subscript_previous('^Population', {'USA', ''})
18000804
> ydb.subscript_previous('^Population', {'USA', '18000804'})
17900802
> ydb.subscript_previous('^Population', {'USA', '17900802'})
nil
> ydb.subscript_previous('^Population', {'USA'})
Thailand
>
tp()¶
As a wrapper for the C function ydb_tp_s() , it provides support for full ACID transactions.
tp(id, varnames, f, ...)
Parameters:
id : Optional string transaction id
varnames : Optional list of variable names to restore on transaction restart
f : Function to call
… : Optional arguments to pass to f
Example:
local ydb = require('yottadb')
function transfer_to_savings(t)
local ok, e = pcall(ydb.incr, '^checking', -t)
if (ydb.get_error_code(e) == ydb.YDB_TP_RESTART) then
return ydb.YDB_TP_RESTART
end
if (not ok or tonumber(e)<0) then
return ydb.YDB_TP_ROLLBACK
end
local ok, e = pcall(ydb.incr, '^savings', t)
if (ydb.get_error_code(e) == ydb.YDB_TP_RESTART) then
return ydb.YDB_TP_RESTART
end
if (not ok) then
return ydb.YDB_TP_ROLLBACK
end
return ydb.YDB_OK
end
ydb.set('^checking', 200)
ydb.set('^savings', 85000)
print("Amount currently in checking account: $" .. ydb.get('^checking'))
print("Amount currently in savings account: $" .. ydb.get('^savings'))
print("Transferring $10 from checking to savings")
local ok, e = pcall(ydb.tp, '', {'*'}, transfer_to_savings, 10)
if (not e) then
print("Transfer successful")
elseif (ydb.get_error_code(e) == ydb.YDB_TP_ROLLBACK) then
print("Transfer not possible. Insufficient funds")
end
print("Amount in checking account: $" .. ydb.get('^checking'))
print("Amount in savings account: $" .. ydb.get('^savings'))
print("Transferring $1000 from checking to savings")
local ok, e = pcall(ydb.tp, '', {'*'}, transfer_to_savings, 1000)
if (not e) then
print("Transfer successful")
elseif (ydb.get_error_code(e) == ydb.YDB_TP_ROLLBACK) then
print("Transfer not possible. Insufficient funds")
end
print("Amount in checking account: $" .. ydb.get('^checking'))
print("Amount in savings account: $" .. ydb.get('^savings'))
Output:
Amount currently in checking account: $200
Amount currently in savings account: $85000
Transferring $10 from checking to savings
Transfer successful
Amount in checking account: $190
Amount in savings account: $85010
Transferring $1000 from checking to savings
Transfer not possible. Insufficient funds
Amount in checking account: $190
Amount in savings account: $85010
Note
When using the tp()
function, restarts and rollbacks need to be handled appropriately.
zwr2str()¶
As a wrapper for the C function ydb_zwr2str_s(), zwr2str()
provides the string format of the zwrite formatted string.
zwr2str(s)
Parameters:
s : String in zwrite format
Return value:
string
Example:
> ydb=require('yottadb')
> str1='The quick brown dog\b\b\bfox jumps over the lazy fox\b\b\bdog.'
> zwr_str=ydb.str2zwr(str1)
> print(zwr_str)
"The quick brown dog"_$C(8,8,8)_"fox jumps over the lazy fox"_$C(8,8,8)_"dog."
> str2=ydb.zwr2str(zwr_str)
> print(str2)
The quick brown fox jumps over the lazy dog.
> str1==str2
true
>
Other API Functions¶
get_error_code()¶
Returns the YottaDB error code (if any) for the given error message.
get_error_code(message)
Parameters:
message : String error message
Return value:
numeric YottaDB error code or nil
The return value is nil
if the message is not a YDB error.
get_error_code()
expects the error message string to start with YDB Error:
.
Example:
> ydb=require('yottadb')
> ydb.get_error_code('YDB Error: -150374122: %YDB-E-ZGBLDIRACC, Cannot access global directory !AD!AD!AD.')
-150374122
key()¶
Creates and returns a new YottaDB key object.
Parameters:
varname : String variable name
Return value:
key
The YottaDB object key has the following fields available:
name : key’s subscript or variable name
value : key’s value in the YottaDB database
data : refer data()
has_value : checks whether or not the key has a value
has_tree : checks whether or not the key has a subtree
The YottaDB key object can access other API functions in the following manner, key:func()
.
Example:
> ydb=require('yottadb')
> belgium = ydb.key('^Population')('Belgium')
> belgium.value
1367000
> thailand = ydb.key('^Population')('Thailand')
> thailand.value
8414000
> usa = ydb.key('^Population')('USA')
> usa.value
325737000
> print(usa.has_tree)
true
> for val in usa(''):subscripts() do
>> print(val)
>> end
17900802
18000804
nodes()¶
Returns an iterator for iterating over all the nodes of a global or local variable node.
nodes(varname, subsarray, reverse)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
reverse : Optional flag that indicates whether to iterate backwards. The default value is false.
Return value:
iterator
Example:
> ydb=require('yottadb')
> for nodes in ydb.nodes('^Population') do
>> print(table.concat(nodes, ', '))
>> end
Belgium
Thailand
USA
USA, 17900802
USA, 18000804
> for usa_nodes in ydb.nodes('^Population', {'USA'}) do
>> print(table.concat(usa_nodes, ', '))
>> end
USA, 17900802
USA, 18000804
subscripts()¶
Returns an iterator for iterating over all subscripts in a global or local variable node.
subscripts(varname, subsarray, reverse)
Parameters:
varname : String variable name
subsarray : Optional list of subscripts
reverse : Optional flag that indicates whether to iterate backwards. The default value is false.
Return value:
iterator
Example:
> ydb=require('yottadb')
> for subs in ydb.subscripts('^Population', {''}) do
>> print(subs)
>> end
Belgium
Thailand
USA
> for subs in ydb.subscripts('^Population', {'USA', ''}) do
>> print(subs)
>> end
17900802
18000804
>
transaction()¶
Returns a transaction-safe version of the given functions such that it can be called with YottaDB Transaction Processing.
transaction(f)
Parameters:
f : Function to convert
The transaction is committed if the function returns nothing or yottadb.YDB_OK, restarted if the function returns yottadb.YDB_TP_RESTART (f will be called again), or not committed if the function returns yottadb.YDB_TP_ROLLBACK or errors.
Return value:
transaction-safe function