ruby-informix 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (10) hide show
  1. data/Changelog +47 -0
  2. data/README +8 -5
  3. data/extconf.rb +1 -1
  4. data/ifx_assert.h +45 -0
  5. data/ifx_except.c +523 -0
  6. data/ifx_except.ec +467 -0
  7. data/ifx_except.h +82 -0
  8. data/informix.c +555 -541
  9. data/informix.ec +173 -159
  10. metadata +9 -3
data/Changelog CHANGED
@@ -1,3 +1,50 @@
1
+ 0.6.0 08/28/2007
2
+ ------------------
3
+ New features:
4
+ * Test suite
5
+ * Error, Warning, and AssertionFailure classes replace RuntimeError when
6
+ raising exceptions.
7
+
8
+ Error class methods:
9
+ - message
10
+ - sql_code
11
+ - add_info
12
+ - []
13
+ - each
14
+ - to_s
15
+ - size, length
16
+
17
+ message and sql_code reference the first error message. Following
18
+ errors can be accessed through Error#[] as ExcInfo objects.
19
+
20
+ ExcInfo is a Struct with the following members:
21
+ - sql_code
22
+ - sql_state
23
+ - class_origin_val
24
+ - subclass_origin_val
25
+ - message
26
+ - server_name
27
+ - connection_name
28
+
29
+ See test/testcase.rb for a simple example of exception handling.
30
+
31
+ * Informix.version returns the version of this extension
32
+ * Database#do aliased as Database#execute
33
+ * More documentation
34
+
35
+ Remarks:
36
+ * Database#do is deprecated and will be removed in next versions. Use
37
+ Database#execute or Database#immediate instead.
38
+
39
+ * In case of Informix errors, RuntimeError objects are no longer raised.
40
+ Error, Warning and AssertionFailure objects are raised instead.
41
+
42
+
43
+ Acknowledgments:
44
+ I want to thank Edwin Fine <emofine at finecomputerconsultants dot com>
45
+ who contributed all the functionality of this release.
46
+
47
+
1
48
  0.5.1 08/10/2007
2
49
  ------------------
3
50
  Bugs fixed:
data/README CHANGED
@@ -18,12 +18,15 @@ Ruby/Informix has been tested succesfully on the following platforms:
18
18
 
19
19
  Operating System Architecture Informix CSDK
20
20
  -------------------------------------------------------------
21
+ Solaris 10 SPARC 11.10.UC1 3.00UC2
22
+ Solaris 10 SPARC 9.40FC6 3.00UC2
21
23
  Solaris 9 SPARC 9.40FC6 2.90UC3
22
- Linux Fedora Core 4 i386 10.00.UC3R1 2.90UC4
23
- Linux Fedora Core 5 i386 10.00.UC3R1 2.90UC4
24
- SuSE Linux 9.3 i386 9.30TC1 2.90UC4
25
- Windows XP Pro SP i386 9.40TC3 2.90TC1
26
- Windows XP i386 9.30TC1 2.90TC4
24
+ Fedora Core 5 x86 10.00.UC3R1 2.90UC4
25
+ Fedora Core 4 x86 10.00.UC3R1 2.90UC4
26
+ SuSE Linux 9.3 x86 9.30TC1 2.90UC4
27
+ Gentoo Linux x86-64 7.32.HC1 2.90UC4
28
+ Windows XP Pro SP x86 9.40TC3 2.90TC1
29
+ Windows XP x86 9.30TC1 2.90TC4
27
30
  HP-UX 11.11 PA-RISC 2.0 10.00.FC3R1TL 2.81
28
31
  64-bit
29
32
 
data/extconf.rb CHANGED
@@ -32,5 +32,5 @@ else
32
32
  end
33
33
 
34
34
 
35
- `#{env} #{esql} -e informix.ec`
35
+ `#{env} #{esql} -e informix.ec ifx_except.ec`
36
36
  create_makefile("informix")
