Версия:

Вложенный модуль box.tuple

Вложенный модуль box.tuple

Общие сведения

Вложенный модуль box.tuple предоставляет доступ только для чтения к пользовательским данным типа кортеж tuple. С его помощью для отдельного кортежа можно сделать следующее: выборочно искать содержимое поля, получать информацию о размере, проводить итерацию по всем полям и выполнять преобразование в Lua-таблицу.

Индекс

Ниже приведен перечень всех функций модуля box.tuple.

Имя Использование
box.tuple.new() Создание кортежа
#tuple_object Подсчет полей кортежа
tuple_object:bsize() Подсчет байтов в кортеже
tuple_object[field-number] Get a tuple’s field by specifying a number
tuple_object[field-name] Get a tuple’s field by specifying a name
tuple_object[field-path] Get a tuple’s fields or parts by specifying a path
tuple_object:find() Получение номера первого поля, совпадающего с искомым значением
tuple_object:findall() Получение номеров всех полей, совпадающих с искомым значением
tuple_object:transform() Удаление (и замена) полей кортежа
tuple_object:unpack() Получение полей кортежа
tuple_object:totable() Получение полей кортежа в виде таблицы
tuple_object:tomap() Получение полей кортежа в виде таблицы, а также пар ключ-значение
tuple_object:pairs() Подготовка к итерации
tuple_object:update() Обновление кортежа
box.tuple.new(value)

Создание нового кортежа либо из скаляра, либо из Lua-таблицы. Возможен и вариант получения новых кортежей из запросов select или insert. или replace, или update Tarantool’а, которые можно рассматривать в качестве операторов, косвенно выполняющих операцию создания new().

Параметры:
  • value (lua-value) – значение, которое станет содержимым кортежа.
возвращается:

новый кортеж

тип возвращаемого значения:
 

кортеж

В следующем примере x будет представлять собой новый объект таблицы, который содержит один кортеж, а t будет представлять собой объект кортежа. Если ввести команду t, будет получен весь кортеж t.

Пример:

tarantool> x = box.space.tester:insert{
             >   33,
             >   tonumber('1'),
             >   tonumber64('2')
             > }:totable()
    ---
    ...
    tarantool> t = box.tuple.new{'abc', 'def', 'ghi', 'abc'}
    ---
    ...
    tarantool> t
    ---
    - ['abc', 'def', 'ghi', 'abc']
    ...
object tuple_object
#<tuple_object>

Оператор # на языке Lua означает «вернуть количество компонентов». Таким образом, если t представляет собой кортеж, то #t вернет количество полей.

тип возвращаемого значения:
 число

В следующем примере создается кортеж под названием t, а затем возвращается количество полей в кортеже t.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4'}
    ---
    ...
    tarantool> #t
    ---
    - 4
    ...
tuple_object:bsize()

Если t – это экземпляр кортежа, то t:bsize() вернет количество байтов в кортеже. Как для движка базы данных memtx, так и для движка vinyl максимальное количество, используемое по умолчанию, составляет один мегабайт (memtx_max_tuple_size или vinyl_max_tuple_size). В каждом поле есть один или более байтов «длины», которые предваряют само содержимое поля, поэтому bsize() вернет значение, которое незначительно больше, чем сумма длин всего содержимого.

The value does not include the size of «struct tuple» (for the current size of this structure look in the tuple.h file in Tarantool’s source code).

возвращается:количество байтов
тип возвращаемого значения:
 число

In the following example, a tuple named t is created which has three fields, and for each field it takes one byte to store the length and three bytes to store the contents, and then there is one more byte to store a count of the number of fields, so bsize() returns 3*(1+3)+1. This is the same as the size of the string that msgpack.encode({„aaa“,“bbb“,“ccc“}) would return.

tarantool> t = box.tuple.new{'aaa', 'bbb', 'ccc'}
  ---
  ...
  tarantool> t:bsize()
  ---
  - 13
  ...
