Модуль key_def
В модуле key_def
есть функция, позволяющая создавать определение номеров и типов полей кортежа. Это определение обычно используется вместе с определением индекса, чтобы извлекать или сравнивать значения ключей индекса.
-
key_def.
new
(parts)¶ Создание нового экземпляра key_def.
Параметры: - parts (
table
) – типы и номера полей. В таблицеparts
должен быть хотя бы один элемент. Для каждого элемента обязательны только атрибутыtype
иfieldno
/field
.
возвращает: The parts table has components which are the same as the
parts
option in Options for space_object:create_index().fieldno
(целое число), напримерfieldno = 1
. Вместоfieldno
можно использоватьfield
.type
(строка), напримерtype = 'string'
.Остальные компоненты необязательны.
Пример №1:
key_def.new({{type = 'unsigned', fieldno = 1}})
Пример №2:
key_def.new({{type = 'string', collation = 'unicode', field = 2}})
Since version 3.2.0, you can use the standard lua operator
#
(__len metamethod) to check thekey_def
length (parts count).Example
function is_full_pkey(space, key) return #space.index[0].parts == #key end
- parts (
-
object
key_def_object
¶ Объект key_def возвращается функцией key_def.new(). У него есть следующие методы: extract_key(), compare(), compare_with_key(), merge(), totable().
-
key_def_object:
extract_key
(tuple)¶ Получение кортежа, содержащего только поля объекта
key_def
.Параметры: - tuple (
table
) – кортеж или Lua-таблица с содержимым поля
возвращает: поля, определенные для объекта
key_def
,Пример №1:
-- Предположим, что у некоторого элемента пять полей: -- 1, 99.5, 'X', nil, 99.5 -- Нас интересуют только два из них: -- третье (строка) и первое (целое число). -- Мы можем определить эти поля инструкцией k = key_def.new -- и извлечь значения командой k:extract_key. tarantool> key_def = require('key_def') --- ... tarantool> k = key_def.new({{type = 'string', fieldno = 3}, > {type = 'unsigned', fieldno = 1}}) --- ... tarantool> k:extract_key({1, 99.5, 'X', nil, 99.5}) --- - ['X', 1] ...
Пример №2
-- Теперь предположим, что элемент является кортежем в спейсе. -- У спейса есть составной индекс, построенный по полям 3 и 1. -- Мы можем передать определение индекса в качестве аргумента функции key_def.new, -- а не заполнять определение, как в примере №1. -- Результат будет тот же. key_def = require('key_def') box.schema.space.create('T') i = box.space.T:create_index('I', {parts={3, 'string', 1, 'unsigned'}}) box.space.T:insert{1, 99.5, 'X', nil, 99.5} k = key_def.new(i.parts) k:extract_key(box.space.T:get({'X', 1}))
Пример №3
-- Проходим по всем кортежам во вторичном неуникальном индексе -- и извлекаем из них значения по первичному ключу. -- Затем удаляем значения, используя уникальный индекс. -- Этот код должен входить в Lua-функцию. local key_def_lib = require('key_def') local s = box.schema.space.create('test') local pk = s:create_index('pk') local sk = s:create_index('test', {unique = false, parts = { {2, 'number', path = 'a'}, {2, 'number', path = 'b'}}}) s:insert{1, {a = 1, b = 1}} s:insert{2, {a = 1, b = 2}} local key_def = key_def_lib.new(pk.parts) for _, tuple in sk:pairs({1})) do local key = key_def:extract_key(tuple) pk:delete(key) end
- tuple (
-
key_def_object:
compare
(tuple_1, tuple_2)¶ Сравнение полей кортежей
tuple_1
иtuple_2
по определённому ключу. Пользователю не нужно писать код для сравнения отдельных полей. Учитываются типы полей и параметры сортировки. Фактически сравниваются значенияextract_key(tuple_1)
иextract_key(tuple_2)
.Параметры: возвращает: положительное число, если значения полей tuple_1 больше значений полей tuple_2 по ключу; 0, если они равны; отрицательное число, если значения полей tuple_1 меньше значений полей tuple_2 по ключу
Пример:
-- Результат этого кода будет 0 key_def = require('key_def') k = key_def.new({{type = 'string', fieldno = 3, collation = 'unicode_ci'}, {type = 'unsigned', fieldno = 1}}) k:compare({1, 99.5, 'X', nil, 99.5}, {1, 99.5, 'x', nil, 99.5})
-
key_def_object:
compare_with_key
(tuple_1, tuple_2)¶ Сравнение полей кортежей
tuple_1
с полями кортежаtuple_2
по заданному ключу. Аналогично key_def_object:compare(), за исключением того, чтоtuple_2
содержит только поля ключа. Фактически это сравнениеextract_key(tuple_1)
сtuple_2
.Параметры: возвращает: положительное число, если значения полей tuple_1 больше значений полей tuple_2 по ключу; 0, если они равны; отрицательное число, если значения полей tuple_1 меньше значений полей tuple_2 по ключу
Пример:
-- Результат этого кода будет 0 key_def = require('key_def') k = key_def.new({{type = 'string', fieldno = 3, collation = 'unicode_ci'}, {type = 'unsigned', fieldno = 1}}) k:compare_with_key({1, 99.5, 'X', nil, 99.5}, {'x', 1})
-
key_def_object:
merge
(other_key_def_object)¶ Объединение основного объекта
key_def_object
с другим объектомother_key_def_object
. Возвращает новый объектkey_def_object
, содержащий сначала все поля основного объектаkey_def_object
, а потом те поля объектаother_key_def_object
, которых не было в основном объектеkey_def_object
.Параметры: - other_key_def_object (
key_def_object
) – определение полей, которые нужно добавить
возвращает: key_def_object
Пример:
-- Результатом этого кода будет определение ключа -- по полям с fieldno = 3 и fieldno = 1 key_def = require('key_def') k = key_def.new({{type = 'string', fieldno = 3}}) k2= key_def.new({{type = 'unsigned', fieldno = 1}, {type = 'string', fieldno = 3}}) k:merge(k2)
- other_key_def_object (
-
key_def_object:
totable
()¶ Возвращает таблицу с содержимым
key_def_object
. Функция противоположна функцииkey_def.new()
:key_def.new()
принимает таблицу, а возвращает объектkey_def
.key_def_object:totable()
принимает объектkey_def
, а возвращает таблицу.
Это удобно при подготовке входных данных для методов сериализации (
_serialize
).возвращает: таблица Пример:
-- Результатом этого кода будет таблица с type = 'string', fieldno = 3 key_def = require('key_def') k = key_def.new({{type = 'string', fieldno = 3}}) k:totable()
-
key_def_object:
validate_key
(key)¶ Since version 3.1.0
Validates all parts of the specified key match the key definition. Partial keys are considered valid. Returns nothing on success.
If the key fails the validation, a
box.error
type exception is raised.Пример:
-- Create a rule: key = {1 ('unsigned'), 2 (string)} -- Validate key {1001} (only id data type). Returns nothing -- Validate key {'x'}. ER_KEY_PART_TYPE is raised -- Validate key ({1000, 2000}). ER_KEY_PART_TYPE is raised -- Validate key ({1000, 'abc', 'xyz'}). ER_KEY_PART_COUNT is raised tarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'}, > {fieldno = 2, type = 'string'}}) --- ... tarantool> key_def:validate_key({1001}) --- ... tarantool> key_def:validate_key({'x'}) --- - error: 'Supplied key type of part 0 does not match index part type: expected unsigned' ... tarantool> key_def:validate_key({1000, 2000}) --- - error: 'Supplied key type of part 1 does not match index part type: expected string' ... tarantool> key_def:validate_key({1000, 'abc', 'xyz'}) --- - error: 'Invalid key part count: (expected [0..2], got 3) ...
-
key_def_object:
validate_full_key
(key)¶ Since version 3.1.0
Validates whether they input
key
contains all fields and mathces the rules of the key definition object. Returns nothing on success.If the key fails the validation, a
box.error
type exception is raised.Пример:
-- Create a rule: key = {1 ('unsigned'), 2 (string)} -- Validate key {100, "Testuser"}. Returns nothing -- Validate key ({100}). ER_EXACT_MATCH is raised tarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'}, > {fieldno = 2, type = 'string'}}) --- ... tarantool> key_def:validate_full_key({100, "Testuser"}) --- ... tarantool> key_def:validate_full_key({100}) --- - error: 'Invalid key part count in an exact match: (expected 2, got 1) ...
-
key_def_object:
validate_tuple
(tuple)¶ Since version 3.1.0
Validates whether the
tuple
matches the rules of the key definition object Returns nothing on success.If the key fails the validation, a
box.error
type exception is raised.Пример:
-- Create a rule: tuple = {id (number), name (string), age (number)} -- Validate tuple {1001, "Testuser", 28}. Returns nothing tarantool> key_def = require('key_def').new({ > {fieldno = 1, type = 'number'}, > {fieldno = 2, type = 'string'}, > {fieldno = 3, type = 'number'}) --- ... tarantool> key_def:validate_tuple({1001, "Testuser", 28}) --- ...
-
key_def_object:
compare_keys
(key_a, key_b)¶ Since version 3.1.0
Compares two keys against each other and according to the key definition object. On success, returns:
<0
ifkey_a
parts are less thankey_b
parts0
ifkey_a
parts are equal tokey_b
parts>0
ifkey_a
parts are greater thankey_b
parts
If any key does not match the key definition rules, a
box.error
type exception is raised.Пример:
-- Create a rule: key = {1 ('unsigned'), 2 (string)} -- Validate keys ({1000, 'x'}, {1000, 'y'}). Returns -1 -- Validate keys ({1000, 'x'}, {1000, 'x'}). Returns 0 -- Validate keys ({1000, 'x'}, {1000}). Returns 0 -- Validate keys ({2000, 'x'}, {1000, 'x'}). Returns 1 tarantool> key_def = require('key_def').new({{fieldno = 1, type = 'unsigned'}, > {fieldno = 2, type = 'string'}}) --- ... tarantool> key_def:compare_keys({1000, 'x'}, {1000, 'y'}) --- - -1 ... tarantool> key_def:compare_keys({1000, 'x'}, {1000, 'x'}) --- - 0 ... tarantool> key_def:compare_keys({1000, 'x'}, {1000}) --- - 0 ... tarantool> key_def:compare_keys({2000, 'x'}, {1000, 'x'}) --- - 1 ...
-