-
Notifications
You must be signed in to change notification settings - Fork 2
/
sqlite-list-append.lua
121 lines (105 loc) · 3.37 KB
/
sqlite-list-append.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
-- https://www.sqlite.org/isolation.html
-- https://www.sqlite.org/threadsafe.html
-- https://www.sqlite.org/atomiccommit.html
local sqlite3 = require('lsqlite3')
local molly = require('molly')
local os = require('os')
print('SQLite version:', sqlite3.version())
print('lsqlite3 library version:', sqlite3.lversion())
local function sqlite_insert(stmt, key, val)
local ok = stmt:bind_values(key, val)
if ok ~= sqlite3.OK then
return false
end
ok = stmt:step()
if ok ~= sqlite3.DONE then
return false
end
stmt:reset()
return true
end
local function sqlite_select(stmt, key)
local values = {}
for row in stmt:nrows() do
if row.key == key then
table.insert(values, row.val)
end
end
return values
end
local sqlite_list_append = molly.client.new()
sqlite_list_append.open = function(self)
assert(type(self) == 'table')
self.db = assert(sqlite3.open_memory(), 'database handle is nil')
if self.db == nil then
error('database handle is nil')
end
-- See explanation in https://www.sqlite.org/pragma.html
assert(sqlite3.OK == self.db:exec('PRAGMA journal_mode = WAL'))
assert(sqlite3.OK == self.db:exec('PRAGMA synchronous = normal'))
assert(sqlite3.OK == self.db:exec('PRAGMA mmap_size = 30000000000'))
assert(sqlite3.OK == self.db:exec('PRAGMA page_size = 32768'))
return true
end
sqlite_list_append.setup = function(self)
assert(type(self) == 'table')
assert(sqlite3.OK == self.db:exec('CREATE TABLE IF NOT EXISTS list_append (key INT NOT NULL, val INT)'))
self.insert_stmt = assert(self.db:prepare('INSERT INTO list_append VALUES (?, ?)'))
self.select_stmt = assert(self.db:prepare('SELECT key, val FROM list_append ORDER BY key'))
return true
end
local IDX_MOP_TYPE = 1
local IDX_MOP_KEY = 2
local IDX_MOP_VAL = 3
sqlite_list_append.invoke = function(self, op)
assert(type(self) == 'table')
local mop = op.value[1] -- TODO: Support more than one mop in operation.
local mop_key = mop[IDX_MOP_KEY]
local type = 'ok'
if mop[IDX_MOP_TYPE] == 'r' then
mop[IDX_MOP_VAL] = sqlite_select(self.select_stmt, mop_key)
elseif mop[IDX_MOP_TYPE] == 'append' then
local ok = sqlite_insert(self.insert_stmt, mop_key, mop[IDX_MOP_VAL])
if ok == false then
type = 'fail'
end
else
error('Unknown operation')
end
return {
value = { mop },
f = op.f,
process = op.process,
type = type,
}
end
sqlite_list_append.teardown = function(self)
assert(type(self) == 'table')
return true
end
sqlite_list_append.close = function(self)
assert(type(self) == 'table')
-- Close database. All SQL statements prepared using
-- db:prepare() should have been finalized before this
-- function is called. The function returns sqlite3.OK on
-- success or else a numerical error code.
if self.db:isopen() then
assert(self.db:close() == sqlite3.OK)
end
return true
end
local test_options = {
create_reports = true,
threads = 1,
}
local ok, err = molly.runner.run_test({
client = sqlite_list_append,
generator = molly.gen.time_limit(molly.tests.list_append_gen(), 0.05)
}, test_options)
if not ok then
print('Test has failed:', err)
end
if os.getenv('DEV') ~= 'ON' then
os.remove('history.json')
os.remove('history.txt')
end