vincentchu-handlersocket 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. data/ext/HandlerSocket-Plugin-for-MySQL/AUTHORS +22 -0
  2. data/ext/HandlerSocket-Plugin-for-MySQL/COPYING +30 -0
  3. data/ext/HandlerSocket-Plugin-for-MySQL/ChangeLog +12 -0
  4. data/ext/HandlerSocket-Plugin-for-MySQL/Makefile.am +87 -0
  5. data/ext/HandlerSocket-Plugin-for-MySQL/README +78 -0
  6. data/ext/HandlerSocket-Plugin-for-MySQL/autogen.sh +117 -0
  7. data/ext/HandlerSocket-Plugin-for-MySQL/client/Makefile.am +24 -0
  8. data/ext/HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp +88 -0
  9. data/ext/HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp +1041 -0
  10. data/ext/HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl +224 -0
  11. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.cpp +1532 -0
  12. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest.pl +228 -0
  13. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs.sh +4 -0
  14. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_hs_more50.sh +4 -0
  15. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_md.sh +7 -0
  16. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my.sh +3 -0
  17. data/ext/HandlerSocket-Plugin-for-MySQL/client/hstest_my_more50.sh +3 -0
  18. data/ext/HandlerSocket-Plugin-for-MySQL/configure.ac +144 -0
  19. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/about-handlersocket.en.txt +72 -0
  20. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/configuration-options.en.txt +99 -0
  21. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/installation.en.txt +92 -0
  22. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/perl-client.en.txt +135 -0
  23. data/ext/HandlerSocket-Plugin-for-MySQL/docs-en/protocol.en.txt +205 -0
  24. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/about-handlersocket.ja.txt +51 -0
  25. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/installation.ja.txt +88 -0
  26. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/perl-client.ja.txt +127 -0
  27. data/ext/HandlerSocket-Plugin-for-MySQL/docs-ja/protocol.ja.txt +180 -0
  28. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/COPYRIGHT.txt +27 -0
  29. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.am +10 -0
  30. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/Makefile.plain.template +31 -0
  31. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.cpp +1190 -0
  32. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/database.hpp +142 -0
  33. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.cpp +222 -0
  34. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/handlersocket.spec.template +29 -0
  35. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.cpp +149 -0
  36. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr.hpp +58 -0
  37. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.cpp +951 -0
  38. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/hstcpsvr_worker.hpp +35 -0
  39. data/ext/HandlerSocket-Plugin-for-MySQL/handlersocket/mysql_incl.hpp +50 -0
  40. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/COPYRIGHT.txt +27 -0
  41. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.am +12 -0
  42. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/Makefile.plain +27 -0
  43. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/allocator.hpp +64 -0
  44. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_addrinfo.hpp +49 -0
  45. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_file.hpp +64 -0
  46. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/auto_ptrcontainer.hpp +67 -0
  47. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.cpp +67 -0
  48. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/config.hpp +32 -0
  49. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.cpp +127 -0
  50. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/escape.hpp +66 -0
  51. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.cpp +36 -0
  52. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/fatal.hpp +22 -0
  53. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.cpp +441 -0
  54. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/hstcpcli.hpp +62 -0
  55. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/libhsclient.spec.template +39 -0
  56. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/mutex.hpp +51 -0
  57. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.cpp +186 -0
  58. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/socket.hpp +51 -0
  59. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_buffer.hpp +118 -0
  60. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_ref.hpp +63 -0
  61. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.cpp +182 -0
  62. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/string_util.hpp +53 -0
  63. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/thread.hpp +84 -0
  64. data/ext/HandlerSocket-Plugin-for-MySQL/libhsclient/util.hpp +25 -0
  65. data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-hs.log +130 -0
  66. data/ext/HandlerSocket-Plugin-for-MySQL/misc/microbench-my.log +125 -0
  67. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/COPYRIGHT.txt +27 -0
  68. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Changes +6 -0
  69. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/HandlerSocket.xs +632 -0
  70. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/MANIFEST +8 -0
  71. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL +18 -0
  72. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/Makefile.PL.installed +20 -0
  73. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/README +30 -0
  74. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket.pm +68 -0
  75. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm +362 -0
  76. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template +127 -0
  77. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/ppport.h +6375 -0
  78. data/ext/HandlerSocket-Plugin-for-MySQL/perl-Net-HandlerSocket/t/Net-HandlerSocket.t +15 -0
  79. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/Makefile +79 -0
  80. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/binary_my.cnf +4 -0
  81. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/compat.sh +29 -0
  82. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/common/hstest.pm +66 -0
  83. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/Makefile +4 -0
  84. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/run.sh +27 -0
  85. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.expected +100 -0
  86. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test01.pl +38 -0
  87. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.expected +100 -0
  88. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test02.pl +49 -0
  89. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.expected +771 -0
  90. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test03.pl +61 -0
  91. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.expected +0 -0
  92. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test04.pl +63 -0
  93. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.expected +771 -0
  94. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test05.pl +59 -0
  95. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.expected +644 -0
  96. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test06.pl +90 -0
  97. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.expected +304 -0
  98. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test07.pl +98 -0
  99. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.expected +2 -0
  100. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test08.pl +48 -0
  101. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.expected +12 -0
  102. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test09.pl +67 -0
  103. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.expected +771 -0
  104. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test10.pl +93 -0
  105. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.expected +37 -0
  106. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test11.pl +112 -0
  107. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.expected +273 -0
  108. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test12.pl +134 -0
  109. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.expected +92 -0
  110. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test13.pl +92 -0
  111. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.expected +144 -0
  112. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test14.pl +80 -0
  113. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.expected +764 -0
  114. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test15.pl +114 -0
  115. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.expected +66 -0
  116. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test16.pl +88 -0
  117. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.expected +0 -0
  118. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test17.pl +125 -0
  119. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.expected +22 -0
  120. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test18.pl +63 -0
  121. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.expected +14894 -0
  122. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test19.pl +190 -0
  123. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.expected +2 -0
  124. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test20.pl +33 -0
  125. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.expected +11 -0
  126. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test21.pl +58 -0
  127. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.expected +9 -0
  128. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test22.pl +61 -0
  129. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.expected +101 -0
  130. data/ext/HandlerSocket-Plugin-for-MySQL/regtest/test_01_lib/test23.pl +53 -0
  131. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/README +33 -0
  132. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/extconf.rb +27 -0
  133. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.cpp +437 -0
  134. data/ext/winebarrel-ruby-handlersocket-c19841e47ea2/handlersocket.h +32 -0
  135. metadata +200 -0
