Skip to content

Commit 5934251

Browse files
committed
Index options API
1 parent 6c889b2 commit 5934251

38 files changed

+1177
-799
lines changed

doc/code_snippets/README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,26 @@ To test all the examples, go to the `doc/code_snippets` folder and execute the `
2727
.rocks/bin/luatest
2828
```
2929

30-
To run a specific example with tests, use the `luatest` command with the `-c` option, for example:
30+
To test the examples from the specified directory, pass its relative path to the `luatest` command:
31+
32+
```shell
33+
.rocks/bin/luatest test/transactions
34+
```
35+
36+
To test a specific example with the `stdout` output enabled, use the `luatest` command with the `-c` option, for example:
3137

3238
```shell
3339
.rocks/bin/luatest -c test/http_client/get_test.lua
3440
```
3541

36-
You can also run the `httpbin` service locally using Docker:
42+
Note that the HTTP client samples (placed in `test/http_client`) use the `httpbin` service.
43+
You can run `httpbin` locally using Docker to stabilize test results:
3744

3845
```shell
3946
docker run -p 80:80 kennethreitz/httpbin
4047
```
4148

42-
In this case, replace `https://httpbin.org` links with `http://127.0.0.1` to test the examples.
49+
In this case, you need to replace `https://httpbin.org` links with `http://127.0.0.1`.
4350

4451

