ruby-informix 0.5.1 → 0.6.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 (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"