lwtarantool 0.0.2

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +84 -0
  3. data/ext/lwtarantool/conn.c +314 -0
  4. data/ext/lwtarantool/depend +23 -0
  5. data/ext/lwtarantool/errors.c +24 -0
  6. data/ext/lwtarantool/extconf.rb +8 -0
  7. data/ext/lwtarantool/lwtarantool.c +12 -0
  8. data/ext/lwtarantool/lwtarantool.h +38 -0
  9. data/ext/lwtarantool/request.c +124 -0
  10. data/ext/lwtarantool/vendor/msgpuck/CMakeLists.txt +73 -0
  11. data/ext/lwtarantool/vendor/msgpuck/hints.c +674 -0
  12. data/ext/lwtarantool/vendor/msgpuck/msgpuck.c +375 -0
  13. data/ext/lwtarantool/vendor/msgpuck/msgpuck.h +2195 -0
  14. data/ext/lwtarantool/vendor/msgpuck/test/CMakeLists.txt +25 -0
  15. data/ext/lwtarantool/vendor/msgpuck/test/msgpuck.c +1126 -0
  16. data/ext/lwtarantool/vendor/msgpuck/test/test.c +105 -0
  17. data/ext/lwtarantool/vendor/msgpuck/test/test.h +123 -0
  18. data/ext/lwtarantool/vendor/tarantool-c/CMakeLists.txt +89 -0
  19. data/ext/lwtarantool/vendor/tarantool-c/cmake/FindMsgPuck.cmake +18 -0
  20. data/ext/lwtarantool/vendor/tarantool-c/cmake/FindSphinx.cmake +10 -0
  21. data/ext/lwtarantool/vendor/tarantool-c/doc/CMakeLists.txt +15 -0
  22. data/ext/lwtarantool/vendor/tarantool-c/doc/source/example.c +340 -0
  23. data/ext/lwtarantool/vendor/tarantool-c/include/CMakeLists.txt +6 -0
  24. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tarantool.h +67 -0
  25. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_auth.h +72 -0
  26. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_buf.h +88 -0
  27. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_call.h +83 -0
  28. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_delete.h +52 -0
  29. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_execute.h +24 -0
  30. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_insert.h +62 -0
  31. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_io.h +67 -0
  32. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_iob.h +62 -0
  33. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_iter.h +301 -0
  34. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_mem.h +102 -0
  35. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_net.h +242 -0
  36. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_object.h +248 -0
  37. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_opt.h +138 -0
  38. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_ping.h +49 -0
  39. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_proto.h +295 -0
  40. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_reply.h +204 -0
  41. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_request.h +377 -0
  42. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_schema.h +165 -0
  43. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_select.h +59 -0
  44. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_stream.h +79 -0
  45. data/ext/lwtarantool/vendor/tarantool-c/include/tarantool/tnt_update.h +226 -0
  46. data/ext/lwtarantool/vendor/tarantool-c/include/tp.h +1998 -0
  47. data/ext/lwtarantool/vendor/tarantool-c/test/CMakeLists.txt +36 -0
  48. data/ext/lwtarantool/vendor/tarantool-c/test/common.c +233 -0
  49. data/ext/lwtarantool/vendor/tarantool-c/test/common.h +28 -0
  50. data/ext/lwtarantool/vendor/tarantool-c/test/plain_test.c +152 -0
  51. data/ext/lwtarantool/vendor/tarantool-c/test/tarantool_call.c +57 -0
  52. data/ext/lwtarantool/vendor/tarantool-c/test/tarantool_disconnect.c +31 -0
  53. data/ext/lwtarantool/vendor/tarantool-c/test/tarantool_tcp.c +840 -0
  54. data/ext/lwtarantool/vendor/tarantool-c/test/tarantool_unix.c +384 -0
  55. data/ext/lwtarantool/vendor/tarantool-c/test/test.c +72 -0
  56. data/ext/lwtarantool/vendor/tarantool-c/test/test.h +94 -0
  57. data/ext/lwtarantool/vendor/tarantool-c/test/tnt_assoc.c +6 -0
  58. data/ext/lwtarantool/vendor/tarantool-c/test/tnt_assoc.h +67 -0
  59. data/ext/lwtarantool/vendor/tarantool-c/third_party/PMurHash.c +317 -0
  60. data/ext/lwtarantool/vendor/tarantool-c/third_party/PMurHash.h +68 -0
  61. data/ext/lwtarantool/vendor/tarantool-c/third_party/base64.c +300 -0
  62. data/ext/lwtarantool/vendor/tarantool-c/third_party/base64.h +91 -0
  63. data/ext/lwtarantool/vendor/tarantool-c/third_party/mhash.h +589 -0
  64. data/ext/lwtarantool/vendor/tarantool-c/third_party/sha1.c +219 -0
  65. data/ext/lwtarantool/vendor/tarantool-c/third_party/sha1.h +24 -0
  66. data/ext/lwtarantool/vendor/tarantool-c/third_party/uri.c +6528 -0
  67. data/ext/lwtarantool/vendor/tarantool-c/third_party/uri.h +81 -0
  68. data/ext/lwtarantool/vendor/tarantool-c/tnt/CMakeLists.txt +83 -0
  69. data/ext/lwtarantool/vendor/tarantool-c/tnt/pmatomic.h +494 -0
  70. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_assoc.c +9 -0
  71. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_assoc.h +172 -0
  72. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_auth.c +118 -0
  73. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_buf.c +171 -0
  74. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_call.c +79 -0
  75. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_delete.c +52 -0
  76. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_execute.c +60 -0
  77. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_insert.c +60 -0
  78. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_io.c +520 -0
  79. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_iob.c +75 -0
  80. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_iter.c +293 -0
  81. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_mem.c +82 -0
  82. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_net.c +336 -0
  83. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_object.c +476 -0
  84. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_opt.c +117 -0
  85. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_ping.c +38 -0
  86. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_proto_internal.h +43 -0
  87. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_reply.c +300 -0
  88. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_request.c +336 -0
  89. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_schema.c +334 -0
  90. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_select.c +58 -0
  91. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_stream.c +71 -0
  92. data/ext/lwtarantool/vendor/tarantool-c/tnt/tnt_update.c +247 -0
  93. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/CMakeLists.txt +69 -0
  94. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_dir.c +173 -0
  95. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_dir.h +58 -0
  96. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_log.c +329 -0
  97. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_log.h +119 -0
  98. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_rpl.c +189 -0
  99. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_rpl.h +47 -0
  100. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_snapshot.c +163 -0
  101. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_snapshot.h +50 -0
  102. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_xlog.c +163 -0
  103. data/ext/lwtarantool/vendor/tarantool-c/tntrpl/tnt_xlog.h +50 -0
  104. data/lib/lwtarantool/connection.rb +84 -0
  105. data/lib/lwtarantool/request.rb +58 -0
  106. data/lib/lwtarantool.rb +23 -0
  107. metadata +164 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a10bfa0d8c43049eaff1705cb971ae461cca2bc
