ekaranto-rubywmq 2.0.0

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 (51) hide show
  1. data/.document +4 -0
  2. data/LICENSE.txt +201 -0
  3. data/README.md +408 -0
  4. data/Rakefile +87 -0
  5. data/examples/each_a.rb +16 -0
  6. data/examples/each_b.rb +25 -0
  7. data/examples/each_header.rb +22 -0
  8. data/examples/files_to_q.cfg +24 -0
  9. data/examples/files_to_q.rb +31 -0
  10. data/examples/get_a.rb +19 -0
  11. data/examples/get_client.rb +35 -0
  12. data/examples/put1_a.rb +9 -0
  13. data/examples/put1_b.rb +17 -0
  14. data/examples/put1_c.rb +16 -0
  15. data/examples/put_a.rb +19 -0
  16. data/examples/put_b.rb +27 -0
  17. data/examples/put_dlh.rb +25 -0
  18. data/examples/put_dynamic_q.rb +22 -0
  19. data/examples/put_group_a.rb +35 -0
  20. data/examples/put_group_b.rb +37 -0
  21. data/examples/put_rfh.rb +51 -0
  22. data/examples/put_rfh2_a.rb +27 -0
  23. data/examples/put_rfh2_b.rb +27 -0
  24. data/examples/put_xmit_q.rb +17 -0
  25. data/examples/q_to_files.cfg +17 -0
  26. data/examples/q_to_files.rb +32 -0
  27. data/examples/request.rb +44 -0
  28. data/examples/server.rb +81 -0
  29. data/ext/decode_rfh.c +348 -0
  30. data/ext/decode_rfh.h +45 -0
  31. data/ext/extconf.rb +30 -0
  32. data/ext/extconf_client.rb +24 -0
  33. data/ext/generate/generate_const.rb +140 -0
  34. data/ext/generate/generate_reason.rb +233 -0
  35. data/ext/generate/generate_structs.rb +82 -0
  36. data/ext/generate/wmq_structs.erb +341 -0
  37. data/ext/wmq.c +90 -0
  38. data/ext/wmq.h +371 -0
  39. data/ext/wmq_message.c +671 -0
  40. data/ext/wmq_mq_load.c +217 -0
  41. data/ext/wmq_queue.c +1411 -0
  42. data/ext/wmq_queue_manager.c +1570 -0
  43. data/lib/rubywmq.rb +1 -0
  44. data/lib/wmq/message.rb +70 -0
  45. data/lib/wmq/queue_manager.rb +110 -0
  46. data/lib/wmq/version.rb +3 -0
  47. data/lib/wmq.rb +16 -0
  48. data/nbproject/project.properties +11 -0
  49. data/nbproject/project.xml +17 -0
  50. data/tests/test.rb +318 -0
  51. metadata +115 -0