@@ -0,0 +1,45 @@
1
+ /* $Id: ifx_assert.h,v 1.1 2007/01/31 02:16:32 santana Exp $ */
2
+ /*
3
+ * Copyright (c) 2006, 2007 Edwin M. Fine <efine@finecomputerconsultants.com>
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ *
10
+ * 1. Redistributions of source code must retain the above copyright
11
+ * notice, this list of conditions and the following disclaimer.
12
+ * 2. Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ * 3. The name of the author may not be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ * POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #if !defined(IFX_ASSERT_H_INCLUDED)
32
+ #define IFX_ASSERT_H_INCLUDED
33
+
34
+ #define RBIFX_ASSERT(x) \
35
+ do { if (!(x)) ifx_assertion_exception("Assertion", #x, __FILE__, __LINE__) } while(0)
36
+ #define RBIFX_PRECOND(x) \
37
+ do { if (!(x)) ifx_assertion_exception("Precondition", #x, __FILE__, __LINE__) } while(0)
38
+
39
+ /* Correctness (DBC) support */
40
+ void ifx_assertion_exception(const char *failure_type,
41
+ const char *what_failed,
42
+ const char *file,
43
+ int line);
44
+
45
+ #endif
@@ -0,0 +1,523 @@
1
+ #include <sqlhdr.h>
2
+ #include <sqliapi.h>
3
+ #line 1 "ifx_except.ec"
4
+ /* $Id: ifx_except.ec,v 1.1 2007/01/31 02:16:32 santana Exp $ */
5
+ /*
6
+ * Copyright (c) 2006, 2007 Edwin M. Fine <efine@finecomputerconsultants.com>
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions
11
+ * are met:
12
+ *
13
+ * 1. Redistributions of source code must retain the above copyright
14
+ * notice, this list of conditions and the following disclaimer.
15
+ * 2. Redistributions in binary form must reproduce the above copyright
16
+ * notice, this list of conditions and the following disclaimer in the
17
+ * documentation and/or other materials provided with the distribution.
18
+ * 3. The name of the author may not be used to endorse or promote products
19
+ * derived from this software without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ * POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+
34
+ #include "ifx_except.h"
35
+ #include "ifx_assert.h"
36
+
37
+ #include <ruby.h>
38
+ #include <stdlib.h>
39
+ #include <stdio.h>
40
+ #include <sqlstype.h>
41
+ #include <sqltypes.h>
42
+
43
+ /* Convenience macros */
44
+ #define TRIM_BLANKS(s) ((s)[byleng(s, stleng(s))] = '\0')
45
+ #define NUM_ELEMS(arr) (sizeof(arr) / sizeof(*arr))
46
+
47
+ /* Future use: definition of interpretation of sql_state */
48
+ #define IS_SQL_SUCCESS(sql_state) ((sql_state)[0] == '0' && (sql_state)[1] == '0')
49
+ #define IS_SQL_WARNING(sql_state) ((sql_state)[0] == '0' && (sql_state)[1] == '1')
50
+ #define IS_SQL_NO_DATA_FOUND(sql_state) ((sql_state)[0] == '0' && (sql_state)[1] == '2')
51
+ #define IS_SQL_ERROR(sql_state) ((sql_state)[0] > '0' || (sql_state)[1] > '2')
52
+
53
+ /* Constants */
54
+ #define NUM_SQL_EXCEPTION_ARGS 7 /* Number of things we get from GET EXCEPTION */
55
+
56
+ static const char * const vcs_id = "$Id: ifx_except.ec,v 1.1 2007/01/31 02:16:32 santana Exp $";
57
+
58
+ /*
59
+ * Ruby object/class/module handles
60
+ */
61
+ static ifx_except_symbols_t sym;
62
+
63
+ /**
64
+ * Implementation
65
+ */
66
+
67
+ /* class Informix::Error ------------------------------------------------ */
68
+
69
+ /**
70
+ * call-seq:
71
+ * Informix::Error.new([string|array]) => obj
72
+ *
73
+ * Optional string is the exception message.
74
+ * Optional array must contain only instances of Informix::ExcInfo structs.
75
+ *
76
+ * Examples:
77
+ * exc = Informix::Error.new
78
+ * arr = [ExcInfo.new(x,y,z...), ExcInfo.new(a,b,c...)]
79
+ * exc = Informix::Error.new(arr)
80
+ */
81
+ static VALUE ifx_exc_init(int argc, VALUE *argv, VALUE self)
82
+ {
83
+ VALUE arr;
84
+ VALUE arg;
85
+
86
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
87
+ arr = rb_ary_new();
88
+ }
89
+ else if (TYPE(arg) == T_STRING) {
90
+ arr = rb_ary_new();
91
+ rb_call_super(argc, argv);
92
+ }
93
+ else if (TYPE(arg) == T_ARRAY) {
94
+ arr = arg;
95
+ if (RARRAY(arg)->len > 0) {
96
+ long i;
97
+ for (i = 0; i < RARRAY(arg)->len; ++i)
98
+ if (!rb_obj_is_instance_of(rb_ary_entry(arg, i), sym.sExcInfo))
99
+ rb_raise(rb_eTypeError, "Array may contain only Informix::ExcInfo structs");
100
+ }
101
+ }
102
+ else {
103
+ rb_raise(rb_eTypeError,
104
+ "Expected string, or array of Informix::ExcInfo, as argument");
105
+ }
106
+
107
+ rb_iv_set(self, "@info", arr);
108
+
109
+ return self;
110
+ }
111
+
112
+ /* Implementation note:
113
+ * argv must contain the following values in the order given:
114
+ * sql_code FIXNUM
115
+ * sql_state STRING
116
+ * class_origin STRING
117
+ * subclass_origin STRING
118
+ * message STRING
119
+ * server_name STRING
120
+ * connection_name STRING
121
+ */
122
+
123
+ /**
124
+ * call-seq:
125
+ * exc.add_info(sql_code, sql_state, class_origin, subclass_origin, message, server_name, connection_name) => self
126
+ *
127
+ * Appends the given information to the exception.
128
+ */
129
+ static VALUE ifx_exc_add_info(int argc, VALUE *argv, VALUE self)
130
+ {
131
+ VALUE info_arr = rb_iv_get(self, "@info");
132
+ VALUE sInfo;
133
+
134
+ #if defined(DEBUG)
135
+ printf("%s:%d argc = %d\n", "ifx_exc_add_info", __LINE__, argc);
136
+ #endif
137
+
138
+ if (argc != NUM_SQL_EXCEPTION_ARGS)
139
+ rb_raise(rb_eArgError, "Invalid number of arguments (got %d, need %d)", argc, NUM_SQL_EXCEPTION_ARGS);
140
+ if (info_arr == Qnil) { /* Add the array if missing */
141
+ info_arr = rb_ary_new();
142
+ rb_iv_set(self, "@info", info_arr);
143
+ }
144
+
145
+ sInfo =
146
+ rb_struct_new(sym.sExcInfo,
147
+ argv[0], argv[1], argv[2], argv[3],
148
+ argv[4], argv[5], argv[6], NULL);
149
+
150
+ /* Add the new struct instance to end of our array */
151
+ rb_ary_push(info_arr, sInfo);
152
+
153
+ return self;
154
+ }
155
+
156
+ /**
157
+ * call-seq:
158
+ * exc.size => num
159
+ *
160
+ * Returns the number of Informix exception messages in the exception.
161
+ */
162
+ static VALUE ifx_exc_size(VALUE self)
163
+ {
164
+ VALUE info_arr = rb_iv_get(self, "@info");
165
+ return info_arr != Qnil ? LONG2NUM(RARRAY(info_arr)->len) : Qnil;
166
+ }
167
+
168
+ /**
169
+ * call-seq:
170
+ * exc.each {|exc_info| block } => exc_info
171
+ *
172
+ * Calls block once for each Informix::ExcInfo object in the exception.
173
+ */
174
+ static VALUE ifx_exc_each(VALUE self)
175
+ {
176
+ VALUE info_arr = rb_iv_get(self, "@info");
177
+ return info_arr != Qnil ? rb_iterate(rb_each, info_arr, rb_yield, 0) : Qnil;
178
+ }
179
+
180
+ /**
181
+ * call-seq:
182
+ * exc.at(index) => info
183
+ *
184
+ * Returns the ExcInfo object at index.
185
+ */
186
+ static VALUE ifx_exc_at(VALUE self, VALUE index)
187
+ {
188
+ VALUE info_arr = rb_iv_get(self, "@info");
189
+ long n = NUM2LONG(rb_Integer(index));
190
+
191
+ #if defined(DEBUG)
192
+ printf("Getting value at %ld\n", n);
193
+ #endif
194
+
195
+ return info_arr != Qnil ? rb_ary_entry(info_arr, n) : Qnil;
196
+ }
197
+
198
+ /**
199
+ * call-seq:
200
+ * exc.to_s => string
201
+ *
202
+ * Returns a string representation of self.
203
+ */
204
+ static VALUE ifx_exc_to_s(VALUE self)
205
+ {
206
+ const VALUE nl = rb_str_new2("\n");
207
+ VALUE s;
208
+ VALUE info_arr = rb_iv_get(self, "@info");
209
+ long info_arr_len;
210
+ VALUE sInfo;
211
+ long i;
212
+ size_t j;
213
+
214
+ info_arr_len = info_arr == Qnil ? 0 : RARRAY(info_arr)->len;
215
+
216
+ if (info_arr_len > 0) {
217
+ VALUE fmt_str = rb_str_new2("%-15s: %s\n");
218
+
219
+ ID fields[] = { /* Fields will be displayed in this order */
220
+ sym.id_message,
221
+ sym.id_sql_code,
222
+ sym.id_sql_state,
223
+ sym.id_class_origin,
224
+ sym.id_subclass_origin,
225
+ sym.id_server_name,
226
+ sym.id_connection_name
227
+ };
228
+
229
+ s = rb_str_new2("\n");
230
+
231
+ for (i = 0; i < info_arr_len; ++i) {
232
+ sInfo = RARRAY(info_arr)->ptr[i];
233
+
234
+ for (j = 0; j < NUM_ELEMS(fields); ++j) {
235
+ ID field = fields[j];
236
+ VALUE struct_ref = rb_struct_getmember(sInfo, field);
237
+ VALUE item_value = rb_String(struct_ref);
238
+ VALUE args[] = { fmt_str, rb_String(ID2SYM(field)), item_value };
239
+
240
+ if (RSTRING(item_value)->len != 0) { /* Skip empty fields */
241
+ rb_str_concat(s, rb_f_sprintf(NUM_ELEMS(args), args));
242
+ }
243
+ }
244
+
245
+ rb_str_concat(s, nl);
246
+ }
247
+ }
248
+ else { /* Call super's to_s */
249
+ s = rb_call_super(0, 0);
250
+ }
251
+
252
+ return s;
253
+ }
254
+
255
+ /**
256
+ * Overrides Exception#message. Returns first message in ExcInfo array,
257
+ * or if the array is empty, delegates back to the parent class.
258
+ */
259
+ static VALUE ifx_exc_message(VALUE self)
260
+ {
261
+ VALUE info_arr = rb_iv_get(self, "@info");
262
+
263
+ return (info_arr != Qnil && RARRAY(info_arr)->len > 0)
264
+ ? rb_struct_getmember(RARRAY(info_arr)->ptr[0], sym.id_message)
265
+ : rb_call_super(0, 0);
266
+ }
267
+
268
+ /**
269
+ * call-seq:
270
+ * exc.sqlcode => fixnum
271
+ *
272
+ * Returns the SQLCODE for the first stored ExcInfo struct, or 0
273
+ * if none are stored.
274
+ */
275
+ static VALUE ifx_exc_sql_code(VALUE self)
276
+ {
277
+ VALUE info_arr = rb_iv_get(self, "@info");
278
+
279
+ return (info_arr != Qnil && RARRAY(info_arr)->len > 0)
280
+ ? rb_struct_getmember(RARRAY(info_arr)->ptr[0], sym.id_sql_code)
281
+ : INT2FIX(0);
282
+ }
283
+
284
+ /*
285
+ * C helper functions (see ifx_except.h for documentation)
286
+ */
287
+ void raise_ifx_extended(void)
288
+ {
289
+ rb_exc_raise(rbifx_ext_exception(sym.eDatabaseError));
290
+ }
291
+
292
+ VALUE rbifx_ext_exception(VALUE exception_class)
293
+ {
294
+ VALUE new_instance;
295
+
296
+ /*
297
+ * EXEC SQL BEGIN DECLARE SECTION;
298
+ */
299
+ #line 293 "ifx_except.ec"
300
+ #line 294 "ifx_except.ec"
301
+ int4 sql_code;
302
+ char sql_state[6];
303
+ char class_origin_val[256];
304
+ char subclass_origin_val[256];
305
+ char message[8192];
306
+ char server_name[256];
307
+ char connection_name[256];
308
+ mint sql_exception_number;
309
+ mint exc_count = 0;
310
+ mint message_len;
311
+ /*
312
+ * EXEC SQL END DECLARE SECTION;
313
+ */
314
+ #line 307 "ifx_except.ec"
315
+
316
+
317
+ new_instance = rb_class_new_instance(0, 0, exception_class);
318
+
319
+ /* Check that instance of exception_class is derived from
320
+ * Informix::Error
321
+ */
322
+ if (!rb_obj_is_kind_of(new_instance, sym.eError) &&
323
+ !rb_obj_is_kind_of(new_instance, sym.eWarning)) {
324
+ rb_raise(rb_eRuntimeError,
325
+ "Can't instantiate exception from %s, only from %s or %s or their children",
326
+ rb_class2name(exception_class),
327
+ rb_class2name(sym.eWarning),
328
+ rb_class2name(sym.eError));
329
+ }
330
+
331
+ /*
332
+ * EXEC SQL GET DIAGNOSTICS :exc_count = NUMBER;
333
+ */
334
+ #line 323 "ifx_except.ec"
335
+ {
336
+ #line 323 "ifx_except.ec"
337
+ static ifx_hostvar_t _SQhtab[] =
338
+ {
339
+ { 0, 1, 102, sizeof(exc_count), 0, 0, 0, 0 },
340
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
341
+ #line 323 "ifx_except.ec"
342
+ };
343
+ _SQhtab[0].hostaddr = (char *)&exc_count;
344
+ #line 323 "ifx_except.ec"
345
+ sqli_diag_get(ESQLINTVERSION, _SQhtab, -1);
346
+ #line 323 "ifx_except.ec"
347
+ }
348
+
349
+ if (exc_count == 0) { /* Something went wrong */
350
+ char message[128];
351
+ snprintf(message,
352
+ sizeof(message),
353
+ "SQL ERROR: SQLCODE %d (sorry, no GET DIAGNOSTICS information available)",
354
+ SQLCODE);
355
+
356
+ {
357
+ VALUE argv[] = { rb_str_new2(message) };
358
+ return rb_class_new_instance(NUM_ELEMS(argv), argv, sym.eOperationalError);
359
+ }
360
+ }
361
+
362
+ mint i;
363
+
364
+ for (i = 0; i < exc_count; ++i) {
365
+ sql_exception_number = i + 1;
366
+
367
+ /*
368
+ * EXEC SQL GET DIAGNOSTICS EXCEPTION :sql_exception_number
369
+ * :sql_code = INFORMIX_SQLCODE,
370
+ * :sql_state = RETURNED_SQLSTATE,
371
+ * :class_origin_val = CLASS_ORIGIN,
372
+ * :subclass_origin_val = SUBCLASS_ORIGIN,
373
+ * :message = MESSAGE_TEXT,
374
+ * :message_len = MESSAGE_LENGTH,
375
+ * :server_name = SERVER_NAME,
376
+ * :connection_name = CONNECTION_NAME
377
+ * ;
378
+ */
379
+ #line 343 "ifx_except.ec"
380
+ {
381
+ #line 352 "ifx_except.ec"
382
+ static ifx_hostvar_t _SQhtab[] =
383
+ {
384
+ { 0, 11, 103, sizeof(sql_code), 0, 0, 0, 0 },
385
+ { 0, 3, 100, 6, 0, 0, 0, 0 },
386
+ { 0, 4, 100, 256, 0, 0, 0, 0 },
387
+ { 0, 5, 100, 256, 0, 0, 0, 0 },
388
+ { 0, 6, 100, 8192, 0, 0, 0, 0 },
389
+ { 0, 7, 102, sizeof(message_len), 0, 0, 0, 0 },
390
+ { 0, 9, 100, 256, 0, 0, 0, 0 },
391
+ { 0, 10, 100, 256, 0, 0, 0, 0 },
392
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
393
+ #line 352 "ifx_except.ec"
394
+ };
395
+ _SQhtab[0].hostaddr = (char *)&sql_code;
396
+ _SQhtab[1].hostaddr = (sql_state);
397
+ _SQhtab[2].hostaddr = (class_origin_val);
398
+ _SQhtab[3].hostaddr = (subclass_origin_val);
399
+ _SQhtab[4].hostaddr = (message);
400
+ _SQhtab[5].hostaddr = (char *)&message_len;
401
+ _SQhtab[6].hostaddr = (server_name);
402
+ _SQhtab[7].hostaddr = (connection_name);
403
+ #line 352 "ifx_except.ec"
404
+ sqli_diag_get(ESQLINTVERSION, _SQhtab, sql_exception_number);
405
+ #line 352 "ifx_except.ec"
406
+ }
407
+
408
+ TRIM_BLANKS(class_origin_val);
409
+ TRIM_BLANKS(subclass_origin_val);
410
+ TRIM_BLANKS(server_name);
411
+ TRIM_BLANKS(connection_name);
412
+ message[message_len - 1] = '\0';
413
+ TRIM_BLANKS(message);
414
+
415
+ {
416
+ VALUE sprintf_args[] = { rb_str_new2(message), rb_str_new2(sqlca.sqlerrm) };
417
+ VALUE argv[] = {
418
+ INT2FIX(sql_code),
419
+ rb_str_new2(sql_state),
420
+ rb_str_new2(class_origin_val),
421
+ rb_str_new2(subclass_origin_val),
422
+ rb_f_sprintf(NUM_ELEMS(sprintf_args), sprintf_args),
423
+ rb_str_new2(server_name),
424
+ rb_str_new2(connection_name)
425
+ };
426
+
427
+ ifx_exc_add_info(NUM_ELEMS(argv), argv, new_instance);
428
+ }
429
+ }
430
+
431
+ return new_instance;
432
+ }
433
+
434
+ /**
435
+ * Raises Informix::AssertionFailure exception
436
+ */
437
+ void ifx_assertion_exception(const char *failure_type,
438
+ const char *what_failed,
439
+ const char *file,
440
+ int line)
441
+ {
442
+ VALUE sprintf_args[] = {
443
+ rb_str_new2("%s failed on line %d of file %s: %s"),
444
+ rb_str_new2(failure_type),
445
+ INT2FIX(line),
446
+ rb_str_new2(file),
447
+ rb_str_new2(what_failed)
448
+ };
449
+
450
+ VALUE args[] = { rb_f_sprintf(NUM_ELEMS(sprintf_args), sprintf_args) };
451
+
452
+ rb_exc_raise(rb_class_new_instance(NUM_ELEMS(args), args, sym.lib_eAssertion));
453
+ }
454
+
455
+ /* Init module with shared value(s) from main informix classes */
456
+ void rbifx_except_init(VALUE mInformix, ifx_except_symbols_t *syms)
457
+ {
458
+ VALUE sym_ExcInfo;
459
+
460
+ sym.mInformix = mInformix; // Informix module object handle
461
+
462
+ /* class Error --------------------------------------------------------- */
463
+ sym.eError = rb_define_class_under(mInformix, "Error", rb_eStandardError);
464
+ sym.eWarning = rb_define_class_under(mInformix, "Warning", rb_eStandardError);
465
+
466
+ sym.eInterfaceError = rb_define_class_under(mInformix, "InterfaceError", sym.eError);
467
+ sym.eDatabaseError = rb_define_class_under(mInformix, "DatabaseError", sym.eError);
468
+ sym.eDataError = rb_define_class_under(mInformix, "DataError", sym.eError);
469
+ sym.eOperationalError = rb_define_class_under(mInformix, "OperationalError", sym.eError);
470
+ sym.eIntegrityError = rb_define_class_under(mInformix, "IntegrityError", sym.eError);
471
+ sym.eInternalError = rb_define_class_under(mInformix, "InternalError", sym.eError);
472
+ sym.eProgrammingError = rb_define_class_under(mInformix, "ProgrammingError", sym.eError);
473
+ sym.eNotSupportedError = rb_define_class_under(mInformix, "NotSupportedError", sym.eError);
474
+
475
+ /* Make base class enumerable */
476
+ rb_include_module(sym.eError, rb_mEnumerable);
477
+
478
+ /* Precondition exception class */
479
+ sym.lib_eAssertion = rb_define_class_under(mInformix, "AssertionFailure", rb_eStandardError);
480
+
481
+ rb_define_method(sym.eError, "initialize", ifx_exc_init, -1);
482
+ rb_define_method(sym.eError, "message", ifx_exc_message, 0);
483
+ rb_define_method(sym.eError, "sql_code", ifx_exc_sql_code, 0);
484
+ rb_define_method(sym.eError, "add_info", ifx_exc_add_info, -1);
485
+ rb_define_method(sym.eError, "[]", ifx_exc_at, 1);
486
+ rb_define_method(sym.eError, "each", ifx_exc_each, 0);
487
+ rb_define_method(sym.eError, "to_s", ifx_exc_to_s, 0);
488
+ rb_define_method(sym.eError, "size", ifx_exc_size, 0);
489
+ rb_define_alias(sym.eError, "length", "size");
490
+
491
+ sym_ExcInfo = rb_intern("ExcInfo");
492
+
493
+ sym.id_sql_code = rb_intern("sql_code");
494
+ sym.id_sql_state = rb_intern("sql_state");
495
+ sym.id_class_origin = rb_intern("class_origin");
496
+ sym.id_subclass_origin = rb_intern("subclass_origin");
497
+ sym.id_message = rb_intern("message");
498
+ sym.id_server_name = rb_intern("server_name");
499
+ sym.id_connection_name = rb_intern("connection_name");
500
+
501
+ /* Define ExcInfo as a struct in the Informix module */
502
+ rb_define_const(mInformix,
503
+ "ExcInfo",
504
+ rb_struct_define(NULL,
505
+ rb_id2name(sym.id_sql_code),
506
+ rb_id2name(sym.id_sql_state),
507
+ rb_id2name(sym.id_class_origin),
508
+ rb_id2name(sym.id_subclass_origin),
509
+ rb_id2name(sym.id_message),
510
+ rb_id2name(sym.id_server_name),
511
+ rb_id2name(sym.id_connection_name),
512
+ NULL));
513
+
514
+ sym.sExcInfo = rb_const_get(mInformix, sym_ExcInfo);
515
+
516
+ if (syms)
517
+ {
518
+ *syms = sym;
519
+ }
520
+ }
521
+
522
+
523
+ #line 467 "ifx_except.ec"