4552
## Referencing code snippets
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_indexes = function(cg)
19+
cg.server:exec(function()
20+
-- Create a space --
21+
bands = box.schema.space.create('bands')
22+
23+
-- Specify field names and types --
24+
box.space.bands:format({
25+
{ name = 'id', type = 'unsigned' },
26+
{ name = 'band_name', type = 'string' },
27+
{ name = 'year', type = 'unsigned' }
28+
})
29+
30+
-- Create a primary index --
31+
box.space.bands:create_index('primary', { parts = { 1 } })
32+
33+
-- Create a unique secondary index --
34+
box.space.bands:create_index('band', { parts = { 2 } })
35+
36+
-- Create a non-unique secondary index --
37+
box.space.bands:create_index('year', { parts = { { 3 } }, unique = false })
38+
39+
-- Create a multi-part index --
40+
box.space.bands:create_index('year_band', { parts = { 3, 2 } })
41+
42+
-- Insert test data --
43+
box.space.bands:insert { 1, 'Roxette', 1986 }
44+
box.space.bands:insert { 2, 'Scorpions', 1965 }
45+
box.space.bands:insert { 3, 'Ace of Base', 1987 }
46+
box.space.bands:insert { 4, 'The Beatles', 1960 }
47+
box.space.bands:insert { 5, 'Pink Floyd', 1965 }
48+
box.space.bands:insert { 6, 'The Rolling Stones', 1962 }
49+
box.space.bands:insert { 7, 'The Doors', 1965 }
50+
box.space.bands:insert { 8, 'Nirvana', 1987 }
51+
box.space.bands:insert { 9, 'Led Zeppelin', 1968 }
52+
box.space.bands:insert { 10, 'Queen', 1970 }
53+
54+
select_all = bands.index.band:select()
55+
select_one = bands.index.year_band:select { 1960, 'The Beatles' }
56+
select_limit = bands.index.year:select({ 1965 }, { iterator = 'GT', limit = 3 })
57+
select_after_tuple = bands.index.primary:select({}, { after = { 4, 'The Beatles', 1960 }, limit = 3 })
58+
59+
result, position = bands.index.primary:select({}, { limit = 3, fetch_pos = true })
60+
select_after_position = bands.index.primary:select({}, { limit = 3, after = position })
61+
62+
-- Tests --
63+
t.assert_equals(select_all[1], { 3, 'Ace of Base', 1987 })
64+
t.assert_equals(select_one[1], {4, 'The Beatles', 1960})
65+
t.assert_equals(select_limit, { { 9, 'Led Zeppelin', 1968 }, { 10, 'Queen', 1970 }, { 1, 'Roxette', 1986 } })
66+
t.assert_equals(select_after_tuple, { { 5, 'Pink Floyd', 1965 }, { 6, 'The Rolling Stones', 1962 }, { 7, 'The Doors', 1965 } })
67+
t.assert_equals(select_after_position, { { 4, 'The Beatles', 1960 }, { 5, 'Pink Floyd', 1965 }, { 6, 'The Rolling Stones', 1962 } })
68+
end)
69+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_func_multikey_index = function(cg)
19+
cg.server:exec(function()
20+
tester = box.schema.space.create('withdata')
21+
tester:format({ { name = 'name', type = 'string' },
22+
{ name = 'address', type = 'string' } })
23+
name_index = tester:create_index('name', { parts = { { field = 1, type = 'string' } } })
24+
function_code = [[function(tuple)
25+
local address = string.split(tuple[2])
26+
local ret = {}
27+
for _, v in pairs(address) do
28+
table.insert(ret, {utf8.upper(v)})
29+
end
30+
return ret
31+
end]]
32+
box.schema.func.create('address',
33+
{ body = function_code,
34+
is_deterministic = true,
35+
is_sandboxed = true,
36+
is_multikey = true })
37+
addr_index = tester:create_index('addr', { unique = false,
38+
func = 'address',
39+
parts = { { field = 1, type = 'string',
40+
collation = 'unicode_ci' } } })
41+
tester:insert({ "James", "SIS Building Lambeth London UK" })
42+
tester:insert({ "Sherlock", "221B Baker St Marylebone London NW1 6XE UK" })
43+
addr_index:select('Uk')
44+
45+
-- Tests --
46+
t.assert_equals(addr_index:select('Uk'), {
47+
{ 'James', 'SIS Building Lambeth London UK' },
48+
{ 'Sherlock', '221B Baker St Marylebone London NW1 6XE UK' },
49+
})
50+
end)
51+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_func_index = function(cg)
19+
cg.server:exec(function()
20+
box.schema.space.create('tester')
21+
box.space.tester:create_index('i', { parts = { { field = 1, type = 'string' } } })
22+
function_code = [[function(tuple) return {string.sub(tuple[2],1,1)} end]]
23+
box.schema.func.create('my_func',
24+
{ body = function_code, is_deterministic = true, is_sandboxed = true })
25+
box.space.tester:create_index('func_index', { parts = { { field = 1, type = 'string' } },
26+
func = 'my_func' })
27+
box.space.tester:insert({ 'a', 'wombat' })
28+
box.space.tester:insert({ 'b', 'rabbit' })
29+
box.space.tester.index.func_index:select('w')
30+
box.space.tester.index.func_index:select(box.func.my_func:call({ { 'tester', 'wombat' } }))
31+
32+
-- Tests --
33+
t.assert_equals(box.space.tester.index.func_index:select('w')[1], { 'a', 'wombat' })
34+
t.assert_equals(box.space.tester.index.func_index:select(box.func.my_func:call({ { 'tester', 'wombat' } }))[1], { 'a', 'wombat' })
35+
end)
36+
end
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_json_path_index = function(cg)
19+
cg.server:exec(function()
20+
box.schema.space.create('space1')
21+
box.space.space1:create_index('primary', { parts = { { field = 1,
22+
type = 'scalar',
23+
path = 'age' } } })
24+
box.space.space1:insert({ { age = 44 } })
25+
box.space.space1:select(44)
26+
27+
box.schema.space.create('space2')
28+
box.space.space2:format({ { 'id', 'unsigned' }, { 'data', 'map' } })
29+
box.space.space2:create_index('info', { parts = { { 'data.full_name["firstname"]', 'str' },
30+
{ 'data.full_name["surname"]', 'str' } } })
31+
box.space.space2:insert({ 1, { full_name = { firstname = 'John', surname = 'Doe' } } })
32+
box.space.space2:select { 'John' }
33+
34+
-- Tests --
35+
json = require('json')
36+
t.assert_equals(json.encode(box.space.space1:select(44)[1][1]), "{\"age\":44}")
37+
t.assert_equals(json.encode(box.space.space2:select { 'John' }[1][2]), "{\"full_name\":{\"surname\":\"Doe\",\"firstname\":\"John\"}}")
38+
end)
39+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_indexes = function(cg)
19+
cg.server:exec(function()
20+
-- Create a space --
21+
box.schema.space.create('tester')
22+
23+
-- Use the 'unicode' collation --
24+
box.space.tester:create_index('unicode', { parts = { { field = 1,
25+
type = 'string',
26+
collation = 'unicode' } } })
27+
28+
-- Use the 'unicode_ci' collation --
29+
box.space.tester:create_index('unicode_ci', { parts = { { field = 1,
30+
type = 'string',
31+
collation = 'unicode_ci' } } })
32+
33+
-- Insert test data --
34+
box.space.tester:insert { 'ЕЛЕ' }
35+
box.space.tester:insert { 'елейный' }
36+
box.space.tester:insert { 'ёлка' }
37+
38+
-- Returns nil --
39+
select_unicode = box.space.tester.index.unicode:select({ 'ЁлКа' })
40+
-- Returns 'ёлка' --
41+
select_unicode_ci = box.space.tester.index.unicode_ci:select({ 'ЁлКа' })
42+
43+
-- Tests --
44+
t.assert_equals(select_unicode[1], nil)
45+
t.assert_equals(select_unicode_ci[1], { 'ёлка' })
46+
end)
47+
end
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
local fio = require('fio')
2+
local server = require('luatest.server')
3+
local t = require('luatest')
4+
local g = t.group()
5+
g.before_each(function(cg)
6+
cg.server = server:new {
7+
box_cfg = {},
8+
workdir = fio.cwd() .. '/tmp'
9+
}
10+
cg.server:start()
11+
end)
12+
13+
g.after_each(function(cg)
14+
cg.server:stop()
15+
cg.server:drop()
16+
end)
17+
18+
g.test_indexes = function(cg)
19+
cg.server:exec(function()
20+
-- Create a space --
21+
bands = box.schema.space.create('bands')
22+
23+
-- Specify field names and types --
24+
box.space.bands:format({
25+
{ name = 'id', type = 'unsigned' },
26+
{ name = 'band_name', type = 'string' },
27+
{ name = 'year', type = 'unsigned' }
28+
})
29+
30+
-- Create a primary index --
31+
box.space.bands:create_index('primary', { parts = { 'id' } })
32+
33+
-- Create a unique secondary index --
34+
box.space.bands:create_index('band', { parts = { 'band_name' } })
35+
36+
-- Create a non-unique secondary index --
37+
box.space.bands:create_index('year', { parts = { { 'year' } }, unique = false })
38+
39+
-- Create a multi-part index --
40+
box.space.bands:create_index('year_band', { parts = { { 'year' }, { 'band_name' } } })
41+
42+
-- Insert test data --
43+
box.space.bands:insert { 1, 'Roxette', 1986 }
44+
box.space.bands:insert { 2, 'Scorpions', 1965 }
45+
box.space.bands:insert { 3, 'Ace of Base', 1987 }
46+
box.space.bands:insert { 4, 'The Beatles', 1960 }
47+
box.space.bands:insert { 5, 'Pink Floyd', 1965 }
48+
box.space.bands:insert { 6, 'The Rolling Stones', 1962 }
49+
box.space.bands:insert { 7, 'The Doors', 1965 }
50+
box.space.bands:insert { 8, 'Nirvana', 1987 }
51+
box.space.bands:insert { 9, 'Led Zeppelin', 1968 }
52+
box.space.bands:insert { 10, 'Queen', 1970 }
53+
54+
-- Count the number of tuples that match the full key value
55+
count = box.space.bands.index.year:count(1965)
56+
--[[
57+
---
58+
- 3
59+
...
60+
--]]
61+
62+
-- Count the number of tuples that match the partial key value
63+
count_partial = box.space.bands.index.year_band:count(1965)
64+
--[[
65+
---
66+
- 3
67+
...
68+
--]]
69+
70+
-- Find the minimum value in the specified index
71+
min = box.space.bands.index.year:min()
72+
--[[
73+
---
74+
- [4, 'The Beatles', 1960]
75+
...
76+
--]]
77+
78+
-- Find the minimum value that matches the partial key value
79+
min_partial = box.space.bands.index.year_band:min(1965)
80+
--[[
81+
---
82+
- [5, 'Pink Floyd', 1965]
83+
...
84+
--]]
85+
86+
-- Find the maximum value in the specified index
87+
max = box.space.bands.index.year:max()
88+
--[[
89+
---
90+
- [8, 'Nirvana', 1987]
91+
...
92+
--]]
93+
94+
-- Find the maximum value that matches the partial key value
95+
max_partial = box.space.bands.index.year_band:max(1965)
96+
--[[
97+
---
98+
- [7, 'The Doors', 1965]
99+
...
100+
--]]
101+
102+
-- Tests --
103+
t.assert_equals(count, 3)
104+
t.assert_equals(count_partial, 3)
105+
t.assert_equals(min, { 4, 'The Beatles', 1960 })
106+
t.assert_equals(min_partial, { 5, 'Pink Floyd', 1965 })
107+
t.assert_equals(max, { 8, 'Nirvana', 1987 })
108+
t.assert_equals(max_partial, { 7, 'The Doors', 1965 })
109+
end)
110+
end

0 commit comments

Comments
 (0)