data/ext/wmq.h ADDED
@@ -0,0 +1,371 @@
1
+ /* --------------------------------------------------------------------------
2
+ * Copyright 2006 J. Reid Morrison
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ * --------------------------------------------------------------------------*/
16
+
17
+ #include <ruby.h>
18
+
19
+ /* New with Ruby 1.9, define for prior Ruby versions */
20
+ #ifndef RSTRING_PTR
21
+ #define RSTRING_PTR(str) RSTRING(str)->ptr
22
+ #endif
23
+ #ifndef RSTRING_LEN
24
+ #define RSTRING_LEN(str) RSTRING(str)->len
25
+ #endif
26
+ #ifndef RARRAY_PTR
27
+ #define RARRAY_PTR(ary) RARRAY(ary)->ptr
28
+ #endif
29
+ #ifndef RARRAY_LEN
30
+ #define RARRAY_LEN(ary) RARRAY(ary)->len
31
+ #endif
32
+ #ifndef HAVE_RB_STR_SET_LEN
33
+ #define rb_str_set_len(str, length) (RSTRING_LEN(str) = (length))
34
+ #endif
35
+
36
+ #ifndef _int64
37
+ #define _int64 long long
38
+ #endif
39
+
40
+ #include <cmqc.h>
41
+ #include <cmqxc.h>
42
+
43
+ /* Todo: Add a #ifdef here to exclude the following includes when applicable */
44
+ #include <cmqcfc.h> /* PCF */
45
+ #include <cmqbc.h> /* MQAI */
46
+
47
+ #ifdef _WIN32
48
+ #define WMQ_EXPORT __declspec(dllexport)
49
+ #else
50
+ #define WMQ_EXPORT
51
+ #endif
52
+
53
+ void QueueManager_id_init();
54
+ void QueueManager_selector_id_init();
55
+ void QueueManager_command_id_init();
56
+ VALUE QUEUE_MANAGER_alloc(VALUE klass);
57
+ VALUE QueueManager_singleton_connect(int argc, VALUE *argv, VALUE self);
58
+ VALUE QueueManager_open_queue(int argc, VALUE *argv, VALUE self);
59
+ VALUE QueueManager_initialize(VALUE self, VALUE parms);
60
+ VALUE QueueManager_connect(VALUE self);
61
+ VALUE QueueManager_disconnect(VALUE self);
62
+ VALUE QueueManager_begin(VALUE self);
63
+ VALUE QueueManager_commit(VALUE self);
64
+ VALUE QueueManager_backout(VALUE self);
65
+ VALUE QueueManager_put(VALUE self, VALUE parms);
66
+ VALUE QueueManager_reason_code(VALUE self);
67
+ VALUE QueueManager_comp_code(VALUE self);
68
+ VALUE QueueManager_reason(VALUE self);
69
+ VALUE QueueManager_exception_on_error(VALUE self);
70
+ VALUE QueueManager_connected_q(VALUE self);
71
+ VALUE QueueManager_name(VALUE self);
72
+ VALUE QueueManager_execute(VALUE self, VALUE hash);
73
+
74
+ void Queue_id_init();
75
+ VALUE QUEUE_alloc(VALUE klass);
76
+ VALUE Queue_initialize(VALUE self, VALUE parms);
77
+ VALUE Queue_singleton_open(int argc, VALUE *argv, VALUE self);
78
+ VALUE Queue_open(VALUE self);
79
+ VALUE Queue_close(VALUE self);
80
+ VALUE Queue_put(VALUE self, VALUE parms);
81
+ VALUE Queue_get(VALUE self, VALUE parms);
82
+ VALUE Queue_each(int argc, VALUE *argv, VALUE self);
83
+ VALUE Queue_name(VALUE self);
84
+ VALUE Queue_reason_code(VALUE self);
85
+ VALUE Queue_comp_code(VALUE self);
86
+ VALUE Queue_reason(VALUE self);
87
+ VALUE Queue_open_q(VALUE self);
88
+
89
+ void Queue_extract_put_message_options(VALUE hash, PMQPMO ppmo);
90
+
91
+ extern VALUE wmq_queue;
92
+ extern VALUE wmq_queue_manager;
93
+ extern VALUE wmq_message;
94
+ extern VALUE wmq_exception;
95
+
96
+ #define WMQ_EXEC_STRING_INQ_BUFFER_SIZE 32768 /* Todo: Should we make the mqai string return buffer dynamic? */
97
+
98
+ /* Internal C Structures for holding MQ data types */
99
+ typedef struct tagQUEUE_MANAGER QUEUE_MANAGER;
100
+ typedef QUEUE_MANAGER MQPOINTER PQUEUE_MANAGER;
101
+
102
+ struct tagQUEUE_MANAGER {
103
+ MQHCONN hcon; /* connection handle */
104
+ MQLONG comp_code; /* completion code */
105
+ MQLONG reason_code; /* reason code for MQCONN */
106
+ MQLONG exception_on_error; /* Non-Zero means throw exception*/
107
+ MQLONG already_connected; /* Already connected means don't disconnect */
108
+ MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
109
+ MQCNO connect_options; /* MQCONNX Connection Options */
110
+ #ifdef MQCNO_VERSION_2
111
+ MQCD client_conn; /* Client Connection */
112
+ #endif
113
+ #ifdef MQCNO_VERSION_4
114
+ MQSCO ssl_config_opts; /* Security options */
115
+ #endif
116
+ #ifdef MQCD_VERSION_6
117
+ MQPTR long_remote_user_id_ptr;
118
+ #endif
119
+ #ifdef MQCD_VERSION_7
120
+ MQPTR ssl_peer_name_ptr;
121
+ #endif
122
+ #ifdef MQHB_UNUSABLE_HBAG
123
+ MQHBAG admin_bag;
124
+ MQHBAG reply_bag;
125
+ #endif
126
+ PMQBYTE p_buffer; /* message buffer */
127
+ MQLONG buffer_size; /* Allocated size of buffer */
128
+
129
+ MQLONG is_client_conn; /* Is this a Client Connection? */
130
+ void* mq_lib_handle; /* Handle to MQ library */
131
+
132
+ void(*MQCONNX)(PMQCHAR,PMQCNO,PMQHCONN,PMQLONG,PMQLONG);
133
+ void(*MQCONN) (PMQCHAR,PMQHCONN,PMQLONG,PMQLONG);
134
+ void(*MQDISC) (PMQHCONN,PMQLONG,PMQLONG);
135
+ void(*MQBEGIN)(MQHCONN,PMQVOID,PMQLONG,PMQLONG);
136
+ void(*MQBACK) (MQHCONN,PMQLONG,PMQLONG);
137
+ void(*MQCMIT) (MQHCONN,PMQLONG,PMQLONG);
138
+ void(*MQPUT1) (MQHCONN,PMQVOID,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
139
+
140
+ void(*MQOPEN) (MQHCONN,PMQVOID,MQLONG,PMQHOBJ,PMQLONG,PMQLONG);
141
+ void(*MQCLOSE)(MQHCONN,PMQHOBJ,MQLONG,PMQLONG,PMQLONG);
142
+ void(*MQGET) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG,PMQLONG);
143
+ void(*MQPUT) (MQHCONN,MQHOBJ,PMQVOID,PMQVOID,MQLONG,PMQVOID,PMQLONG,PMQLONG);
144
+
145
+ void(*MQINQ) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
146
+ void(*MQSET) (MQHCONN,MQHOBJ,MQLONG,PMQLONG,MQLONG,PMQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
147
+
148
+ void(*mqCreateBag)(MQLONG,PMQHBAG,PMQLONG,PMQLONG);
149
+ void(*mqDeleteBag)(PMQHBAG,PMQLONG,PMQLONG);
150
+ void(*mqClearBag)(MQHBAG,PMQLONG,PMQLONG);
151
+ void(*mqExecute)(MQHCONN,MQLONG,MQHBAG,MQHBAG,MQHBAG,MQHOBJ,MQHOBJ,PMQLONG,PMQLONG);
152
+ void(*mqCountItems)(MQHBAG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
153
+ void(*mqInquireBag)(MQHBAG,MQLONG,MQLONG,PMQHBAG,PMQLONG,PMQLONG);
154
+ void(*mqInquireItemInfo)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
155
+ void(*mqInquireInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG,PMQLONG);
156
+ void(*mqInquireString)(MQHBAG,MQLONG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG,PMQLONG,PMQLONG);
157
+ void(*mqAddInquiry)(MQHBAG,MQLONG,PMQLONG,PMQLONG);
158
+ void(*mqAddInteger)(MQHBAG,MQLONG,MQLONG,PMQLONG,PMQLONG);
159
+ void(*mqAddString)(MQHBAG,MQLONG,MQLONG,PMQCHAR,PMQLONG,PMQLONG);
160
+ };
161
+
162
+ void Queue_manager_mq_load(PQUEUE_MANAGER pqm);
163
+ void Queue_manager_mq_free(PQUEUE_MANAGER pqm);
164
+
165
+
166
+ /*
167
+ * Message
168
+ */
169
+ struct Message_build_header_arg {
170
+ PMQBYTE* pp_buffer; /* Autosize: Pointer to start of total buffer */
171
+ PMQLONG p_buffer_size; /* Autosize: Size of total buffer */
172
+ MQLONG data_length; /* Autosize: Length of the data being written */
173
+ PMQLONG p_data_offset; /* Current offset of data portion in total buffer */
174
+ MQLONG trace_level; /* Trace level. 0==None, 1==Info 2==Debug ..*/
175
+ ID next_header_id; /* Used for setting MQ Format to next header */
176
+ PMQBYTE data_format; /* Format of data. Used when next_header_id == 0 */
177
+ };
178
+
179
+ void Message_id_init();
180
+ VALUE Message_initialize(int argc, VALUE *argv, VALUE self);
181
+ VALUE Message_clear(VALUE self);
182
+ PMQBYTE Message_autogrow_data_buffer(struct Message_build_header_arg* parg, MQLONG additional_size);
183
+ void Message_build_rf_header (VALUE hash, struct Message_build_header_arg* parg);
184
+ MQLONG Message_deblock_rf_header (VALUE hash, PMQBYTE p_data, MQLONG data_len);
185
+ void Message_build_rf_header_2 (VALUE hash, struct Message_build_header_arg* parg);
186
+ MQLONG Message_deblock_rf_header_2 (VALUE hash, PMQBYTE p_data, MQLONG data_len);
187
+
188
+ void Message_build_set_format(ID header_type, PMQBYTE p_format);
189
+ void Message_build(PMQBYTE* pq_pp_buffer, PMQLONG pq_p_buffer_size, MQLONG trace_level,
190
+ VALUE parms, PPMQVOID pp_buffer, PMQLONG p_total_length, PMQMD pmqmd);
191
+ void Message_build_mqmd(VALUE self, PMQMD pmqmd);
192
+ void Message_deblock(VALUE message, PMQMD pmqmd, PMQBYTE p_buffer, MQLONG total_length, MQLONG trace_level);
193
+
194
+ int Message_build_header(VALUE hash, struct Message_build_header_arg* parg);
195
+
196
+ /* Utility methods */
197
+
198
+ /* --------------------------------------------------
199
+ * Set internal variable based on value passed in from
200
+ * a hash
201
+ * --------------------------------------------------*/
202
+ void setFromHashString(VALUE self, VALUE hash, char* pKey, char* pAttribute, char* pDefault);
203
+ void setFromHashValue(VALUE self, VALUE hash, char* pKey, char* pAttribute, VALUE valDefault);
204
+
205
+ void to_mqmd(VALUE hash, MQMD* pmqmd);
206
+ void from_mqmd(VALUE hash, MQMD* pmqmd);
207
+
208
+ void to_mqdlh(VALUE hash, MQDLH* pmqdlh);
209
+ void from_mqdlh(VALUE hash, MQDLH* pmqdlh);
210
+
211
+ void wmq_structs_id_init();
212
+ void Message_to_mqmd(VALUE hash, MQMD* pmqmd);
213
+ void Message_to_mqmd1(VALUE hash, MQMD1* pmqmd1);
214
+ void Message_to_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
215
+ void Message_to_mqrfh(VALUE hash, MQRFH* pmqrfh);
216
+ void Message_to_mqdlh(VALUE hash, MQDLH* pmqdlh);
217
+ void Message_to_mqcih(VALUE hash, MQCIH* pmqcih);
218
+ void Message_to_mqdh(VALUE hash, MQDH* pmqdh);
219
+ void Message_to_mqiih(VALUE hash, MQIIH* pmqiih);
220
+ void Message_to_mqrmh(VALUE hash, MQRMH* pmqrmh);
221
+ void Message_to_mqtm(VALUE hash, MQTM* pmqtm);
222
+ void Message_to_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
223
+ void Message_to_mqwih(VALUE hash, MQWIH* pmqwih);
224
+ void Message_to_mqxqh(VALUE hash, MQXQH* pmqxqh);
225
+ void Message_from_mqmd(VALUE hash, MQMD* pmqmd);
226
+ void Message_from_mqmd1(VALUE hash, MQMD1* pmqmd1);
227
+ void Message_from_mqrfh2(VALUE hash, MQRFH2* pmqrfh2);
228
+ void Message_from_mqrfh(VALUE hash, MQRFH* pmqrfh);
229
+ void Message_from_mqdlh(VALUE hash, MQDLH* pmqdlh);
230
+ void Message_from_mqcih(VALUE hash, MQCIH* pmqcih);
231
+ void Message_from_mqdh(VALUE hash, MQDH* pmqdh);
232
+ void Message_from_mqiih(VALUE hash, MQIIH* pmqiih);
233
+ void Message_from_mqrmh(VALUE hash, MQRMH* pmqrmh);
234
+ void Message_from_mqtm(VALUE hash, MQTM* pmqtm);
235
+ void Message_from_mqtmc2(VALUE hash, MQTMC2* pmqtmc2);
236
+ void Message_from_mqwih(VALUE hash, MQWIH* pmqwih);
237
+ void Message_from_mqxqh(VALUE hash, MQXQH* pmqxqh);
238
+
239
+ char* wmq_reason(MQLONG reason_code);
240
+ ID wmq_selector_id(MQLONG selector);
241
+ MQLONG wmq_command_lookup(ID command_id);
242
+ void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector);
243
+
244
+ /* --------------------------------------------------
245
+ * MACROS for moving data between Ruby and MQ
246
+ * --------------------------------------------------*/
247
+ #define WMQ_STR2MQLONG(STR,ELEMENT) \
248
+ ELEMENT = NUM2LONG(STR);
249
+
250
+ #define WMQ_STR2MQCHAR(STR,ELEMENT) \
251
+ ELEMENT = NUM2LONG(STR);
252
+
253
+ #define WMQ_STR2MQCHARS(STR,ELEMENT) \
254
+ str = StringValue(STR); \
255
+ length = RSTRING_LEN(STR); \
256
+ size = sizeof(ELEMENT); \
257
+ strncpy(ELEMENT, RSTRING_PTR(STR), length > size ? size : length);
258
+
259
+ #define WMQ_STR2MQBYTES(STR,ELEMENT) \
260
+ str = StringValue(STR); \
261
+ length = RSTRING_LEN(str); \
262
+ size = sizeof(ELEMENT); \
263
+ if (length >= size) \
264
+ { \
265
+ memcpy(ELEMENT, RSTRING_PTR(str), size); \
266
+ } \
267
+ else \
268
+ { \
269
+ memcpy(ELEMENT, RSTRING_PTR(str), length); \
270
+ memset(ELEMENT+length, 0, size-length); \
271
+ }
272
+
273
+ #define WMQ_HASH2MQLONG(HASH,KEY,ELEMENT) \
274
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
275
+ if (!NIL_P(val)) { WMQ_STR2MQLONG(val,ELEMENT) }
276
+
277
+ #define WMQ_HASH2MQCHARS(HASH,KEY,ELEMENT) \
278
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
279
+ if (!NIL_P(val)) \
280
+ { \
281
+ WMQ_STR2MQCHARS(val,ELEMENT) \
282
+ }
283
+
284
+ #define WMQ_HASH2MQCHAR(HASH,KEY,ELEMENT) \
285
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
286
+ if (!NIL_P(val)) { WMQ_STR2MQCHAR(val,ELEMENT); } \
287
+
288
+ #define WMQ_HASH2MQBYTES(HASH,KEY,ELEMENT) \
289
+ val = rb_hash_aref(HASH, ID2SYM(ID_##KEY)); \
290
+ if (!NIL_P(val)) \
291
+ { \
292
+ WMQ_STR2MQBYTES(val,ELEMENT) \
293
+ }
294
+
295
+ #define WMQ_HASH2BOOL(HASH,KEY,ELEMENT) \
296
+ val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
297
+ if (!NIL_P(val)) \
298
+ { \
299
+ if(TYPE(val) == T_TRUE) ELEMENT = 1; \
300
+ else if(TYPE(val) == T_FALSE) ELEMENT = 0; \
301
+ else \
302
+ rb_raise(rb_eTypeError, ":" #KEY \
303
+ " must be true or false"); \
304
+ }
305
+
306
+ #define IF_TRUE(KEY,DEFAULT) \
307
+ val = rb_hash_aref(hash, ID2SYM(ID_##KEY)); \
308
+ if (NIL_P(val)) \
309
+ { \
310
+ flag = DEFAULT; \
311
+ } \
312
+ else \
313
+ { \
314
+ if(TYPE(val) == T_TRUE) flag = 1; \
315
+ else if(TYPE(val) == T_FALSE) flag = 0; \
316
+ else \
317
+ rb_raise(rb_eTypeError, ":" #KEY \
318
+ " must be true or false"); \
319
+ } \
320
+ if (flag)
321
+
322
+ /* --------------------------------------------------
323
+ * Strip trailing nulls and spaces
324
+ * --------------------------------------------------*/
325
+ #define WMQ_MQCHARS2STR(ELEMENT, TARGET) \
326
+ size = sizeof(ELEMENT); \
327
+ length = 0; \
328
+ pChar = ELEMENT + size-1; \
329
+ for (i = size; i > 0; i--) \
330
+ { \
331
+ if (*pChar != ' ' && *pChar != 0) \
332
+ { \
333
+ length = i; \
334
+ break; \
335
+ } \
336
+ pChar--; \
337
+ } \
338
+ TARGET = rb_str_new(ELEMENT,length);
339
+
340
+ #define WMQ_MQCHARS2HASH(HASH,KEY,ELEMENT) \
341
+ WMQ_MQCHARS2STR(ELEMENT, str) \
342
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
343
+
344
+ #define WMQ_MQLONG2HASH(HASH,KEY,ELEMENT) \
345
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
346
+
347
+ #define WMQ_MQCHAR2HASH(HASH,KEY,ELEMENT) \
348
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), LONG2NUM(ELEMENT));
349
+
350
+ /* --------------------------------------------------
351
+ * Trailing Spaces are important with binary fields
352
+ * --------------------------------------------------*/
353
+ #define WMQ_MQBYTES2STR(ELEMENT,TARGET) \
354
+ size = sizeof(ELEMENT); \
355
+ length = 0; \
356
+ pChar = ELEMENT + size-1; \
357
+ for (i = size; i > 0; i--) \
358
+ { \
359
+ if (*pChar != 0) \
360
+ { \
361
+ length = i; \
362
+ break; \
363
+ } \
364
+ pChar--; \
365
+ } \
366
+ TARGET = rb_str_new(ELEMENT,length);
367
+
368
+ #define WMQ_MQBYTES2HASH(HASH,KEY,ELEMENT) \
369
+ WMQ_MQBYTES2STR(ELEMENT, str) \
370
+ rb_hash_aset(HASH, ID2SYM(ID_##KEY), str);
371
+