diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml index 2e6ce5636c81b3876c91a38c478af24edecd04b7..f022711a1cabd3e4d4173b89de67150dc073215d 100644 --- a/doc/user/stored-procedures.xml +++ b/doc/user/stored-procedures.xml @@ -726,6 +726,38 @@ lua box.dostring('local f = function(key) t=box.select(0, 0, key); if t ~= nil t </para> </listitem> </varlistentry> + <varlistentry> + <term> + <emphasis role="lua">box.uuid()</emphasis> + </term> + <listitem> + <para> + Generates 128-bit (16 bytes) unique id. + </para> + <para> + Requires <emphasis>libuuid</emphasis> to be + installed. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <emphasis role="lua">box.uuid_hex()</emphasis> + </term> + <listitem> + <para> + Generates hex-string of 128-bit (16 bytes) unique id. + Returns 32-bytes string. + </para> + <bridgehead renderas="sect4">Example</bridgehead> + <programlisting> + lua box.uuid_hex() + --- + - a4f29fa0eb6d11e19f7737696d7fa8ff + ... + </programlisting> + </listitem> + </varlistentry> </variablelist> <variablelist> diff --git a/mod/box/CMakeLists.txt b/mod/box/CMakeLists.txt index 9b3ec9b45f6839d9f4782c928f55be0f8e5bdbd7..7c99f08466708b6c2275e37fba0162e630c49575 100644 --- a/mod/box/CMakeLists.txt +++ b/mod/box/CMakeLists.txt @@ -39,4 +39,5 @@ set_source_files_properties(memcached.m PROPERTIES COMPILE_FLAGS "-Wno-uninitialized") tarantool_module("box" tuple.m index.m tree.m space.m port.m request.m - txn.m box.m box.lua.c box_lua.m memcached.m memcached-grammar.m) + txn.m box.m box.lua.c box_lua.m memcached.m memcached-grammar.m + box_lua_uuid.m) diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m index 9b87474bc83b9278763b42d6f8b24c040ea59010..d0ea9fb50cb9f0708a486f55a7cb3e0f9d509345 100644 --- a/mod/box/box_lua.m +++ b/mod/box/box_lua.m @@ -43,6 +43,8 @@ #include "space.h" #include "port.h" +#include "box_lua_uuid.h" + /* contents of box.lua */ extern const char box_lua[]; @@ -868,6 +870,8 @@ static int lbox_process(lua_State *L) static const struct luaL_reg boxlib[] = { {"process", lbox_process}, + {"uuid", lbox_uuid}, + {"uuid_hex", lbox_uuid_hex}, {NULL, NULL} }; diff --git a/mod/box/box_lua_uuid.h b/mod/box/box_lua_uuid.h new file mode 100644 index 0000000000000000000000000000000000000000..c2fbb0ba6b60644c5fae33c4f19b081d8549f249 --- /dev/null +++ b/mod/box/box_lua_uuid.h @@ -0,0 +1,9 @@ +#ifndef __BOX_LUA_UUID_H__ +#define __BOX_LUA_UUID_H__ + +struct lua_State; + +int lbox_uuid(struct lua_State *L); +int lbox_uuid_hex(struct lua_State *L); + +#endif /* __BOX_LUA_UUID_H__ */ diff --git a/mod/box/box_lua_uuid.m b/mod/box/box_lua_uuid.m new file mode 100644 index 0000000000000000000000000000000000000000..dd4f6f0028dd04a85d12087c2d2fc6ebc34978df --- /dev/null +++ b/mod/box/box_lua_uuid.m @@ -0,0 +1,67 @@ +#include <dlfcn.h> +#include <string.h> +#include <stdio.h> +#include "box_lua_uuid.h" +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" + + +#define UUIDLIB_SOVERSION "1" +#define LIBNAME ( "libuuid.so." UUIDLIB_SOVERSION ) + +typedef unsigned char uuid_t[16]; + +static void (*uuid_generate)(uuid_t out); +static char *error; + +static void check_lib(struct lua_State *L) { + + if (uuid_generate) + return; + + if (error) + luaL_error( L, "box.uuid() error: %s", error ); + + void *dl = dlopen(LIBNAME, RTLD_LAZY); + if (!dl) { + error = strdup( dlerror() ); + luaL_error( L, "box.uuid() error: %s", error ); + } + + uuid_generate = dlsym(dl, "uuid_generate"); + if (!uuid_generate) { + error = strdup( dlerror() ); + luaL_error( L, "box.uuid() error: %s", error ); + } +} + + +int lbox_uuid(struct lua_State *L) { + check_lib(L); + + uuid_t uuid; + uuid_generate(uuid); + lua_pushlstring( L, (char *)uuid, sizeof(uuid_t) ); + + return 1; +} + +int lbox_uuid_hex(struct lua_State *L) { + + unsigned i; + char uuid_hex[ sizeof(uuid_t) * 2 + 1 ]; + + + check_lib(L); + + uuid_t uuid; + uuid_generate(uuid); + + for (i = 0; i < sizeof(uuid_t); i++) + snprintf( uuid_hex + i * 2, 3, "%02x", (unsigned)uuid[ i ] ); + + lua_pushlstring( L, uuid_hex, sizeof(uuid_t) * 2 ); + return 1; +} + diff --git a/test/box/lua.result b/test/box/lua.result index 60b5a3b8429e7c59fd042bcd2e3db74f275c408f..f0d8ae6c44d38b42c585cd52a467242603c410e4 100644 --- a/test/box/lua.result +++ b/test/box/lua.result @@ -1584,3 +1584,16 @@ lua box.dostring('return ...', 1, 2, 3) - 2 - 3 ... +# box.uuid() +lua box.dostring('return string.len(box.uuid())') +--- + - 16 +... +lua box.dostring('return string.len(box.uuid_hex())') +--- + - 32 +... +lua box.dostring('return string.match(box.uuid_hex(), "^[a-f0-9]+$")') ~= nil +--- + - true +... diff --git a/test/box/lua.test b/test/box/lua.test index 1efa74501939728373c563b65ef4e5b48ae2492e..2b217be496f71ecc3b42a775ffe38eb0d0e78c65 100644 --- a/test/box/lua.test +++ b/test/box/lua.test @@ -534,3 +534,9 @@ exec admin "lua box.dostring('abc=2')" exec admin "lua box.dostring('return abc')" exec admin "lua box.dostring('return ...', 1, 2, 3)" + +print """# box.uuid()""" +# exec admin "lua box.uuid()" +exec admin "lua box.dostring('return string.len(box.uuid())')" +exec admin "lua box.dostring('return string.len(box.uuid_hex())')" +exec admin """lua box.dostring('return string.match(box.uuid_hex(), "^[a-f0-9]+$")') ~= nil"""