<tuple_object>[field-number]

Если t – это экземпляр кортежа, то t[номер-поля] вернет поле под номером номер-поля в кортеже. Первое поле – это t[1].

возвращается:значение поля.
тип возвращаемого значения:
 Lua-значение

В следующем примере создается кортеж под названием t, а затем возвращается второе поле в кортеже t.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4'}
  ---
  ...
  tarantool> t[2]
  ---
  - Fld#2
  ...
<tuple_object>[field-name]

If t is a tuple instance, t['field-name'] will return the field named „field-name“ in the tuple. Fields have names if the tuple has been retrieved from a space that has an associated format.

возвращается:значение поля.
тип возвращаемого значения:
 Lua-значение

In the following example, a tuple named t is returned from replace and then the second field in t named „field2“ is returned.

tarantool> format = {}
---
...
tarantool> format[1] = {name = 'field1', type = 'unsigned'}
---
...
tarantool> format[2] = {name = 'field2', type = 'string'}
---
...
tarantool> s = box.schema.space.create('test', {format = format})
---
...
tarantool> pk = s:create_index('pk')
---
...
tarantool> t = s:replace{1, 'Я'}
---
...
tarantool> t['field2']
---
- Я
...
<tuple_object>[field-path]

If t is a tuple instance, t['path'] will return the field or subset of fields that are in path. path must be a well formed JSON specification. path may contain field names if the tuple has been retrieved from a space that has an associated format.

To prevent ambiguity, Tarantool first tries to interpret the request as tuple_object[field-number] or tuple_object[field-name]. If and only if that fails, Tarantool tries to interpret the request as tuple_object[field-path].

The path must be a well formed JSON specification, but it may be preceded by „.“. The „.“ is a signal that the path acts as a suffix for the tuple.

The advantage of specifying a path is that Tarantool will use it to search through a tuple body and get only the tuple part, or parts, that are actually necessary.

In the following example, a tuple named t is returned from replace and then only the relevant part (in this case, matching a name) of a relevant field is returned. Namely: the second field, the sixth part, the value following „value=“.

tarantool> format = {}
---
...
tarantool> format[1] = {name = 'field1', type = 'unsigned'}
---
...
tarantool> format[2] = {name = 'field2', type = 'array'}
---
...
tarantool> format[3] = {name = 'field4', type = 'string' }
---
...
tarantool> format[4] = {name = "[2][6]['пw']['Я']", type = 'string'}
---
...
tarantool> s = box.schema.space.create('test', {format = format})
---
...
tarantool> pk = s:create_index('pk')
---
...
tarantool> field2 = {1, 2, 3, "4", {5,6,7}, {пw={Я="п"}, key="V!", value="K!"}}
---
...
tarantool> t = s:replace{1, field2, "123456", "Not K!"}
---
...
tarantool> t["[2][6]['value']"]
---
- K!
...
tuple_object:find([field-number, ]search-value)
tuple_object:findall([field-number, ]search-value)

Если t – это экземпляр кортежа, то t:find(search-value) вернет номер первого поля в t, которое совпадает с искомым значением, а t:findall(search-value [, search-value ...]) вернет номера всех колей в t, которые совпадают с искомым значением. Можно дополнительно добавить числовой аргумент field-number перед search-value, чтобы задать условие “начинать поиск с номера поля field-number.”

возвращается:номер поля в кортеже.
тип возвращаемого значения:
 число

В следующем примере создается кортеж с именем t, а затем: возвращается номер первого поля в t, которое совпадает с „a“, затем возвращаются номера всех полей в t, которые совпадают с „a“, затем возвращаются номера всех полей в t, которые совпадают с „a“, и находятся на втором месте или далее.

tarantool> t = box.tuple.new{'a', 'b', 'c', 'a'}
  ---
  ...
  tarantool> t:find('a')
  ---
  - 1
  ...
  tarantool> t:findall('a')
  ---
  - 1
  - 4
  ...
  tarantool> t:findall(2, 'a')
  ---
  - 4
  ...