4
+ data.tar.gz: d823ef8761beeb1f8f44babb0162891549c8e2af
5
+ SHA512:
6
+ metadata.gz: 69a06f61c2a266a33ec9a4f3bc40df1c12eeda7ee23caafa37d86bd3ffcdaac947aa55e65943ba9456ef6118738559e8e5a82c39339f30eac0181970933ae8b0
7
+ data.tar.gz: 08d0f5c944dbf08a519b95ef625e6389356f58eeef0497fca8067bbada91facfe05f185aad213c033002b4c2c07402da251a4230339e6b98123d2052cb82847d
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # LWTarantool - Ruby client for Tarantool 1.7+
2
+
3
+ [![Build Status](https://semaphoreci.com/api/v1/0xbf/lwtarantool/branches/master/shields_badge.svg)](https://semaphoreci.com/0xbf/lwtarantool)
4
+ [![Gem Version](https://badge.fury.io/rb/lwtarantool.svg)](https://badge.fury.io/rb/lwtarantool)
5
+
6
+ ## About
7
+
8
+ A Ruby client for Tarantool 1.7+.
9
+
10
+ It doesn't support all tarantool protocol features, the only function calls, but allow work with tarantool in async paradigm.
11
+
12
+ Based on official [tarantool-c](https://github.com/tarantool/tarantool-c) connector.
13
+
14
+ ## Getting started
15
+
16
+ ### Install
17
+
18
+ ```
19
+ $ gem install lwtarantool
20
+ ```
21
+
22
+ ### Connect
23
+
24
+ ```ruby
25
+ require 'lwtarantool'
26
+ tnt = LWTarantool.new(url: '127.0.0.1:3301')
27
+ ```
28
+
29
+ ### Pipelining
30
+
31
+ ```ruby
32
+ reqs = []
33
+ reqs << conn.call('box.slab.info', [])
34
+ reqs << conn.call('box.runtime.info', [])
35
+
36
+ reqs.each(&:wait)
37
+
38
+ if reqs[0].result
39
+ puts "req0 result: #{reqs[0].result.inspect}"
40
+ else
41
+ puts "req0 error: #{reqs[0].error}"
42
+ end
43
+
44
+ if reqs[1].result
45
+ puts "req1 result: #{reqs[1].result.inspect}"
46
+ else
47
+ puts "req1 error: #{reqs[1].error}"
48
+ end
49
+ ```
50
+
51
+ ### Async requests
52
+
53
+ ```ruby
54
+ slab_req = conn.call('box.slab.info', [])
55
+ runtime_req = conn.call('box.runtime.info', [])
56
+
57
+ 2.times do
58
+ req = conn.read
59
+ case req
60
+ when slab_req
61
+ if req.result
62
+ puts "slab info: #{req.result.inspect}"
63
+ else
64
+ puts "slab info error: #{req.error}"
65
+ end
66
+ when runtime_req
67
+ if req.result
68
+ puts "runtime info: #{req.result.inspect}"
69
+ else
70
+ puts "runtime info error: #{req.error}"
71
+ end
72
+ end
73
+ end
74
+ ```
75
+
76
+ ## Error handling
77
+
78
+ ## Testing
79
+
80
+ This library is tested against recent Ruby versions. Check [Semaphore CI](https://semaphoreci.com/0xbf/lwtarantool) for the exact versions supported.
81
+
82
+ ## Contributing
83
+
84
+ Fork the project and send pull requests.
@@ -0,0 +1,314 @@
1
+ #include <ruby.h>
2
+ #include <ruby/st.h>
3
+
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+
7
+ #include <tarantool/tarantool.h>
8
+ #include <tarantool/tnt_net.h>
9
+ #include <tarantool/tnt_opt.h>
10
+
11
+ #include "lwtarantool.h"
12
+
13
+
14
+ static int
15
+ lwt_conn_interrupt_request(uint64_t *id, VALUE req) {
16
+ struct tnt_reply *reply = tnt_reply_init(NULL);
17
+
18
+ char * error = "Request canceled due to connection close";
19
+
20
+ reply->code = -1;
21
+ reply->error = error;
22
+ reply->error_end = error + strlen(error);
23
+
24
+ lwt_request_add_reply(req, reply);
25
+
26
+ return ST_DELETE;
27
+ }
28
+
29
+ static int
30
+ lwt_conn_mark_request(uint64_t *id, VALUE req) {
31
+ rb_gc_mark(req);
32
+ return ST_CONTINUE;
33
+ }
34
+
35
+ static void
36
+ lwt_conn_mark(void *s) {
37
+ lwt_conn_t *conn = (lwt_conn_t *) s;
38
+ st_foreach(conn->requests, lwt_conn_mark_request, 0);
39
+ }
40
+
41
+ static void
42
+ lwt_conn_dealloc(lwt_conn_t *conn) {
43
+ if (conn == NULL)
44
+ return;
45
+
46
+ if (conn->tnt != NULL) {
47
+ tnt_close(conn->tnt);
48
+ tnt_stream_free(conn->tnt);
49
+ }
50
+ if (conn->requests) {
51
+ st_clear(conn->requests);
52
+ st_free_table(conn->requests);
53
+ }
54
+ }
55
+
56
+ static VALUE
57
+ lwt_conn_alloc( VALUE klass) {
58
+ lwt_conn_t * conn;
59
+ conn = ZALLOC(lwt_conn_t);
60
+
61
+ conn->tnt = tnt_net(NULL);
62
+ conn->requests = st_init_numtable();
63
+
64
+ return Data_Wrap_Struct( klass, lwt_conn_mark, lwt_conn_dealloc, conn);
65
+ }
66
+
67
+ static void
68
+ lwt_conn_raise_error(lwt_conn_t *conn) {
69
+ switch(tnt_error(conn->tnt)) {
70
+ case TNT_EMEMORY:
71
+ rb_raise(rb_eNoMemError, tnt_strerror(conn->tnt));
72
+ break;
73
+ case TNT_ERESOLVE:
74
+ rb_raise(lwt_eResolvError, tnt_strerror(conn->tnt));
75
+ break;
76
+ case TNT_ETMOUT:
77
+ rb_raise(lwt_eTimeoutError, tnt_strerror(conn->tnt));
78
+ break;
79
+ case TNT_ELOGIN:
80
+ rb_raise(lwt_eLoginError, tnt_strerror(conn->tnt));
81
+ break;
82
+ case TNT_ESYSTEM:
83
+ rb_raise(lwt_eSystemError, tnt_strerror(conn->tnt));
84
+ break;
85
+ case TNT_EFAIL:
86
+ case TNT_EBIG:
87
+ default:
88
+ rb_raise(lwt_eUnknownError, tnt_strerror(conn->tnt));
89
+ break;
90
+ }
91
+ }
92
+
93
+ static VALUE
94
+ lwt_conn_connect(VALUE self) {
95
+ lwt_conn_t * conn;
96
+ Data_Get_Struct(self, lwt_conn_t, conn);
97
+
98
+ if (tnt_connect(conn->tnt) < 0)
99
+ lwt_conn_raise_error(conn);
100
+
101
+ return Qtrue;
102
+ }
103
+
104
+ static VALUE
105
+ lwt_conn_disconnect(VALUE self) {
106
+ lwt_conn_t * conn;
107
+ Data_Get_Struct(self, lwt_conn_t, conn);
108
+
109
+ tnt_close(conn->tnt);
110
+ st_foreach(conn->requests, lwt_conn_interrupt_request, 0);
111
+
112
+ return Qtrue;
113
+ }
114
+
115
+ /**
116
+ * Document-class: LWTarantool::Connection
117
+ *
118
+ * Create new connection to Tarantool.
119
+ *
120
+ * @param [Hash] args the options to establish connection
121
+ * @option args [String] :url The tarantool address
122
+ *
123
+ * @example
124
+ * LWTarantool::Connection.new(url: 'tcp://127.0.0.1:3301')
125
+ *
126
+ * @return [LWTarantool::Connection] a new connection instance.
127
+ *
128
+ * @raise [LWTarantool::ResolvError] destination host can't be resolved
129
+ * @raise [LWTarantool::TimeoutError] connect timeout reached
130
+ * @raise [LWTarantool::LoginError] incorrect login or password
131
+ * @raise [LWTarantool::SystemError] connection failed
132
+ * @raise [LWTarantool::UnknownError] unknown error
133
+ */
134
+ static VALUE
135
+ lwt_conn_initialize(VALUE self, VALUE args) {
136
+ lwt_conn_t * conn;
137
+ Data_Get_Struct(self, lwt_conn_t, conn);
138
+
139
+ VALUE val;
140
+
141
+ val = rb_mutex_new();
142
+ rb_iv_set(self, "@mutex", val);
143
+
144
+ if (TYPE(args) != T_HASH)
145
+ rb_raise(rb_eArgError, "args must be a Hash");
146
+
147
+ val = rb_hash_aref(args, ID2SYM(rb_intern( "url")));
148
+ if (TYPE(val) != T_STRING)
149
+ rb_raise(rb_eArgError, "url must be a String");
150
+
151
+ int url_len = RSTRING_LEN(val);
152
+ char url[url_len+1];
153
+ url[url_len] = '\0';
154
+ strncpy(url, RSTRING_PTR(val), url_len);
155
+
156
+ tnt_set(conn->tnt, TNT_OPT_URI, url);
157
+
158
+ lwt_conn_connect(self);
159
+
160
+ return Qnil;
161
+ }
162
+
163
+ static VALUE
164
+ lwt_conn_call(VALUE self, VALUE func, VALUE args) {
165
+ lwt_conn_t * conn;
166
+ Data_Get_Struct(self, lwt_conn_t, conn);
167
+
168
+ if (TYPE(func) != T_STRING)
169
+ rb_raise(rb_eArgError, "function name must be a String");
170
+
171
+ if (TYPE(args) != T_STRING)
172
+ rb_raise(rb_eArgError, "args must be a string with msgpack array");
173
+
174
+ int func_len = RSTRING_LEN(func);
175
+ char func_name[func_len+1];
176
+ func_name[func_len] = '\0';
177
+ strncpy(func_name, RSTRING_PTR(func), func_len);
178
+
179
+ uint64_t reqid = conn->tnt->reqid;
180
+ VALUE req;
181
+
182
+ struct tnt_stream * data;
183
+ data = tnt_object(NULL);
184
+ if (data == NULL)
185
+ rb_raise(rb_eNoMemError, "Can't create tnt_object");
186
+
187
+ if (data->write(data, RSTRING_PTR(args), RSTRING_LEN(args)) < 0) {
188
+ tnt_stream_free(data);
189
+ rb_raise(rb_eNoMemError, "Can't store args");
190
+ }
191
+
192
+ if (tnt_call(conn->tnt, func_name, func_len, data) < 0) {
193
+ tnt_stream_free(data);
194
+ lwt_conn_raise_error(conn);
195
+ }
196
+
197
+ if (tnt_flush(conn->tnt) < 0) {
198
+ tnt_stream_free(data);
199
+ lwt_conn_raise_error(conn);
200
+ }
201
+
202
+ tnt_stream_free(data);
203
+
204
+ req = lwt_request_create(self, reqid);
205
+ st_insert( conn->requests, reqid, req);
206
+
207
+ return req;
208
+ }
209
+
210
+ static VALUE
211
+ lwt_conn_read(VALUE self) {
212
+ lwt_conn_t * conn;
213
+ Data_Get_Struct(self, lwt_conn_t, conn);
214
+
215
+ VALUE req;
216
+ struct tnt_reply *reply = tnt_reply_init(NULL);
217
+
218
+ int rc = conn->tnt->read_reply(conn->tnt, reply);
219
+ //printf("sync: %d, code: %d, err: %d, errno: %d, strerr: %s\n", rc, reply->sync, reply->code, tnt_error(conn->tnt), tnt_errno(conn->tnt), tnt_strerror(conn->tnt));
220
+
221
+ if (rc == 1)
222
+ return Qnil;
223
+
224
+ if (rc == -1)
225
+ lwt_conn_raise_error(conn);
226
+
227
+ if (rc != 0)
228
+ rb_raise( lwt_eUnknownError, "read_reply() return code %d", rc);
229
+
230
+ if (st_delete(conn->requests, &reply->sync, &req) != 1)
231
+ rb_raise(lwt_eSyncError, "Bad sync id %lu in tarantool reply", reply->sync);
232
+
233
+ lwt_request_add_reply( req, reply);
234
+
235
+ return req;
236
+ }
237
+
238
+ /**
239
+ * Document-class: LWTarantool::Connection
240
+ *
241
+ * Check if connection established.
242
+ *
243
+ * @example
244
+ * conn.connected?
245
+ *
246
+ * @return [Boolean]
247
+ */
248
+ static VALUE
249
+ lwt_conn_is_connected(VALUE self) {
250
+ lwt_conn_t * conn;
251
+ Data_Get_Struct(self, lwt_conn_t, conn);
252
+
253
+ struct tnt_stream_net *sn = TNT_SNET_CAST(conn->tnt);
254
+
255
+ if (sn->connected)
256
+ return Qtrue;
257
+ else
258
+ return Qfalse;
259
+ }
260
+
261
+ static VALUE
262
+ lwt_conn_error(VALUE self) {
263
+ lwt_conn_t * conn;
264
+ Data_Get_Struct(self, lwt_conn_t, conn);
265
+
266
+ return rb_uint2inum(tnt_error(conn->tnt));
267
+ }
268
+
269
+ static VALUE
270
+ lwt_conn_errno(VALUE self) {
271
+ lwt_conn_t * conn;
272
+ Data_Get_Struct(self, lwt_conn_t, conn);
273
+
274
+ return rb_uint2inum(tnt_errno(conn->tnt));
275
+ }
276
+
277
+ static VALUE
278
+ lwt_conn_strerror(VALUE self) {
279
+ lwt_conn_t * conn;
280
+ Data_Get_Struct(self, lwt_conn_t, conn);
281
+
282
+ return rb_str_new_cstr(tnt_strerror(conn->tnt));
283
+ }
284
+
285
+ void init_conn() {
286
+ /*
287
+ * Document-class: LWTarantool::Connection
288
+ *
289
+ * Class for work with Tarantool connections
290
+ */
291
+ VALUE cClass = rb_define_class_under( lwt_Class, "Connection", rb_cObject);
292
+
293
+ rb_const_set( lwt_Class, rb_intern("TNT_EFAIL"), rb_uint2inum(TNT_EFAIL));
294
+ rb_const_set( lwt_Class, rb_intern("TNT_EMEMORY"), rb_uint2inum(TNT_EMEMORY));
295
+ rb_const_set( lwt_Class, rb_intern("TNT_ESYSTEM"), rb_uint2inum(TNT_ESYSTEM));
296
+ rb_const_set( lwt_Class, rb_intern("TNT_EBIG"), rb_uint2inum(TNT_EBIG));
297
+ rb_const_set( lwt_Class, rb_intern("TNT_ESIZE"), rb_uint2inum(TNT_ESIZE));
298
+ rb_const_set( lwt_Class, rb_intern("TNT_ERESOLVE"), rb_uint2inum(TNT_ERESOLVE));
299
+ rb_const_set( lwt_Class, rb_intern("TNT_ETMOUT"), rb_uint2inum(TNT_ETMOUT));
300
+ rb_const_set( lwt_Class, rb_intern("TNT_EBADVAL"), rb_uint2inum(TNT_EBADVAL));
301
+ rb_const_set( lwt_Class, rb_intern("TNT_ELOGIN"), rb_uint2inum(TNT_ELOGIN));
302
+
303
+ rb_define_alloc_func(cClass, lwt_conn_alloc);
304
+ rb_define_method(cClass, "initialize", lwt_conn_initialize, 1);
305
+ rb_define_private_method(cClass, "_connect", lwt_conn_connect, 0);
306
+ rb_define_private_method(cClass, "_disconnect", lwt_conn_disconnect, 0);
307
+ rb_define_private_method(cClass, "_error", lwt_conn_error, 0);
308
+ rb_define_private_method(cClass, "_errno", lwt_conn_errno, 0);
309
+ rb_define_private_method(cClass, "_strerror", lwt_conn_strerror, 0);
310
+ rb_define_private_method(cClass, "_call", lwt_conn_call, 2);
311
+ rb_define_private_method(cClass, "_read", lwt_conn_read, 0);
312
+
313
+ rb_define_method(cClass, "connected?", lwt_conn_is_connected, 0);
314
+ }
@@ -0,0 +1,23 @@
1
+ $(DLLIB): tarantool-c/libtarantool.a msgpuck/libmsgpuck.a
2
+
3
+ $(OBJS): $(HDRS) $(ruby_headers)
4
+
5
+ msgpuck/libmsgpuck.a: Makefile
6
+ mkdir -p msgpuck
7
+ cd msgpuck && cmake ../$(srcdir)/vendor/msgpuck
8
+ make -C msgpuck msgpuck
9
+
10
+ tarantool-c/libtarantool.a: Makefile
11
+ mkdir -p tarantool-c
12
+ cd tarantool-c && cmake ../$(srcdir)/vendor/tarantool-c -DMSGPUCK_INCLUDE_DIR=../$(srcdir)/vendor/msgpuck -DMSGPUCK_LIBRARY=../$(srcdir)/vendor/msgpuck
13
+ make -C tarantool-c tnt
14
+
15
+ .PHONY: clean-msgpuck clean-tarantool-c
16
+
17
+ clean: clean-msgpuck clean-tarantool-c
18
+
19
+ clean-msgpuck:
20
+ -rm -rf msgpuck
21
+
22
+ clean-tarantool-c:
23
+ -rm -rf tarantool-c
@@ -0,0 +1,24 @@
1
+ #include <ruby.h>
2
+ #include "lwtarantool.h"
3
+
4
+ VALUE lwt_eError = NULL;
5
+ VALUE lwt_eLoginError = NULL;
6
+ VALUE lwt_eResolvError = NULL;
7
+ VALUE lwt_eSyncError = NULL;
8
+ VALUE lwt_eSystemError = NULL;
9
+ VALUE lwt_eTimeoutError = NULL;
10
+ VALUE lwt_eUnknownError = NULL;
11
+
12
+ void init_errors() {
13
+ lwt_eError = rb_define_class_under( lwt_Class, "Error", rb_eStandardError);
14
+ lwt_eLoginError = rb_define_class_under( lwt_Class, "LoginError", lwt_eError);
15
+ lwt_eSyncError = rb_define_class_under( lwt_Class, "SyncError", lwt_eError);
16
+ lwt_eSystemError = rb_define_class_under( lwt_Class, "SystemError", lwt_eError);
17
+ lwt_eResolvError = rb_define_class_under( lwt_Class, "ResolvError", lwt_eError);
18
+ lwt_eTimeoutError = rb_define_class_under( lwt_Class, "TimeoutError", lwt_eError);
19
+ lwt_eUnknownError = rb_define_class_under( lwt_Class, "UnknownError", lwt_eError);
20
+
21
+ //lwt_eLoginError = rb_define_class_under( lwt_Class, "LoginError", lwt_eError);
22
+ //lwt_eLoginError = rb_define_class_under( lwt_Class, "LoginError", lwt_eError);
23
+ //lwt_eLoginError = rb_define_class_under( lwt_Class, "LoginError", lwt_eError);
24
+ }
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ $INCFLAGS << ' -I$(srcdir)/vendor/tarantool-c/include'
4
+ $LIBPATH << 'msgpuck/'
5
+ $LIBPATH << 'tarantool-c/tnt/'
6
+ $LOCAL_LIBS = '-ltarantool -lmsgpuck'
7
+
8
+ create_makefile 'lwtarantool/lwtarantool'
@@ -0,0 +1,12 @@
1
+ #include <ruby.h>
2
+ #include "lwtarantool.h"
3
+
4
+ VALUE lwt_Class;
5
+
6
+ void Init_lwtarantool() {
7
+ lwt_Class = rb_define_module( "LWTarantool");
8
+
9
+ init_errors();
10
+ init_conn();
11
+ init_request();
12
+ }
@@ -0,0 +1,38 @@
1
+ #include <ruby.h>
2
+ #include <tarantool/tnt_reply.h>
3
+ #include <tarantool/tnt_stream.h>
4
+
5
+ #ifndef ZALLOC
6
+ # define ZALLOC_N(type,n) ((type*)xcalloc((n),sizeof(type)))
7
+ # define ZALLOC(type) (ZALLOC_N(type,1))
8
+ #endif
9
+
10
+ extern VALUE lwt_Class;
11
+
12
+ extern VALUE lwt_eError;
13
+ extern VALUE lwt_eLoginError;
14
+ extern VALUE lwt_eResolvError;
15
+ extern VALUE lwt_eSyncError;
16
+ extern VALUE lwt_eSystemError;
17
+ extern VALUE lwt_eTimeoutError;
18
+ extern VALUE lwt_eUnknownError;
19
+
20
+
21
+ typedef struct {
22
+ VALUE mutex;
23
+ struct tnt_stream *tnt;
24
+ st_table *requests;
25
+ } lwt_conn_t;
26
+
27
+ typedef struct {
28
+ VALUE conn;
29
+ uint64_t id;
30
+ struct tnt_reply *reply;
31
+ } lwt_request_t;
32
+
33
+ VALUE lwt_request_create( VALUE conn, uint64_t id);
34
+ void lwt_request_add_reply( VALUE self, struct tnt_reply *reply);
35
+
36
+ void init_conn();
37
+ void init_request();
38
+ void init_errors();
@@ -0,0 +1,124 @@
1
+ #include <ruby.h>
2
+ #include "lwtarantool.h"
3
+
4
+ static VALUE rClass;
5
+
6
+ VALUE
7
+ lwt_request_create( VALUE conn, uint64_t id) {
8
+ VALUE self;
9
+ lwt_request_t * req;
10
+
11
+ req = ZALLOC(lwt_request_t);
12
+ req->id = id;
13
+
14
+ self = Data_Wrap_Struct( rClass, NULL, NULL, req);
15
+ rb_iv_set(self, "@conn", conn);
16
+
17
+ //printf("Create request %p, reply: %p\n", req, req->reply);
18
+
19
+ return self;
20
+ }
21
+
22
+ void
23
+ lwt_request_add_reply( VALUE self, struct tnt_reply *reply) {
24
+ lwt_request_t * req;
25
+ Data_Get_Struct(self, lwt_request_t, req);
26
+
27
+ //printf("Add reply %p to request %p\n", reply, req);
28
+
29
+ req->reply = reply;
30
+ }
31
+
32
+ /*
33
+ * Document-class: LWTarantool::Request
34
+ *
35
+ * Request id
36
+ *
37
+ * @return [Integer] id
38
+ */
39
+ static VALUE
40
+ lwt_request_id( VALUE self) {
41
+ lwt_request_t * req;
42
+ Data_Get_Struct(self, lwt_request_t, req);
43
+
44
+ return rb_uint2inum(req->id);
45
+ }
46
+
47
+ /*
48
+ * Document-class: LWTarantool::Request
49
+ *
50
+ * Check if request already processed.
51
+ */
52
+ static VALUE
53
+ lwt_request_is_ready( VALUE self) {
54
+ lwt_request_t * req;
55
+ Data_Get_Struct(self, lwt_request_t, req);
56
+
57
+ if (req->reply == NULL)
58
+ return Qfalse;
59
+ else
60
+ return Qtrue;
61
+ }
62
+
63
+ /*
64
+ static VALUE
65
+ lwt_request_code( VALUE self) {
66
+ lwt_request_t * req;
67
+ Data_Get_Struct(self, lwt_request_t, req);
68
+
69
+ if (req->reply == NULL)
70
+ return Qnil;
71
+
72
+ return rb_uint2inum(req->reply->code);
73
+ }
74
+ */
75
+
76
+ static VALUE
77
+ lwt_request_error( VALUE self) {
78
+ lwt_request_t * req;
79
+ Data_Get_Struct(self, lwt_request_t, req);
80
+
81
+ if (req->reply == NULL)
82
+ return Qnil;
83
+
84
+ if (req->reply->code == 0)
85
+ return Qnil;
86
+
87
+ if (req->reply->error == NULL)
88
+ return Qnil;
89
+
90
+ const char *data = req->reply->error;
91
+ size_t data_len = req->reply->error_end - data;
92
+ return rb_str_new(data, data_len);
93
+ }
94
+
95
+ static VALUE
96
+ lwt_request_result( VALUE self) {
97
+ lwt_request_t * req;
98
+ Data_Get_Struct(self, lwt_request_t, req);
99
+
100
+ if (req->reply == NULL)
101
+ return Qnil;
102
+
103
+ if (req->reply->code != 0)
104
+ return Qnil;
105
+
106
+ const char *data = req->reply->data;
107
+ size_t data_len = req->reply->data_end - data;
108
+ return rb_str_new(data, data_len);
109
+ }
110
+
111
+ void init_request() {
112
+ /*
113
+ * Document-class: LWTarantool::Request
114
+ *
115
+ * Class for work with Tarantool requests
116
+ */
117
+ rClass = rb_define_class_under( lwt_Class, "Request", rb_cObject);
118
+
119
+ rb_define_method(rClass, "id", lwt_request_id, 0);
120
+ rb_define_method(rClass, "ready?", lwt_request_is_ready, 0);
121
+ //rb_define_method(rClass, "code", lwt_request_code, 0);
122
+ rb_define_private_method(rClass, "_error", lwt_request_error, 0);
123
+ rb_define_private_method(rClass, "_result", lwt_request_result, 0);
124
+ }