Модуль key_def | Tarantool
Документация на русском языке
поддерживается сообществом

Модуль key_def

В модуле key_def есть функция, позволяющая создавать определение номеров и типов полей кортежа. Это определение обычно используется вместе с определением индекса, чтобы извлекать или сравнивать значения ключей индекса.

key_def.new(parts)

Создание нового экземпляра key_def.

Параметры:
  • parts (table) – типы и номера полей. В таблице parts должен быть хотя бы один элемент. Для каждого элемента обязательны только атрибуты type и fieldno/field.
возвращает:

объект key_def

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 the key_def length (parts count).

Example

function is_full_pkey(space, key)
return #space.index[0].parts == #key
end
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
key_def_object:compare(tuple_1, tuple_2)

Сравнение полей кортежей tuple_1 и tuple_2 по определённому ключу. Пользователю не нужно писать код для сравнения отдельных полей. Учитываются типы полей и параметры сортировки. Фактически сравниваются значения extract_key(tuple_1) и extract_key(tuple_2).

Параметры:
  • tuple1 (table) – кортеж или Lua-таблица с содержимым поля
  • tuple2 (table) – кортеж или Lua-таблица с содержимым поля
возвращает:

положительное число, если значения полей 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.

Параметры:
  • tuple1 (table) – кортеж или Lua-таблица с содержимым поля
  • tuple2 (table) – кортеж или Lua-таблица с содержимым поля
возвращает:

положительное число, если значения полей 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)
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 if key_a parts are less than key_b parts
  • 0 if key_a parts are equal to key_b parts
  • >0 if key_a parts are greater than key_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
...
Нашли ответ на свой вопрос?
Обратная связь