tuple_object:transform(start-field-number, fields-to-remove[, field-value, ...])

Если t – это экземпляр кортежа, то t:transform(start-field-number,fields-to-remove) вернет кортеж, где начиная с поля start-field-number, удаляется количество полей (fields-to-remove). Дополнительно можно добавить аргументы после fields-to-remove, чтобы указать новые значения на замену удаленных.

If the original tuple comes from a space that has been formatted with a format clause, the formatting will not be preserved for the result tuple.

Параметры:
  • start-field-number (integer) – начиная с 1, может быть отрицательным
  • fields-to-remove (integer) –
  • field-value(s) (lua-value) –
возвращается:

кортеж

тип возвращаемого значения:
 

кортеж

В следующем примере создается кортеж под названием t, а затем начиная со второго поля, удаляются два поля, а одно новое поле добавляется, затем возвращается результат.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'}
  ---
  ...
  tarantool> t:transform(2, 2, 'x')
  ---
  - ['Fld#1', 'x', 'Fld#4', 'Fld#5']
  ...
tuple_object:unpack([start-field-number[, end-field-number]])

Если t – это экземпляр кортежа, то t:unpack() вернет все поля, t:unpack(1) вернет все поля, начиная с поля №1, t:unpack(1,5) вернет все поля между полем №1 и полем №5.

возвращается:поле или поля из кортежа.
тип возвращаемого значения:
 Lua-значение

В следующем примере создается кортеж под названием t, а затем делается выборка всех полей, возвращается результат.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'}
  ---
  ...
  tarantool> t:unpack()
  ---
  - Fld#1
  - Fld#2
  - Fld#3
  - Fld#4
  - Fld#5
  ...
tuple_object:totable([start-field-number[, end-field-number]])

Если t – это экземпляр кортежа, то t:totable() вернет все поля, t:totable(1) вернет все поля, начиная с поля №1, t:totable(1,5) вернет все поля между полем №1 и полем №5.

Рекомендуется использовать t:totable(), а не t:unpack().

возвращается:поле или поля из кортежа
тип возвращаемого значения:
 Lua-таблица

В следующем примере создается кортеж под названием t, а затем делается выборка всех полей, возвращается результат.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'}
  ---
  ...
  tarantool> t:totable()
  ---
  - ['Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5']
  ...
tuple_object:tomap([options])

В Lua-таблице могут быть индексированные значения, которые также называются пары ключ-значение. Например, здесь:

a = {}; a['field1'] = 10; a['field2'] = 20

a – это таблица с «field1: 10» и «field2: 20».

Функция tuple_object:totable() вернет только таблицу со значениями. А функция tuple_object:tomap() вернет таблицу не только со значениями, но и с парами ключ-значение.

Это сработает только в том случае, если кортеж приходит из спейса, который был форматирован посредством оператора формата.

Параметры:
  • options (table) –

    the only possible option is names_only.

    If names_only is false or omitted (default), then all the fields will appear twice, first with numeric headings and second with name headings.

    If names_only is true, then all the fields will appear only once, with name headings.

возвращается:

field-number:value pair(s) and key:value pair(s) from the tuple

тип возвращаемого значения:
 

Lua-таблица

In the following example, a tuple named t1 is returned from a space that has been formatted, then tables named t1map1 and t1map2 are produced from t1.

format = {{'field1', 'unsigned'}, {'field2', 'unsigned'}}
s = box.schema.space.create('test', {format = format})
s:create_index('pk',{parts={1,'unsigned',2,'unsigned'}})
t1 = s:insert{10, 20}
t1map = t1:tomap()
t1map_names_only = t1:tomap({names_only=true})

t1map will contain «1: 10», «2: 20», «field1: 10», «field2: 20».

t1map_names_only will contain «field1: 10», «field2: 20».