@@ -0,0 +1,32 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #ifndef DENA_CONFIG_HPP
10
+ #define DENA_CONFIG_HPP
11
+
12
+ #include <string>
13
+ #include <map>
14
+
15
+ #define DENA_VERBOSE(lv, x) if (dena::verbose_level >= (lv)) { (x); }
16
+
17
+ namespace dena {
18
+
19
+ struct config : public std::map<std::string, std::string> {
20
+ std::string get_str(const std::string& key, const std::string& def = "")
21
+ const;
22
+ long long get_int(const std::string& key, long long def = 0) const;
23
+ };
24
+
25
+ void parse_args(int argc, char **argv, config& conf);
26
+
27
+ extern unsigned int verbose_level;
28
+
29
+ };
30
+
31
+ #endif
32
+
@@ -0,0 +1,127 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <stdio.h>
10
+
11
+ #include "escape.hpp"
12
+ #include "string_buffer.hpp"
13
+ #include "fatal.hpp"
14
+ #include "string_util.hpp"
15
+
16
+ #define DBG_OP(x)
17
+ #define DBG_BUF(x)
18
+
19
+ namespace dena {
20
+
21
+ enum special_char_t {
22
+ special_char_escape_prefix = 0x01, /* SOH */
23
+ special_char_noescape_min = 0x10, /* DLE */
24
+ special_char_escape_shift = 0x40, /* '@' */
25
+ };
26
+
27
+ void
28
+ escape_string(char *& wp, const char *start, const char *finish)
29
+ {
30
+ while (start != finish) {
31
+ const unsigned char c = *start;
32
+ if (c >= special_char_noescape_min) {
33
+ wp[0] = c; /* no need to escape */
34
+ } else {
35
+ wp[0] = special_char_escape_prefix;
36
+ ++wp;
37
+ wp[0] = c + special_char_escape_shift;
38
+ }
39
+ ++start;
40
+ ++wp;
41
+ }
42
+ }
43
+
44
+ void
45
+ escape_string(string_buffer& ar, const char *start, const char *finish)
46
+ {
47
+ const size_t buflen = (finish - start) * 2;
48
+ char *const wp_begin = ar.make_space(buflen);
49
+ char *wp = wp_begin;
50
+ escape_string(wp, start, finish);
51
+ ar.space_wrote(wp - wp_begin);
52
+ }
53
+
54
+ bool
55
+ unescape_string(char *& wp, const char *start, const char *finish)
56
+ {
57
+ /* works even if wp == start */
58
+ while (start != finish) {
59
+ const unsigned char c = *start;
60
+ if (c != special_char_escape_prefix) {
61
+ wp[0] = c;
62
+ } else if (start + 1 != finish) {
63
+ ++start;
64
+ const unsigned char cn = *start;
65
+ if (cn < special_char_escape_shift) {
66
+ return false;
67
+ }
68
+ wp[0] = cn - special_char_escape_shift;
69
+ } else {
70
+ return false;
71
+ }
72
+ ++start;
73
+ ++wp;
74
+ }
75
+ return true;
76
+ }
77
+
78
+ bool
79
+ unescape_string(string_buffer& ar, const char *start, const char *finish)
80
+ {
81
+ const size_t buflen = finish - start;
82
+ char *const wp_begin = ar.make_space(buflen);
83
+ char *wp = wp_begin;
84
+ const bool r = unescape_string(wp, start, finish);
85
+ ar.space_wrote(wp - wp_begin);
86
+ return r;
87
+ }
88
+
89
+ uint32_t
90
+ read_ui32(char *& start, char *finish)
91
+ {
92
+ char *const n_begin = start;
93
+ read_token(start, finish);
94
+ char *const n_end = start;
95
+ uint32_t v = 0;
96
+ for (char *p = n_begin; p != n_end; ++p) {
97
+ const char ch = p[0];
98
+ if (ch >= '0' && ch <= '9') {
99
+ v *= 10;
100
+ v += (ch - '0');
101
+ }
102
+ }
103
+ return v;
104
+ }
105
+
106
+ void
107
+ write_ui32(string_buffer& buf, uint32_t v)
108
+ {
109
+ char *wp = buf.make_space(12);
110
+ int len = snprintf(wp, 12, "%u", v);
111
+ if (len > 0) {
112
+ buf.space_wrote(len);
113
+ }
114
+ }
115
+
116
+ void
117
+ write_ui64(string_buffer& buf, uint64_t v)
118
+ {
119
+ char *wp = buf.make_space(22);
120
+ int len = snprintf(wp, 22, "%llu", static_cast<unsigned long long>(v));
121
+ if (len > 0) {
122
+ buf.space_wrote(len);
123
+ }
124
+ }
125
+
126
+ };
127
+
@@ -0,0 +1,66 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <stdint.h>
10
+
11
+ #include "string_buffer.hpp"
12
+ #include "string_ref.hpp"
13
+ #include "string_util.hpp"
14
+
15
+ #ifndef DENA_ESCAPE_HPP
16
+ #define DENA_ESCAPE_HPP
17
+
18
+ namespace dena {
19
+
20
+ void escape_string(char *& wp, const char *start, const char *finish);
21
+ void escape_string(string_buffer& ar, const char *start, const char *finish);
22
+ bool unescape_string(char *& wp, const char *start, const char *finish);
23
+ /* unescaped_string() works even if wp == start */
24
+ bool unescape_string(string_buffer& ar, const char *start, const char *finish);
25
+
26
+ uint32_t read_ui32(char *& start, char *finish);
27
+ void write_ui32(string_buffer& buf, uint32_t v);
28
+ void write_ui64(string_buffer& buf, uint64_t v);
29
+
30
+ inline bool
31
+ is_null_expression(const char *start, const char *finish)
32
+ {
33
+ return (finish == start + 1 && start[0] == 0);
34
+ }
35
+
36
+ inline void
37
+ read_token(char *& start, char *finish)
38
+ {
39
+ char *const p = memchr_char(start, '\t', finish - start);
40
+ if (p == 0) {
41
+ start = finish;
42
+ } else {
43
+ start = p;
44
+ }
45
+ }
46
+
47
+ inline void
48
+ skip_token_delim_fold(char *& start, char *finish)
49
+ {
50
+ while (start != finish && start[0] == '\t') {
51
+ ++start;
52
+ }
53
+ }
54
+
55
+ inline void
56
+ skip_one(char *& start, char *finish)
57
+ {
58
+ if (start != finish) {
59
+ ++start;
60
+ }
61
+ }
62
+
63
+ };
64
+
65
+ #endif
66
+
@@ -0,0 +1,36 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <stdlib.h>
10
+ #include <stdio.h>
11
+ #include <syslog.h>
12
+
13
+ #include "fatal.hpp"
14
+
15
+ namespace dena {
16
+
17
+ const int opt_syslog = LOG_ERR | LOG_PID | LOG_CONS;
18
+
19
+ void
20
+ fatal_exit(const std::string& message)
21
+ {
22
+ fprintf(stderr, "FATAL_EXIT: %s\n", message.c_str());
23
+ syslog(opt_syslog, "FATAL_EXIT: %s", message.c_str());
24
+ _exit(1);
25
+ }
26
+
27
+ void
28
+ fatal_abort(const std::string& message)
29
+ {
30
+ fprintf(stderr, "FATAL_COREDUMP: %s\n", message.c_str());
31
+ syslog(opt_syslog, "FATAL_COREDUMP: %s", message.c_str());
32
+ abort();
33
+ }
34
+
35
+ };
36
+
@@ -0,0 +1,22 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #ifndef DENA_FATAL_HPP
10
+ #define DENA_FATAL_HPP
11
+
12
+ #include <string>
13
+
14
+ namespace dena {
15
+
16
+ void fatal_exit(const std::string& message);
17
+ void fatal_abort(const std::string& message);
18
+
19
+ };
20
+
21
+ #endif
22
+
@@ -0,0 +1,441 @@
1
+
2
+ // vim:sw=2:ai
3
+
4
+ /*
5
+ * Copyright (C) 2010 DeNA Co.,Ltd.. All rights reserved.
6
+ * See COPYRIGHT.txt for details.
7
+ */
8
+
9
+ #include <stdexcept>
10
+
11
+ #include "hstcpcli.hpp"
12
+ #include "auto_file.hpp"
13
+ #include "string_util.hpp"
14
+ #include "auto_addrinfo.hpp"
15
+ #include "escape.hpp"
16
+ #include "util.hpp"
17
+
18
+ /* TODO */
19
+ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(MSG_NOSIGNAL)
20
+ #define MSG_NOSIGNAL 0
21
+ #endif
22
+
23
+ #define DBG(x)
24
+
25
+ namespace dena {
26
+
27
+ struct hstcpcli : public hstcpcli_i, private noncopyable {
28
+ hstcpcli(const socket_args& args);
29
+ virtual void close();
30
+ virtual int reconnect();
31
+ virtual bool stable_point();
32
+ virtual void request_buf_open_index(size_t pst_id, const char *dbn,
33
+ const char *tbl, const char *idx, const char *retflds, const char *filflds);
34
+ virtual void request_buf_auth(const char *secret, const char *typ);
35
+ virtual void request_buf_exec_generic(size_t pst_id, const string_ref& op,
36
+ const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
37
+ const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
38
+ const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
39
+ const string_ref *invalues, size_t invalueslen);
40
+ virtual int request_send();
41
+ virtual int response_recv(size_t& num_flds_r);
42
+ virtual const string_ref *get_next_row();
43
+ virtual void response_buf_remove();
44
+ virtual int get_error_code();
45
+ virtual std::string get_error();
46
+ private:
47
+ int read_more();
48
+ void clear_error();
49
+ int set_error(int code, const std::string& str);
50
+ private:
51
+ auto_file fd;
52
+ socket_args sargs;
53
+ string_buffer readbuf;
54
+ string_buffer writebuf;
55
+ size_t response_end_offset; /* incl newline */
56
+ size_t cur_row_offset;
57
+ size_t num_flds;
58
+ size_t num_req_bufd; /* buffered but not yet sent */
59
+ size_t num_req_sent; /* sent but not yet received */
60
+ size_t num_req_rcvd; /* received but not yet removed */
61
+ int error_code;
62
+ std::string error_str;
63
+ std::vector<string_ref> flds;
64
+ };
65
+
66
+ hstcpcli::hstcpcli(const socket_args& args)
67
+ : sargs(args), response_end_offset(0), cur_row_offset(0), num_flds(0),
68
+ num_req_bufd(0), num_req_sent(0), num_req_rcvd(0), error_code(0)
69
+ {
70
+ std::string err;
71
+ if (socket_connect(fd, sargs, err) != 0) {
72
+ set_error(-1, err);
73
+ }
74
+ }
75
+
76
+ void
77
+ hstcpcli::close()
78
+ {
79
+ fd.close();
80
+ readbuf.clear();
81
+ writebuf.clear();
82
+ flds.clear();
83
+ response_end_offset = 0;
84
+ cur_row_offset = 0;
85
+ num_flds = 0;
86
+ num_req_bufd = 0;
87
+ num_req_sent = 0;
88
+ num_req_rcvd = 0;
89
+ }
90
+
91
+ int
92
+ hstcpcli::reconnect()
93
+ {
94
+ clear_error();
95
+ close();
96
+ std::string err;
97
+ if (socket_connect(fd, sargs, err) != 0) {
98
+ set_error(-1, err);
99
+ }
100
+ return error_code;
101
+ }
102
+
103
+ bool
104
+ hstcpcli::stable_point()
105
+ {
106
+ /* returns true if cli can send a new request */
107
+ return fd.get() >= 0 && num_req_bufd == 0 && num_req_sent == 0 &&
108
+ num_req_rcvd == 0 && response_end_offset == 0;
109
+ }
110
+
111
+ int
112
+ hstcpcli::get_error_code()
113
+ {
114
+ return error_code;
115
+ }
116
+
117
+ std::string
118
+ hstcpcli::get_error()
119
+ {
120
+ return error_str;
121
+ }
122
+
123
+ int
124
+ hstcpcli::read_more()
125
+ {
126
+ const size_t block_size = 4096; // FIXME
127
+ char *const wp = readbuf.make_space(block_size);
128
+ const ssize_t rlen = read(fd.get(), wp, block_size);
129
+ if (rlen <= 0) {
130
+ if (rlen < 0) {
131
+ error_str = "read: failed";
132
+ } else {
133
+ error_str = "read: eof";
134
+ }
135
+ return rlen;
136
+ }
137
+ readbuf.space_wrote(rlen);
138
+ return rlen;
139
+ }
140
+
141
+ void
142
+ hstcpcli::clear_error()
143
+ {
144
+ DBG(fprintf(stderr, "CLEAR_ERROR: %d\n", error_code));
145
+ error_code = 0;
146
+ error_str.clear();
147
+ }
148
+
149
+ int
150
+ hstcpcli::set_error(int code, const std::string& str)
151
+ {
152
+ DBG(fprintf(stderr, "SET_ERROR: %d\n", code));
153
+ error_code = code;
154
+ error_str = str;
155
+ return error_code;
156
+ }
157
+
158
+ void
159
+ hstcpcli::request_buf_open_index(size_t pst_id, const char *dbn,
160
+ const char *tbl, const char *idx, const char *retflds, const char *filflds)
161
+ {
162
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
163
+ close();
164
+ set_error(-1, "request_buf_open_index: protocol out of sync");
165
+ return;
166
+ }
167
+ const string_ref dbn_ref(dbn, strlen(dbn));
168
+ const string_ref tbl_ref(tbl, strlen(tbl));
169
+ const string_ref idx_ref(idx, strlen(idx));
170
+ const string_ref rfs_ref(retflds, strlen(retflds));
171
+ writebuf.append_literal("P\t");
172
+ append_uint32(writebuf, pst_id); // FIXME size_t ?
173
+ writebuf.append_literal("\t");
174
+ writebuf.append(dbn_ref.begin(), dbn_ref.end());
175
+ writebuf.append_literal("\t");
176
+ writebuf.append(tbl_ref.begin(), tbl_ref.end());
177
+ writebuf.append_literal("\t");
178
+ writebuf.append(idx_ref.begin(), idx_ref.end());
179
+ writebuf.append_literal("\t");
180
+ writebuf.append(rfs_ref.begin(), rfs_ref.end());
181
+ if (filflds != 0) {
182
+ const string_ref fls_ref(filflds, strlen(filflds));
183
+ writebuf.append_literal("\t");
184
+ writebuf.append(fls_ref.begin(), fls_ref.end());
185
+ }
186
+ writebuf.append_literal("\n");
187
+ ++num_req_bufd;
188
+ }
189
+
190
+ void
191
+ hstcpcli::request_buf_auth(const char *secret, const char *typ)
192
+ {
193
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
194
+ close();
195
+ set_error(-1, "request_buf_auth: protocol out of sync");
196
+ return;
197
+ }
198
+ if (typ == 0) {
199
+ typ = "1";
200
+ }
201
+ const string_ref typ_ref(typ, strlen(typ));
202
+ const string_ref secret_ref(secret, strlen(secret));
203
+ writebuf.append_literal("A\t");
204
+ writebuf.append(typ_ref.begin(), typ_ref.end());
205
+ writebuf.append_literal("\t");
206
+ writebuf.append(secret_ref.begin(), secret_ref.end());
207
+ writebuf.append_literal("\n");
208
+ ++num_req_bufd;
209
+ }
210
+
211
+ namespace {
212
+
213
+ void
214
+ append_delim_value(string_buffer& buf, const char *start, const char *finish)
215
+ {
216
+ if (start == 0) {
217
+ /* null */
218
+ const char t[] = "\t\0";
219
+ buf.append(t, t + 2);
220
+ } else {
221
+ /* non-null */
222
+ buf.append_literal("\t");
223
+ escape_string(buf, start, finish);
224
+ }
225
+ }
226
+
227
+ };
228
+
229
+ void
230
+ hstcpcli::request_buf_exec_generic(size_t pst_id, const string_ref& op,
231
+ const string_ref *kvs, size_t kvslen, uint32_t limit, uint32_t skip,
232
+ const string_ref& mod_op, const string_ref *mvs, size_t mvslen,
233
+ const hstcpcli_filter *fils, size_t filslen, int invalues_keypart,
234
+ const string_ref *invalues, size_t invalueslen)
235
+ {
236
+ if (num_req_sent > 0 || num_req_rcvd > 0) {
237
+ close();
238
+ set_error(-1, "request_buf_exec_generic: protocol out of sync");
239
+ return;
240
+ }
241
+ append_uint32(writebuf, pst_id); // FIXME size_t ?
242
+ writebuf.append_literal("\t");
243
+ writebuf.append(op.begin(), op.end());
244
+ writebuf.append_literal("\t");
245
+ append_uint32(writebuf, kvslen); // FIXME size_t ?
246
+ for (size_t i = 0; i < kvslen; ++i) {
247
+ const string_ref& kv = kvs[i];
248
+ append_delim_value(writebuf, kv.begin(), kv.end());
249
+ }
250
+ if (limit != 0 || skip != 0 || invalues_keypart >= 0 ||
251
+ mod_op.size() != 0 || filslen != 0) {
252
+ /* has more option */
253
+ writebuf.append_literal("\t");
254
+ append_uint32(writebuf, limit); // FIXME size_t ?
255
+ if (skip != 0 || invalues_keypart >= 0 ||
256
+ mod_op.size() != 0 || filslen != 0) {
257
+ writebuf.append_literal("\t");
258
+ append_uint32(writebuf, skip); // FIXME size_t ?
259
+ }
260
+ if (invalues_keypart >= 0) {
261
+ writebuf.append_literal("\t@\t");
262
+ append_uint32(writebuf, invalues_keypart);
263
+ writebuf.append_literal("\t");
264
+ append_uint32(writebuf, invalueslen);
265
+ for (size_t i = 0; i < invalueslen; ++i) {
266
+ const string_ref& s = invalues[i];
267
+ append_delim_value(writebuf, s.begin(), s.end());
268
+ }
269
+ }
270
+ for (size_t i = 0; i < filslen; ++i) {
271
+ const hstcpcli_filter& f = fils[i];
272
+ writebuf.append_literal("\t");
273
+ writebuf.append(f.filter_type.begin(), f.filter_type.end());
274
+ writebuf.append_literal("\t");
275
+ writebuf.append(f.op.begin(), f.op.end());
276
+ writebuf.append_literal("\t");
277
+ append_uint32(writebuf, f.ff_offset);
278
+ append_delim_value(writebuf, f.val.begin(), f.val.end());
279
+ }
280
+ if (mod_op.size() != 0) {
281
+ writebuf.append_literal("\t");
282
+ writebuf.append(mod_op.begin(), mod_op.end());
283
+ for (size_t i = 0; i < mvslen; ++i) {
284
+ const string_ref& mv = mvs[i];
285
+ append_delim_value(writebuf, mv.begin(), mv.end());
286
+ }
287
+ }
288
+ }
289
+ writebuf.append_literal("\n");
290
+ ++num_req_bufd;
291
+ }
292
+
293
+ int
294
+ hstcpcli::request_send()
295
+ {
296
+ if (error_code < 0) {
297
+ return error_code;
298
+ }
299
+ clear_error();
300
+ if (fd.get() < 0) {
301
+ close();
302
+ return set_error(-1, "write: closed");
303
+ }
304
+ if (num_req_bufd == 0 || num_req_sent > 0 || num_req_rcvd > 0) {
305
+ close();
306
+ return set_error(-1, "request_send: protocol out of sync");
307
+ }
308
+ const size_t wrlen = writebuf.size();
309
+ const ssize_t r = send(fd.get(), writebuf.begin(), wrlen, MSG_NOSIGNAL);
310
+ if (r <= 0) {
311
+ close();
312
+ return set_error(-1, r < 0 ? "write: failed" : "write: eof");
313
+ }
314
+ writebuf.erase_front(r);
315
+ if (static_cast<size_t>(r) != wrlen) {
316
+ close();
317
+ return set_error(-1, "write: incomplete");
318
+ }
319
+ num_req_sent = num_req_bufd;
320
+ num_req_bufd = 0;
321
+ DBG(fprintf(stderr, "REQSEND 0\n"));
322
+ return 0;
323
+ }
324
+
325
+ int
326
+ hstcpcli::response_recv(size_t& num_flds_r)
327
+ {
328
+ if (error_code < 0) {
329
+ return error_code;
330
+ }
331
+ clear_error();
332
+ if (num_req_bufd > 0 || num_req_sent == 0 || num_req_rcvd > 0 ||
333
+ response_end_offset != 0) {
334
+ close();
335
+ return set_error(-1, "response_recv: protocol out of sync");
336
+ }
337
+ cur_row_offset = 0;
338
+ num_flds_r = num_flds = 0;
339
+ if (fd.get() < 0) {
340
+ return set_error(-1, "read: closed");
341
+ }
342
+ size_t offset = 0;
343
+ while (true) {
344
+ const char *const lbegin = readbuf.begin() + offset;
345
+ const char *const lend = readbuf.end();
346
+ const char *const nl = memchr_char(lbegin, '\n', lend - lbegin);
347
+ if (nl != 0) {
348
+ offset = (nl + 1) - readbuf.begin();
349
+ break;
350
+ }
351
+ if (read_more() <= 0) {
352
+ close();
353
+ return set_error(-1, "read: eof");
354
+ }
355
+ }
356
+ response_end_offset = offset;
357
+ --num_req_sent;
358
+ ++num_req_rcvd;
359
+ char *start = readbuf.begin();
360
+ char *const finish = start + response_end_offset - 1;
361
+ const size_t resp_code = read_ui32(start, finish);
362
+ skip_one(start, finish);
363
+ num_flds_r = num_flds = read_ui32(start, finish);
364
+ if (resp_code != 0) {
365
+ skip_one(start, finish);
366
+ char *const err_begin = start;
367
+ read_token(start, finish);
368
+ char *const err_end = start;
369
+ std::string e = std::string(err_begin, err_end - err_begin);
370
+ if (e.empty()) {
371
+ e = "unknown_error";
372
+ }
373
+ return set_error(resp_code, e);
374
+ }
375
+ cur_row_offset = start - readbuf.begin();
376
+ DBG(fprintf(stderr, "[%s] ro=%zu eol=%zu\n",
377
+ std::string(readbuf.begin(), readbuf.begin() + response_end_offset)
378
+ .c_str(),
379
+ cur_row_offset, response_end_offset));
380
+ DBG(fprintf(stderr, "RES 0\n"));
381
+ return 0;
382
+ }
383
+
384
+ const string_ref *
385
+ hstcpcli::get_next_row()
386
+ {
387
+ if (num_flds == 0) {
388
+ DBG(fprintf(stderr, "GNR NF 0\n"));
389
+ return 0;
390
+ }
391
+ if (flds.size() < num_flds) {
392
+ flds.resize(num_flds);
393
+ }
394
+ char *start = readbuf.begin() + cur_row_offset;
395
+ char *const finish = readbuf.begin() + response_end_offset - 1;
396
+ if (start >= finish) { /* start[0] == nl */
397
+ DBG(fprintf(stderr, "GNR FIN 0 %p %p\n", start, finish));
398
+ return 0;
399
+ }
400
+ for (size_t i = 0; i < num_flds; ++i) {
401
+ skip_one(start, finish);
402
+ char *const fld_begin = start;
403
+ read_token(start, finish);
404
+ char *const fld_end = start;
405
+ char *wp = fld_begin;
406
+ if (is_null_expression(fld_begin, fld_end)) {
407
+ /* null */
408
+ flds[i] = string_ref();
409
+ } else {
410
+ unescape_string(wp, fld_begin, fld_end); /* in-place */
411
+ flds[i] = string_ref(fld_begin, wp);
412
+ }
413
+ }
414
+ cur_row_offset = start - readbuf.begin();
415
+ return &flds[0];
416
+ }
417
+
418
+ void
419
+ hstcpcli::response_buf_remove()
420
+ {
421
+ if (response_end_offset == 0) {
422
+ close();
423
+ set_error(-1, "response_buf_remove: protocol out of sync");
424
+ return;
425
+ }
426
+ readbuf.erase_front(response_end_offset);
427
+ response_end_offset = 0;
428
+ --num_req_rcvd;
429
+ cur_row_offset = 0;
430
+ num_flds = 0;
431
+ flds.clear();
432
+ }
433
+
434
+ hstcpcli_ptr
435
+ hstcpcli_i::create(const socket_args& args)
436
+ {
437
+ return hstcpcli_ptr(new hstcpcli(args));
438
+ }
439
+
440
+ };
441
+