vincentchu-handlersocket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+