tuple_object:pairs()

В языке Lua метод lua-table-value:pairs() возвращает: функция, значение-Lua-таблицы, nil. В Tarantool’е метод расширен так, что tuple-value:pairs() возвращает: функция, значение-кортежа, nil, – что используется для Lua-итераторов, поскольку они обходят компоненты значения до тех пор, пока не достигнут маркера.

возвращается:функция, значение кортежа, nil
тип возвращаемого значения:
 функция, Lua-значение, nil

В следующем примере создается кортеж под названием t, а затем все его поля выбираются с помощью Lua-цикла for.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'}
  ---
  ...
  tarantool> tmp = ''
  ---
  ...
  tarantool> for k, v in t:pairs() do
           >   tmp = tmp .. v
           > end
  ---
  ...
  tarantool> tmp
  ---
  - Fld#1Fld#2Fld#3Fld#4Fld#5
  ...
tuple_object:update({{operator, field_no, value}, ...})

Обновление кортежа.

Эта функция обновляет кортеж, который находится не в спейсе. Ср. функцию box.space.space-name:update(key, {{format, field_no, value}, ...}), которая обновляет кортеж в спейсе.

Более подробную информацию см. в описании operator, field_no и value в разделе box.space.space-name:update{key, format, {field_number, value}…).

If the original tuple comes from a space that has been formatted with a format clause, the formatting will be preserved for the result tuple.

Параметры:
  • operator (string) – тип операции, представленный строкой (например, „=“ означает „присвоить новое значение“)
  • field_no (number) – к какому полю применяется операция. Номер поля может быть отрицательным, что означает, что позиция рассчитывается с конца кортежа. (#кортеж + отрицательный номер поля + 1)
  • value (lua_value) – какое значение применяется
возвращается:

новый кортеж

тип возвращаемого значения:
 

кортеж

В следующем примере создается кортеж под названием t, а затем второе поле обновляется до равного „B“.

tarantool> t = box.tuple.new{'Fld#1', 'Fld#2', 'Fld#3', 'Fld#4', 'Fld#5'}
  ---
  ...
  tarantool> t:update({{'=', 2, 'B'}})
  ---
  - ['Fld#1', 'B', 'Fld#3', 'Fld#4', 'Fld#5']
  ...

Пример

Представленная ниже функция проиллюстрирует, как можно преобразовать кортежи в Lua-таблицы и списки скаляров и обратно:

tuple = box.tuple.new({scalar1, scalar2, ... scalar_n}) -- скаляры в кортеж
  lua_table = {tuple:unpack()}                            -- кортеж в Lua-таблицу
  lua_table = tuple:totable()                             -- кортеж в Lua-таблицу
  scalar1, scalar2, ... scalar_n = tuple:unpack()         -- кортеж в скаляры
  tuple = box.tuple.new(lua_table)                        -- Lua-таблицу в кортеж

Затем она найдет поле, которое содержит значение „b“, удалит это поле из кортежа и отобразит количество байтов, оставшихся в кортеже. Данная функция использует следующие функции box.tuple Tarantool’а: new(), unpack(), find(), transform(), bsize().

function example()
    local tuple1, tuple2, lua_table_1, scalar1, scalar2, scalar3, field_number
    local luatable1 = {}
    tuple1 = box.tuple.new({'a', 'b', 'c'})
    luatable1 = tuple1:totable()
    scalar1, scalar2, scalar3 = tuple1:unpack()
    tuple2 = box.tuple.new(luatable1[1],luatable1[2],luatable1[3])
    field_number = tuple2:find('b')
    tuple2 = tuple2:transform(field_number, 1)
    return 'tuple2 = ' , tuple2 , ' # of bytes = ' , tuple2:bsize()
  end

… А вот что происходит, когда вызывается функция:

tarantool> example()
  ---
  - tuple2 =
  - ['a', 'c']
  - ' # of bytes = '
  - 5
  ...