ruby-informix 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,166 @@
1
+ testdir = File.expand_path(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift File.join(testdir, "..")
3
+
4
+ require 'test/unit'
5
+ require 'informix'
6
+ require 'date'
7
+ require 'stringio'
8
+
9
+ module Informix
10
+ class TestCase < Test::Unit::TestCase
11
+ NOW = Time.now.utc
12
+ TODAY = Date.today
13
+ MIN_INT64 = -9_223_372_036_854_775_807
14
+ MAX_INT64= 9_223_372_036_854_775_807
15
+ MAX_INT32 = 2_147_483_647
16
+ MIN_INT32 = -2_147_483_647
17
+ MIN_INT16 = -32767
18
+ MAX_INT16 = 32767
19
+ E = 2.71828183
20
+ PI = 3.1415926535897932385
21
+ DATE = '04/07/2006'
22
+ DATE_TIME = '2006-04-07 01:40:55.000'
23
+ BIGDECIMAL1 = BigDecimal.new('12456.78')
24
+ BIGDECIMAL2 = BigDecimal.new('90123.45')
25
+ INTERVALYM1 = -Informix::Interval.year_to_month(999999999, 11)
26
+ INTERVALDS1 = -Informix::Interval.day_to_second(999999999, 23, 59,
27
+ Rational(5999999, 100000))
28
+ INTERVALYM2 = Informix::Interval.year_to_month(999999999, 11)
29
+ INTERVALDS2 = Informix::Interval.day_to_second(999999999, 23, 59,
30
+ Rational(5999999, 100000))
31
+ TEXT = StringIO.new(<<-end_text)
32
+ This is a TEXT field. You can
33
+ write them using IO/IO-like objects
34
+ and read them into Strings.
35
+ end_text
36
+
37
+ TEST_TABLE_NAME = "test"
38
+
39
+ attr_reader :db
40
+
41
+ def quote_strings(arr)
42
+ arr.map { |v| if v.nil? then "NULL" else "\"#{v.to_s}\"" end }
43
+ end
44
+
45
+ def supported_data_type?(db, data_type)
46
+ begin
47
+ is_supported = true
48
+ db.execute("create temp table temp_#{TEST_TABLE_NAME}(test_column #{data_type})")
49
+ rescue Informix::Error => exc
50
+ raise unless exc[0].sql_code == -201 # Syntax error
51
+ is_supported = false
52
+ ensure
53
+ drop_table("temp_#{TEST_TABLE_NAME}") rescue nil
54
+ end
55
+ is_supported
56
+ end
57
+
58
+ def create_test_table
59
+ columns = [
60
+ ['id', 'serial', 'not null primary key'],
61
+ ['char', 'char', '(30)'],
62
+ ['varchar', 'varchar', '(30)'],
63
+ ['smallint', 'smallint', '' ],
64
+ ['integer', 'integer', '' ],
65
+ ['smallfloat', 'smallfloat', '' ],
66
+ ['float', 'float', '' ],
67
+ ['date', 'date', '' ],
68
+ ['datetime', 'datetime', 'year to fraction(5)' ],
69
+ ['intervalym', 'interval', 'year(9) to month' ],
70
+ ['intervalds', 'interval', 'day(9) to fraction(5)' ],
71
+ ['decimal', 'decimal', '(9, 2)' ],
72
+ ['text', 'text', '' ]
73
+ ]
74
+
75
+ if supported_data_type?(db, "boolean")
76
+ columns << ['boolean', 'boolean', '' ]
77
+ end
78
+
79
+ if supported_data_type?(db, "int8")
80
+ columns << ['int8', 'int8', '' ]
81
+ end
82
+
83
+ col_list = columns.map { |arr| arr.join(' ') }
84
+ sql = "create temp table #{TEST_TABLE_NAME} (#{col_list.join(",")})"
85
+ db.execute sql
86
+ end
87
+
88
+ def drop_test_table
89
+ drop_table TEST_TABLE_NAME
90
+ end
91
+
92
+ def rewind_data
93
+ @rows.each { |arr| arr.each { |elem| elem.rewind if elem.respond_to?(:rewind) }}
94
+ TEXT.rewind
95
+ end
96
+
97
+ def populate_test_table
98
+ sql = "insert into test values(#{quote_strings(@rows[0]).join(',')})"
99
+
100
+ assert_nothing_raised(Informix::Error, "Inserting record with db.do, sql = [#{sql}]") do
101
+ db.execute sql
102
+ end
103
+
104
+ sql = "insert into test values(#{"?," * (@rows[1].size - 1)}#{"?"})"
105
+
106
+ assert_nothing_raised(Informix::Error, "Inserting record with stmt.execute, sql = [#{sql}]") do
107
+ stmt = db.prepare sql
108
+ stmt.execute(*@rows[1])
109
+ end
110
+ ensure
111
+ rewind_data
112
+ end
113
+
114
+ def drop_table(name)
115
+ self.db.execute "drop table #{name}"
116
+ rescue Informix::Error => exc
117
+ # If table did not exist, ignore the error
118
+ raise unless exc[0].sql_code == -206
119
+ end
120
+
121
+ # call-seq: obj.setup(connect_string, user_name=nil, password=nil)
122
+ #
123
+ # Make a single connection for all the test cases, because
124
+ # of the excessive overhead involved to do it once every setup call.
125
+ #
126
+ def setup(*args)
127
+ unless args.empty?
128
+ @db ||= Informix.connect(args[0], args[1], args[2])
129
+ @supported = {}
130
+ @supported["boolean"] = true if supported_data_type?(@db, "boolean")
131
+ @supported["int8"] = true if supported_data_type?(@db, "int8")
132
+
133
+ @rows = [
134
+ [
135
+ 1, 'char1'.ljust(30, ' '), 'varchar1', MIN_INT16,
136
+ MIN_INT32, E, PI, DATE, DATE_TIME, INTERVALYM1, INTERVALDS1,
137
+ BIGDECIMAL1, nil
138
+ ],
139
+ [
140
+ 2, 'char2'.ljust(30, ' '), 'varchar2', MAX_INT16,
141
+ MAX_INT32, 8.9, 8.9, TODAY.strftime("%m/%d/%Y"),
142
+ NOW.strftime("%Y-%m-%d %H:%M:%S.000"), INTERVALYM2, INTERVALDS2,
143
+ BIGDECIMAL2, TEXT
144
+ ]
145
+ ]
146
+
147
+ if @supported["boolean"]
148
+ @rows[0] << 't'
149
+ @rows[1] << 'f'
150
+ end
151
+
152
+ if @supported["int8"]
153
+ @rows[0] << MIN_INT64
154
+ @rows[1] << MAX_INT64
155
+ end
156
+ @rows.freeze
157
+ end
158
+
159
+ end
160
+
161
+ # Override the base class version of default_test() so that
162
+ # a test case with no tests doesn't trigger an error.
163
+ def default_test; end
164
+ end
165
+ end
166
+
metadata CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: ruby-informix
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.6.2
7
- date: 2007-10-20 00:00:00 -05:00
8
- summary: Informix driver for Ruby
6
+ version: 0.7.0
7
+ date: 2008-03-31 00:00:00 -06:00
8
+ summary: Ruby library for IBM Informix
9
9
  require_paths:
10
10
  - lib
11
11
  email: gerardo.santana@gmail.com
12
12
  homepage: http://santanatechnotes.blogspot.com
13
13
  rubyforge_project: ruby-informix
14
- description: Ruby extension for connecting to IBM Informix Dynamic Server, written in ESQL/C.
14
+ description: Ruby library for connecting to IBM Informix 7 and above
15
15
  autorequire: informix
16
16
  default_executable:
17
17
  bindir: bin
@@ -29,27 +29,45 @@ post_install_message:
29
29
  authors:
30
30
  - Gerardo Santana Gomez Garrido
31
31
  files:
32
- - informix.ec
33
- - ifx_except.ec
34
- - ifx_assert.h
35
- - ifx_except.h
32
+ - ext/informixc.ec
33
+ - lib/informix.rb
34
+ - lib/informix/interval.rb
35
+ - lib/informix/scrollcursor.rb
36
+ - lib/informix/seqcursor.rb
37
+ - lib/informix/CVS
38
+ - lib/informix/exceptions.rb
39
+ - test/testcase.rb
40
+ - test/ifx_all.rb
41
+ - test/ifx_test_create_table.rb
42
+ - test/ifx_test_errinfo.rb
43
+ - test/ifx_test_exceptions.rb
44
+ - test/ifx_test_fetch_n_each.rb
45
+ - test/ifx_test_insert.rb
46
+ - test/ifx_test_select.rb
36
47
  - COPYRIGHT
37
48
  - Changelog
38
49
  - README
39
- - informix.c
40
- - ifx_except.c
50
+ - ext/informixc.c
41
51
  test_files: []
42
52
 
43
53
  rdoc_options:
44
54
  - --title
45
- - Ruby/Informix -- Informix driver for Ruby
55
+ - Ruby/Informix -- Ruby library for IBM Informix
56
+ - --exclude
57
+ - test
58
+ - --exclude
59
+ - extconf.rb
60
+ - --inline-source
61
+ - --line-numbers
62
+ - --main
63
+ - README
46
64
  extra_rdoc_files:
47
- - informix.c
48
- - ifx_except.c
65
+ - README
66
+ - ext/informixc.c
49
67
  executables: []
50
68
 
51
69
  extensions:
52
- - extconf.rb
70
+ - ext/extconf.rb
53
71
  requirements: []
54
72
 
55
73
  dependencies: []
@@ -1,45 +0,0 @@
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
@@ -1,522 +0,0 @@
1
- #include <sqlhdr.h>
2
- #include <sqliapi.h>
3
- #line 1 "ifx_except.ec"
4
- /* $Id: ifx_except.ec,v 1.2 2007/10/20 10:17:35 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.2 2007/10/20 10:17:35 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
- mint i;
312
- /*
313
- * EXEC SQL END DECLARE SECTION;
314
- */
315
- #line 308 "ifx_except.ec"
316
-
317
-
318
- new_instance = rb_class_new_instance(0, 0, exception_class);
319
-
320
- /* Check that instance of exception_class is derived from
321
- * Informix::Error
322
- */
323
- if (!rb_obj_is_kind_of(new_instance, sym.eError) &&
324
- !rb_obj_is_kind_of(new_instance, sym.eWarning)) {
325
- rb_raise(rb_eRuntimeError,
326
- "Can't instantiate exception from %s, only from %s or %s or their children",
327
- rb_class2name(exception_class),
328
- rb_class2name(sym.eWarning),
329
- rb_class2name(sym.eError));
330
- }
331
-
332
- /*
333
- * EXEC SQL GET DIAGNOSTICS :exc_count = NUMBER;
334
- */
335
- #line 324 "ifx_except.ec"
336
- {
337
- #line 324 "ifx_except.ec"
338
- static ifx_hostvar_t _SQhtab[] =
339
- {
340
- { 0, 1, 102, sizeof(exc_count), 0, 0, 0, 0 },
341
- { 0, 0, 0, 0, 0, 0, 0, 0 }
342
- #line 324 "ifx_except.ec"
343
- };
344
- _SQhtab[0].hostaddr = (char *)&exc_count;
345
- #line 324 "ifx_except.ec"
346
- sqli_diag_get(ESQLINTVERSION, _SQhtab, -1);
347
- #line 324 "ifx_except.ec"
348
- }
349
-
350
- if (exc_count == 0) { /* Something went wrong */
351
- char message[128];
352
- snprintf(message,
353
- sizeof(message),
354
- "SQL ERROR: SQLCODE %d (sorry, no GET DIAGNOSTICS information available)",
355
- SQLCODE);
356
-
357
- {
358
- VALUE argv[] = { rb_str_new2(message) };
359
- return rb_class_new_instance(NUM_ELEMS(argv), argv, sym.eOperationalError);
360
- }
361
- }
362
-
363
- for (i = 0; i < exc_count; ++i) {
364
- sql_exception_number = i + 1;
365
-
366
- /*
367
- * EXEC SQL GET DIAGNOSTICS EXCEPTION :sql_exception_number
368
- * :sql_code = INFORMIX_SQLCODE,
369
- * :sql_state = RETURNED_SQLSTATE,
370
- * :class_origin_val = CLASS_ORIGIN,
371
- * :subclass_origin_val = SUBCLASS_ORIGIN,
372
- * :message = MESSAGE_TEXT,
373
- * :message_len = MESSAGE_LENGTH,
374
- * :server_name = SERVER_NAME,
375
- * :connection_name = CONNECTION_NAME
376
- * ;
377
- */
378
- #line 342 "ifx_except.ec"
379
- {
380
- #line 351 "ifx_except.ec"
381
- static ifx_hostvar_t _SQhtab[] =
382
- {
383
- { 0, 11, 103, sizeof(sql_code), 0, 0, 0, 0 },
384
- { 0, 3, 100, 6, 0, 0, 0, 0 },
385
- { 0, 4, 100, 256, 0, 0, 0, 0 },
386
- { 0, 5, 100, 256, 0, 0, 0, 0 },
387
- { 0, 6, 100, 8192, 0, 0, 0, 0 },
388
- { 0, 7, 102, sizeof(message_len), 0, 0, 0, 0 },
389
- { 0, 9, 100, 256, 0, 0, 0, 0 },
390
- { 0, 10, 100, 256, 0, 0, 0, 0 },
391
- { 0, 0, 0, 0, 0, 0, 0, 0 }
392
- #line 351 "ifx_except.ec"
393
- };
394
- _SQhtab[0].hostaddr = (char *)&sql_code;
395
- _SQhtab[1].hostaddr = (sql_state);
396
- _SQhtab[2].hostaddr = (class_origin_val);
397
- _SQhtab[3].hostaddr = (subclass_origin_val);
398
- _SQhtab[4].hostaddr = (message);
399
- _SQhtab[5].hostaddr = (char *)&message_len;
400
- _SQhtab[6].hostaddr = (server_name);
401
- _SQhtab[7].hostaddr = (connection_name);
402
- #line 351 "ifx_except.ec"
403
- sqli_diag_get(ESQLINTVERSION, _SQhtab, sql_exception_number);
404
- #line 351 "ifx_except.ec"
405
- }
406
-
407
- TRIM_BLANKS(class_origin_val);
408
- TRIM_BLANKS(subclass_origin_val);
409
- TRIM_BLANKS(server_name);
410
- TRIM_BLANKS(connection_name);
411
- message[message_len - 1] = '\0';
412
- TRIM_BLANKS(message);
413
-
414
- {
415
- VALUE sprintf_args[] = { rb_str_new2(message), rb_str_new2(sqlca.sqlerrm) };
416
- VALUE argv[] = {
417
- INT2FIX(sql_code),
418
- rb_str_new2(sql_state),
419
- rb_str_new2(class_origin_val),
420
- rb_str_new2(subclass_origin_val),
421
- rb_f_sprintf(NUM_ELEMS(sprintf_args), sprintf_args),
422
- rb_str_new2(server_name),
423
- rb_str_new2(connection_name)
424
- };
425
-
426
- ifx_exc_add_info(NUM_ELEMS(argv), argv, new_instance);
427
- }
428
- }
429
-
430
- return new_instance;
431
- }
432
-
433
- /**
434
- * Raises Informix::AssertionFailure exception
435
- */
436
- void ifx_assertion_exception(const char *failure_type,
437
- const char *what_failed,
438
- const char *file,
439
- int line)
440
- {
441
- VALUE sprintf_args[] = {
442
- rb_str_new2("%s failed on line %d of file %s: %s"),
443
- rb_str_new2(failure_type),
444
- INT2FIX(line),
445
- rb_str_new2(file),
446
- rb_str_new2(what_failed)
447
- };
448
-
449
- VALUE args[] = { rb_f_sprintf(NUM_ELEMS(sprintf_args), sprintf_args) };
450
-
451
- rb_exc_raise(rb_class_new_instance(NUM_ELEMS(args), args, sym.lib_eAssertion));
452
- }
453
-
454
- /* Init module with shared value(s) from main informix classes */
455
- void rbifx_except_init(VALUE mInformix, ifx_except_symbols_t *syms)
456
- {
457
- VALUE sym_ExcInfo;
458
-
459
- sym.mInformix = mInformix; // Informix module object handle
460
-
461
- /* class Error --------------------------------------------------------- */
462
- sym.eError = rb_define_class_under(mInformix, "Error", rb_eStandardError);
463
- sym.eWarning = rb_define_class_under(mInformix, "Warning", rb_eStandardError);
464
-
465
- sym.eInterfaceError = rb_define_class_under(mInformix, "InterfaceError", sym.eError);
466
- sym.eDatabaseError = rb_define_class_under(mInformix, "DatabaseError", sym.eError);
467
- sym.eDataError = rb_define_class_under(mInformix, "DataError", sym.eError);
468
- sym.eOperationalError = rb_define_class_under(mInformix, "OperationalError", sym.eError);
469
- sym.eIntegrityError = rb_define_class_under(mInformix, "IntegrityError", sym.eError);
470
- sym.eInternalError = rb_define_class_under(mInformix, "InternalError", sym.eError);
471
- sym.eProgrammingError = rb_define_class_under(mInformix, "ProgrammingError", sym.eError);
472
- sym.eNotSupportedError = rb_define_class_under(mInformix, "NotSupportedError", sym.eError);
473
-
474
- /* Make base class enumerable */
475
- rb_include_module(sym.eError, rb_mEnumerable);
476
-
477
- /* Precondition exception class */
478
- sym.lib_eAssertion = rb_define_class_under(mInformix, "AssertionFailure", rb_eStandardError);
479
-
480
- rb_define_method(sym.eError, "initialize", ifx_exc_init, -1);
481
- rb_define_method(sym.eError, "message", ifx_exc_message, 0);
482
- rb_define_method(sym.eError, "sql_code", ifx_exc_sql_code, 0);
483
- rb_define_method(sym.eError, "add_info", ifx_exc_add_info, -1);
484
- rb_define_method(sym.eError, "[]", ifx_exc_at, 1);
485
- rb_define_method(sym.eError, "each", ifx_exc_each, 0);
486
- rb_define_method(sym.eError, "to_s", ifx_exc_to_s, 0);
487
- rb_define_method(sym.eError, "size", ifx_exc_size, 0);
488
- rb_define_alias(sym.eError, "length", "size");
489
-
490
- sym_ExcInfo = rb_intern("ExcInfo");
491
-
492
- sym.id_sql_code = rb_intern("sql_code");
493
- sym.id_sql_state = rb_intern("sql_state");
494
- sym.id_class_origin = rb_intern("class_origin");
495
- sym.id_subclass_origin = rb_intern("subclass_origin");
496
- sym.id_message = rb_intern("message");
497
- sym.id_server_name = rb_intern("server_name");
498
- sym.id_connection_name = rb_intern("connection_name");
499
-
500
- /* Define ExcInfo as a struct in the Informix module */
501
- rb_define_const(mInformix,
502
- "ExcInfo",
503
- rb_struct_define(NULL,
504
- rb_id2name(sym.id_sql_code),
505
- rb_id2name(sym.id_sql_state),
506
- rb_id2name(sym.id_class_origin),
507
- rb_id2name(sym.id_subclass_origin),
508
- rb_id2name(sym.id_message),
509
- rb_id2name(sym.id_server_name),
510
- rb_id2name(sym.id_connection_name),
511
- NULL));
512
-
513
- sym.sExcInfo = rb_const_get(mInformix, sym_ExcInfo);
514
-
515
- if (syms)
516
- {
517
- *syms = sym;
518
- }
519
- }
520
-
521
-
522
- #line 466 "ifx_except.ec"