Вложенный модуль box.space¶
The box.space
submodule has the data-manipulation functions select
,
insert
, replace
, update
, upsert
, delete
, get
, put
.
It also has members, such as id, and whether or not a space is enabled. Submodule
source code is available in file
src/box/lua/schema.lua.
A list of all box.space
functions follows, then comes a list of all
box.space
members.
The functions and members of box.space
Name Use space_object:auto_increment() Generate key + Insert a tuple space_object:count() Get count of tuples space_object:create_index() Create an index space_object:dec() Decrement a tuple’s counter space_object:delete() Delete a tuple space_object:drop() Destroy a space space_object:get() Select a tuple space_object:inc() Increment a tuple’s counter space_object:insert() Insert a tuple space_object:len() Get count of tuples space_object:on_replace() Create a replace trigger space_object:pairs() Prepare for iterating space_object:put() Insert or replace a tuple space_object:rename() Rename a space space_object:replace() Insert or replace a tuple space_object:run_triggers() Enable/disable a replace trigger space_object:select() Select one or more tuples space_object:truncate() Delete all tuples space_object:update() Update a tuple space_object:upsert() Update a tuple space_object.enabled Flag, true if space is enabled space_object.field_count Required number of fields space_object.id Numeric identifier of space space_object.index Container of space’s indexes box.space._cluster (Metadata) List of replica sets box.space._func (Metadata) List of function tuples box.space._index (Metadata) List of indexes box.space._priv (Metadata) List of privileges box.space._schema (Metadata) List of schemas box.space._space (Metadata) List of spaces box.space._user (Metadata) List of users
-
object
space_object
¶ -
space_object:
auto_increment
(tuple)¶ Insert a new tuple using an auto-increment primary key. The space specified by space_object must have a
num
primary key index of typeTREE
. The primary-key field will be incremented before the insert.Параметры: - space_object (space_object) – an object reference
- tuple (table/tuple) – tuple’s fields, other than the primary-key field
Return: the inserted tuple.
Rtype: tuple
Complexity factors: Index size, Index type, Number of indexes accessed, WAL settings.
Possible errors: index has wrong type or primary-key indexed field is not a number.
Example:
tarantool> box.space.tester:auto_increment{'Fld#1', 'Fld#2'} --- - [1, 'Fld#1', 'Fld#2'] ... tarantool> box.space.tester:auto_increment{'Fld#3'} --- - [2, 'Fld#3'] ...
-
space_object:
count
([key][, iterator])¶ Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – primary-key field values, must be passed as a Lua table if key is multi-part
- iterator – comparison method
Return: Number of tuples.
Example:
tarantool> box.space.tester:count(2, {iterator='GE'}) --- - 1 ...
-
space_object:
create_index
(index-name[, options])¶ Create an index. It is mandatory to create an index for a space before trying to insert tuples into it, or select tuples from it. The first created index, which will be used as the primary-key index, must be unique.
Параметры: - space_object (space_object) – an object reference
- index_name (string) – name of index, which should not be a number and should not contain special characters
- options (table) –
Return: index object
Rtype: index_object
Options for
space_object:create_index
:Name Effect Type Default type type of index string („HASH“ or „TREE“ or „BITSET“ or „RTREE“) „TREE“ id unique identifier number last index’s id, +1 unique index is unique boolean true
if_not_exists no error if duplicate name boolean false
parts field-numbers + types {field_no, „NUM“ or „STR“ or „ARRAY“) {1, 'NUM'}
dimension affects RTREE only number 2 distance affects RTREE only string („euclid“ or „manhattan“) „euclid“ Possible errors: too many parts. Index „…“ already exists. Primary key must be unique.
tarantool> s = box.space.space55 --- ... tarantool> s:create_index('primary', {unique = true, parts = {1, 'NUM', 2, 'STR'}}) --- ...
Details about index field types:
The three index field types (NUM | STR | ARRAY) differ depending on what values are allowed, and what index types are allowed.
- NUM: unsigned integers between 0 and 18446744073709551615, about 18 quintillion. The name will be changed to „unsigned“ in Tarantool version 1.7. Legal in memtx TREE or HASH indexes.
- STR: any set of octets, up to the maximum length. The name will be changed to „string“ in Tarantool version 1.7. Legal in memtx TREE or HASH or BITSET indexes.
- ARRAY: array of integers between -9223372036854775808 and 9223372036854775807. Legal in memtx RTREE indexes.
Index field types to use in create_index
Тип поля для индексирования What can be in it Where is it legal Примеры: NUM integers between 0 and 18446744073709551615 memtx TREE or HASH indexes, 123456 STR strings – any set of octets memtx TREE or HASH indexes „A B C“
„\65 \66 \67“ARRAY array of integers between -9223372036854775808 and 9223372036854775807 memtx RTREE indexes {10, 11}
{3, 5, 9, 10}-
space_object:
dec
{field-value[, field-value ...]}¶ Decrements a counter in a tuple whose primary key matches the
field-value(s)
. The field following the primary-key fields will be the counter. If there is no tuple matching thefield-value(s)
, a new one is not inserted. If the counter value drops to zero, the tuple is deleted.Parameters:
space_object
= an object reference; field-value(s) (type = Lua table or scalar) = values which must match the primary key.Return: the new counter value Rtype: number Complexity factors: Index size, Index type, WAL settings.
Example:
tarantool> s = box.schema.space.create('space19') --- ... tarantool> s:create_index('primary', { > unique = true, > parts = {1, 'NUM', 2, 'STR'} > }) --- ... tarantool> box.space.space19:insert{1, 'a', 1000} --- - [1, 'a', 1000] ... tarantool> box.space.space19:dec{1, 'a'} --- - 999 ... tarantool> box.space.space19:dec{1, 'a'} --- - 998 ...
-
space_object:
delete
(key)¶ Delete a tuple identified by a primary key.
Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – primary-key field values, must be passed as a Lua table if key is multi-part
Return: the deleted tuple
Rtype: tuple
Complexity factors: Index size, Index type
Example:
tarantool> box.space.tester:delete(1) --- - [1, 'My first tuple'] ... tarantool> box.space.tester:delete(1) --- ... tarantool> box.space.tester:delete('a') --- - error: 'Supplied key type of part 0 does not match index part type: expected num' ...
-
space_object:
drop
()¶ Drop a space.
Параметры: - space_object (space_object) – an object reference
Return: nil
Possible errors: If
space_object
does not exist.Complexity factors: Index size, Index type, Number of indexes accessed, WAL settings.
Example:
box.space.space_that_does_not_exist:drop()
-
space_object:
get
(key)¶ Search for a tuple in the given space.
Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – value to be matched against the index key, which may be multi-part.
Return: the tuple whose index key matches
key
, ornil
.Rtype: tuple
Possible errors: If space_object does not exist.
Complexity factors: Index size, Index type, Number of indexes accessed, WAL settings.
The
box.space...select
function returns a set of tuples as a Lua table; thebox.space...get
function returns at most a single tuple. And it is possible to get the first tuple in a space by appending[1]
. Thereforebox.space.tester:get{1}
has the same effect asbox.space.tester:select{1}[1]
, if exactly one tuple is found.Example:
box.space.tester:get{1}
-
space_object:
inc
{field-value[, field-value ...]}¶ Increments a counter in a tuple whose primary key matches the field-value(s). The field following the primary-key fields will be the counter. If there is no tuple matching the
field-value(s)
, a new one is inserted with initial counter value set to1
.Parameters:
space_object
= an object reference; field-value(s) (type = Lua table or scalar) = values which must match the primary key.Return: the new counter value Rtype: number Complexity Factors: Index size, Index type, WAL settings.
Example:
tarantool> s = box.schema.space.create('forty_second_space') --- ... tarantool> s:create_index('primary', { > unique = true, > parts = {1, 'NUM', 2, 'STR'} > }) --- ... tarantool> box.space.forty_second_space:inc{1, 'a'} --- - 1 ... tarantool> box.space.forty_second_space:inc{1, 'a'} --- - 2 ...
-
space_object:
insert
(tuple)¶ Insert a tuple into a space.
Параметры: - space_object (space_object) – an object reference
- tuple (tuple/table) – tuple to be inserted.
Return: the inserted tuple
Rtype: tuple
Possible errors: If a tuple with the same unique-key value already exists, returns
ER_TUPLE_FOUND
.Example:
tarantool> box.space.tester:insert{5000,'tuple number five thousand'} --- - [5000, 'tuple number five thousand'] ...
-
space_object:
len
()¶ Параметры: - space_object (space_object) – an object reference
Return: Number of tuples in the space.
Example:
tarantool> box.space.tester:len() --- - 2 ...
-
space_object:
on_replace
(trigger-function[, old-trigger-function])¶ Create a «replace trigger». The
trigger-function
will be executed whenever areplace()
orinsert()
orupdate()
orupsert()
ordelete()
happens to a tuple in<space-name>
.Параметры: - trigger-function (function) – function which will become the trigger function
- old-trigger-function (function) – existing trigger function which will be replaced by trigger-function
Return: nil or function pointer
If the parameters are (nil, old-trigger-function), then the old trigger is deleted. Details about trigger characteristics are in the triggers section.
Example #1:
tarantool> function f () > x = x + 1 > end tarantool> box.space.X:on_replace(f)
The
trigger-function
can have two parameters: old tuple, new tuple. For example, the following code causes nil to be printed when the insert request is processed, and causes [1, „Hi“] to be printed when the delete request is processed:box.schema.space.create('space_1') box.space.space_1:create_index('space_1_index',{}) function on_replace_function (old, new) print(old) end box.space.space_1:on_replace(on_replace_function) box.space.space_1:insert{1,'Hi'} box.space.space_1:delete{1}
Example #2:
The following series of requests will create a space, create an index, create a function which increments a counter, create a trigger, do two inserts, drop the space, and display the counter value - which is 2, because the function is executed once after each insert.
tarantool> s = box.schema.space.create('space53') tarantool> s:create_index('primary', {parts = {1, 'NUM'}}) tarantool> function replace_trigger() > replace_counter = replace_counter + 1 > end tarantool> s:on_replace(replace_trigger) tarantool> replace_counter = 0 tarantool> t = s:insert{1, 'First replace'} tarantool> t = s:insert{2, 'Second replace'} tarantool> s:drop() tarantool> replace_counter
-
space_object:
pairs
([key[, iterator]])¶ Search for a tuple or a set of tuples in the given space, and allow iterating over one tuple at a time.
Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – value to be matched against the index key, which may be multi-part
- iterator – see index_object:pairs
Return: iterator which can be used in a for/end loop or with totable()
Possible errors: No such space; wrong type.
Complexity factors: Index size, Index type.
For examples of complex
pairs
requests, where one can specify which index to search and what condition to use (for example «greater than» instead of «equal to»), see the later section index_object:pairs.Example:
tarantool> s = box.schema.space.create('space33') --- ... tarantool> -- index 'X' has default parts {1, 'NUM'} tarantool> s:create_index('X', {}) --- ... tarantool> s:insert{0, 'Hello my '}, s:insert{1, 'Lua world'} --- - [0, 'Hello my '] - [1, 'Lua world'] ... tarantool> tmp = '' --- ... tarantool> for k, v in s:pairs() do > tmp = tmp .. v[2] > end --- ... tarantool> tmp --- - Hello my Lua world ...
-
space_object:
rename
(space-name)¶ Rename a space.
Параметры: - space_object (space_object) – an object reference
- space-name (string) – new name for space
Return: nil
Possible errors:
space_object
does not exist.Example:
tarantool> box.space.space55:rename('space56') --- ... tarantool> box.space.space56:rename('space55') --- ...
-
space_object:
replace
(tuple)¶ -
space_object:
put
(tuple)¶ Insert a tuple into a space. If a tuple with the same primary key already exists,
box.space...:replace()
replaces the existing tuple with a new one. The syntax variantsbox.space...:replace()
andbox.space...:put()
have the same effect; the latter is sometimes used to show that the effect is the converse ofbox.space...:get()
.Параметры: - space_object (space_object) – an object reference
- tuple (table/tuple) – tuple to be inserted
Return: the inserted tuple.
Rtype: tuple
Possible errors: If a different tuple with the same unique-key value already exists, returns
ER_TUPLE_FOUND
. (This will only happen if there is a unique secondary index.)Complexity factors: Index size, Index type, Number of indexes accessed, WAL settings.
Example:
box.space.tester:replace{5000, 'tuple number five thousand'}
-
space_object:
run_triggers
(true|false)¶ At the time that a trigger is defined, it is automatically enabled - that is, it will be executed. Replace triggers can be disabled with
box.space.space-name:run_triggers(false)
and re-enabled withbox.space.space-name:run_triggers(true)
.Return: nil Example:
The following series of requests will associate an existing function named F with an existing space named T, associate the function a second time with the same space (so it will be called twice), disable all triggers of T, and delete each trigger by replacing with
nil
.tarantool> box.space.T:on_replace(F) tarantool> box.space.T:on_replace(F) tarantool> box.space.T:run_triggers(false) tarantool> box.space.T:on_replace(nil, F) tarantool> box.space.T:on_replace(nil, F)
-
space_object:
select
([key])¶ Search for a tuple or a set of tuples in the given space.
Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – value to be matched against the index key, which may be multi-part.
Return: the tuples whose primary-key fields are equal to the fields of the passed key. If the number of passed fields is less than the number of fields in the primary key, then only the passed fields are compared, so
select{1,2}
will match a tuple whose primary key is{1,2,3}
.Rtype: array of tuples
Possible errors: No such space; wrong type.
Complexity factors: Index size, Index type.
Example:
tarantool> s = box.schema.space.create('tmp', {temporary=true}) --- ... tarantool> s:create_index('primary',{parts = {1,'NUM', 2, 'STR'}}) --- ... tarantool> s:insert{1,'A'} --- - [1, 'A'] ... tarantool> s:insert{1,'B'} --- - [1, 'B'] ... tarantool> s:insert{1,'C'} --- - [1, 'C'] ... tarantool> s:insert{2,'D'} --- - [2, 'D'] ... tarantool> -- must equal both primary-key fields tarantool> s:select{1,'B'} --- - - [1, 'B'] ... tarantool> -- must equal only one primary-key field tarantool> s:select{1} --- - - [1, 'A'] - [1, 'B'] - [1, 'C'] ... tarantool> -- must equal 0 fields, so returns all tuples tarantool> s:select{} --- - - [1, 'A'] - [1, 'B'] - [1, 'C'] - [2, 'D'] ...
For examples of complex
select
requests, where one can specify which index to search and what condition to use (for example «greater than» instead of «equal to») and how many tuples to return, see the later section index_object:select.
-
space_object:
truncate
()¶ Deletes all tuples.
Параметры: - space_object (space_object) – an object reference
Complexity factors: Index size, Index type, Number of tuples accessed.
Return: nil Примечание
Note that
truncate
must be called only by the user who created the space OR under a setuid function created by that user. Read more about setuid functions in reference on box.schema.func.create().Example:
tarantool> box.space.tester:truncate() --- ... tarantool> box.space.tester:len() --- - 0 ...
-
space_object:
update
(key, {{operator, field_no, value}, ...})¶ Update a tuple.
The
update
function supports operations on fields — assignment, arithmetic (if the field is numeric), cutting and pasting fragments of a field, deleting or inserting a field. Multiple operations can be combined in a single update request, and in this case they are performed atomically and sequentially. Each operation requires specification of a field number. When multiple operations are present, the field number for each operation is assumed to be relative to the most recent state of the tuple, that is, as if all previous operations in a multi-operation update have already been applied. In other words, it is always safe to merge multipleupdate
invocations into a single invocation, with no change in semantics.Possible operators are:
+
for addition (values must be numeric)-
for subtraction (values must be numeric)&
for bitwise AND (values must be unsigned numeric)|
for bitwise OR (values must be unsigned numeric)^
for bitwise XOR (values must be unsigned numeric):
for string splice!
for insertion#
for deletion=
for assignment
For
!
and=
operations the field number can be-1
, meaning the last field in the tuple.Параметры: - space_object (space_object) – an object reference
- key (scalar/table) – primary-key field values, must be passed as a Lua table if key is multi-part
- operator (string) – operation type represented in string
- field_no (number) – what field the operation will apply to. The field number can be negative, meaning the position from the end of tuple. (#tuple + negative field number + 1)
- value (lua_value) – what value will be applied
Return: the updated tuple.
Rtype: tuple
Possible errors: it is illegal to modify a primary-key field.
Complexity factors: Index size, Index type, number of indexes accessed, WAL settings.
Thus, in the instruction:
s:update(44, {{'+', 1, 55 }, {'=', 3, 'x'}})
the primary-key value is
44
, the operators are'+'
and'='
meaning add a value to a field and then assign a value to a field, the first affected field is field1
and the value which will be added to it is55
, the second affected field is field3
and the value which will be assigned to it is'x'
.Example:
Assume that initially there is a space named
tester
with a primary-key index whose type isnum
. There is one tuple, withfield[1]
=999
andfield[2]
='A'
.In the update:
box.space.tester:update(999, {{'=', 2, 'B'}})
The first argument istester
, that is, the affected space istester
. The second argument is999
, that is, the affected tuple is identified by primary key value = 999. The third argument is=
, that is, there is one operation — assignment to a field. The fourth argument is2
, that is, the affected field isfield[2]
. The fifth argument is'B'
, that is,field[2]
contents change to'B'
. Therefore, after this update,field[1]
=999
andfield[2]
='B'
.In the update:
box.space.tester:update({999}, {{'=', 2, 'B'}})
the arguments are the same, except that the key is passed as a Lua table (inside braces). This is unnecessary when the primary key has only one field, but would be necessary if the primary key had more than one field. Therefore, after this update,field[1]
=999
andfield[2]
='B'
(no change).In the update:
box.space.tester:update({999}, {{'=', 3, 1}})
the arguments are the same, except that the fourth argument is3
, that is, the affected field isfield[3]
. It is okay that, until now,field[3]
has not existed. It gets added. Therefore, after this update,field[1]
=999
,field[2]
='B'
,field[3]
=1
.In the update:
box.space.tester:update({999}, {{'+', 3, 1}})
the arguments are the same, except that the third argument is'+'
, that is, the operation is addition rather than assignment. Sincefield[3]
previously contained1
, this means we’re adding1
to1
. Therefore, after this update,field[1]
=999
,field[2]
='B'
,field[3]
=2
.In the update:
box.space.tester:update({999}, {{'|', 3, 1}, {'=', 2, 'C'}})
the idea is to modify two fields at once. The formats are'|'
and=
, that is, there are two operations, OR and assignment. The fourth and fifth arguments mean thatfield[3]
gets OR’ed with1
. The seventh and eighth arguments mean thatfield[2]
gets assigned'C'
. Therefore, after this update,field[1]
=999
,field[2]
='C'
,field[3]
=3
.In the update:
box.space.tester:update({999}, {{'#', 2, 1}, {'-', 2, 3}})
The idea is to deletefield[2]
, then subtract3
fromfield[3]
. But after the delete, there is a renumbering, sofield[3]
becomesfield[2]`
before we subtract3
from it, and that’s why the seventh argument is2
, not3
. Therefore, after this update,field[1]
=999
,field[2]
=0
.In the update:
box.space.tester:update({999}, {{'=', 2, 'XYZ'}})
we’re making a long string so that splice will work in the next example. Therefore, after this update,field[1]
=999
,field[2]
='XYZ'
.In the update:
box.space.tester:update({999}, {{':', 2, 2, 1, '!!'}})
The third argument is':'
, that is, this is the example of splice. The fourth argument is2
because the change will occur infield[2]
. The fifth argument is 2 because deletion will begin with the second byte. The sixth argument is 1 because the number of bytes to delete is 1. The seventh argument is'!!'
, because'!!'
is to be added at this position. Therefore, after this update,field[1]
=999
,field[2]
='X!!Z'
.
-
space_object:
upsert
(tuple_value, {{operator, field_no, value}, ...})¶ Update or insert a tuple.
If there is an existing tuple which matches the key fields of
tuple_value
, then the request has the same effect as space_object:update() and the{{operator, field_no, value}, ...}
parameter is used. If there is no existing tuple which matches the key fields oftuple_value
, then the request has the same effect as space_object:insert() and the{tuple_value}
parameter is used. However, unlikeinsert
orupdate
,upsert
will not read a tuple and perform error checks before returning – this is a design feature which enhances throughput but requires more caution on the part of the user.Параметры: - space_object (space_object) – an object reference
- tuple (table/tuple) – default tuple to be inserted, if analogue isn’t found
- operator (string) – operation type represented in string
- field_no (number) – what field the operation will apply to. The field number can be negative, meaning the position from the end of tuple. (#tuple + negative field number + 1)
- value (lua_value) – what value will be applied
Return: null
Possible errors: it is illegal to modify a primary-key field. It is illegal to use upsert with a space that has a unique secondary index.
Complexity factors: Index size, Index type, number of indexes accessed, WAL settings.
Example:
box.space.tester:upsert({12,'c'}, {{'=', 3, 'a'}, {'=', 4, 'b'}})
-
space_object.
enabled
¶ Whether or not this space is enabled. The value is
false
if the space has no index.
-
space_object.
field_count
¶ The required field count for all tuples in this space. The field_count can be set initially with:
box.schema.space.create(..., { ... , field_count = field_count_value , ... })
The default value is
0
, which means there is no required field count.Example:
tarantool> box.space.tester.field_count --- - 0 ...
-
space_object.
id
¶ Ordinal space number. Spaces can be referenced by either name or number. Thus, if space
tester
hasid = 800
, thenbox.space.tester:insert{0}
andbox.space[800]:insert{0}
are equivalent requests.Example:
tarantool> box.space.tester.id --- - 512 ...
-
-
box.space.
_cluster
¶ _cluster
is a system space for support of the replication feature.
-
box.space.
_func
¶ _func
is a system space with function tuples made by box.schema.func.create().Tuples in this space contain the following fields:
- the numeric function id, a number,
- the function name,
- flag,
- a language name (optional): „LUA“ (default) or „C“.
The
_func
space does not include the function’s body. You continue to create Lua functions in the usual way, by sayingfunction function_name () ... end
, without adding anything in the_func
space. The_func
space only exists for storing function tuples so that their names can be used within grant/revoke functions.You can:
- Create a
_func
tuple with box.schema.func.create(), - Drop a
_func
tuple with box.schema.func.drop(), - Check whether a
_func
tuple exists with box.schema.func.exists().
Example:
In the following example, we create a function named ‘f7’, put it into Tarantool’s
_func
space and grant „execute“ privilege for this function to „guest“ user.tarantool> function f7() > box.session.uid() > end --- ... tarantool> box.schema.func.create('f7') --- ... tarantool> box.schema.user.grant('guest', 'execute', 'function', 'f7') --- ... tarantool> box.schema.user.revoke('guest', 'execute', 'function', 'f7') --- ...
-
box.space.
_index
¶ _index
is a system space.Tuples in this space contain the following fields:
id
(= id of space),iid
(= index number within space),name
,type
,opts
(e.g. unique option), [tuple-field-no
,tuple-field-type
…].
Here is what
_index
contains in a typical installation:tarantool> box.space._index:select{} --- - - [272, 0, 'primary', 'tree', {'unique': true}, [[0, 'str']]] - [280, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]] - [280, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]] - [280, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]] - [281, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]] - [281, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]] - [281, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]] - [288, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]] - [288, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]] - [289, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]] - [289, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]] - [296, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]] - [296, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]] - [296, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]] --- ...
-
box.space.
_priv
¶ _priv
is a system space where privileges are stored.Tuples in this space contain the following fields:
- the numeric id of the user who gave the privilege («grantor_id»),
- the numeric id of the user who received the privilege («grantee_id»),
- the type of object: „space“, „function“ or „universe“,
- the numeric id of the object,
- the type of operation: «read» = 1, «write» = 2, «execute» = 4, or a combination such as «read,write,execute».
You can:
- Grant a privilege with box.schema.user.grant().
- Revoke a privilege with box.schema.user.revoke().
Примечание
- Generally, privileges are granted or revoked by the owner of the object (the user who created it), or by the „admin“ user.
- Before dropping any objects or users, make sure that all their associated privileges have been revoked.
- Only the „admin“ user can grant privileges for the „universe“.
- Only the „admin“ user or the creator of a space can drop, alter, or truncate the space.
- Only the „admin“ user or the creator of a user can change a different user’s password.
-
box.space.
_schema
¶ _schema
is a system space.This space contains the following tuples:
version
tuple with version information for this Tarantool instance,cluster
tuple with the instance’s replica set ID,max_id
tuple with the maximal space ID,once...
tuples that correspond to specific box.once() blocks from the instance’s initialization file. The first field in these tuples contains thekey
value from the correspondingbox.once()
block prefixed with „once“ (e.g. oncehello), so you can easily find a tuple that corresponds to a specificbox.once()
block.
Example:
Here is what
_schema
contains in a typical installation (notice the tuples for twobox.once()
blocks,'oncebye'
and'oncehello'
):tarantool> box.space._schema:select{} --- - - ['cluster', 'b4e15788-d962-4442-892e-d6c1dd5d13f2'] - ['max_id', 512] - ['oncebye'] - ['oncehello'] - ['version', 1, 6, 8]
-
box.space.
_space
¶ _space
is a system space.Tuples in this space contain the following fields:
id
,owner
(= id of user who owns the space),name
,engine
,field_count
,flags
(e.g. temporary),format
.
These fields are established by space.create().
Example #1:
The following function will display all simple fields in all tuples of
_space
.function example() local ta = {} local i, line for k, v in box.space._space:pairs() do i = 1 line = '' while i <= #v do if type(v[i]) ~= 'table' then line = line .. v[i] .. ' ' end i = i + 1 end table.insert(ta, line) end return ta end
Here is what
example()
returns in a typical installation:tarantool> example() --- - - '272 1 _schema memtx 0 ' - '280 1 _space memtx 0 ' - '281 1 _vspace sysview 0 ' - '288 1 _index memtx 0 ' - '296 1 _func memtx 0 ' - '304 1 _user memtx 0 ' - '305 1 _vuser sysview 0 ' - '312 1 _priv memtx 0 ' - '313 1 _vpriv sysview 0 ' - '320 1 _cluster memtx 0 ' - '512 1 tester memtx 0 ' - '514 1 archive memtx 0 ' ...
Example #2:
The following requests will create a space using
box.schema.space.create()
with aformat
clause. Then it retrieves the_space
tuple for the new space. This illustrates the typical use of theformat
clause, it shows the recommended names and data types for the fields.tarantool> box.schema.space.create('TM', { > id = 12345, > format = { > [1] = {["name"] = "field_1"}, > [2] = {["type"] = "num"} > } > }) --- - index: [] on_replace: 'function: 0x41c67338' temporary: false id: 12345 engine: memtx enabled: false name: TM field_count: 0 - created ... tarantool> box.space._space:select(12345) --- - - [12345, 1, 'TM', 'memtx', 0, {}, [{'name': 'field_1'}, {'type': 'num'}]] ...
-
box.space.
_user
¶ _user
is a system space where user-names and password hashes are stored.Tuples in this space contain the following fields:
- the numeric id of the tuple («id»),
- the numeric id of the tuple’s creator,
- the name,
- the type: „user“ or „role“,
- optional password.
There are four special tuples in the
_user
space: „guest“, „admin“, „public“ and „replication“.Name ID Type Description guest 0 user Default user when connecting remotely. Usually an untrusted user with few privileges. admin 1 user Default user when using Tarantool as a console. Usually an administrative user with all privileges. public 2 role Pre-defined role, automatically assigned to new users when they are created with box.schema.user.create(user-name)
. Therefore, a convenient way to grant „read“ on space „t“ to every user that will ever exist is withbox.schema.role.grant('public','read','space','t')
.replication 3 role Pre-defined role, assigned by the „admin“ user to users who need to use replication features. To select a tuple from the
_user
space, usebox.space._user:select()
. For example, here is what happens with a select for user id = 0, which is the „guest“ user, which by default has no password:tarantool> box.space._user:select{0} --- - - [0, 1, 'guest', 'user'] ...
Предупреждение
To change tuples in the
_user
space, do not use ordinarybox.space
functions for insert or update or delete. The_user
space is special, so there are special functions which have appropriate error checking.To create a new user, use box.schema.user.create():
box.schema.user.create(user-name) box.schema.user.create(user-name, {if_not_exists = true}) box.schema.user.create(user-name, {password = password})
To change the user’s password, use box.schema.user.password():
-- To change the current user's password box.schema.user.passwd(password) -- To change a different user's password -- (usually only 'admin' can do it) box.schema.user.passwd(user-name, password)
To drop a user, use box.schema.user.drop():
box.schema.user.drop(user-name)
To check whether a user exists, use box.schema.user.exists(), which returns
true
orfalse
:box.schema.user.exists(user-name)
To find what privileges a user has, use box.schema.user.info():
box.schema.user.info(user-name)
Примечание
The maximum number of users is 32.
Example:
Here is a session which creates a new user with a strong password, selects a tuple in the
_user
space, and then drops the user.tarantool> box.schema.user.create('JeanMartin', {password = 'Iwtso_6_os$$'}) --- ... tarantool> box.space._user.index.name:select{'JeanMartin'} --- - - [17, 1, 'JeanMartin', 'user', {'chap-sha1': 't3xjUpQdrt857O+YRvGbMY5py8Q='}] ... tarantool> box.schema.user.drop('JeanMartin') --- ...
Example: use box.space functions to read _space tuples¶
This function will illustrate how to look at all the spaces, and for each
display: approximately how many tuples it contains, and the first field of
its first tuple. The function uses Tarantool box.space
functions len()
and pairs()
. The iteration through the spaces is coded as a scan of the
_space
system space, which contains metadata. The third field in
_space
contains the space name, so the key instruction
space_name = v[3]
means space_name
is the space_name
field in
the tuple of _space
that we’ve just fetched with pairs()
. The function
returns a table:
function example()
local tuple_count, space_name, line
local ta = {}
for k, v in box.space._space:pairs() do
space_name = v[3]
if box.space[space_name].index[0] ~= nil then
tuple_count = '1 or more'
else
tuple_count = '0'
end
line = space_name .. ' tuple_count =' .. tuple_count
if tuple_count == '1 or more' then
for k1, v1 in box.space[space_name]:pairs() do
line = line .. '. first field in first tuple = ' .. v1[1]
break
end
end
table.insert(ta, line)
end
return ta
end
And here is what happens when one invokes the function:
tarantool> example()
---
- - _schema tuple_count =1 or more. first field in first tuple = cluster
- _space tuple_count =1 or more. first field in first tuple = 272
- _vspace tuple_count =1 or more. first field in first tuple = 272
- _index tuple_count =1 or more. first field in first tuple = 272
- _vindex tuple_count =1 or more. first field in first tuple = 272
- _func tuple_count =1 or more. first field in first tuple = 1
- _vfunc tuple_count =1 or more. first field in first tuple = 1
- _user tuple_count =1 or more. first field in first tuple = 0
- _vuser tuple_count =1 or more. first field in first tuple = 0
- _priv tuple_count =1 or more. first field in first tuple = 1
- _vpriv tuple_count =1 or more. first field in first tuple = 1
- _cluster tuple_count =1 or more. first field in first tuple = 1
...
Example: use box.space functions to organize a _space tuple¶
The objective is to display field names and field types of a system space – using metadata to find metadata.
To begin: how can one select the _space tuple that describes _space?
A simple way is to look at the constants in box.schema, which tell us that there is an item named SPACE_ID == 288, so these statements will retrieve the correct tuple:
box.space._space:select{ 288 }
box.space._space:select{ box.schema.SPACE_ID }
Another way is to look at the tuples in box.space._index, which tell us that there is a secondary index named „name“ for space number 288, so this statement also will retrieve the correct tuple:
box.space._space.index.name:select{ '_space' }
However, the retrieved tuple is not easy to read:
tarantool> box.space._space.index.name:select{'_space'}
---
- - [280, 1, '_space', 'memtx', 0, {}, [{'name': 'id', 'type': 'num'}, {'name': 'owner',
'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},
{'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {
'name': 'format', 'type': '*'}]]
...
It looks disorganized because field number 7 has been formatted with recommended names and data types. How can one get those specific sub-fields? Since it’s visible that field number 7 is an array of maps, this for loop will do the organizing:
tarantool> do
> local tuple_of_space = box.space._space.index.name:get{'_space'}
> for _, field in ipairs(tuple_of_space[7]) do
> print(field.name .. ', ' .. field.type)
> end
> end
id, num
owner, num
name, str
engine, str
field_count, num
flags, str
format, *
---
...