5
* Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
* See COPYRIGHT.txt for details.
15
#include "hstcpcli.hpp"
20
arr_get_entry(AV *av, I32 avmax, I32 idx)
23
DBG(fprintf(stderr, "arr_get_entry1 %d %d\n", avmax, idx));
26
SV **const ev = av_fetch(av, idx, 0);
28
DBG(fprintf(stderr, "arr_get_entry2 %d %d\n", avmax, idx));
35
arr_get_intval(AV *av, I32 avmax, I32 idx, int default_val = 0)
37
SV *const e = arr_get_entry(av, avmax, idx);
47
if (sv == 0 || !SvPOK(sv)) {
48
DBG(fprintf(stderr, "sv_get_strval\n"));
51
return SvPV_nolen(sv);
55
arr_get_strval(AV *av, I32 avmax, I32 idx)
57
SV *const e = arr_get_entry(av, avmax, idx);
58
return sv_get_strval(e);
64
if (sv == 0 || !SvROK(sv)) {
65
DBG(fprintf(stderr, "sv_get_arrval1\n"));
68
SV *const svtarget = SvRV(sv);
69
if (svtarget == 0 || SvTYPE(svtarget) != SVt_PVAV) {
70
DBG(fprintf(stderr, "sv_get_arrval2\n"));
73
return (AV *)svtarget;
77
arr_get_arrval(AV *av, I32 avmax, I32 idx)
79
SV *const e = arr_get_entry(av, avmax, idx);
81
DBG(fprintf(stderr, "arr_get_arrval1\n"));
84
return sv_get_arrval(e);
88
hv_to_strmap(HV *hv, std::map<std::string, std::string>& m_r)
95
while ((hent = hv_iternext(hv)) != 0) {
97
char *const k = hv_iterkey(hent, &klen);
98
DBG(fprintf(stderr, "k=%s\n", k));
99
const std::string key(k, klen);
100
SV *const vsv = hv_iterval(hv, hent);
102
char *const v = SvPV(vsv, vlen);
103
DBG(fprintf(stderr, "v=%s\n", v));
104
const std::string val(v, vlen);
110
strrefarr_push_back(std::vector<dena::string_ref>& a_r, SV *sv)
112
if (sv == 0 || SvTYPE(sv) == SVt_NULL) {
113
DBG(fprintf(stderr, "strrefarr_push_back: null\n"));
114
return a_r.push_back(dena::string_ref());
117
char *const v = SvPV(sv, vlen);
118
DBG(fprintf(stderr, "strrefarr_push_back: %s\n", v));
119
a_r.push_back(dena::string_ref(v, vlen));
123
av_to_strrefarr(AV *av, std::vector<dena::string_ref>& a_r)
128
const I32 len = av_len(av) + 1;
129
for (I32 i = 0; i < len; ++i) {
130
SV **const ev = av_fetch(av, i, 0);
131
strrefarr_push_back(a_r, ev ? *ev : 0);
135
static dena::string_ref
136
sv_get_string_ref(SV *sv)
139
return dena::string_ref();
142
char *const v = SvPV(sv, vlen);
143
return dena::string_ref(v, vlen);
149
if (sv == 0 || !SvIOK(sv)) {
156
av_to_filters(AV *av, std::vector<dena::hstcpcli_filter>& f_r)
158
DBG(fprintf(stderr, "av_to_filters: %p\n", av));
162
const I32 len = av_len(av) + 1;
163
DBG(fprintf(stderr, "av_to_filters: len=%d\n", (int)len));
164
for (I32 i = 0; i < len; ++i) {
165
AV *const earr = arr_get_arrval(av, len, i);
169
const I32 earrlen = av_len(earr) + 1;
170
dena::hstcpcli_filter fe;
171
fe.filter_type = sv_get_string_ref(arr_get_entry(earr, earrlen, 0));
172
fe.op = sv_get_string_ref(arr_get_entry(earr, earrlen, 1));
173
fe.ff_offset = sv_get_iv(arr_get_entry(earr, earrlen, 2));
174
fe.val = sv_get_string_ref(arr_get_entry(earr, earrlen, 3));
176
DBG(fprintf(stderr, "av_to_filters: %s %s %d %s\n",
177
fe.filter_action.begin(), fe.filter_op.begin(), (int)fe.ff_offset,
183
set_process_verbose_level(const std::map<std::string, std::string>& m)
185
std::map<std::string, std::string>::const_iterator iter = m.find("verbose");
186
if (iter != m.end()) {
187
dena::verbose_level = atoi(iter->second.c_str());
192
execute_internal(SV *obj, int id, const char *op, AV *keys, int limit,
193
int skip, const char *modop, AV *modvals, AV *filters)
195
AV *retval = (AV *)&PL_sv_undef;
196
dena::hstcpcli_i *const ptr =
197
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
199
std::vector<dena::string_ref> keyarr, mvarr;
200
std::vector<dena::hstcpcli_filter> farr;
201
av_to_strrefarr(keys, keyarr);
202
dena::string_ref modop_ref;
204
modop_ref = dena::string_ref(modop, strlen(modop));
205
av_to_strrefarr(modvals, mvarr);
208
av_to_filters(filters, farr);
210
ptr->request_buf_exec_generic(id, dena::string_ref(op, strlen(op)),
211
&keyarr[0], keyarr.size(), limit, skip, modop_ref, &mvarr[0],
212
mvarr.size(), &farr[0], farr.size());
213
AV *const av = newAV();
215
if (ptr->request_send() != 0) {
219
ptr->response_recv(nflds);
220
const int e = ptr->get_error_code();
221
DBG(fprintf(stderr, "e=%d nflds=%zu\n", e, nflds));
222
av_push(av, newSViv(e));
224
const std::string s = ptr->get_error();
225
av_push(av, newSVpvn(s.data(), s.size()));
227
const dena::string_ref *row = 0;
228
while ((row = ptr->get_next_row()) != 0) {
229
DBG(fprintf(stderr, "row=%p\n", row));
230
for (size_t i = 0; i < nflds; ++i) {
231
const dena::string_ref& v = row[i];
232
DBG(fprintf(stderr, "FLD %zu v=%s vbegin=%p\n", i,
233
std::string(v.begin(), v.size())
234
.c_str(), v.begin()));
235
if (v.begin() != 0) {
236
SV *const e = newSVpvn(
237
v.begin(), v.size());
240
av_push(av, &PL_sv_undef);
246
ptr->response_buf_remove();
261
execute_arg() : id(0), op(0), keys(0), limit(0), skip(0), modop(0),
262
modvals(0), filters(0) { }
266
execute_multi_internal(SV *obj, const execute_arg *args, size_t num_args)
268
dena::hstcpcli_i *const ptr =
269
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
270
/* appends multiple requests to the send buffer */
271
for (size_t i = 0; i < num_args; ++i) {
272
std::vector<dena::string_ref> keyarr, mvarr;
273
std::vector<dena::hstcpcli_filter> farr;
274
const execute_arg& arg = args[i];
275
av_to_strrefarr(arg.keys, keyarr);
276
dena::string_ref modop_ref;
277
if (arg.modop != 0) {
278
modop_ref = dena::string_ref(arg.modop, strlen(arg.modop));
279
av_to_strrefarr(arg.modvals, mvarr);
281
if (arg.filters != 0) {
282
av_to_filters(arg.filters, farr);
284
ptr->request_buf_exec_generic(arg.id,
285
dena::string_ref(arg.op, strlen(arg.op)), &keyarr[0], keyarr.size(),
286
arg.limit, arg.skip, modop_ref, &mvarr[0], mvarr.size(), &farr[0],
289
AV *const retval = newAV();
290
/* sends the requests */
291
if (ptr->request_send() < 0) {
293
AV *const av_respent = newAV();
294
av_push(retval, newRV_noinc((SV *)av_respent));
295
av_push(av_respent, newSViv(ptr->get_error_code()));
296
const std::string& s = ptr->get_error();
297
av_push(av_respent, newSVpvn(s.data(), s.size()));
298
return retval; /* retval : [ [ err_code, err_message ] ] */
300
/* receives responses */
301
for (size_t i = 0; i < num_args; ++i) {
302
AV *const av_respent = newAV();
303
av_push(retval, newRV_noinc((SV *)av_respent));
305
const int e = ptr->response_recv(nflds);
306
av_push(av_respent, newSViv(e));
308
const std::string& s = ptr->get_error();
309
av_push(av_respent, newSVpvn(s.data(), s.size()));
311
const dena::string_ref *row = 0;
312
while ((row = ptr->get_next_row()) != 0) {
313
for (size_t i = 0; i < nflds; ++i) {
314
const dena::string_ref& v = row[i];
315
DBG(fprintf(stderr, "%zu %s\n", i,
316
std::string(v.begin(), v.size()).c_str()));
317
if (v.begin() != 0) {
318
av_push(av_respent, newSVpvn(v.begin(), v.size()));
321
av_push(av_respent, &PL_sv_undef);
327
ptr->response_buf_remove();
336
MODULE = Net::HandlerSocket PACKAGE = Net::HandlerSocket
343
RETVAL = &PL_sv_undef;
345
hv_to_strmap(args, conf);
346
set_process_verbose_level(conf);
347
dena::socket_args sargs;
349
dena::hstcpcli_ptr p = dena::hstcpcli_i::create(sargs);
350
SV *const objref = newSViv(0);
351
SV *const obj = newSVrv(objref, klass);
352
dena::hstcpcli_i *const ptr = p.get();
353
sv_setiv(obj, reinterpret_cast<IV>(ptr));
364
dena::hstcpcli_i *const ptr =
365
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
372
dena::hstcpcli_i *const ptr =
373
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
381
dena::hstcpcli_i *const ptr =
382
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
383
RETVAL = ptr->reconnect();
392
dena::hstcpcli_i *const ptr =
393
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
394
const bool rv = ptr->stable_point();
395
RETVAL = static_cast<int>(rv);
404
dena::hstcpcli_i *const ptr =
405
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
406
RETVAL = ptr->get_error_code();
414
RETVAL = &PL_sv_undef;
415
dena::hstcpcli_i *const ptr =
416
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
417
const std::string s = ptr->get_error();
418
RETVAL = newSVpvn(s.data(), s.size());
423
open_index(obj, id, db, table, index, fields, ffields = 0)
432
const char *const ffields_str = sv_get_strval(ffields);
434
dena::hstcpcli_i *const ptr =
435
reinterpret_cast<dena::hstcpcli_i *>(SvIV(SvRV(obj)));
437
ptr->request_buf_open_index(id, db, table, index, fields, ffields_str);
438
if (ptr->request_send() != 0) {
442
ptr->response_recv(nflds);
443
const int e = ptr->get_error_code();
444
DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
446
ptr->response_buf_remove();
448
DBG(fprintf(stderr, "errcode=%d\n", ptr->get_error_code()));
450
RETVAL = ptr->get_error_code();
455
execute_single(obj, id, op, keys, limit, skip, mop = 0, mvs = 0, fils = 0)
466
const char *const mop_str = sv_get_strval(mop);
467
AV *const mvs_av = sv_get_arrval(mvs);
468
AV *const fils_av = sv_get_arrval(fils);
469
RETVAL = execute_internal(obj, id, op, keys, limit, skip, mop_str, mvs_av,
471
sv_2mortal((SV *)RETVAL);
476
execute_multi(obj, cmds)
480
DBG(fprintf(stderr, "execute_multi0\n"));
481
const I32 cmdsmax = av_len(cmds);
482
execute_arg args[cmdsmax + 1]; /* GNU */
483
for (I32 i = 0; i <= cmdsmax; ++i) {
484
AV *const avtarget = arr_get_arrval(cmds, cmdsmax, i);
486
DBG(fprintf(stderr, "execute_multi1 %d\n", i));
489
const I32 argmax = av_len(avtarget);
491
DBG(fprintf(stderr, "execute_multi2 %d\n", i));
494
execute_arg& ag = args[i];
495
ag.id = arr_get_intval(avtarget, argmax, 0);
496
ag.op = arr_get_strval(avtarget, argmax, 1);
497
ag.keys = arr_get_arrval(avtarget, argmax, 2);
498
ag.limit = arr_get_intval(avtarget, argmax, 3);
499
ag.skip = arr_get_intval(avtarget, argmax, 4);
500
ag.modop = arr_get_strval(avtarget, argmax, 5);
501
ag.modvals = arr_get_arrval(avtarget, argmax, 6);
502
ag.filters = arr_get_arrval(avtarget, argmax, 7);
503
DBG(fprintf(stderr, "execute_multi3 %d: %d %s %p %d %d %s %p %p\n",
504
i, ag.id, ag.op, ag.keys, ag.limit, ag.skip, ag.modop, ag.modvals,
507
RETVAL = execute_multi_internal(obj, args, cmdsmax + 1);
508
sv_2mortal((SV *)RETVAL);
513
execute_find(obj, id, op, keys, limit, skip, mop = 0, mvs = 0, fils = 0)
524
const char *const mop_str = sv_get_strval(mop);
525
AV *const mvs_av = sv_get_arrval(mvs);
526
AV *const fils_av = sv_get_arrval(fils);
527
RETVAL = execute_internal(obj, id, op, keys, limit, skip, mop_str, mvs_av,
529
sv_2mortal((SV *)RETVAL);
534
execute_update(obj, id, op, keys, limit, skip, modvals, fils = 0)
544
AV *const fils_av = sv_get_arrval(fils);
545
RETVAL = execute_internal(obj, id, op, keys, limit, skip, "U",
547
sv_2mortal((SV *)RETVAL);
552
execute_delete(obj, id, op, keys, limit, skip, fils = 0)
561
AV *const fils_av = sv_get_arrval(fils);
562
RETVAL = execute_internal(obj, id, op, keys, limit, skip, "D", 0, fils_av);
563
sv_2mortal((SV *)RETVAL);
568
execute_insert(obj, id, fvals)
573
RETVAL = execute_internal(obj, id, "+", fvals, 0, 0, 0, 0, 0);
574
sv_2mortal((SV *)RETVAL);