-
Notifications
You must be signed in to change notification settings - Fork 23
/
hermes.lua
162 lines (137 loc) · 4.77 KB
/
hermes.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
--
-- hermes.lua
--
--
-- Folder bindings for imap collector.
--
--
-- Space 0: Folder Bindings and IMAP Collector State.
-- Tuple: { coll_id (NUM), rmt_fld_id (STR), fld_id (NUM), uid_validity (NUM), up_uid (NUM), down_uid (NUM), up_date (NUM), down_date (NUM), modseq (STR), state (STR) }
-- Index 0: TREE { coll_id, rmt_fld_id }
--
-- Space 1: Errors that occurred during synchronization of local changes on the remote side.
-- Tuple: { email (STR), error_index (NUM), timestamp (NUM), description (STR) }
-- Index 0: TREE { email, error_index }
--
-- Description field contains some tarantool independent information about a problem.
-- Example:
-- '[email protected]': {1, 1441822966, 'error while appending message on storage'}
--
function hermes_get(coll_id)
coll_id = box.unpack('i', coll_id)
return box.select_limit(0, 0, 0, 1000000, coll_id)
end
function hermes_drop(coll_id)
coll_id = box.unpack('i', coll_id)
local tuples = { box.select_limit(0, 0, 0, 1000000, coll_id) }
for _, tuple in pairs(tuples) do
box.delete(0, coll_id, tuple[1])
end
end
function hermes_rebase(coll_id)
coll_id = box.unpack('i', coll_id)
for tuple in box.space[0].index[0]:iterator(box.index.EQ, coll_id) do
box.update(0, { coll_id, tuple[1] }, "=p", 2, -1)
end
end
function hermes_update(coll_id, rmt_fld_id, fld_id, uid_validity, up_uid, down_uid, up_date, down_date)
coll_id = box.unpack('i', coll_id)
fld_id = box.unpack('i', fld_id)
uid_validity = box.unpack('i', uid_validity)
up_uid = box.unpack('i', up_uid)
down_uid = box.unpack('i', down_uid)
up_date = box.unpack('i', up_date)
down_date = box.unpack('i', down_date)
local status, t = pcall(box.update, 0, { coll_id, rmt_fld_id }, "=p=p=p=p=p=p", 2, fld_id, 3, uid_validity, 4, up_uid, 5, down_uid, 6, up_date, 7, down_date)
if not status or t == nil then
box.replace(0, coll_id, rmt_fld_id, fld_id, uid_validity, up_uid, down_uid, up_date, down_date)
end
end
function hermes_drop_by_rmt_fld(coll_id, rmt_fld_id)
coll_id = box.unpack('i', coll_id)
box.delete(0, coll_id, rmt_fld_id)
end
function hermes_drop_by_fld(coll_id, fld_id)
coll_id = box.unpack('i', coll_id)
fld_id = box.unpack('i', fld_id)
local tuples = { box.select_limit(0, 0, 0, 1000000, coll_id) }
for _, tuple in pairs(tuples) do
if box.unpack('i', tuple[2]) == fld_id then
box.delete(0, coll_id, tuple[1])
end
end
end
function hermes_update_up_uid(coll_id, rmt_fld_id, up_uid, up_date)
coll_id = box.unpack('i', coll_id)
up_uid = box.unpack('i', up_uid)
up_date = box.unpack('i', up_date)
local t = box.update(0, { coll_id, rmt_fld_id }, "=p=p", 4, up_uid, 6, up_date)
if t ~= nil then return 1 else return 0 end
end
function hermes_update_rmt_fld(coll_id, fld_id, new_rmt_fld_id)
coll_id = box.unpack('i', coll_id)
fld_id = box.unpack('i', fld_id)
local tuples = { box.select_limit(0, 0, 0, 1000000, coll_id) }
for _, tuple in pairs(tuples) do
if box.unpack('i', tuple[2]) == fld_id then
box.update(0, { coll_id, tuple[1] }, "=p", 1, new_rmt_fld_id)
return 1
end
end
return 0
end
function hermes_update_modseq(coll_id, rmt_fld_id, modseq)
coll_id = box.unpack('i', coll_id)
local t = box.update(0, { coll_id, rmt_fld_id }, "=p", 8, modseq)
if t ~= nil then return 1 else return 0 end
end
function hermes_update_state(coll_id, rmt_fld_id, state)
coll_id = box.unpack('i', coll_id)
local status, t = pcall(box.update, 0, { coll_id, rmt_fld_id }, "=p", 9, state)
if not status then
t = box.update(0, { coll_id, rmt_fld_id }, "=p=p", 8, "", 9, state)
end
if t ~= nil then return 1 else return 0 end
end
local MAX_STORED_ERRORS = 50
local AUTO_INC_ERR_ID_KEY = 'auto_increment_error_id'
function hermes_error_add(key, timestamp, error_description)
local done = nil
timestamp = box.unpack('i', timestamp)
while not done do
local data = { box.select(1, 0, key) }
for _, v in pairs(data) do
-- To prevent records duplicates
if v[3] == error_description then
return
end
end
if #data >= MAX_STORED_ERRORS then
-- Remove oldest record
-- Records are in the correct order throwgh tarantool index format
local min_id = box.unpack('i', data[1][1])
box.delete(1, key, min_id)
end
local max_id = box.counter.inc(1, AUTO_INC_ERR_ID_KEY, 0)
done = box.insert(1, key, max_id, timestamp, error_description)
end
end
function hermes_errors_del(key, ...)
local local_indexes = {...}
for i = 1, #local_indexes do
box.delete(1, key, box.unpack('i', local_indexes[i]))
end
end
function hermes_error_replace(key, err_no, new_content)
err_no = box.unpack('i', err_no)
box.replace(1, key, err_no, new_content)
end
function hermes_errors_get(key)
return { box.select(1, 0, key) }
end
function hermes_errors_clear(key)
local data = { box.select(1, 0, key) }
for _, v in pairs(data) do
box.delete(1, key, box.unpack('i', v[1]))
end
end