Line data Source code
1 :
2 :
3 : #include "prefixdb_cmd.hpp"
4 : #include "../api/common_status_json.hpp"
5 : #include <sstream>
6 : #include <string>
7 : #include <iostream>
8 :
9 : namespace wamba{ namespace prefixdb{ namespace service{
10 :
11 : namespace
12 : {
13 0 : void delay_background_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
14 : {
15 0 : time_t delay_s = 0;
16 0 : bool force = false;
17 0 : ss >> delay_s;
18 0 : ss >> force;
19 0 : auto req = std::make_unique<request::delay_background>();
20 0 : req->delay_timeout_s = delay_s;
21 0 : req->contunue_force = force;
22 0 : db->delay_background(std::move(req), [handler, delay_s, force](response::delay_background::ptr res)
23 : {
24 0 : std::stringstream ss2;
25 0 : ss2 << res->status << ". Backgrounds delayed on " << delay_s << " seconds. force=" << force;
26 0 : handler( iow::io::make(ss2.str()) );
27 0 : });
28 0 : }
29 :
30 0 : void continue_background_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
31 : {
32 0 : bool force = false;
33 :
34 0 : ss >> force;
35 0 : auto req = std::make_unique<request::continue_background>();
36 0 : req->force = force;
37 0 : db->continue_background(std::move(req), [handler, force](response::continue_background::ptr res)
38 : {
39 0 : std::stringstream ss2;
40 0 : ss2 << res->status << ". Continue backgrounds. force=" << force;
41 0 : handler( iow::io::make(ss2.str()) );
42 0 : });
43 0 : }
44 :
45 0 : void detach_prefixes_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
46 : {
47 0 : auto req = std::make_unique<request::detach_prefixes>();
48 0 : time_t deny_timeout = 0;
49 0 : ss >> deny_timeout;
50 0 : req->deny_timeout_s = deny_timeout;
51 :
52 0 : std::string prefix;
53 : for (;;)
54 : {
55 0 : prefix.clear();
56 0 : ss >> prefix;
57 0 : if (prefix.empty()) break;
58 0 : req->prefixes.push_back(prefix);
59 : }
60 :
61 0 : db->detach_prefixes( std::move(req), [handler, deny_timeout](response::detach_prefixes::ptr res)
62 : {
63 0 : std::stringstream ss2;
64 0 : ss2 << res->status << ". Prefixes detached. Deny timeout " << deny_timeout << " seconds. ";
65 0 : handler( iow::io::make(ss2.str()) );
66 0 : } );
67 0 : }
68 :
69 0 : void get_all_prefixes_( std::shared_ptr<iprefixdb> db, std::stringstream& , wfc::iinterface::output_handler_t handler)
70 : {
71 0 : auto req = std::make_unique<request::get_all_prefixes>();
72 0 : db->get_all_prefixes( std::move(req), [handler](response::get_all_prefixes::ptr res)
73 : {
74 0 : std::stringstream ss;
75 0 : if ( res!=nullptr ) for (const std::string& preffix: res->prefixes )
76 : {
77 0 : ss << preffix << std::endl;
78 : }
79 0 : ss << res->status;
80 0 : handler( ::iow::io::make(ss.str()) );
81 0 : } );
82 0 : }
83 :
84 0 : void get_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
85 : {
86 0 : auto req = std::make_unique<request::get>();
87 0 : ss >> req->prefix;
88 0 : while (ss)
89 : {
90 0 : std::string name;
91 0 : ss >> name;
92 0 : if ( !name.empty() )
93 0 : req->fields.push_back(name);
94 0 : }
95 0 : db->get( std::move(req), [handler](response::get::ptr res)
96 : {
97 0 : std::stringstream oss;
98 0 : if ( res!=nullptr ) for (const auto& field: res->fields )
99 : {
100 0 : oss << field.first << "=" << field.second << std::endl;
101 : }
102 0 : oss << res->status;
103 0 : handler( ::iow::io::make(oss.str()) );
104 0 : } );
105 0 : }
106 :
107 0 : void del_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
108 : {
109 0 : auto req = std::make_unique<request::del>();
110 0 : ss >> req->prefix;
111 0 : while (ss)
112 : {
113 0 : std::string name;
114 0 : ss >> name;
115 0 : if ( !name.empty() )
116 0 : req->fields.push_back(name);
117 0 : }
118 0 : req->nores = false;
119 0 : req->noval = false;
120 :
121 0 : db->del( std::move(req), [handler](response::del::ptr res)
122 : {
123 0 : std::stringstream oss;
124 0 : if ( res!=nullptr ) for (const auto& field: res->fields )
125 : {
126 0 : oss << field.first << "=" << field.second << std::endl;
127 : }
128 0 : oss << res->status;
129 0 : handler( ::iow::io::make(oss.str()) );
130 0 : } );
131 0 : }
132 :
133 0 : void set_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
134 : {
135 0 : auto req = std::make_unique<request::set>();
136 0 : ss >> req->prefix;
137 0 : req->fields.resize(1);
138 0 : ss >> req->fields.back().first;
139 0 : ss >> req->fields.back().second;
140 :
141 0 : db->set( std::move(req), [handler](response::set::ptr )
142 : {
143 0 : handler( ::iow::io::make("OK") );
144 0 : } );
145 0 : }
146 :
147 0 : void inc_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
148 : {
149 :
150 0 : auto req = std::make_unique<request::inc>();
151 0 : ss >> req->prefix;
152 0 : req->fields.resize(1);
153 0 : std::string key = "null";
154 0 : std::string inc = "null";
155 0 : std::string val = "null";
156 0 : ss >> key >> inc >> val;
157 0 : std::stringstream param;
158 0 : param << "{\"inc\":"<< inc << ",\"val\":" << val << "}";
159 0 : req->fields.back().first = key;
160 0 : req->fields.back().second = param.str();
161 :
162 0 : db->inc( std::move(req), [handler](response::inc::ptr )
163 : {
164 0 : handler( ::iow::io::make("OK") );
165 0 : } );
166 :
167 0 : }
168 :
169 0 : void compact_prefix_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
170 : {
171 0 : auto req = std::make_unique<request::compact_prefix>();
172 0 : ss >> req->prefix;
173 0 : ss >> req->from;
174 0 : ss >> req->to;
175 0 : db->compact_prefix( std::move(req), [handler](response::compact_prefix::ptr res)
176 : {
177 0 : if ( res->status == common_status::OK )
178 0 : handler( ::iow::io::make("OK") );
179 : else
180 0 : handler( ::iow::io::make("FAIL") );
181 0 : } );
182 0 : }
183 :
184 0 : void range_( std::shared_ptr<iprefixdb> db, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
185 : {
186 0 : auto req = std::make_unique<request::range>();
187 0 : ss >> req->prefix;
188 0 : if (ss) ss >> req->from;
189 0 : if (ss) ss >> req->to;
190 0 : if (ss) ss >> req->offset;
191 0 : if (ss) ss >> req->limit;
192 0 : if ( req->limit == 0 )
193 0 : req->limit = 100;
194 :
195 0 : db->range( std::move(req), [handler](response::range::ptr res)
196 : {
197 0 : std::stringstream oss;
198 0 : if ( res!=nullptr ) for (const auto& field: res->fields )
199 : {
200 0 : oss << field.first << "=" << field.second << std::endl;
201 : }
202 0 : oss << res->status;
203 0 : handler( ::iow::io::make(oss.str()) );
204 0 : } );
205 0 : }
206 :
207 : const char* help_str[][4] = {
208 : {"h", "help", "[<<command>>]", "Подсказка по конкретной команде. Если не указана, то список всех комманд."},
209 : {"e", "exit", "", "Выход."},
210 : {"db", "delay_background", "[0](delay seconds) [0](force)", "Завершает все фоновые процессы на delay_s секунд. \n"
211 : "Если force=1 то по завершению таймаута гарантировано запустит все фоновые \n"
212 : "процессы, даже если в это время были вызовы delay_background c большим таймаутом. "
213 : "Для гаранитированного запуска используй: 'db 0 1'"},
214 : {"cb", "continue_background", " [0](force)", ""},
215 : {"cp", "compact_prefix", "<<prefix>> [<<from>> [<<to>>] ]", "compact для префикса"},
216 : {"dp", "detach_prefixes", "[0](access denied in sec) <<prefix1>> [<<prefix2>> ...]", "Отсоединяет префиксы на заданный таймаут. База префиксов перемещаеться в указанное \n"
217 : "в конфигурации место. Префикс станет доступен через заданное первым параметром число секунд." },
218 : {"gap", "get_all_prefixes", "", "Получить спискок всех доступных префиксов" },
219 : {"g", "get", "<<prefix>> <<key1>> [<<key2>> ....]", "Получить значения полей в указанном префиксе"},
220 : {"d", "del", "<<prefix>> <<key1>> [<<key2>> ....]", "Удалить поля в указанном префиксе"},
221 : {"s", "set", "<<prefix>> <<key>> <<value>>", "Изменить значение поля в указанном префиксе"},
222 : {"i", "inc", "<<prefix>> <<key>> <<increment>> [<<default value>>]", "Инкрементировать значение поля для указанном префиксе"},
223 : {"r", "range", "<<prefix>> [from [to [offset [limit] ] ]] ", "Получить значения полей в указанном префиксе по диапазону. Примеры:\n"
224 : "\tr test - получить первые 25 полей \n"
225 : "\tr test key1 - получить первые 25 полей начиная с key1 \n"
226 : "\tr test key1 key2- получить первые 25 полей начиная с key1 до key2 включительно\n"
227 : "\tr test key1 key2 25 75 - получить 75 полей начиная с key1 до key2 включительно, пропустив первые 25"
228 : },
229 :
230 :
231 : };
232 0 : void help_( std::shared_ptr<iprefixdb> /*db*/, std::stringstream& ss, wfc::iinterface::output_handler_t handler)
233 : {
234 0 : std::stringstream oss;
235 0 : std::string cmd;
236 0 : ss >> cmd;
237 0 : for (auto hlp: help_str)
238 : {
239 0 : if ( cmd.empty() || cmd==std::string(hlp[0]) || cmd==std::string(hlp[1]) )
240 : {
241 0 : if ( !std::string(hlp[0]).empty() )
242 0 : oss << hlp[0] << "|";
243 0 : oss << hlp[1] << " " << hlp[2] << std::endl;
244 0 : if ( !cmd.empty() )
245 : {
246 0 : oss << hlp[3] << std::endl;
247 : }
248 : }
249 : }
250 0 : auto res = oss.str();
251 0 : res.resize(res.size() - 1);
252 0 : handler( ::iow::io::make( res) );
253 0 : }
254 : }
255 :
256 0 : void prefixdb_cmd( std::shared_ptr<iprefixdb> db, ::wfc::iinterface::data_ptr d, wfc::iinterface::output_handler_t handler)
257 : {
258 0 : std::stringstream ss;
259 0 : ss << std::string( d->begin(), d->end() );
260 0 : std::string method;
261 0 : ss >> method;
262 :
263 0 : if ( method == "help" || method == "h")
264 : {
265 0 : help_(db, ss, std::move(handler) );
266 : }
267 0 : else if ( method == "exit" || method == "e")
268 : {
269 0 : handler(nullptr);
270 : }
271 0 : else if ( method == "db" || method=="delay_background")
272 : {
273 0 : delay_background_(db, ss, std::move(handler) );
274 : }
275 0 : else if ( method == "cb" || method=="continue_background")
276 : {
277 0 : continue_background_(db, ss, std::move(handler) );
278 : }
279 0 : else if ( method == "dp" || method=="detach_prefixes")
280 : {
281 0 : detach_prefixes_(db, ss, std::move(handler) );
282 : }
283 0 : else if ( method == "gap" || method=="get_all_prefixes")
284 : {
285 0 : get_all_prefixes_(db, ss, std::move(handler) );
286 : }
287 0 : else if ( method == "g" || method=="get")
288 : {
289 0 : get_(db, ss, std::move(handler) );
290 : }
291 0 : else if ( method == "s" || method=="set")
292 : {
293 0 : set_(db, ss, std::move(handler) );
294 : }
295 0 : else if ( method == "i" || method=="inc")
296 : {
297 0 : inc_(db, ss, std::move(handler) );
298 : }
299 0 : else if ( method == "d" || method=="del")
300 : {
301 0 : del_(db, ss, std::move(handler) );
302 : }
303 0 : else if ( method == "r" || method=="range")
304 : {
305 0 : range_(db, ss, std::move(handler) );
306 : }
307 0 : else if ( method=="cp" || method=="compact_prefix")
308 : {
309 0 : compact_prefix_(db, ss, std::move(handler) );
310 : }
311 : else
312 : {
313 0 : handler( ::iow::io::make("Unknown method") );
314 0 : }
315 :
316 0 : }
317 :
318 3 : }}}
|