ruby-informix 0.6.2 → 0.7.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.
data/COPYRIGHT CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2007, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.com>
1
+ Copyright (c) 2006-2008, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.com>
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/Changelog CHANGED
@@ -1,3 +1,46 @@
1
+ 0.7.0 03/31/2008
2
+ ------------------
3
+ New features:
4
+ * Experimental support for the INTERVAL data type:
5
+ - year_to_month, day_to_fraction, from_months and from_seconds class
6
+ methods for creating an Interval object
7
+ - +@ and -@ unary operators
8
+ - +, * and / operations available with Integer, Rational, Date, Time
9
+ and DateTime objects
10
+ - methods for returning the respective fields of an Interval object
11
+ individually (years, months, days, hours, minutes and seconds)
12
+ - to_a method for returning the fields of an Interval object as an array
13
+ - methods for converting the Interval object to the given unit, where
14
+ apply (to_years, to_months, to_days, to_hours, to_minutes and
15
+ to_seconds)
16
+ - to_s method for displaying an Interval object as an string according
17
+ to ANSI SQL standards
18
+ - includes Comparable
19
+ * Database#version returns a struct with version information of the database
20
+ server.
21
+ * Database#each and Database#each_hash shortcut methods for declaring and
22
+ opening a cursor in a single step.
23
+ Contributed by Reid Morrison <reidmo at gmail>
24
+ * Database#execute is not an alias for Database#immediate any more.
25
+ It has become a shortcut for preparing and executing a statement in a
26
+ single step.
27
+ * SequentialCursor includes Enumerable
28
+ * Ruby 1.9 compatible
29
+ * More and better documentation
30
+
31
+ Bugs fixed:
32
+ * The documentation for class Error was not being recognized by rdoc
33
+
34
+ Remarks:
35
+ * Database.new deprecated in favor of Database.open
36
+ * Database#do was removed
37
+ * A lot of C code has been reimplemented in Ruby
38
+ * Modules and classes have been reorganized
39
+ * Database#execute still behaves the same, except that it can also accept
40
+ input parameters and return at most one record. Database#immediate is
41
+ more efficient though.
42
+
43
+
1
44
  0.6.2 10/20/2007
2
45
  ------------------
3
46
  Bugs fixed:
data/README CHANGED
@@ -1,84 +1,145 @@
1
- Ruby/Informix
2
- ---------------
3
- Ruby extension for connecting to IBM Informix Dynamic Server, written in ESQL/C.
4
-
5
- For installation instructions please read INSTALL.
6
-
7
- 1. Supported platforms
8
- 2. Documentation
9
- 3. Data types
10
- 4. Recommendations
11
- 5. Caveats
12
- 6. Support
13
-
14
-
15
- 1. Supported platforms
16
-
17
- Ruby/Informix has been tested succesfully on the following platforms:
18
-
19
- Operating System Architecture Informix CSDK
20
- -------------------------------------------------------------
21
- Solaris 10 SPARC64 11.10.UC1 3.00UC2
22
- Solaris 10 SPARC64 9.40FC6 3.00UC2
23
- Solaris 9 SPARC64 9.40FC6 2.90UC3
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
30
- HP-UX 11.11 PA-RISC 2.0 10.00.FC3R1TL 2.81
31
- 64-bit
1
+ = Ruby/Informix -- Ruby library for connecting to IBM Informix.
2
+
3
+ == Motivation
4
+ The situation that started it all [link][http://santanatechnotes.blogspot.com/2006/03/informix-driver-for-ruby.html].
5
+
6
+ == Download
7
+
8
+ The latest version of Ruby/Informix can be found at:
9
+
10
+ http://rubyforge.org/projects/ruby-informix
11
+
12
+ == Supported platforms
13
+
14
+ Ruby/Informix has been tested succesfully with Informix 7 and above, and
15
+ Informix CSDK 2.81 and above, on the following platforms:
16
+
17
+ Operating System Architecture
18
+ -----------------------------------------
19
+ Solaris SPARC64
20
+ GNU/Linux x86, x86-64
21
+ Windows XP/2000 x86
22
+ HP-UX 11.11 PA-RISC 2.0 64-bit
32
23
 
33
24
  Send me an e-mail if you have [un]succesfully tested Ruby/Informix on another
34
25
  platform.
35
26
 
27
+ == Installation
28
+
29
+ === Requirements
30
+
31
+ * Informix CSDK 2.81 or above
32
+
33
+ If you want to build Ruby/Informix instead of installing a precompiled gem,
34
+ you will also need:
35
+
36
+ * Microsoft Visual Studio 6.0, for Windows or
37
+ * an ANSI C compiler, for UNIX and Linux
38
+
39
+ === Rubygem installation
40
+
41
+ gem install ruby-informix
42
+
43
+ == Documentation
44
+
45
+ RDoc and ri documentation is automatically installed. It can also be found
46
+ online at:
47
+
48
+ http://ruby-informix.rubyforge.org/doc
36
49
 
37
- 2. Documentation
50
+ == Examples
38
51
 
39
- Documentation generated by RDoc for each class, module and method can be found
40
- under the doc/ directory in this distribution and at the following web address:
52
+ === Connecting to a database
41
53
 
42
- http://ruby-informix.rubyforge.org/doc/
54
+ db = Informix.connect('stores')
43
55
 
44
- Examples of use can be found at:
56
+ === Fetching all records from a table
45
57
 
46
- http://ruby-informix.rubyforge.org
58
+ cur = db.cursor('select * from stock')
59
+ cur.open
60
+ records = cur.fetch_all
61
+ cur.drop # or close, if you want to reopen it later
47
62
 
63
+ === Same thing, with blocks
48
64
 
49
- 3. Data types
65
+ records = db.cursor('select * from stock') do |cur|
66
+ cur.open
67
+ cur.fetch_all
68
+ end
50
69
 
51
- All built-in data types are supported, except interval. As you would expect,
52
- numeric, string and boolean data types are mapped to their respective objects
53
- in Ruby; DECIMAL/MONEY, DATE, DATETIME and NULL are mapped to BigDecimal, Date,
54
- Time and nil respectively.
70
+ === Inserting records
55
71
 
56
- The notable exception is TEXT/BYTE columns, where Ruby/Informix expects an
57
- IO-based (File) or IO-like (StringIO) object as input, and returns an String
58
- object as output.
72
+ stmt = db.prepare('insert into state values(?, ?)')
73
+ stmt.execute('CA', 'California')
74
+ stmt.call('NM', 'New Mexico')
75
+ stmt['TX', 'Texas']
59
76
 
60
- An Slob class exists in the Informix module for working with Smart Large
61
- Objects (CLOB/BLOB).
77
+ === Iterating over a table using a hash (shortcut)
62
78
 
79
+ db.each_hash('select * from customers') do |cust|
80
+ puts "#{cust['firstname']} #{cust['lastname']}"
81
+ end
63
82
 
64
- 4. Recommendations
83
+ More examples can be found at:
65
84
 
66
- * use #drop for prepared statements and cursors or use them with blocks,
67
- to release Informix resources.
85
+ http://ruby-informix.rubyforge.org/examples.html
86
+
87
+
88
+ == Data types supported
89
+
90
+ Informix Ruby
91
+ -----------------------------------------------------------------------------
92
+ SMALLINT, INT, INT8, FLOAT, Numeric
93
+ SERIAL, SERIAL8
94
+ CHAR, NCHAR, VARCHAR, NVARCHAR String
95
+ DATE Date
96
+ DATETIME Time
97
+ INTERVAL Informix::IntervalYTM, Informix::IntervalDTS
98
+ DECIMAL, MONEY BigDecimal
99
+ BOOL TrueClass, FalseClass
100
+ BYTE, TEXT StringIO, String
101
+ CLOB, BLOB Informix::Slob
102
+
103
+
104
+ NULL values can be inserted and are retrieved as +nil+.
105
+
106
+ BYTE and TEXT are retrieved as Strings, but for supplying them as input
107
+ parameters, a StringIO object, or a anyother IO-like object that provides
108
+ a #read method must be used.
109
+
110
+ Strings can be used in the cases where Informix accepts them for non-character
111
+ data types, like DATE, DATETIME, INTERVAL, BOOL, DECIMAL and MONEY
112
+
113
+
114
+ == Recommendations
115
+
116
+ * use blocks to release Informix resources automatically as soon as possible,
117
+ or use #drop
68
118
  * you can optimize cursor execution by changing the size of fetch and insert
69
119
  buffers, setting the environment variable FET_BUF_SIZE to up to 32767.
70
120
 
71
121
 
72
- 5. Caveats
122
+ == Support
73
123
 
74
- * INTERVAL not implemented yet
124
+ Feel free to send me bug reports, feature requests, comments, patches or
125
+ questions directly to my mailbox or the following forums:
75
126
 
76
- 6. Support
127
+ * Online forums at Rubyforge [link][http://rubyforge.org/forum/?group_id=1378]
128
+ * Mailing list [link][http://rubyforge.org/mailman/listinfo/ruby-informix-misc]
77
129
 
78
- Feel free to send me bug reports, feature requests, comments, patches or
79
- questions to my mailbox or Ruby/Informix's forums and mailing list at
80
- Rubyforge (http://rubyforge.org/projects/ruby-informix/)
81
130
 
131
+ == Presentations and articles about Ruby/Informix
132
+
133
+ * "Talking with Perl, PHP, Python, Ruby to IDS" [link][http://www.informix-zone.com/informix-script-dbapi], Eric Herber, The Informix Zone.
134
+ * "Informix on Rails" [link][http://www.ibm.com/developerworks/blogs/page/gbowerman?entry=informix_on_rails], Guy Bowerman, IBM developerWorks Blogs: Informix Application Development.
135
+ * "Ruby/Informix, and the Ruby Common client" [link][http://www.ibm.com/developerworks/blogs/page/gbowerman?entry=ruby_informix_and_the_ruby], Guy Bowerman, IBM developerWorks Blogs: Informix Application Development.
136
+ * "Using IBM Informix Dynamic Server on Microsoft Windows, Part 6" [link][http://www.ibm.com/developerworks/offers/lp/demos/summary/usingids6.html], Akmal B. Chaudhri, IBM developerWorks: On demand demos.
137
+
138
+ == License
139
+
140
+ Ruby/Informix is available under the three-clause BSD license
141
+
142
+ :include: COPYRIGHT
82
143
 
83
144
  -----------------------------------------
84
145
  Gerardo Santana <gerardo.santana gmail>
@@ -32,5 +32,5 @@ else
32
32
  end
33
33
 
34
34
 
35
- `#{env} #{esql} -e informix.ec ifx_except.ec`
36
- create_makefile("informix")
35
+ `#{env} #{esql} -e informixc.ec`
36
+ create_makefile("informixc")
@@ -1,58 +1,67 @@
1
1
  #include <sqlhdr.h>
2
2
  #include <sqliapi.h>
3
- #line 1 "informix.ec"
4
- /* $Id: informix.ec,v 1.12 2007/10/14 00:18:50 santana Exp $ */
5
- /*
6
- * Copyright (c) 2006-2007, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.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
- static const char rcsid[] = "$Id: informix.ec,v 1.12 2007/10/14 00:18:50 santana Exp $";
3
+ #line 1 "informixc.ec"
4
+ /* $Id: informixc.ec,v 1.26 2008/04/01 05:30:21 santana Exp $ */
5
+ /*
6
+ * Copyright (c) 2006-2008, Gerardo Santana Gomez Garrido <gerardo.santana@gmail.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
+ static const char rcsid[] = "$Id: informixc.ec,v 1.26 2008/04/01 05:30:21 santana Exp $";
35
35
 
36
36
  #include "ruby.h"
37
- #include "ifx_except.h"
38
37
 
39
38
  #include <sqlstype.h>
40
39
  #include <sqltypes.h>
41
40
 
42
- static VALUE rb_cDate, rb_cBigDecimal;
41
+ static VALUE rb_cDate, rb_cBigDecimal, rb_cRational;
43
42
 
43
+ /* Modules */
44
44
  static VALUE rb_mInformix;
45
- static VALUE rb_mSequentialCursor;
46
- static VALUE rb_mScrollCursor;
47
- static VALUE rb_mInsertCursor;
45
+ static VALUE rb_mInterval;
46
+ static VALUE rb_mCursor;
48
47
 
48
+ /* Classes */
49
49
  static VALUE rb_cSlob, rb_cSlobStat;
50
50
  static VALUE rb_cDatabase;
51
- static VALUE rb_cStatement;
52
- static VALUE rb_cCursor;
51
+ static VALUE rb_cStatement, rb_cCursorBase;
52
+ static VALUE rb_cSequentialCursor, rb_cScrollCursor, rb_cInsertCursor;
53
+ static VALUE rb_cIfxVersion;
54
+
55
+ static VALUE rb_cArray;
56
+
57
+ /* Exceptions */
58
+ static VALUE rb_eError, rb_eWarning, rb_eInternalError;
59
+ static VALUE rb_eProgrammingError, rb_eOperationalError, rb_eDatabaseError;
53
60
 
54
61
  static ID s_read, s_new, s_utc, s_day, s_month, s_year;
55
62
  static ID s_hour, s_min, s_sec, s_usec, s_to_s, s_to_i;
63
+ static ID s_add_info, s_from_months, s_from_seconds;
64
+ static ID s_add, s_mul;
56
65
 
57
66
  static VALUE sym_name, sym_type, sym_nullable, sym_stype, sym_length;
58
67
  static VALUE sym_precision, sym_scale, sym_default, sym_xid;
@@ -61,9 +70,6 @@ static VALUE sym_col_info, sym_sbspace, sym_estbytes, sym_extsz;
61
70
  static VALUE sym_createflags, sym_openflags, sym_maxbytes;
62
71
  static VALUE sym_params;
63
72
 
64
- /* Symbols from ifx_except module */
65
- static ifx_except_symbols_t esyms;
66
-
67
73
  #define IDSIZE 30
68
74
 
69
75
  typedef struct {
@@ -97,17 +103,213 @@ do { \
97
103
  char *c_str = StringValueCStr(str); \
98
104
  mint ret = ifx_int8cvasc(c_str, strlen(c_str), (int8addr)); \
99
105
  if (ret < 0) \
100
- rb_raise(esyms.eOperationalError, "Could not convert %s to int8", c_str); \
106
+ rb_raise(rb_eOperationalError, "Could not convert %s to INT8 [Error %d]", c_str, ret); \
101
107
  } while(0)
102
108
 
103
109
  #define INT82NUM(int8addr, num) \
104
110
  do { \
105
111
  char str[21]; \
106
- ifx_int8toasc((int8addr), str, sizeof(str) - 1); \
112
+ mint ret; \
113
+ ret = ifx_int8toasc((int8addr), str, sizeof(str) - 1); \
114
+ if (ret < 0) \
115
+ rb_raise(rb_eOperationalError, \
116
+ "Unable to convert INT8 to Bignum [Error %d]", ret); \
107
117
  str[sizeof(str) - 1] = 0; \
108
118
  num = rb_cstr2inum(str, 10); \
109
119
  } while(0)
110
120
 
121
+ /*
122
+ *****************************************************************************
123
+ * Begins code copyrighted by Edwin M. Fine
124
+ *****************************************************************************
125
+ *
126
+ * Copyright (c) 2006, 2007 Edwin M. Fine <efine@finecomputerconsultants.com>
127
+ * All rights reserved.
128
+ *
129
+ * Redistribution and use in source and binary forms, with or without
130
+ * modification, are permitted provided that the following conditions
131
+ * are met:
132
+ *
133
+ * 1. Redistributions of source code must retain the above copyright
134
+ * notice, this list of conditions and the following disclaimer.
135
+ * 2. Redistributions in binary form must reproduce the above copyright
136
+ * notice, this list of conditions and the following disclaimer in the
137
+ * documentation and/or other materials provided with the distribution.
138
+ * 3. The name of the author may not be used to endorse or promote products
139
+ * derived from this software without specific prior written permission.
140
+ *
141
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
142
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
145
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
146
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
147
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
148
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
149
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
150
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
151
+ * POSSIBILITY OF SUCH DAMAGE.
152
+ *****************************************************************************
153
+ */
154
+ #define TRIM_BLANKS(s) ((s)[byleng(s, stleng(s))] = '\0')
155
+ #define NUM_ELEMS(arr) (sizeof(arr) / sizeof(*arr))
156
+
157
+ static VALUE
158
+ rbifx_ext_exception(VALUE exception_class)
159
+ {
160
+ VALUE new_instance;
161
+
162
+ /*
163
+ * EXEC SQL BEGIN DECLARE SECTION;
164
+ */
165
+ #line 159 "informixc.ec"
166
+ #line 160 "informixc.ec"
167
+ int4 sql_code;
168
+ char sql_state[6];
169
+ char class_origin_val[256];
170
+ char subclass_origin_val[256];
171
+ char message[8192];
172
+ char server_name[256];
173
+ char connection_name[256];
174
+ mint sql_exception_number;
175
+ mint exc_count = 0;
176
+ mint message_len;
177
+ mint i;
178
+ /*
179
+ * EXEC SQL END DECLARE SECTION;
180
+ */
181
+ #line 174 "informixc.ec"
182
+
183
+
184
+ new_instance = rb_class_new_instance(0, 0, exception_class);
185
+
186
+ /* Check that instance of exception_class is derived from
187
+ * Informix::Error
188
+ */
189
+ if (!rb_obj_is_kind_of(new_instance, rb_eError) &&
190
+ !rb_obj_is_kind_of(new_instance, rb_eWarning)) {
191
+ rb_raise(rb_eRuntimeError,
192
+ "Can't instantiate exception from %s, only from %s or %s or their children",
193
+ rb_class2name(exception_class),
194
+ rb_class2name(rb_eWarning),
195
+ rb_class2name(rb_eError));
196
+ }
197
+
198
+ /*
199
+ * EXEC SQL GET DIAGNOSTICS :exc_count = NUMBER;
200
+ */
201
+ #line 190 "informixc.ec"
202
+ {
203
+ #line 190 "informixc.ec"
204
+ static ifx_hostvar_t _SQhtab[] =
205
+ {
206
+ { 0, 1, 102, sizeof(exc_count), 0, 0, 0, 0 },
207
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
208
+ #line 190 "informixc.ec"
209
+ };
210
+ _SQhtab[0].hostaddr = (char *)&exc_count;
211
+ #line 190 "informixc.ec"
212
+ sqli_diag_get(ESQLINTVERSION, _SQhtab, -1);
213
+ #line 190 "informixc.ec"
214
+ }
215
+
216
+ if (exc_count == 0) { /* Something went wrong */
217
+ char message[128];
218
+ snprintf(message,
219
+ sizeof(message),
220
+ "SQL ERROR: SQLCODE %d (sorry, no GET DIAGNOSTICS information available)",
221
+ SQLCODE);
222
+
223
+ {
224
+ VALUE argv[] = { rb_str_new2(message) };
225
+ return rb_class_new_instance(NUM_ELEMS(argv), argv, rb_eOperationalError);
226
+ }
227
+ }
228
+
229
+ for (i = 0; i < exc_count; ++i) {
230
+ sql_exception_number = i + 1;
231
+
232
+ /*
233
+ * EXEC SQL GET DIAGNOSTICS EXCEPTION :sql_exception_number
234
+ * :sql_code = INFORMIX_SQLCODE,
235
+ * :sql_state = RETURNED_SQLSTATE,
236
+ * :class_origin_val = CLASS_ORIGIN,
237
+ * :subclass_origin_val = SUBCLASS_ORIGIN,
238
+ * :message = MESSAGE_TEXT,
239
+ * :message_len = MESSAGE_LENGTH,
240
+ * :server_name = SERVER_NAME,
241
+ * :connection_name = CONNECTION_NAME
242
+ * ;
243
+ */
244
+ #line 208 "informixc.ec"
245
+ {
246
+ #line 217 "informixc.ec"
247
+ static ifx_hostvar_t _SQhtab[] =
248
+ {
249
+ { 0, 11, 103, sizeof(sql_code), 0, 0, 0, 0 },
250
+ { 0, 3, 100, 6, 0, 0, 0, 0 },
251
+ { 0, 4, 100, 256, 0, 0, 0, 0 },
252
+ { 0, 5, 100, 256, 0, 0, 0, 0 },
253
+ { 0, 6, 100, 8192, 0, 0, 0, 0 },
254
+ { 0, 7, 102, sizeof(message_len), 0, 0, 0, 0 },
255
+ { 0, 9, 100, 256, 0, 0, 0, 0 },
256
+ { 0, 10, 100, 256, 0, 0, 0, 0 },
257
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
258
+ #line 217 "informixc.ec"
259
+ };
260
+ _SQhtab[0].hostaddr = (char *)&sql_code;
261
+ _SQhtab[1].hostaddr = (sql_state);
262
+ _SQhtab[2].hostaddr = (class_origin_val);
263
+ _SQhtab[3].hostaddr = (subclass_origin_val);
264
+ _SQhtab[4].hostaddr = (message);
265
+ _SQhtab[5].hostaddr = (char *)&message_len;
266
+ _SQhtab[6].hostaddr = (server_name);
267
+ _SQhtab[7].hostaddr = (connection_name);
268
+ #line 217 "informixc.ec"
269
+ sqli_diag_get(ESQLINTVERSION, _SQhtab, sql_exception_number);
270
+ #line 217 "informixc.ec"
271
+ }
272
+
273
+ TRIM_BLANKS(class_origin_val);
274
+ TRIM_BLANKS(subclass_origin_val);
275
+ TRIM_BLANKS(server_name);
276
+ TRIM_BLANKS(connection_name);
277
+ message[message_len - 1] = '\0';
278
+ TRIM_BLANKS(message);
279
+
280
+ {
281
+ VALUE sprintf_args[] = { rb_str_new2(message), rb_str_new2(sqlca.sqlerrm) };
282
+ VALUE argv[] = {
283
+ INT2FIX(sql_code),
284
+ rb_str_new2(sql_state),
285
+ rb_str_new2(class_origin_val),
286
+ rb_str_new2(subclass_origin_val),
287
+ rb_f_sprintf(NUM_ELEMS(sprintf_args), sprintf_args),
288
+ rb_str_new2(server_name),
289
+ rb_str_new2(connection_name)
290
+ };
291
+
292
+ rb_funcall(new_instance, s_add_info, 1, rb_ary_new4(7, argv));
293
+ }
294
+ }
295
+
296
+ return new_instance;
297
+ }
298
+
299
+ /*
300
+ * C helper functions (see ifx_except.h for documentation)
301
+ */
302
+ static void
303
+ raise_ifx_extended(void)
304
+ {
305
+ rb_exc_raise(rbifx_ext_exception(rb_eDatabaseError));
306
+ }
307
+ /*
308
+ *****************************************************************************
309
+ * Ends code copyrighted by Edwin M. Fine
310
+ *****************************************************************************
311
+ */
312
+
111
313
  /* class Slob::Stat ------------------------------------------------------ */
112
314
 
113
315
  static void
@@ -142,31 +344,31 @@ rb_slobstat_initialize(VALUE self, VALUE slob)
142
344
  /*
143
345
  * EXEC SQL begin declare section;
144
346
  */
145
- #line 139 "informix.ec"
146
- #line 140 "informix.ec"
347
+ #line 290 "informixc.ec"
348
+ #line 291 "informixc.ec"
147
349
  char *did;
148
350
  /*
149
351
  * EXEC SQL end declare section;
150
352
  */
151
- #line 141 "informix.ec"
353
+ #line 292 "informixc.ec"
152
354
 
153
355
 
154
356
  Data_Get_Struct(slob, slob_t, sb);
155
357
  Data_Get_Struct(self, slobstat_t, stat);
156
358
 
157
359
  if (sb->fd == -1)
158
- rb_raise(esyms.eProgrammingError,
360
+ rb_raise(rb_eProgrammingError,
159
361
  "Open the Slob object before getting its status");
160
362
 
161
363
  did = sb->database_id;
162
364
  /*
163
365
  * EXEC SQL set connection :did;
164
366
  */
165
- #line 151 "informix.ec"
367
+ #line 302 "informixc.ec"
166
368
  {
167
- #line 151 "informix.ec"
369
+ #line 302 "informixc.ec"
168
370
  sqli_connect_set(0, did, 0);
169
- #line 151 "informix.ec"
371
+ #line 302 "informixc.ec"
170
372
  }
171
373
  if (SQLCODE < 0)
172
374
  raise_ifx_extended();
@@ -186,7 +388,7 @@ rb_slobstat_initialize(VALUE self, VALUE slob)
186
388
 
187
389
  if (stat->atime == -1 || stat->ctime == -1 || stat->mtime == -1 ||
188
390
  stat->refcnt == -1 || ret == -1) {
189
- rb_raise(esyms.eOperationalError, "Unable to get status");
391
+ rb_raise(rb_eOperationalError, "Unable to get status");
190
392
  }
191
393
 
192
394
  return self;
@@ -313,24 +515,24 @@ slob_free(slob_t *slob)
313
515
  /*
314
516
  * EXEC SQL begin declare section;
315
517
  */
316
- #line 294 "informix.ec"
317
- #line 295 "informix.ec"
518
+ #line 445 "informixc.ec"
519
+ #line 446 "informixc.ec"
318
520
  char *did;
319
521
  /*
320
522
  * EXEC SQL end declare section;
321
523
  */
322
- #line 296 "informix.ec"
524
+ #line 447 "informixc.ec"
323
525
 
324
526
 
325
527
  did = slob->database_id;
326
528
  /*
327
529
  * EXEC SQL set connection :did;
328
530
  */
329
- #line 299 "informix.ec"
531
+ #line 450 "informixc.ec"
330
532
  {
331
- #line 299 "informix.ec"
533
+ #line 450 "informixc.ec"
332
534
  sqli_connect_set(0, did, 0);
333
- #line 299 "informix.ec"
535
+ #line 450 "informixc.ec"
334
536
  }
335
537
  if (SQLCODE >= 0)
336
538
  ifx_lo_close(slob->fd);
@@ -357,6 +559,7 @@ slob_alloc(VALUE klass)
357
559
  return Data_Wrap_Struct(klass, slob_mark, slob_free, slob);
358
560
  }
359
561
 
562
+ /* :nodoc: */
360
563
  static VALUE
361
564
  rb_slob_initialize(int argc, VALUE *argv, VALUE self)
362
565
  {
@@ -367,13 +570,13 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
367
570
  /*
368
571
  * EXEC SQL begin declare section;
369
572
  */
370
- #line 332 "informix.ec"
371
- #line 333 "informix.ec"
573
+ #line 484 "informixc.ec"
574
+ #line 485 "informixc.ec"
372
575
  char *did;
373
576
  /*
374
577
  * EXEC SQL end declare section;
375
578
  */
376
- #line 334 "informix.ec"
579
+ #line 486 "informixc.ec"
377
580
 
378
581
 
379
582
  rb_scan_args(argc, argv, "12", &db, &type, &options);
@@ -382,11 +585,11 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
382
585
  /*
383
586
  * EXEC SQL set connection :did;
384
587
  */
385
- #line 339 "informix.ec"
588
+ #line 491 "informixc.ec"
386
589
  {
387
- #line 339 "informix.ec"
590
+ #line 491 "informixc.ec"
388
591
  sqli_connect_set(0, did, 0);
389
- #line 339 "informix.ec"
592
+ #line 491 "informixc.ec"
390
593
  }
391
594
  if (SQLCODE < 0)
392
595
  raise_ifx_extended();
@@ -398,7 +601,7 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
398
601
  if (!NIL_P(type)) {
399
602
  int t = FIX2INT(type);
400
603
  if (t != XID_CLOB && t != XID_BLOB)
401
- rb_raise(esyms.eInternalError, "Invalid type %d for an SLOB", t);
604
+ rb_raise(rb_eInternalError, "Invalid type %d for an SLOB", t);
402
605
  slob->type = t;
403
606
  }
404
607
 
@@ -429,7 +632,7 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
429
632
  char *c_sbspace = StringValueCStr(sbspace);
430
633
  ret = ifx_lo_specset_sbspace(slob->spec, c_sbspace);
431
634
  if (ret == -1)
432
- rb_raise(esyms.eOperationalError, "Could not set sbspace name to %s", c_sbspace);
635
+ rb_raise(rb_eOperationalError, "Could not set sbspace name to %s", c_sbspace);
433
636
  }
434
637
  if (!NIL_P(estbytes)) {
435
638
  ifx_int8_t estbytes8;
@@ -437,17 +640,17 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
437
640
  NUM2INT8(estbytes, &estbytes8);
438
641
  ret = ifx_lo_specset_estbytes(slob->spec, &estbytes8);
439
642
  if (ret == -1)
440
- rb_raise(esyms.eOperationalError, "Could not set estbytes");
643
+ rb_raise(rb_eOperationalError, "Could not set estbytes");
441
644
  }
442
645
  if (!NIL_P(extsz)) {
443
646
  ret = ifx_lo_specset_extsz(slob->spec, FIX2LONG(extsz));
444
647
  if (ret == -1)
445
- rb_raise(esyms.eOperationalError, "Could not set extsz to %d", FIX2LONG(extsz));
648
+ rb_raise(rb_eOperationalError, "Could not set extsz to %ld", FIX2LONG(extsz));
446
649
  }
447
650
  if (!NIL_P(createflags)) {
448
651
  ret = ifx_lo_specset_flags(slob->spec, FIX2LONG(createflags));
449
652
  if (ret == -1)
450
- rb_raise(esyms.eOperationalError, "Could not set crate-time flags to 0x%X", FIX2LONG(createflags));
653
+ rb_raise(rb_eOperationalError, "Could not set crate-time flags to 0x%X", FIX2LONG(createflags));
451
654
  }
452
655
  if (!NIL_P(maxbytes)) {
453
656
  ifx_int8_t maxbytes8;
@@ -455,7 +658,7 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
455
658
  NUM2INT8(maxbytes, (&maxbytes8));
456
659
  ret = ifx_lo_specset_maxbytes(slob->spec, &maxbytes8);
457
660
  if (ret == -1)
458
- rb_raise(esyms.eOperationalError, "Could not set maxbytes");
661
+ rb_raise(rb_eOperationalError, "Could not set maxbytes");
459
662
  }
460
663
 
461
664
  slob->fd = ifx_lo_create(slob->spec, RTEST(openflags)? FIX2LONG(openflags): LO_RDWR, &slob->lo, &error);
@@ -465,41 +668,6 @@ rb_slob_initialize(int argc, VALUE *argv, VALUE self)
465
668
  return self;
466
669
  }
467
670
 
468
- static VALUE rb_slob_close(VALUE self);
469
- /*
470
- * call-seq:
471
- * Slob.new(database, type = Slob::CLOB, options = nil) => slob
472
- * Slob.new(database, type = Slob::CLOB, options = nil) {|slob| block } => obj
473
- *
474
- * Creates a Smart Large Object of type <i>type</i> in <i>database</i>.
475
- * Returns a <code>Slob</code> object pointing to it.
476
- *
477
- * <i>type</i> can be Slob::BLOB or Slob::CLOB
478
- *
479
- * <i>options</i> can be nil or a Hash object with the following possible keys:
480
- *
481
- * :sbspace => Sbspace name
482
- * :estbytes => Estimated size, in bytes
483
- * :extsz => Allocation extent size
484
- * :createflags => Create-time flags
485
- * :openflags => Access mode
486
- * :maxbytes => Maximum size
487
- * :col_info => Get the previous values from the column-level storage
488
- * characteristics for the specified database column
489
- */
490
- static VALUE
491
- rb_slob_s_new(int argc, VALUE *argv, VALUE klass)
492
- {
493
- VALUE slob;
494
-
495
- slob = rb_class_new_instance(argc, argv, klass);
496
-
497
- if (rb_block_given_p())
498
- return rb_ensure(rb_yield, slob, rb_slob_close, slob);
499
-
500
- return slob;
501
- }
502
-
503
671
  /*
504
672
  * call-seq:
505
673
  * slob.open(access = Slob::RDONLY) => slob
@@ -529,13 +697,13 @@ rb_slob_open(int argc, VALUE *argv, VALUE self)
529
697
  /*
530
698
  * EXEC SQL begin declare section;
531
699
  */
532
- #line 478 "informix.ec"
533
- #line 479 "informix.ec"
700
+ #line 595 "informixc.ec"
701
+ #line 596 "informixc.ec"
534
702
  char *did;
535
703
  /*
536
704
  * EXEC SQL end declare section;
537
705
  */
538
- #line 480 "informix.ec"
706
+ #line 597 "informixc.ec"
539
707
 
540
708
 
541
709
  Data_Get_Struct(self, slob_t, slob);
@@ -547,11 +715,11 @@ rb_slob_open(int argc, VALUE *argv, VALUE self)
547
715
  /*
548
716
  * EXEC SQL set connection :did;
549
717
  */
550
- #line 488 "informix.ec"
718
+ #line 605 "informixc.ec"
551
719
  {
552
- #line 488 "informix.ec"
720
+ #line 605 "informixc.ec"
553
721
  sqli_connect_set(0, did, 0);
554
- #line 488 "informix.ec"
722
+ #line 605 "informixc.ec"
555
723
  }
556
724
  if (SQLCODE < 0)
557
725
  raise_ifx_extended();
@@ -582,24 +750,24 @@ rb_slob_close(VALUE self)
582
750
  /*
583
751
  * EXEC SQL begin declare section;
584
752
  */
585
- #line 515 "informix.ec"
586
- #line 516 "informix.ec"
753
+ #line 632 "informixc.ec"
754
+ #line 633 "informixc.ec"
587
755
  char *did;
588
756
  /*
589
757
  * EXEC SQL end declare section;
590
758
  */
591
- #line 517 "informix.ec"
759
+ #line 634 "informixc.ec"
592
760
 
593
761
 
594
762
  did = slob->database_id;
595
763
  /*
596
764
  * EXEC SQL set connection :did;
597
765
  */
598
- #line 520 "informix.ec"
766
+ #line 637 "informixc.ec"
599
767
  {
600
- #line 520 "informix.ec"
768
+ #line 637 "informixc.ec"
601
769
  sqli_connect_set(0, did, 0);
602
- #line 520 "informix.ec"
770
+ #line 637 "informixc.ec"
603
771
  }
604
772
  if (SQLCODE < 0)
605
773
  return self;
@@ -630,30 +798,30 @@ rb_slob_read(VALUE self, VALUE nbytes)
630
798
  /*
631
799
  * EXEC SQL begin declare section;
632
800
  */
633
- #line 547 "informix.ec"
634
- #line 548 "informix.ec"
801
+ #line 664 "informixc.ec"
802
+ #line 665 "informixc.ec"
635
803
  char *did;
636
804
  /*
637
805
  * EXEC SQL end declare section;
638
806
  */
639
- #line 549 "informix.ec"
807
+ #line 666 "informixc.ec"
640
808
 
641
809
 
642
810
 
643
811
  Data_Get_Struct(self, slob_t, slob);
644
812
 
645
813
  if (slob->fd == -1)
646
- rb_raise(esyms.eProgrammingError, "Open the Slob object before reading");
814
+ rb_raise(rb_eProgrammingError, "Open the Slob object before reading");
647
815
 
648
816
  did = slob->database_id;
649
817
  /*
650
818
  * EXEC SQL set connection :did;
651
819
  */
652
- #line 558 "informix.ec"
820
+ #line 675 "informixc.ec"
653
821
  {
654
- #line 558 "informix.ec"
822
+ #line 675 "informixc.ec"
655
823
  sqli_connect_set(0, did, 0);
656
- #line 558 "informix.ec"
824
+ #line 675 "informixc.ec"
657
825
  }
658
826
  if (SQLCODE < 0)
659
827
  raise_ifx_extended();
@@ -693,36 +861,36 @@ rb_slob_write(VALUE self, VALUE data)
693
861
  /*
694
862
  * EXEC SQL begin declare section;
695
863
  */
696
- #line 594 "informix.ec"
697
- #line 595 "informix.ec"
864
+ #line 711 "informixc.ec"
865
+ #line 712 "informixc.ec"
698
866
  char *did;
699
867
  /*
700
868
  * EXEC SQL end declare section;
701
869
  */
702
- #line 596 "informix.ec"
870
+ #line 713 "informixc.ec"
703
871
 
704
872
 
705
873
  Data_Get_Struct(self, slob_t, slob);
706
874
 
707
875
  if (slob->fd == -1)
708
- rb_raise(esyms.eProgrammingError, "Open the Slob object before writing");
876
+ rb_raise(rb_eProgrammingError, "Open the Slob object before writing");
709
877
 
710
878
  did = slob->database_id;
711
879
  /*
712
880
  * EXEC SQL set connection :did;
713
881
  */
714
- #line 604 "informix.ec"
882
+ #line 721 "informixc.ec"
715
883
  {
716
- #line 604 "informix.ec"
884
+ #line 721 "informixc.ec"
717
885
  sqli_connect_set(0, did, 0);
718
- #line 604 "informix.ec"
886
+ #line 721 "informixc.ec"
719
887
  }
720
888
  if (SQLCODE < 0)
721
889
  raise_ifx_extended();
722
890
 
723
891
  str = rb_obj_as_string(data);
724
- buffer = RSTRING(str)->ptr;
725
- nbytes = RSTRING(str)->len;
892
+ buffer = RSTRING_PTR(str);
893
+ nbytes = RSTRING_LEN(str);
726
894
 
727
895
  ret = ifx_lo_write(slob->fd, buffer, nbytes, &error);
728
896
 
@@ -777,29 +945,29 @@ rb_slob_seek(VALUE self, VALUE offset, VALUE whence)
777
945
  /*
778
946
  * EXEC SQL begin declare section;
779
947
  */
780
- #line 662 "informix.ec"
781
- #line 663 "informix.ec"
948
+ #line 779 "informixc.ec"
949
+ #line 780 "informixc.ec"
782
950
  char *did;
783
951
  /*
784
952
  * EXEC SQL end declare section;
785
953
  */
786
- #line 664 "informix.ec"
954
+ #line 781 "informixc.ec"
787
955
 
788
956
 
789
957
  Data_Get_Struct(self, slob_t, slob);
790
958
 
791
959
  if (slob->fd == -1)
792
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
960
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
793
961
 
794
962
  did = slob->database_id;
795
963
  /*
796
964
  * EXEC SQL set connection :did;
797
965
  */
798
- #line 672 "informix.ec"
966
+ #line 789 "informixc.ec"
799
967
  {
800
- #line 672 "informix.ec"
968
+ #line 789 "informixc.ec"
801
969
  sqli_connect_set(0, did, 0);
802
- #line 672 "informix.ec"
970
+ #line 789 "informixc.ec"
803
971
  }
804
972
  if (SQLCODE < 0)
805
973
  raise_ifx_extended();
@@ -855,29 +1023,29 @@ rb_slob_tell(VALUE self)
855
1023
  /*
856
1024
  * EXEC SQL begin declare section;
857
1025
  */
858
- #line 724 "informix.ec"
859
- #line 725 "informix.ec"
1026
+ #line 841 "informixc.ec"
1027
+ #line 842 "informixc.ec"
860
1028
  char *did;
861
1029
  /*
862
1030
  * EXEC SQL end declare section;
863
1031
  */
864
- #line 726 "informix.ec"
1032
+ #line 843 "informixc.ec"
865
1033
 
866
1034
 
867
1035
  Data_Get_Struct(self, slob_t, slob);
868
1036
 
869
1037
  if (slob->fd == -1)
870
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1038
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
871
1039
 
872
1040
  did = slob->database_id;
873
1041
  /*
874
1042
  * EXEC SQL set connection :did;
875
1043
  */
876
- #line 734 "informix.ec"
1044
+ #line 851 "informixc.ec"
877
1045
  {
878
- #line 734 "informix.ec"
1046
+ #line 851 "informixc.ec"
879
1047
  sqli_connect_set(0, did, 0);
880
- #line 734 "informix.ec"
1048
+ #line 851 "informixc.ec"
881
1049
  }
882
1050
  if (SQLCODE < 0)
883
1051
  raise_ifx_extended();
@@ -908,29 +1076,29 @@ rb_slob_truncate(VALUE self, VALUE offset)
908
1076
  /*
909
1077
  * EXEC SQL begin declare section;
910
1078
  */
911
- #line 761 "informix.ec"
912
- #line 762 "informix.ec"
1079
+ #line 878 "informixc.ec"
1080
+ #line 879 "informixc.ec"
913
1081
  char *did;
914
1082
  /*
915
1083
  * EXEC SQL end declare section;
916
1084
  */
917
- #line 763 "informix.ec"
1085
+ #line 880 "informixc.ec"
918
1086
 
919
1087
 
920
1088
  Data_Get_Struct(self, slob_t, slob);
921
1089
 
922
1090
  if (slob->fd == -1)
923
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1091
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
924
1092
 
925
1093
  did = slob->database_id;
926
1094
  /*
927
1095
  * EXEC SQL set connection :did;
928
1096
  */
929
- #line 771 "informix.ec"
1097
+ #line 888 "informixc.ec"
930
1098
  {
931
- #line 771 "informix.ec"
1099
+ #line 888 "informixc.ec"
932
1100
  sqli_connect_set(0, did, 0);
933
- #line 771 "informix.ec"
1101
+ #line 888 "informixc.ec"
934
1102
  }
935
1103
  if (SQLCODE < 0)
936
1104
  raise_ifx_extended();
@@ -980,29 +1148,29 @@ rb_slob_lock(VALUE self, VALUE offset, VALUE whence, VALUE range, VALUE mode)
980
1148
  /*
981
1149
  * EXEC SQL begin declare section;
982
1150
  */
983
- #line 817 "informix.ec"
984
- #line 818 "informix.ec"
1151
+ #line 934 "informixc.ec"
1152
+ #line 935 "informixc.ec"
985
1153
  char *did;
986
1154
  /*
987
1155
  * EXEC SQL end declare section;
988
1156
  */
989
- #line 819 "informix.ec"
1157
+ #line 936 "informixc.ec"
990
1158
 
991
1159
 
992
1160
  Data_Get_Struct(self, slob_t, slob);
993
1161
 
994
1162
  if (slob->fd == -1)
995
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1163
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
996
1164
 
997
1165
  did = slob->database_id;
998
1166
  /*
999
1167
  * EXEC SQL set connection :did;
1000
1168
  */
1001
- #line 827 "informix.ec"
1169
+ #line 944 "informixc.ec"
1002
1170
  {
1003
- #line 827 "informix.ec"
1171
+ #line 944 "informixc.ec"
1004
1172
  sqli_connect_set(0, did, 0);
1005
- #line 827 "informix.ec"
1173
+ #line 944 "informixc.ec"
1006
1174
  }
1007
1175
  if (SQLCODE < 0)
1008
1176
  raise_ifx_extended();
@@ -1040,29 +1208,29 @@ rb_slob_unlock(VALUE self, VALUE offset, VALUE whence, VALUE range)
1040
1208
  /*
1041
1209
  * EXEC SQL begin declare section;
1042
1210
  */
1043
- #line 861 "informix.ec"
1044
- #line 862 "informix.ec"
1211
+ #line 978 "informixc.ec"
1212
+ #line 979 "informixc.ec"
1045
1213
  char *did;
1046
1214
  /*
1047
1215
  * EXEC SQL end declare section;
1048
1216
  */
1049
- #line 863 "informix.ec"
1217
+ #line 980 "informixc.ec"
1050
1218
 
1051
1219
 
1052
1220
  Data_Get_Struct(self, slob_t, slob);
1053
1221
 
1054
1222
  if (slob->fd == -1)
1055
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1223
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
1056
1224
 
1057
1225
  did = slob->database_id;
1058
1226
  /*
1059
1227
  * EXEC SQL set connection :did;
1060
1228
  */
1061
- #line 871 "informix.ec"
1229
+ #line 988 "informixc.ec"
1062
1230
  {
1063
- #line 871 "informix.ec"
1231
+ #line 988 "informixc.ec"
1064
1232
  sqli_connect_set(0, did, 0);
1065
- #line 871 "informix.ec"
1233
+ #line 988 "informixc.ec"
1066
1234
  }
1067
1235
  if (SQLCODE < 0)
1068
1236
  raise_ifx_extended();
@@ -1097,29 +1265,29 @@ slob_specget(VALUE self, slob_option_t option)
1097
1265
  /*
1098
1266
  * EXEC SQL begin declare section;
1099
1267
  */
1100
- #line 902 "informix.ec"
1101
- #line 903 "informix.ec"
1268
+ #line 1019 "informixc.ec"
1269
+ #line 1020 "informixc.ec"
1102
1270
  char *did;
1103
1271
  /*
1104
1272
  * EXEC SQL end declare section;
1105
1273
  */
1106
- #line 904 "informix.ec"
1274
+ #line 1021 "informixc.ec"
1107
1275
 
1108
1276
 
1109
1277
  Data_Get_Struct(self, slob_t, slob);
1110
1278
 
1111
1279
  if (slob->fd == -1)
1112
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1280
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
1113
1281
 
1114
1282
  did = slob->database_id;
1115
1283
  /*
1116
1284
  * EXEC SQL set connection :did;
1117
1285
  */
1118
- #line 912 "informix.ec"
1286
+ #line 1029 "informixc.ec"
1119
1287
  {
1120
- #line 912 "informix.ec"
1288
+ #line 1029 "informixc.ec"
1121
1289
  sqli_connect_set(0, did, 0);
1122
- #line 912 "informix.ec"
1290
+ #line 1029 "informixc.ec"
1123
1291
  }
1124
1292
  if (SQLCODE < 0)
1125
1293
  raise_ifx_extended();
@@ -1131,7 +1299,7 @@ slob_specget(VALUE self, slob_option_t option)
1131
1299
  spec = ifx_lo_stat_cspec(stat);
1132
1300
  if (spec == NULL) {
1133
1301
  ifx_lo_stat_free(stat);
1134
- rb_raise(esyms.eOperationalError, "Unable to get storage characteristics");
1302
+ rb_raise(rb_eOperationalError, "Unable to get storage characteristics");
1135
1303
  }
1136
1304
 
1137
1305
  switch(option) {
@@ -1153,7 +1321,7 @@ slob_specget(VALUE self, slob_option_t option)
1153
1321
 
1154
1322
  ifx_lo_stat_free(stat);
1155
1323
  if (ret == -1)
1156
- rb_raise(esyms.eOperationalError, "Unable to get information for %s", str_slob_options[option]);
1324
+ rb_raise(rb_eOperationalError, "Unable to get information for %s", str_slob_options[option]);
1157
1325
 
1158
1326
  switch(option) {
1159
1327
  case slob_estbytes:
@@ -1183,29 +1351,29 @@ slob_specset(VALUE self, slob_option_t option, VALUE value)
1183
1351
  /*
1184
1352
  * EXEC SQL begin declare section;
1185
1353
  */
1186
- #line 972 "informix.ec"
1187
- #line 973 "informix.ec"
1354
+ #line 1089 "informixc.ec"
1355
+ #line 1090 "informixc.ec"
1188
1356
  char *did;
1189
1357
  /*
1190
1358
  * EXEC SQL end declare section;
1191
1359
  */
1192
- #line 974 "informix.ec"
1360
+ #line 1091 "informixc.ec"
1193
1361
 
1194
1362
 
1195
1363
  Data_Get_Struct(self, slob_t, slob);
1196
1364
 
1197
1365
  if (slob->fd == -1)
1198
- rb_raise(esyms.eProgrammingError, "Open the Slob object first");
1366
+ rb_raise(rb_eProgrammingError, "Open the Slob object first");
1199
1367
 
1200
1368
  did = slob->database_id;
1201
1369
  /*
1202
1370
  * EXEC SQL set connection :did;
1203
1371
  */
1204
- #line 982 "informix.ec"
1372
+ #line 1099 "informixc.ec"
1205
1373
  {
1206
- #line 982 "informix.ec"
1374
+ #line 1099 "informixc.ec"
1207
1375
  sqli_connect_set(0, did, 0);
1208
- #line 982 "informix.ec"
1376
+ #line 1099 "informixc.ec"
1209
1377
  }
1210
1378
  if (SQLCODE < 0)
1211
1379
  raise_ifx_extended();
@@ -1217,7 +1385,7 @@ slob_specset(VALUE self, slob_option_t option, VALUE value)
1217
1385
  spec = ifx_lo_stat_cspec(stat);
1218
1386
  if (spec == NULL) {
1219
1387
  ifx_lo_stat_free(stat);
1220
- rb_raise(esyms.eOperationalError, "Unable to get storage characteristics");
1388
+ rb_raise(rb_eOperationalError, "Unable to get storage characteristics");
1221
1389
  }
1222
1390
 
1223
1391
  switch(option) {
@@ -1233,7 +1401,7 @@ slob_specset(VALUE self, slob_option_t option, VALUE value)
1233
1401
 
1234
1402
  ifx_lo_stat_free(stat);
1235
1403
  if (ret == -1)
1236
- rb_raise(esyms.eOperationalError, "Unable to set information for %s", str_slob_options[option]);
1404
+ rb_raise(rb_eOperationalError, "Unable to set information for %s", str_slob_options[option]);
1237
1405
 
1238
1406
  return value;
1239
1407
  }
@@ -1341,30 +1509,30 @@ slob_stat(VALUE self, slob_stat_t stat)
1341
1509
  /*
1342
1510
  * EXEC SQL begin declare section;
1343
1511
  */
1344
- #line 1114 "informix.ec"
1345
- #line 1115 "informix.ec"
1512
+ #line 1231 "informixc.ec"
1513
+ #line 1232 "informixc.ec"
1346
1514
  char *did;
1347
1515
  /*
1348
1516
  * EXEC SQL end declare section;
1349
1517
  */
1350
- #line 1116 "informix.ec"
1518
+ #line 1233 "informixc.ec"
1351
1519
 
1352
1520
 
1353
1521
  Data_Get_Struct(self, slob_t, slob);
1354
1522
 
1355
1523
  if (slob->fd == -1)
1356
- rb_raise(esyms.eProgrammingError,
1524
+ rb_raise(rb_eProgrammingError,
1357
1525
  "Open the Slob object before getting its status");
1358
1526
 
1359
1527
  did = slob->database_id;
1360
1528
  /*
1361
1529
  * EXEC SQL set connection :did;
1362
1530
  */
1363
- #line 1125 "informix.ec"
1531
+ #line 1242 "informixc.ec"
1364
1532
  {
1365
- #line 1125 "informix.ec"
1533
+ #line 1242 "informixc.ec"
1366
1534
  sqli_connect_set(0, did, 0);
1367
- #line 1125 "informix.ec"
1535
+ #line 1242 "informixc.ec"
1368
1536
  }
1369
1537
  if (SQLCODE < 0)
1370
1538
  raise_ifx_extended();
@@ -1394,7 +1562,7 @@ slob_stat(VALUE self, slob_stat_t stat)
1394
1562
  ifx_lo_stat_free(st);
1395
1563
 
1396
1564
  if (ret == -1)
1397
- rb_raise(esyms.eOperationalError, "Unable to get value of %s", str_slob_stats[stat]);
1565
+ rb_raise(rb_eOperationalError, "Unable to get value of %s", str_slob_stats[stat]);
1398
1566
 
1399
1567
  switch(stat) {
1400
1568
  case slob_atime:
@@ -1567,7 +1735,7 @@ alloc_output_slots(cursor_t *c)
1567
1735
  p->loc_loctype = LOCMEMORY;
1568
1736
  p->loc_bufsize = -1;
1569
1737
  }
1570
- if (var->sqltype == SQLDTIME) {
1738
+ if (var->sqltype == SQLDTIME || var->sqltype == SQLINTERVAL) {
1571
1739
  var->sqllen = 0;
1572
1740
  }
1573
1741
  }
@@ -1701,26 +1869,11 @@ bind_input_params(cursor_t *c, VALUE *argv)
1701
1869
  break;
1702
1870
  default:
1703
1871
  klass = rb_obj_class(data);
1704
- if (klass == rb_cDate) {
1705
- int2 mdy[3];
1706
- int4 date;
1707
-
1708
- mdy[0] = FIX2INT(rb_funcall(data, s_month, 0));
1709
- mdy[1] = FIX2INT(rb_funcall(data, s_day, 0));
1710
- mdy[2] = FIX2INT(rb_funcall(data, s_year, 0));
1711
- rmdyjul(mdy, &date);
1712
-
1713
- var->sqldata = (char *)ALLOC(int4);
1714
- *((int4 *)var->sqldata) = date;
1715
- var->sqltype = CDATETYPE;
1716
- var->sqllen = sizeof(int4);
1717
- *var->sqlind = 0;
1718
- break;
1719
- }
1720
1872
  if (klass == rb_cTime) {
1721
1873
  char buffer[30];
1722
1874
  short year, month, day, hour, minute, second;
1723
1875
  int usec;
1876
+ mint ret;
1724
1877
  dtime_t *dt;
1725
1878
 
1726
1879
  year = FIX2INT(rb_funcall(data, s_year, 0));
@@ -1736,7 +1889,11 @@ bind_input_params(cursor_t *c, VALUE *argv)
1736
1889
  dt->dt_qual = TU_DTENCODE(TU_YEAR, TU_F5);
1737
1890
  snprintf(buffer, sizeof(buffer), "%d-%d-%d %d:%d:%d.%d",
1738
1891
  year, month, day, hour, minute, second, usec/10);
1739
- dtcvasc(buffer, dt);
1892
+ ret = dtcvasc(buffer, dt);
1893
+ if (ret < 0)
1894
+ rb_raise(rb_eOperationalError,
1895
+ "Unable to convert '%s' to DATETIME [Error %d]",
1896
+ RSTRING_PTR(data), ret);
1740
1897
 
1741
1898
  var->sqldata = (char *)dt;
1742
1899
  var->sqltype = CDTIMETYPE;
@@ -1757,25 +1914,14 @@ bind_input_params(cursor_t *c, VALUE *argv)
1757
1914
  *var->sqlind = 0;
1758
1915
  break;
1759
1916
  }
1760
- if (klass == rb_cBigDecimal) {
1761
- data = rb_funcall(data, s_to_s, 0);
1762
- var->sqldata = (char *)ALLOC(dec_t);
1763
- deccvasc(RSTRING(data)->ptr, RSTRING(data)->len,
1764
- (dec_t *)var->sqldata);
1765
- var->sqltype = CDECIMALTYPE;
1766
- var->sqllen = sizeof(dec_t);
1767
- *var->sqlind = 0;
1768
- break;
1769
- }
1770
1917
  if (rb_respond_to(data, s_read)) {
1771
1918
  char *str;
1772
1919
  loc_t *loc;
1773
1920
  long len;
1774
1921
 
1775
1922
  data = rb_funcall(data, s_read, 0);
1776
- data = StringValue(data);
1777
- str = RSTRING(data)->ptr;
1778
- len = RSTRING(data)->len;
1923
+ str = RSTRING_PTR(data);
1924
+ len = RSTRING_LEN(data);
1779
1925
 
1780
1926
  loc = (loc_t *)ALLOC(loc_t);
1781
1927
  byfill((char *)loc, sizeof(loc_t), 0);
@@ -1804,8 +1950,8 @@ bind_input_params(cursor_t *c, VALUE *argv)
1804
1950
  char *str;
1805
1951
  long len;
1806
1952
 
1807
- str = RSTRING(data)->ptr;
1808
- len = RSTRING(data)->len;
1953
+ str = RSTRING_PTR(data);
1954
+ len = RSTRING_LEN(data);
1809
1955
  var->sqldata = ALLOC_N(char, len + 1);
1810
1956
  memcpy(var->sqldata, str, len);
1811
1957
  var->sqldata[len] = 0;
@@ -1922,6 +2068,88 @@ make_result(cursor_t *c, VALUE record)
1922
2068
 
1923
2069
  break;
1924
2070
  }
2071
+ case SQLINTERVAL: {
2072
+ VALUE constructor, value;
2073
+ intrvl_t *data, invl;
2074
+ short sign;
2075
+
2076
+ data = (intrvl_t *)var->sqldata;
2077
+ if (TU_START(data->in_qual) <= TU_MONTH) {
2078
+ invl.in_qual = TU_IENCODE(9, TU_YEAR, TU_MONTH);
2079
+ constructor = s_from_months;
2080
+ }
2081
+ else {
2082
+ invl.in_qual = TU_IENCODE(9, TU_DAY, TU_F5);
2083
+ constructor = s_from_seconds;
2084
+ }
2085
+
2086
+ invextend(data, &invl);
2087
+ sign = invl.in_dec.dec_pos == 0? -1 : 1;
2088
+
2089
+ if (TU_START(data->in_qual) <= TU_MONTH) {
2090
+ int i, exp, months;
2091
+ long years;
2092
+ char *dgts;
2093
+
2094
+ exp = invl.in_dec.dec_exp;
2095
+ dgts = invl.in_dec.dec_dgts;
2096
+ months = years = 0;
2097
+
2098
+ for(i = 0; i < invl.in_dec.dec_ndgts; i++, exp--) {
2099
+ if (exp > 5)
2100
+ years = years*100 + dgts[i];
2101
+ else
2102
+ months += dgts[i];
2103
+ }
2104
+ for(i = exp - 5; i > 0; i--)
2105
+ years *= 100;
2106
+ value = LONG2NUM(sign*years);
2107
+ value = rb_funcall(value, s_mul, 1, INT2FIX(12));
2108
+ value = rb_funcall(value, s_add, 1, INT2FIX(sign*months));
2109
+ }
2110
+ else {
2111
+ int i, exp, usec;
2112
+ long days, seconds;
2113
+ char *dgts;
2114
+
2115
+ exp = invl.in_dec.dec_exp;
2116
+ dgts = invl.in_dec.dec_dgts;
2117
+ days = seconds = usec = 0;
2118
+
2119
+ for(i = 0; i < invl.in_dec.dec_ndgts; i++, exp--) {
2120
+ if(exp > 3)
2121
+ days = days*100 + dgts[i];
2122
+ else if (exp == 3)
2123
+ seconds += dgts[i]*60*60;
2124
+ else if (exp == 2)
2125
+ seconds += dgts[i]*60;
2126
+ else if (exp == 1)
2127
+ seconds += dgts[i];
2128
+ else if (exp == 0)
2129
+ usec += dgts[i]*10000;
2130
+ else if (exp == -1)
2131
+ usec += dgts[i]*100;
2132
+ else if (exp == -2)
2133
+ usec += dgts[i];
2134
+ }
2135
+
2136
+ for(i = exp - 3; i > 0; i--)
2137
+ days *= 100;
2138
+
2139
+ value = LONG2FIX(days);
2140
+ value = rb_funcall(value, s_mul, 1, LONG2FIX(sign*24*60*60));
2141
+ value = rb_funcall(value, s_add, 1, LONG2FIX(sign*seconds));
2142
+
2143
+ if (usec != 0) {
2144
+ VALUE argv[2] = { INT2FIX(sign*usec), LONG2FIX(1000000L) };
2145
+ VALUE frac = rb_class_new_instance(2, argv, rb_cRational);
2146
+ value = rb_funcall(frac, s_add, 1, value);
2147
+ }
2148
+ }
2149
+
2150
+ item = rb_funcall(rb_mInterval, constructor, 1, value);
2151
+ break;
2152
+ }
1925
2153
  case SQLDECIMAL:
1926
2154
  case SQLMONEY: {
1927
2155
  char buffer[40];
@@ -1929,9 +2157,9 @@ make_result(cursor_t *c, VALUE record)
1929
2157
 
1930
2158
  ret = dectoasc((dec_t *)var->sqldata, buffer,
1931
2159
  sizeof(buffer) - 1, -1);
1932
- if (ret)
1933
- rb_raise(esyms.eOperationalError,
1934
- "Unable to convert DECIMAL to BigDecimal");
2160
+ if (ret < 0)
2161
+ rb_raise(rb_eOperationalError,
2162
+ "Unable to convert DECIMAL to BigDecimal [Error %d]", ret);
1935
2163
 
1936
2164
  buffer[sizeof(buffer) - 1] = 0;
1937
2165
  item = rb_funcall(rb_cBigDecimal, s_new, 1, rb_str_new2(buffer));
@@ -1987,46 +2215,6 @@ make_result(cursor_t *c, VALUE record)
1987
2215
  return record;
1988
2216
  }
1989
2217
 
1990
- /* module Informix -------------------------------------------------------- */
1991
-
1992
- static VALUE rb_database_s_open(int argc, VALUE *argv, VALUE klass);
1993
- /*
1994
- * call-seq:
1995
- * Informix.connect(dbname, user=nil, password=nil) => database
1996
- * Informix.connect(dbname, user=nil, password=nil) {|database| block } => obj
1997
- *
1998
- * Creates a <code>Database</code> object connected to <i>dbname</i> as
1999
- * <i>user</i> with <i>password</i>. If these are not given, connects to
2000
- * <i>dbname</i> as the current user.
2001
- *
2002
- * The Database object is passed to the block if it's given, and automatically
2003
- * closes the connection when the block terminates, returning the value of
2004
- * the block.
2005
- */
2006
- static VALUE
2007
- rb_informix_connect(int argc, VALUE *argv, VALUE self)
2008
- {
2009
- return rb_database_s_open(argc, argv, rb_cDatabase);
2010
- }
2011
-
2012
- /*
2013
- * call-seq:
2014
- * Informix.version => string
2015
- *
2016
- * Returns the version of this Ruby/Informix driver.
2017
- * Note that this is NOT the Informix database version.
2018
- */
2019
- static VALUE rb_informix_version(void)
2020
- {
2021
- static const char * const ver = "0.6.1";
2022
- static VALUE driver_version;
2023
-
2024
- if (driver_version == 0)
2025
- driver_version = rb_str_freeze(rb_str_new2(ver));
2026
-
2027
- return driver_version;
2028
- }
2029
-
2030
2218
  /* class Database --------------------------------------------------------- */
2031
2219
 
2032
2220
  static void
@@ -2035,24 +2223,24 @@ database_free(void *p)
2035
2223
  /*
2036
2224
  * EXEC SQL begin declare section;
2037
2225
  */
2038
- #line 1792 "informix.ec"
2039
- #line 1793 "informix.ec"
2226
+ #line 1929 "informixc.ec"
2227
+ #line 1930 "informixc.ec"
2040
2228
  char *did;
2041
2229
  /*
2042
2230
  * EXEC SQL end declare section;
2043
2231
  */
2044
- #line 1794 "informix.ec"
2232
+ #line 1931 "informixc.ec"
2045
2233
 
2046
2234
 
2047
2235
  did = p;
2048
2236
  /*
2049
2237
  * EXEC SQL disconnect :did;
2050
2238
  */
2051
- #line 1797 "informix.ec"
2239
+ #line 1934 "informixc.ec"
2052
2240
  {
2053
- #line 1797 "informix.ec"
2241
+ #line 1934 "informixc.ec"
2054
2242
  sqli_connect_close(0, did, 0, 0);
2055
- #line 1797 "informix.ec"
2243
+ #line 1934 "informixc.ec"
2056
2244
  }
2057
2245
  xfree(p);
2058
2246
  }
@@ -2067,27 +2255,34 @@ database_alloc(VALUE klass)
2067
2255
  return Data_Wrap_Struct(klass, 0, database_free, did);
2068
2256
  }
2069
2257
 
2258
+ /* :nodoc: */
2070
2259
  static VALUE
2071
2260
  rb_database_initialize(int argc, VALUE *argv, VALUE self)
2072
2261
  {
2073
- VALUE arg[3];
2262
+ VALUE arg[3], version;
2263
+ VALUE server_type, major, minor, os, level, full;
2074
2264
 
2075
2265
  /*
2076
2266
  * EXEC SQL begin declare section;
2077
2267
  */
2078
- #line 1816 "informix.ec"
2079
- #line 1817 "informix.ec"
2268
+ #line 1955 "informixc.ec"
2269
+ #line 1956 "informixc.ec"
2080
2270
  char *dbname, *user = NULL, *pass = NULL, *did;
2271
+ struct version_t
2272
+ {
2273
+ char server_type[41], major[3], minor[3], os[3], level[3];
2274
+ char full[61];
2275
+ } c_version;
2081
2276
  /*
2082
2277
  * EXEC SQL end declare section;
2083
2278
  */
2084
- #line 1818 "informix.ec"
2279
+ #line 1961 "informixc.ec"
2085
2280
 
2086
2281
 
2087
2282
  rb_scan_args(argc, argv, "12", &arg[0], &arg[1], &arg[2]);
2088
2283
 
2089
2284
  if (NIL_P(arg[0]))
2090
- rb_raise(esyms.eProgrammingError, "A database name must be specified");
2285
+ rb_raise(rb_eProgrammingError, "A database name must be specified");
2091
2286
 
2092
2287
  Data_Get_Struct(self, char, did);
2093
2288
 
@@ -2105,59 +2300,91 @@ rb_database_initialize(int argc, VALUE *argv, VALUE self)
2105
2300
  * EXEC SQL connect to :dbname as :did user :user
2106
2301
  * using :pass with concurrent transaction;
2107
2302
  */
2108
- #line 1837 "informix.ec"
2303
+ #line 1980 "informixc.ec"
2109
2304
  {
2110
- #line 1838 "informix.ec"
2305
+ #line 1981 "informixc.ec"
2111
2306
  ifx_conn_t *_sqiconn;
2112
2307
  _sqiconn = (ifx_conn_t *)ifx_alloc_conn_user(user, pass);
2113
2308
  sqli_connect_open(ESQLINTVERSION, 0, dbname, did, _sqiconn, 1);
2114
2309
  ifx_free_conn_user(&_sqiconn);
2115
- #line 1838 "informix.ec"
2310
+ #line 1981 "informixc.ec"
2116
2311
  }
2117
2312
  else
2118
2313
  /*
2119
2314
  * EXEC SQL connect to :dbname as :did with concurrent transaction;
2120
2315
  */
2121
- #line 1840 "informix.ec"
2316
+ #line 1983 "informixc.ec"
2122
2317
  {
2123
- #line 1840 "informix.ec"
2318
+ #line 1983 "informixc.ec"
2124
2319
  sqli_connect_open(ESQLINTVERSION, 0, dbname, did, (ifx_conn_t *)0, 1);
2125
- #line 1840 "informix.ec"
2320
+ #line 1983 "informixc.ec"
2126
2321
  }
2127
2322
 
2128
2323
  if (SQLCODE < 0)
2129
2324
  raise_ifx_extended();
2130
2325
 
2131
- return self;
2132
- }
2133
-
2134
2326
  /*
2135
- * call-seq:
2136
- * Database.new(dbname, user = nil, password = nil) => database
2137
- * Database.open(dbname, user = nil, password = nil) => database
2138
- * Database.new(dbname, user = nil, password = nil) {|database| block } => obj
2139
- * Database.open(dbname, user = nil, password = nil) {|database| block } => obj
2140
- *
2141
- * Creates a <code>Database</code> object connected to <i>dbname</i> as
2142
- * <i>user</i> with <i>password</i>. If these are not given, connects to
2143
- * <i>dbname</i> as the current user.
2144
- *
2145
- * The Database object is passed to the block if it's given, and automatically
2146
- * closes the connection when the block terminates, returning the value of
2147
- * the block.
2327
+ * EXEC SQL select dbinfo('version', 'server-type'),
2328
+ * dbinfo('version', 'major'),
2329
+ * dbinfo('version', 'minor'),
2330
+ * dbinfo('version', 'os'),
2331
+ * dbinfo('version', 'level'),
2332
+ * dbinfo('version', 'full')
2333
+ * into :c_version from systables where tabid = 1;
2148
2334
  */
2149
- static VALUE rb_database_close(VALUE self);
2150
- static VALUE
2151
- rb_database_s_open(int argc, VALUE *argv, VALUE klass)
2152
- {
2153
- VALUE database;
2335
+ #line 1988 "informixc.ec"
2336
+ {
2337
+ #line 1994 "informixc.ec"
2338
+ static const char *sqlcmdtxt[] =
2339
+ #line 1994 "informixc.ec"
2340
+ {
2341
+ #line 1994 "informixc.ec"
2342
+ "select dbinfo ( 'version' , 'server-type' ) , dbinfo ( 'version' , 'major' ) , dbinfo ( 'version' , 'minor' ) , dbinfo ( 'version' , 'os' ) , dbinfo ( 'version' , 'level' ) , dbinfo ( 'version' , 'full' ) from systables where tabid = 1",
2343
+ 0
2344
+ };
2345
+ #line 1994 "informixc.ec"
2346
+ static ifx_cursor_t _SQ0 = {0};
2347
+ static ifx_sqlvar_t _sqobind[] =
2348
+ {
2349
+ { 114, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2350
+ { 114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2351
+ { 114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2352
+ { 114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2353
+ { 114, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2354
+ { 114, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2355
+ #line 1994 "informixc.ec"
2356
+ };
2357
+ #line 1994 "informixc.ec"
2358
+ _sqobind[0].sqldata = (c_version).server_type;
2359
+ #line 1994 "informixc.ec"
2360
+ _sqobind[1].sqldata = (c_version).major;
2361
+ #line 1994 "informixc.ec"
2362
+ _sqobind[2].sqldata = (c_version).minor;
2363
+ #line 1994 "informixc.ec"
2364
+ _sqobind[3].sqldata = (c_version).os;
2365
+ #line 1994 "informixc.ec"
2366
+ _sqobind[4].sqldata = (c_version).level;
2367
+ #line 1994 "informixc.ec"
2368
+ _sqobind[5].sqldata = (c_version).full;
2369
+ #line 1994 "informixc.ec"
2370
+ sqli_slct(ESQLINTVERSION, &_SQ0,sqlcmdtxt,0,(ifx_sqlvar_t *)0,6,_sqobind,0,(ifx_literal_t *)0,(ifx_namelist_t *)0,0);
2371
+ #line 1994 "informixc.ec"
2372
+ }
2154
2373
 
2155
- database = rb_class_new_instance(argc, argv, klass);
2156
2374
 
2157
- if (rb_block_given_p())
2158
- return rb_ensure(rb_yield, database, rb_database_close, database);
2375
+ OBJ_FREEZE(server_type = rb_str_new2(c_version.server_type));
2376
+ OBJ_FREEZE(major = rb_str_new2(c_version.major));
2377
+ OBJ_FREEZE(minor = rb_str_new2(c_version.minor));
2378
+ OBJ_FREEZE(os = rb_str_new2(c_version.os));
2379
+ OBJ_FREEZE(level = rb_str_new2(c_version.level));
2380
+ OBJ_FREEZE(full = rb_str_new2(c_version.full));
2159
2381
 
2160
- return database;
2382
+ version = rb_struct_new(rb_cIfxVersion, server_type, major, minor, os,
2383
+ level, full, NULL);
2384
+ OBJ_FREEZE(version);
2385
+ rb_iv_set(self, "@version", version);
2386
+
2387
+ return self;
2161
2388
  }
2162
2389
 
2163
2390
  /*
@@ -2172,13 +2399,13 @@ rb_database_close(VALUE self)
2172
2399
  /*
2173
2400
  * EXEC SQL begin declare section;
2174
2401
  */
2175
- #line 1886 "informix.ec"
2176
- #line 1887 "informix.ec"
2402
+ #line 2021 "informixc.ec"
2403
+ #line 2022 "informixc.ec"
2177
2404
  char *did;
2178
2405
  /*
2179
2406
  * EXEC SQL end declare section;
2180
2407
  */
2181
- #line 1888 "informix.ec"
2408
+ #line 2023 "informixc.ec"
2182
2409
 
2183
2410
 
2184
2411
  Data_Get_Struct(self, char, did);
@@ -2187,21 +2414,21 @@ rb_database_close(VALUE self)
2187
2414
  /*
2188
2415
  * EXEC SQL free :did;
2189
2416
  */
2190
- #line 1893 "informix.ec"
2417
+ #line 2028 "informixc.ec"
2191
2418
  {
2192
- #line 1893 "informix.ec"
2419
+ #line 2028 "informixc.ec"
2193
2420
  sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, did, 258));
2194
- #line 1893 "informix.ec"
2421
+ #line 2028 "informixc.ec"
2195
2422
  }
2196
2423
  did -= IDSIZE;
2197
2424
  /*
2198
2425
  * EXEC SQL disconnect :did;
2199
2426
  */
2200
- #line 1895 "informix.ec"
2427
+ #line 2030 "informixc.ec"
2201
2428
  {
2202
- #line 1895 "informix.ec"
2429
+ #line 2030 "informixc.ec"
2203
2430
  sqli_connect_close(0, did, 0, 0);
2204
- #line 1895 "informix.ec"
2431
+ #line 2030 "informixc.ec"
2205
2432
  }
2206
2433
 
2207
2434
  return self;
@@ -2214,7 +2441,17 @@ rb_database_close(VALUE self)
2214
2441
  *
2215
2442
  * Executes <i>query</i> and returns the number of rows affected.
2216
2443
  * <i>query</i> must not return rows. Executes efficiently any
2217
- * non-parameterized or DQL statement.
2444
+ * DDL (CREATE, DROP, ALTER), DCL (GRANT, REVOKE) and non-parameterized
2445
+ * DML (INSERT, UPDATE, DELETE) statements, except SELECT.
2446
+ *
2447
+ * Examples:
2448
+ *
2449
+ * Granting CONNECT to user:
2450
+ * db.immediate "grant connect to #{user}"
2451
+ * Creating a table:
2452
+ * db.immediate 'create table test(id serial, code char(2), desc varchar(30))'
2453
+ * Deleting records:
2454
+ * db.immediate 'delete from test where id = 7'
2218
2455
  */
2219
2456
 
2220
2457
  static VALUE
@@ -2223,13 +2460,13 @@ rb_database_immediate(VALUE self, VALUE arg)
2223
2460
  /*
2224
2461
  * EXEC SQL begin declare section;
2225
2462
  */
2226
- #line 1913 "informix.ec"
2227
- #line 1914 "informix.ec"
2463
+ #line 2058 "informixc.ec"
2464
+ #line 2059 "informixc.ec"
2228
2465
  char *query, *did;
2229
2466
  /*
2230
2467
  * EXEC SQL end declare section;
2231
2468
  */
2232
- #line 1915 "informix.ec"
2469
+ #line 2060 "informixc.ec"
2233
2470
 
2234
2471
 
2235
2472
  Data_Get_Struct(self, char, did);
@@ -2237,11 +2474,11 @@ rb_database_immediate(VALUE self, VALUE arg)
2237
2474
  /*
2238
2475
  * EXEC SQL set connection :did;
2239
2476
  */
2240
- #line 1919 "informix.ec"
2477
+ #line 2064 "informixc.ec"
2241
2478
  {
2242
- #line 1919 "informix.ec"
2479
+ #line 2064 "informixc.ec"
2243
2480
  sqli_connect_set(0, did, 0);
2244
- #line 1919 "informix.ec"
2481
+ #line 2064 "informixc.ec"
2245
2482
  }
2246
2483
  if (SQLCODE < 0)
2247
2484
  raise_ifx_extended();
@@ -2250,11 +2487,11 @@ rb_database_immediate(VALUE self, VALUE arg)
2250
2487
  /*
2251
2488
  * EXEC SQL execute immediate :query;
2252
2489
  */
2253
- #line 1924 "informix.ec"
2490
+ #line 2069 "informixc.ec"
2254
2491
  {
2255
- #line 1924 "informix.ec"
2492
+ #line 2069 "informixc.ec"
2256
2493
  sqli_exec_immed(query);
2257
- #line 1924 "informix.ec"
2494
+ #line 2069 "informixc.ec"
2258
2495
  }
2259
2496
  if (SQLCODE < 0)
2260
2497
  raise_ifx_extended();
@@ -2274,13 +2511,13 @@ rb_database_rollback(VALUE self)
2274
2511
  /*
2275
2512
  * EXEC SQL begin declare section;
2276
2513
  */
2277
- #line 1940 "informix.ec"
2278
- #line 1941 "informix.ec"
2514
+ #line 2085 "informixc.ec"
2515
+ #line 2086 "informixc.ec"
2279
2516
  char *did;
2280
2517
  /*
2281
2518
  * EXEC SQL end declare section;
2282
2519
  */
2283
- #line 1942 "informix.ec"
2520
+ #line 2087 "informixc.ec"
2284
2521
 
2285
2522
 
2286
2523
  Data_Get_Struct(self, char, did);
@@ -2288,11 +2525,11 @@ rb_database_rollback(VALUE self)
2288
2525
  /*
2289
2526
  * EXEC SQL set connection :did;
2290
2527
  */
2291
- #line 1946 "informix.ec"
2528
+ #line 2091 "informixc.ec"
2292
2529
  {
2293
- #line 1946 "informix.ec"
2530
+ #line 2091 "informixc.ec"
2294
2531
  sqli_connect_set(0, did, 0);
2295
- #line 1946 "informix.ec"
2532
+ #line 2091 "informixc.ec"
2296
2533
  }
2297
2534
  if (SQLCODE < 0)
2298
2535
  raise_ifx_extended();
@@ -2300,11 +2537,11 @@ rb_database_rollback(VALUE self)
2300
2537
  /*
2301
2538
  * EXEC SQL rollback;
2302
2539
  */
2303
- #line 1950 "informix.ec"
2540
+ #line 2095 "informixc.ec"
2304
2541
  {
2305
- #line 1950 "informix.ec"
2542
+ #line 2095 "informixc.ec"
2306
2543
  sqli_trans_rollback();
2307
- #line 1950 "informix.ec"
2544
+ #line 2095 "informixc.ec"
2308
2545
  }
2309
2546
  return self;
2310
2547
  }
@@ -2321,13 +2558,13 @@ rb_database_commit(VALUE self)
2321
2558
  /*
2322
2559
  * EXEC SQL begin declare section;
2323
2560
  */
2324
- #line 1963 "informix.ec"
2325
- #line 1964 "informix.ec"
2561
+ #line 2108 "informixc.ec"
2562
+ #line 2109 "informixc.ec"
2326
2563
  char *did;
2327
2564
  /*
2328
2565
  * EXEC SQL end declare section;
2329
2566
  */
2330
- #line 1965 "informix.ec"
2567
+ #line 2110 "informixc.ec"
2331
2568
 
2332
2569
 
2333
2570
  Data_Get_Struct(self, char, did);
@@ -2335,11 +2572,11 @@ rb_database_commit(VALUE self)
2335
2572
  /*
2336
2573
  * EXEC SQL set connection :did;
2337
2574
  */
2338
- #line 1969 "informix.ec"
2575
+ #line 2114 "informixc.ec"
2339
2576
  {
2340
- #line 1969 "informix.ec"
2577
+ #line 2114 "informixc.ec"
2341
2578
  sqli_connect_set(0, did, 0);
2342
- #line 1969 "informix.ec"
2579
+ #line 2114 "informixc.ec"
2343
2580
  }
2344
2581
  if (SQLCODE < 0)
2345
2582
  raise_ifx_extended();
@@ -2347,11 +2584,11 @@ rb_database_commit(VALUE self)
2347
2584
  /*
2348
2585
  * EXEC SQL commit;
2349
2586
  */
2350
- #line 1973 "informix.ec"
2587
+ #line 2118 "informixc.ec"
2351
2588
  {
2352
- #line 1973 "informix.ec"
2589
+ #line 2118 "informixc.ec"
2353
2590
  sqli_trans_commit();
2354
- #line 1973 "informix.ec"
2591
+ #line 2118 "informixc.ec"
2355
2592
  }
2356
2593
  return self;
2357
2594
  }
@@ -2372,6 +2609,20 @@ database_transfail(VALUE self)
2372
2609
  * otherwise.
2373
2610
  *
2374
2611
  * Returns __self__.
2612
+ *
2613
+ * Examples:
2614
+ *
2615
+ * A bulk insert using an insert cursor. Requires a transaction:
2616
+ * db.transaction do |db|
2617
+ * db.cursor('insert into stock values(?, ?, ?, ?, ?, ?)') |cur|
2618
+ * cur.open
2619
+ * # Loading a file separated by '|'
2620
+ * File.open(filename).each do |line|
2621
+ * fields = line.split('|')
2622
+ * cur.put(*fields)
2623
+ * end
2624
+ * end
2625
+ * end
2375
2626
  */
2376
2627
  static VALUE
2377
2628
  rb_database_transaction(VALUE self)
@@ -2380,13 +2631,13 @@ rb_database_transaction(VALUE self)
2380
2631
  /*
2381
2632
  * EXEC SQL begin declare section;
2382
2633
  */
2383
- #line 1998 "informix.ec"
2384
- #line 1999 "informix.ec"
2634
+ #line 2157 "informixc.ec"
2635
+ #line 2158 "informixc.ec"
2385
2636
  char *did;
2386
2637
  /*
2387
2638
  * EXEC SQL end declare section;
2388
2639
  */
2389
- #line 2000 "informix.ec"
2640
+ #line 2159 "informixc.ec"
2390
2641
 
2391
2642
 
2392
2643
  Data_Get_Struct(self, char, did);
@@ -2394,11 +2645,11 @@ rb_database_transaction(VALUE self)
2394
2645
  /*
2395
2646
  * EXEC SQL set connection :did;
2396
2647
  */
2397
- #line 2004 "informix.ec"
2648
+ #line 2163 "informixc.ec"
2398
2649
  {
2399
- #line 2004 "informix.ec"
2650
+ #line 2163 "informixc.ec"
2400
2651
  sqli_connect_set(0, did, 0);
2401
- #line 2004 "informix.ec"
2652
+ #line 2163 "informixc.ec"
2402
2653
  }
2403
2654
  if (SQLCODE < 0)
2404
2655
  raise_ifx_extended();
@@ -2406,117 +2657,37 @@ rb_database_transaction(VALUE self)
2406
2657
  /*
2407
2658
  * EXEC SQL commit;
2408
2659
  */
2409
- #line 2008 "informix.ec"
2660
+ #line 2167 "informixc.ec"
2410
2661
  {
2411
- #line 2008 "informix.ec"
2662
+ #line 2167 "informixc.ec"
2412
2663
  sqli_trans_commit();
2413
- #line 2008 "informix.ec"
2664
+ #line 2167 "informixc.ec"
2414
2665
  }
2415
2666
 
2416
2667
  /*
2417
2668
  * EXEC SQL begin work;
2418
2669
  */
2419
- #line 2010 "informix.ec"
2670
+ #line 2169 "informixc.ec"
2420
2671
  {
2421
- #line 2010 "informix.ec"
2672
+ #line 2169 "informixc.ec"
2422
2673
  sqli_trans_begin2((mint)1);
2423
- #line 2010 "informix.ec"
2674
+ #line 2169 "informixc.ec"
2424
2675
  }
2425
2676
  ret = rb_rescue(rb_yield, self, database_transfail, self);
2426
2677
  if (ret == Qundef)
2427
- rb_raise(esyms.eOperationalError, "Transaction rolled back");
2678
+ rb_raise(rb_eOperationalError, "Transaction rolled back");
2428
2679
  /*
2429
2680
  * EXEC SQL commit;
2430
2681
  */
2431
- #line 2014 "informix.ec"
2682
+ #line 2173 "informixc.ec"
2432
2683
  {
2433
- #line 2014 "informix.ec"
2684
+ #line 2173 "informixc.ec"
2434
2685
  sqli_trans_commit();
2435
- #line 2014 "informix.ec"
2686
+ #line 2173 "informixc.ec"
2436
2687
  }
2437
2688
  return self;
2438
2689
  }
2439
2690
 
2440
- static VALUE statement_s_new(int, VALUE *, VALUE);
2441
- /*
2442
- * call-seq:
2443
- * db.prepare(query) => statement
2444
- * db.prepare(query) {|stmt| block } => obj
2445
- *
2446
- * Creates a <code>Statement</code> object based on <i>query</i>.
2447
- * In the first form the Statement object is returned.
2448
- * In the second form the Statement object is passed to the block and when it
2449
- * terminates, the Statement object is dropped, returning the value of the
2450
- * block.
2451
- *
2452
- * <i>query</i> may contain '?' placeholders for input parameters;
2453
- * it must not be a query returning more than one row
2454
- * (use <code>Database#cursor</code> instead.)
2455
- */
2456
- static VALUE
2457
- rb_database_prepare(VALUE self, VALUE query)
2458
- {
2459
- VALUE argv[2];
2460
-
2461
- argv[0] = self; argv[1] = query;
2462
- return statement_s_new(2, argv, rb_cStatement);
2463
- }
2464
-
2465
- static VALUE rb_cursor_s_new(int argc, VALUE *argv, VALUE klass);
2466
- /*
2467
- * call-seq:
2468
- * db.cursor(query, options = nil) => cursor
2469
- *
2470
- * Returns a <code>Cursor</code> object based on <i>query</i>.
2471
- * <i>query</i> may contain '?' placeholders for input parameters.
2472
- *
2473
- * <i>options</i> must be a hash with the following possible keys:
2474
- *
2475
- * :scroll => true or false
2476
- * :hold => true or false
2477
- *
2478
- */
2479
- static VALUE
2480
- rb_database_cursor(int argc, VALUE *argv, VALUE self)
2481
- {
2482
- VALUE arg[3];
2483
-
2484
- arg[0] = self;
2485
- rb_scan_args(argc, argv, "11", &arg[1], &arg[2]);
2486
- return rb_cursor_s_new(3, arg, rb_cCursor);
2487
- }
2488
-
2489
- /*
2490
- * call-seq:
2491
- * db.slob(type = Slob::CLOB, options = nil) => slob
2492
- * db.slob(type = Slob::CLOB, options = nil) {|slob| block } => obj
2493
- *
2494
- * Creates a Smart Large Object of type <i>type</i>.
2495
- * Returns a <code>Slob</code> object pointing to it.
2496
- *
2497
- * <i>type</i> can be Slob::BLOB or Slob::CLOB
2498
- *
2499
- * <i>options</i> can be nil or a Hash object with the following possible keys:
2500
- *
2501
- * :sbspace => Sbspace name
2502
- * :estbytes => Estimated size, in bytes
2503
- * :extsz => Allocation extent size
2504
- * :createflags => Create-time flags
2505
- * :openflags => Access mode
2506
- * :maxbytes => Maximum size
2507
- * :col_info => Get the previous values from the column-level storage
2508
- * characteristics for the specified database column
2509
- */
2510
- static VALUE
2511
- rb_database_slob(int argc, VALUE *argv, VALUE self)
2512
- {
2513
- VALUE arg[3];
2514
-
2515
- arg[0] = self;
2516
- rb_scan_args(argc, argv, "02", &arg[1], &arg[2]);
2517
- return rb_slob_s_new(3, arg, rb_cSlob);
2518
- }
2519
-
2520
2691
  /*
2521
2692
  * call-seq:
2522
2693
  * db.columns(tablename) => array
@@ -2543,8 +2714,8 @@ rb_database_columns(VALUE self, VALUE tablename)
2543
2714
  /*
2544
2715
  * EXEC SQL begin declare section;
2545
2716
  */
2546
- #line 2121 "informix.ec"
2547
- #line 2122 "informix.ec"
2717
+ #line 2200 "informixc.ec"
2718
+ #line 2201 "informixc.ec"
2548
2719
  char *did, *cid;
2549
2720
  char *tabname;
2550
2721
  int tabid, xid;
@@ -2555,7 +2726,7 @@ short coltype, collength;
2555
2726
  /*
2556
2727
  * EXEC SQL end declare section;
2557
2728
  */
2558
- #line 2129 "informix.ec"
2729
+ #line 2208 "informixc.ec"
2559
2730
 
2560
2731
 
2561
2732
  Data_Get_Struct(self, char, did);
@@ -2563,11 +2734,11 @@ short coltype, collength;
2563
2734
  /*
2564
2735
  * EXEC SQL set connection :did;
2565
2736
  */
2566
- #line 2133 "informix.ec"
2737
+ #line 2212 "informixc.ec"
2567
2738
  {
2568
- #line 2133 "informix.ec"
2739
+ #line 2212 "informixc.ec"
2569
2740
  sqli_connect_set(0, did, 0);
2570
- #line 2133 "informix.ec"
2741
+ #line 2212 "informixc.ec"
2571
2742
  }
2572
2743
  if (SQLCODE < 0)
2573
2744
  raise_ifx_extended();
@@ -2577,39 +2748,39 @@ short coltype, collength;
2577
2748
  /*
2578
2749
  * EXEC SQL select tabid into :tabid from systables where tabname = :tabname;
2579
2750
  */
2580
- #line 2139 "informix.ec"
2751
+ #line 2218 "informixc.ec"
2581
2752
  {
2582
- #line 2139 "informix.ec"
2753
+ #line 2218 "informixc.ec"
2583
2754
  static const char *sqlcmdtxt[] =
2584
- #line 2139 "informix.ec"
2755
+ #line 2218 "informixc.ec"
2585
2756
  {
2586
- #line 2139 "informix.ec"
2757
+ #line 2218 "informixc.ec"
2587
2758
  "select tabid from systables where tabname = ?",
2588
2759
  0
2589
2760
  };
2590
- #line 2139 "informix.ec"
2761
+ #line 2218 "informixc.ec"
2591
2762
  static ifx_cursor_t _SQ0 = {0};
2592
2763
  static ifx_sqlvar_t _sqibind[] =
2593
2764
  {
2594
2765
  { 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2595
- #line 2139 "informix.ec"
2766
+ #line 2218 "informixc.ec"
2596
2767
  };
2597
2768
  static ifx_sqlvar_t _sqobind[] =
2598
2769
  {
2599
2770
  { 102, sizeof(tabid), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2600
- #line 2139 "informix.ec"
2771
+ #line 2218 "informixc.ec"
2601
2772
  };
2602
- #line 2139 "informix.ec"
2773
+ #line 2218 "informixc.ec"
2603
2774
  _sqibind[0].sqldata = tabname;
2604
- #line 2139 "informix.ec"
2775
+ #line 2218 "informixc.ec"
2605
2776
  _sqobind[0].sqldata = (char *) &tabid;
2606
- #line 2139 "informix.ec"
2777
+ #line 2218 "informixc.ec"
2607
2778
  sqli_slct(ESQLINTVERSION, &_SQ0,sqlcmdtxt,1,_sqibind,1,_sqobind,0,(ifx_literal_t *)0,(ifx_namelist_t *)0,0);
2608
- #line 2139 "informix.ec"
2779
+ #line 2218 "informixc.ec"
2609
2780
  }
2610
2781
 
2611
2782
  if (SQLCODE == SQLNOTFOUND)
2612
- rb_raise(esyms.eProgrammingError, "Table '%s' doesn't exist", tabname);
2783
+ rb_raise(rb_eProgrammingError, "Table '%s' doesn't exist", tabname);
2613
2784
 
2614
2785
  result = rb_ary_new();
2615
2786
 
@@ -2619,13 +2790,13 @@ static ifx_cursor_t _SQ0 = {0};
2619
2790
  /*
2620
2791
  * EXEC SQL begin declare section;
2621
2792
  */
2622
- #line 2149 "informix.ec"
2623
- #line 2150 "informix.ec"
2793
+ #line 2228 "informixc.ec"
2794
+ #line 2229 "informixc.ec"
2624
2795
  char sid[IDSIZE];
2625
2796
  /*
2626
2797
  * EXEC SQL end declare section;
2627
2798
  */
2628
- #line 2151 "informix.ec"
2799
+ #line 2230 "informixc.ec"
2629
2800
 
2630
2801
 
2631
2802
  snprintf(sid, IDSIZE, "COLS%lX", self);
@@ -2640,20 +2811,20 @@ static ifx_cursor_t _SQ0 = {0};
2640
2811
  * and c.colno = d.colno
2641
2812
  * order by c.colno';
2642
2813
  */
2643
- #line 2156 "informix.ec"
2814
+ #line 2235 "informixc.ec"
2644
2815
  {
2645
- #line 2162 "informix.ec"
2816
+ #line 2241 "informixc.ec"
2646
2817
  sqli_prep(ESQLINTVERSION, sid, "select colname, coltype, collength, extended_id, type, default, c.colno from syscolumns c, outer sysdefaults d where c.tabid = ? and c.tabid = d.tabid and c.colno = d.colno order by c.colno",(ifx_literal_t *)0, (ifx_namelist_t *)0, 2, 0, 0 );
2647
- #line 2162 "informix.ec"
2818
+ #line 2241 "informixc.ec"
2648
2819
  }
2649
2820
  /*
2650
2821
  * EXEC SQL declare :cid cursor for :sid;
2651
2822
  */
2652
- #line 2163 "informix.ec"
2823
+ #line 2242 "informixc.ec"
2653
2824
  {
2654
- #line 2163 "informix.ec"
2825
+ #line 2242 "informixc.ec"
2655
2826
  sqli_curs_decl_dynm(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 0), cid, sqli_curs_locate(ESQLINTVERSION, sid, 1), 0, 0);
2656
- #line 2163 "informix.ec"
2827
+ #line 2242 "informixc.ec"
2657
2828
  }
2658
2829
  if (SQLCODE < 0) {
2659
2830
  cid[0] = 0;
@@ -2664,19 +2835,19 @@ static ifx_cursor_t _SQ0 = {0};
2664
2835
  /*
2665
2836
  * EXEC SQL open :cid using :tabid;
2666
2837
  */
2667
- #line 2170 "informix.ec"
2838
+ #line 2249 "informixc.ec"
2668
2839
  {
2669
- #line 2170 "informix.ec"
2840
+ #line 2249 "informixc.ec"
2670
2841
  static ifx_sqlvar_t _sqibind[] =
2671
2842
  {
2672
2843
  { 102, sizeof(tabid), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2673
- #line 2170 "informix.ec"
2844
+ #line 2249 "informixc.ec"
2674
2845
  };
2675
2846
  static ifx_sqlda_t _SD0 = { 1, _sqibind, {0}, 1, 0 };
2676
- #line 2170 "informix.ec"
2847
+ #line 2249 "informixc.ec"
2677
2848
  _sqibind[0].sqldata = (char *) &tabid;
2678
2849
  sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), &_SD0, (char *)0, (struct value *)0, 1, 0);
2679
- #line 2170 "informix.ec"
2850
+ #line 2249 "informixc.ec"
2680
2851
  }
2681
2852
  if (SQLCODE < 0)
2682
2853
  raise_ifx_extended();
@@ -2686,9 +2857,9 @@ static ifx_cursor_t _SQ0 = {0};
2686
2857
  * EXEC SQL fetch :cid into :colname, :coltype, :collength, :xid,
2687
2858
  * :deftype, :defvalue;
2688
2859
  */
2689
- #line 2175 "informix.ec"
2860
+ #line 2254 "informixc.ec"
2690
2861
  {
2691
- #line 2176 "informix.ec"
2862
+ #line 2255 "informixc.ec"
2692
2863
  static ifx_sqlvar_t _sqobind[] =
2693
2864
  {
2694
2865
  { 114, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -2697,24 +2868,24 @@ static ifx_cursor_t _SQ0 = {0};
2697
2868
  { 102, sizeof(xid), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2698
2869
  { 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2699
2870
  { 114, 257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
2700
- #line 2176 "informix.ec"
2871
+ #line 2255 "informixc.ec"
2701
2872
  };
2702
2873
  static ifx_sqlda_t _SD0 = { 6, _sqobind, {0}, 6, 0 };
2703
2874
  static _FetchSpec _FS1 = { 0, 1, 0 };
2704
- #line 2176 "informix.ec"
2875
+ #line 2255 "informixc.ec"
2705
2876
  _sqobind[0].sqldata = colname;
2706
- #line 2176 "informix.ec"
2877
+ #line 2255 "informixc.ec"
2707
2878
  _sqobind[1].sqldata = (char *) &coltype;
2708
- #line 2176 "informix.ec"
2879
+ #line 2255 "informixc.ec"
2709
2880
  _sqobind[2].sqldata = (char *) &collength;
2710
- #line 2176 "informix.ec"
2881
+ #line 2255 "informixc.ec"
2711
2882
  _sqobind[3].sqldata = (char *) &xid;
2712
- #line 2176 "informix.ec"
2883
+ #line 2255 "informixc.ec"
2713
2884
  _sqobind[4].sqldata = deftype;
2714
- #line 2176 "informix.ec"
2885
+ #line 2255 "informixc.ec"
2715
2886
  _sqobind[5].sqldata = defvalue;
2716
2887
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, &_SD0, (char *)0, &_FS1);
2717
- #line 2176 "informix.ec"
2888
+ #line 2255 "informixc.ec"
2718
2889
  }
2719
2890
  if (SQLCODE < 0)
2720
2891
  raise_ifx_extended();
@@ -2812,11 +2983,11 @@ static ifx_cursor_t _SQ0 = {0};
2812
2983
  /*
2813
2984
  * EXEC SQL close :cid;
2814
2985
  */
2815
- #line 2270 "informix.ec"
2986
+ #line 2349 "informixc.ec"
2816
2987
  {
2817
- #line 2270 "informix.ec"
2988
+ #line 2349 "informixc.ec"
2818
2989
  sqli_curs_close(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256));
2819
- #line 2270 "informix.ec"
2990
+ #line 2349 "informixc.ec"
2820
2991
  }
2821
2992
 
2822
2993
  return result;
@@ -2837,46 +3008,52 @@ statement_mark(cursor_t *c)
2837
3008
  }
2838
3009
 
2839
3010
  static void
2840
- statement_free(void *p)
3011
+ st_free(cursor_t *c)
2841
3012
  {
2842
3013
  /*
2843
3014
  * EXEC SQL begin declare section;
2844
3015
  */
2845
- #line 2292 "informix.ec"
2846
- #line 2293 "informix.ec"
3016
+ #line 2371 "informixc.ec"
3017
+ #line 2372 "informixc.ec"
2847
3018
  char *sid, *did;
2848
3019
  /*
2849
3020
  * EXEC SQL end declare section;
2850
3021
  */
2851
- #line 2294 "informix.ec"
3022
+ #line 2373 "informixc.ec"
2852
3023
 
2853
3024
 
2854
- free_input_slots(p);
2855
- free_output_slots(p);
3025
+ free_input_slots(c);
3026
+ free_output_slots(c);
2856
3027
 
2857
- did = ((cursor_t *)p)->database_id;
3028
+ did = c->database_id;
2858
3029
  /*
2859
3030
  * EXEC SQL set connection :did;
2860
3031
  */
2861
- #line 2300 "informix.ec"
3032
+ #line 2379 "informixc.ec"
2862
3033
  {
2863
- #line 2300 "informix.ec"
3034
+ #line 2379 "informixc.ec"
2864
3035
  sqli_connect_set(0, did, 0);
2865
- #line 2300 "informix.ec"
3036
+ #line 2379 "informixc.ec"
2866
3037
  }
2867
- if (SQLCODE >= 0) {
2868
- sid = ((cursor_t *)p)->stmt_id;
3038
+ if (SQLCODE < 0)
3039
+ return;
3040
+
3041
+ sid = c->stmt_id;
2869
3042
  /*
2870
- * EXEC SQL free :sid;
3043
+ * EXEC SQL free :sid;
2871
3044
  */
2872
- #line 2303 "informix.ec"
3045
+ #line 2384 "informixc.ec"
2873
3046
  {
2874
- #line 2303 "informix.ec"
3047
+ #line 2384 "informixc.ec"
2875
3048
  sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 258));
2876
- #line 2303 "informix.ec"
3049
+ #line 2384 "informixc.ec"
2877
3050
  }
2878
- }
3051
+ }
2879
3052
 
3053
+ static void
3054
+ statement_free(void *p)
3055
+ {
3056
+ st_free(p);
2880
3057
  xfree(p);
2881
3058
  }
2882
3059
 
@@ -2890,32 +3067,33 @@ statement_alloc(VALUE klass)
2890
3067
  return Data_Wrap_Struct(klass, statement_mark, statement_free, c);
2891
3068
  }
2892
3069
 
3070
+ /* :nodoc: */
2893
3071
  static VALUE
2894
- statement_initialize(VALUE self, VALUE db, VALUE query)
3072
+ rb_statement_initialize(VALUE self, VALUE db, VALUE query)
2895
3073
  {
2896
3074
  struct sqlda *output;
2897
3075
  cursor_t *c;
2898
3076
  /*
2899
3077
  * EXEC SQL begin declare section;
2900
3078
  */
2901
- #line 2324 "informix.ec"
2902
- #line 2325 "informix.ec"
3079
+ #line 2410 "informixc.ec"
3080
+ #line 2411 "informixc.ec"
2903
3081
  char *c_query, *sid, *did;
2904
3082
  /*
2905
3083
  * EXEC SQL end declare section;
2906
3084
  */
2907
- #line 2326 "informix.ec"
3085
+ #line 2412 "informixc.ec"
2908
3086
 
2909
3087
 
2910
3088
  Data_Get_Struct(db, char, did);
2911
3089
  /*
2912
3090
  * EXEC SQL set connection :did;
2913
3091
  */
2914
- #line 2329 "informix.ec"
3092
+ #line 2415 "informixc.ec"
2915
3093
  {
2916
- #line 2329 "informix.ec"
3094
+ #line 2415 "informixc.ec"
2917
3095
  sqli_connect_set(0, did, 0);
2918
- #line 2329 "informix.ec"
3096
+ #line 2415 "informixc.ec"
2919
3097
  }
2920
3098
  if (SQLCODE < 0)
2921
3099
  raise_ifx_extended();
@@ -2931,11 +3109,11 @@ statement_initialize(VALUE self, VALUE db, VALUE query)
2931
3109
  /*
2932
3110
  * EXEC SQL prepare :sid from :c_query;
2933
3111
  */
2934
- #line 2341 "informix.ec"
3112
+ #line 2427 "informixc.ec"
2935
3113
  {
2936
- #line 2341 "informix.ec"
3114
+ #line 2427 "informixc.ec"
2937
3115
  sqli_prep(ESQLINTVERSION, sid, c_query,(ifx_literal_t *)0, (ifx_namelist_t *)0, -1, 0, 0 );
2938
- #line 2341 "informix.ec"
3116
+ #line 2427 "informixc.ec"
2939
3117
  }
2940
3118
  if (SQLCODE < 0)
2941
3119
  raise_ifx_extended();
@@ -2944,11 +3122,11 @@ statement_initialize(VALUE self, VALUE db, VALUE query)
2944
3122
  /*
2945
3123
  * EXEC SQL describe :sid into output;
2946
3124
  */
2947
- #line 2346 "informix.ec"
3125
+ #line 2432 "informixc.ec"
2948
3126
  {
2949
- #line 2346 "informix.ec"
3127
+ #line 2432 "informixc.ec"
2950
3128
  sqli_describe_stmt(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), &output, 0);
2951
- #line 2346 "informix.ec"
3129
+ #line 2432 "informixc.ec"
2952
3130
  }
2953
3131
  c->daOutput = output;
2954
3132
 
@@ -2964,61 +3142,44 @@ statement_initialize(VALUE self, VALUE db, VALUE query)
2964
3142
  return self;
2965
3143
  }
2966
3144
 
2967
- static VALUE statement_drop(VALUE);
2968
- /*
2969
- * call-seq:
2970
- * Statement.new(database, query) => statement
2971
- * Statement.new(database, query) {|stmt| block } => obj
2972
- *
2973
- * Creates a <code>Statement</code> object based on <i>query</i> in the
2974
- * context of <i>database</i>.
2975
- * In the first form the <code>Statement</code> object is returned.
2976
- * In the second form the Statement object is passed to the block and when it
2977
- * terminates, the Statement object is dropped, returning the value of the
2978
- * block.
2979
- *
2980
- * <i>query</i> may contain '?' placeholders for input parameters;
2981
- * it must not be a query returning more than one row
2982
- * (use <code>Cursor</code> instead.)
2983
- */
2984
- static VALUE
2985
- statement_s_new(int argc, VALUE *argv, VALUE klass)
2986
- {
2987
- VALUE stmt;
2988
-
2989
- stmt = rb_class_new_instance(argc, argv, klass);
2990
-
2991
- if (rb_block_given_p())
2992
- return rb_ensure(rb_yield, stmt, statement_drop, stmt);
2993
-
2994
- return stmt;
2995
- }
2996
-
2997
3145
  /*
2998
3146
  * call-seq:
2999
- * stmt[*params] => fixnum or hash
3147
+ * st[*params] => fixnum or hash
3000
3148
  *
3001
3149
  * Executes the previously prepared statement, binding <i>params</i> as
3002
3150
  * input parameters.
3003
3151
  *
3004
3152
  * Returns the record retrieved, in the case of a singleton select, or the
3005
3153
  * number of rows affected, in the case of any other statement.
3154
+ *
3155
+ * Examples:
3156
+ *
3157
+ * Inserting records:
3158
+ * db.prepare('insert into state values(?, ?)') do |st|
3159
+ * st.execute('CA', 'California')
3160
+ * st.call('AZ', 'Arizona')
3161
+ * st['TX', 'Texas')
3162
+ * end
3163
+ * Selecting one record (returns a hash):
3164
+ * cust = db.prepare('select * from customer where num = 101') do |st|
3165
+ * st.execute
3166
+ * end
3006
3167
  */
3007
3168
  static VALUE
3008
- statement_call(int argc, VALUE *argv, VALUE self)
3169
+ rb_statement_call(int argc, VALUE *argv, VALUE self)
3009
3170
  {
3010
3171
  struct sqlda *input, *output;
3011
3172
  cursor_t *c;
3012
3173
  /*
3013
3174
  * EXEC SQL begin declare section;
3014
3175
  */
3015
- #line 2406 "informix.ec"
3016
- #line 2407 "informix.ec"
3176
+ #line 2475 "informixc.ec"
3177
+ #line 2476 "informixc.ec"
3017
3178
  char *sid, *did;
3018
3179
  /*
3019
3180
  * EXEC SQL end declare section;
3020
3181
  */
3021
- #line 2408 "informix.ec"
3182
+ #line 2477 "informixc.ec"
3022
3183
 
3023
3184
 
3024
3185
  Data_Get_Struct(self, cursor_t, c);
@@ -3027,11 +3188,11 @@ statement_call(int argc, VALUE *argv, VALUE self)
3027
3188
  /*
3028
3189
  * EXEC SQL set connection :did;
3029
3190
  */
3030
- #line 2413 "informix.ec"
3191
+ #line 2482 "informixc.ec"
3031
3192
  {
3032
- #line 2413 "informix.ec"
3193
+ #line 2482 "informixc.ec"
3033
3194
  sqli_connect_set(0, did, 0);
3034
- #line 2413 "informix.ec"
3195
+ #line 2482 "informixc.ec"
3035
3196
  }
3036
3197
  if (SQLCODE < 0)
3037
3198
  raise_ifx_extended();
@@ -3051,11 +3212,11 @@ statement_call(int argc, VALUE *argv, VALUE self)
3051
3212
  * EXEC SQL execute :sid into descriptor output
3052
3213
  * using descriptor input;
3053
3214
  */
3054
- #line 2428 "informix.ec"
3215
+ #line 2497 "informixc.ec"
3055
3216
  {
3056
- #line 2429 "informix.ec"
3217
+ #line 2498 "informixc.ec"
3057
3218
  sqli_exec(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), input, (char *)0, (struct value *)0, output, (char *)0, (struct value *)0, 0);
3058
- #line 2429 "informix.ec"
3219
+ #line 2498 "informixc.ec"
3059
3220
  }
3060
3221
  clean_input_slots(c);
3061
3222
  }
@@ -3063,11 +3224,11 @@ statement_call(int argc, VALUE *argv, VALUE self)
3063
3224
  /*
3064
3225
  * EXEC SQL execute :sid into descriptor output;
3065
3226
  */
3066
- #line 2433 "informix.ec"
3227
+ #line 2502 "informixc.ec"
3067
3228
  {
3068
- #line 2433 "informix.ec"
3229
+ #line 2502 "informixc.ec"
3069
3230
  sqli_exec(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, output, (char *)0, (struct value *)0, 0);
3070
- #line 2433 "informix.ec"
3231
+ #line 2502 "informixc.ec"
3071
3232
  }
3072
3233
 
3073
3234
  if (SQLCODE < 0)
@@ -3083,11 +3244,11 @@ statement_call(int argc, VALUE *argv, VALUE self)
3083
3244
  /*
3084
3245
  * EXEC SQL execute :sid using descriptor input;
3085
3246
  */
3086
- #line 2445 "informix.ec"
3247
+ #line 2514 "informixc.ec"
3087
3248
  {
3088
- #line 2445 "informix.ec"
3249
+ #line 2514 "informixc.ec"
3089
3250
  sqli_exec(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), input, (char *)0, (struct value *)0, (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0);
3090
- #line 2445 "informix.ec"
3251
+ #line 2514 "informixc.ec"
3091
3252
  }
3092
3253
  clean_input_slots(c);
3093
3254
  }
@@ -3095,11 +3256,11 @@ statement_call(int argc, VALUE *argv, VALUE self)
3095
3256
  /*
3096
3257
  * EXEC SQL execute :sid;
3097
3258
  */
3098
- #line 2449 "informix.ec"
3259
+ #line 2518 "informixc.ec"
3099
3260
  {
3100
- #line 2449 "informix.ec"
3261
+ #line 2518 "informixc.ec"
3101
3262
  sqli_exec(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0);
3102
- #line 2449 "informix.ec"
3263
+ #line 2518 "informixc.ec"
3103
3264
  }
3104
3265
  }
3105
3266
  if (SQLCODE < 0)
@@ -3110,64 +3271,29 @@ statement_call(int argc, VALUE *argv, VALUE self)
3110
3271
 
3111
3272
  /*
3112
3273
  * call-seq:
3113
- * stmt.drop
3274
+ * st.drop
3114
3275
  *
3115
3276
  * Frees the statement and the memory associated with it.
3116
3277
  */
3117
3278
  static VALUE
3118
- statement_drop(VALUE self)
3279
+ rb_statement_drop(VALUE self)
3119
3280
  {
3120
3281
  cursor_t *c;
3121
- /*
3122
- * EXEC SQL begin declare section;
3123
- */
3124
- #line 2467 "informix.ec"
3125
- #line 2468 "informix.ec"
3126
- char *sid, *did;
3127
- /*
3128
- * EXEC SQL end declare section;
3129
- */
3130
- #line 2469 "informix.ec"
3131
-
3132
3282
 
3133
3283
  Data_Get_Struct(self, cursor_t, c);
3134
- free_input_slots(c);
3135
- free_output_slots(c);
3136
-
3137
- did = c->database_id;
3138
- /*
3139
- * EXEC SQL set connection :did;
3140
- */
3141
- #line 2476 "informix.ec"
3142
- {
3143
- #line 2476 "informix.ec"
3144
- sqli_connect_set(0, did, 0);
3145
- #line 2476 "informix.ec"
3146
- }
3147
- if (SQLCODE < 0)
3148
- return Qnil;
3149
- sid = c->stmt_id;
3150
- /*
3151
- * EXEC SQL free :sid;
3152
- */
3153
- #line 2480 "informix.ec"
3154
- {
3155
- #line 2480 "informix.ec"
3156
- sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 258));
3157
- #line 2480 "informix.ec"
3158
- }
3284
+ st_free(c);
3159
3285
 
3160
3286
  return Qnil;
3161
3287
  }
3162
3288
 
3163
- /* module SequentialCursor ----------------------------------------------- */
3289
+ /* class SequentialCursor ------------------------------------------------ */
3164
3290
 
3165
3291
  /* Decides whether to use an Array or a Hash, and instantiate a new
3166
3292
  * object or reuse an existing one.
3167
3293
  */
3168
3294
  #define RECORD(c, type, bang, record) \
3169
3295
  do {\
3170
- if (type == T_ARRAY) {\
3296
+ if (type == rb_cArray) {\
3171
3297
  if (bang) {\
3172
3298
  if (!c->array)\
3173
3299
  c->array = rb_ary_new2(c->daOutput->sqld);\
@@ -3191,36 +3317,37 @@ do {\
3191
3317
  * Base function for fetch* methods, except *_many
3192
3318
  */
3193
3319
  static VALUE
3194
- fetch(VALUE self, VALUE type, int bang)
3320
+ fetch(VALUE self, VALUE type, VALUE bang)
3195
3321
  {
3196
3322
  /*
3197
3323
  * EXEC SQL begin declare section;
3198
3324
  */
3199
- #line 2518 "informix.ec"
3200
- #line 2519 "informix.ec"
3325
+ #line 2576 "informixc.ec"
3326
+ #line 2577 "informixc.ec"
3201
3327
  char *cid, *did;
3202
3328
  /*
3203
3329
  * EXEC SQL end declare section;
3204
3330
  */
3205
- #line 2520 "informix.ec"
3331
+ #line 2578 "informixc.ec"
3206
3332
 
3333
+ short c_bang;
3207
3334
  cursor_t *c;
3208
3335
  struct sqlda *output;
3209
3336
  VALUE record;
3210
3337
 
3211
3338
  Data_Get_Struct(self, cursor_t, c);
3212
3339
  if (!c->is_open)
3213
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3340
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3214
3341
 
3215
3342
  did = c->database_id;
3216
3343
  /*
3217
3344
  * EXEC SQL set connection :did;
3218
3345
  */
3219
- #line 2530 "informix.ec"
3346
+ #line 2589 "informixc.ec"
3220
3347
  {
3221
- #line 2530 "informix.ec"
3348
+ #line 2589 "informixc.ec"
3222
3349
  sqli_connect_set(0, did, 0);
3223
- #line 2530 "informix.ec"
3350
+ #line 2589 "informixc.ec"
3224
3351
  }
3225
3352
  if (SQLCODE < 0)
3226
3353
  raise_ifx_extended();
@@ -3231,12 +3358,12 @@ fetch(VALUE self, VALUE type, int bang)
3231
3358
  /*
3232
3359
  * EXEC SQL fetch :cid using descriptor output;
3233
3360
  */
3234
- #line 2537 "informix.ec"
3361
+ #line 2596 "informixc.ec"
3235
3362
  {
3236
- #line 2537 "informix.ec"
3363
+ #line 2596 "informixc.ec"
3237
3364
  static _FetchSpec _FS0 = { 0, 1, 0 };
3238
3365
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, output, (char *)0, &_FS0);
3239
- #line 2537 "informix.ec"
3366
+ #line 2596 "informixc.ec"
3240
3367
  }
3241
3368
  if (SQLCODE < 0)
3242
3369
  raise_ifx_extended();
@@ -3244,72 +3371,11 @@ fetch(VALUE self, VALUE type, int bang)
3244
3371
  if (SQLCODE == SQLNOTFOUND)
3245
3372
  return Qnil;
3246
3373
 
3247
- RECORD(c, type, bang, record);
3374
+ c_bang = RTEST(bang);
3375
+ RECORD(c, type, c_bang, record);
3248
3376
  return make_result(c, record);
3249
3377
  }
3250
3378
 
3251
- /*
3252
- * call-seq:
3253
- * cursor.fetch => array or nil
3254
- *
3255
- * Fetches the next record.
3256
- *
3257
- * Returns the record fetched as an array, or nil if there are no
3258
- * records left.
3259
- */
3260
- static VALUE
3261
- seqcur_fetch(VALUE self)
3262
- {
3263
- return fetch(self, T_ARRAY, 0);
3264
- }
3265
-
3266
- /*
3267
- * call-seq:
3268
- * cursor.fetch! => array or nil
3269
- *
3270
- * Fetches the next record, storing it in the same Array object every time
3271
- * it is called.
3272
- *
3273
- * Returns the record fetched as an array, or nil if there are no
3274
- * records left.
3275
- */
3276
- static VALUE
3277
- seqcur_fetch_bang(VALUE self)
3278
- {
3279
- return fetch(self, T_ARRAY, 1);
3280
- }
3281
-
3282
- /*
3283
- * call-seq:
3284
- * cursor.fetch_hash => hash or nil
3285
- *
3286
- * Fetches the next record.
3287
- *
3288
- * Returns the record fetched as a hash, or nil if there are no
3289
- * records left.
3290
- */
3291
- static VALUE
3292
- seqcur_fetch_hash(VALUE self)
3293
- {
3294
- return fetch(self, T_HASH, 0);
3295
- }
3296
-
3297
- /*
3298
- * call-seq:
3299
- * cursor.fetch_hash! => hash or nil
3300
- *
3301
- * Fetches the next record, storing it in the same Hash object every time
3302
- * it is called.
3303
- *
3304
- * Returns the record fetched as a hash, or nil if there are no
3305
- * records left.
3306
- */
3307
- static VALUE
3308
- seqcur_fetch_hash_bang(VALUE self)
3309
- {
3310
- return fetch(self, T_HASH, 1);
3311
- }
3312
-
3313
3379
  /*
3314
3380
  * Base function for fetch*_many, fetch*_all and each_by methods
3315
3381
  */
@@ -3319,13 +3385,13 @@ fetch_many(VALUE self, VALUE n, VALUE type)
3319
3385
  /*
3320
3386
  * EXEC SQL begin declare section;
3321
3387
  */
3322
- #line 2616 "informix.ec"
3323
- #line 2617 "informix.ec"
3388
+ #line 2614 "informixc.ec"
3389
+ #line 2615 "informixc.ec"
3324
3390
  char *cid, *did;
3325
3391
  /*
3326
3392
  * EXEC SQL end declare section;
3327
3393
  */
3328
- #line 2618 "informix.ec"
3394
+ #line 2616 "informixc.ec"
3329
3395
 
3330
3396
  cursor_t *c;
3331
3397
  struct sqlda *output;
@@ -3335,17 +3401,17 @@ fetch_many(VALUE self, VALUE n, VALUE type)
3335
3401
 
3336
3402
  Data_Get_Struct(self, cursor_t, c);
3337
3403
  if (!c->is_open)
3338
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3404
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3339
3405
 
3340
3406
  did = c->database_id;
3341
3407
  /*
3342
3408
  * EXEC SQL set connection :did;
3343
3409
  */
3344
- #line 2630 "informix.ec"
3410
+ #line 2628 "informixc.ec"
3345
3411
  {
3346
- #line 2630 "informix.ec"
3412
+ #line 2628 "informixc.ec"
3347
3413
  sqli_connect_set(0, did, 0);
3348
- #line 2630 "informix.ec"
3414
+ #line 2628 "informixc.ec"
3349
3415
  }
3350
3416
  if (SQLCODE < 0)
3351
3417
  raise_ifx_extended();
@@ -3365,12 +3431,12 @@ fetch_many(VALUE self, VALUE n, VALUE type)
3365
3431
  /*
3366
3432
  * EXEC SQL fetch :cid using descriptor output;
3367
3433
  */
3368
- #line 2646 "informix.ec"
3434
+ #line 2644 "informixc.ec"
3369
3435
  {
3370
- #line 2646 "informix.ec"
3436
+ #line 2644 "informixc.ec"
3371
3437
  static _FetchSpec _FS0 = { 0, 1, 0 };
3372
3438
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, output, (char *)0, &_FS0);
3373
- #line 2646 "informix.ec"
3439
+ #line 2644 "informixc.ec"
3374
3440
  }
3375
3441
  if (SQLCODE < 0)
3376
3442
  raise_ifx_extended();
@@ -3378,7 +3444,7 @@ fetch_many(VALUE self, VALUE n, VALUE type)
3378
3444
  if (SQLCODE == SQLNOTFOUND)
3379
3445
  break;
3380
3446
 
3381
- if (type == T_ARRAY)
3447
+ if (type == rb_cArray)
3382
3448
  record = rb_ary_new2(c->daOutput->sqld);
3383
3449
  else
3384
3450
  record = rb_hash_new();
@@ -3388,91 +3454,42 @@ fetch_many(VALUE self, VALUE n, VALUE type)
3388
3454
  return records;
3389
3455
  }
3390
3456
 
3457
+
3391
3458
  /*
3392
- * call-seq:
3393
- * cursor.fetch_many(n) => array
3394
- *
3395
- * Reads at most <i>n</i> records.
3396
- *
3397
- * Returns the records read as an array of arrays
3459
+ * Base function for each* methods, except each*_by
3398
3460
  */
3399
3461
  static VALUE
3400
- seqcur_fetch_many(VALUE self, VALUE n)
3401
- {
3402
- return fetch_many(self, n, T_ARRAY);
3403
- }
3404
-
3405
- /*
3406
- * call-seq:
3407
- * cursor.fetch_hash_many(n) => array
3408
- *
3409
- * Reads at most <i>n</i> records.
3410
- * Returns the records read as an array of hashes.
3411
- */
3412
- static VALUE
3413
- seqcur_fetch_hash_many(VALUE self, VALUE n)
3414
- {
3415
- return fetch_many(self, n, T_HASH);
3416
- }
3417
-
3418
- /*
3419
- * call-seq:
3420
- * cursor.fetch_all => array
3421
- *
3422
- * Returns all the records left as an array of arrays
3423
- */
3424
- static VALUE
3425
- seqcur_fetch_all(VALUE self)
3426
- {
3427
- return fetch_many(self, Qnil, T_ARRAY);
3428
- }
3429
-
3430
- /*
3431
- * call-seq:
3432
- * cursor.fetch_hash_all => array
3433
- *
3434
- * Returns all the records left as an array of hashes
3435
- */
3436
- static VALUE
3437
- seqcur_fetch_hash_all(VALUE self)
3438
- {
3439
- return fetch_many(self, Qnil, T_HASH);
3440
- }
3441
-
3442
- /*
3443
- * Base function for each* methods, except each*_by
3444
- */
3445
- static VALUE
3446
- each(VALUE self, VALUE type, int bang)
3462
+ each(VALUE self, VALUE type, VALUE bang)
3447
3463
  {
3448
3464
  cursor_t *c;
3449
3465
  /*
3450
3466
  * EXEC SQL begin declare section;
3451
3467
  */
3452
- #line 2721 "informix.ec"
3453
- #line 2722 "informix.ec"
3468
+ #line 2669 "informixc.ec"
3469
+ #line 2670 "informixc.ec"
3454
3470
  char *cid, *did;
3455
3471
  /*
3456
3472
  * EXEC SQL end declare section;
3457
3473
  */
3458
- #line 2723 "informix.ec"
3474
+ #line 2671 "informixc.ec"
3459
3475
 
3476
+ short c_bang;
3460
3477
  struct sqlda *output;
3461
3478
  VALUE record;
3462
3479
 
3463
3480
  Data_Get_Struct(self, cursor_t, c);
3464
3481
  if (!c->is_open)
3465
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3482
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3466
3483
 
3467
3484
  did = c->database_id;
3468
3485
  /*
3469
3486
  * EXEC SQL set connection :did;
3470
3487
  */
3471
- #line 2732 "informix.ec"
3488
+ #line 2681 "informixc.ec"
3472
3489
  {
3473
- #line 2732 "informix.ec"
3490
+ #line 2681 "informixc.ec"
3474
3491
  sqli_connect_set(0, did, 0);
3475
- #line 2732 "informix.ec"
3492
+ #line 2681 "informixc.ec"
3476
3493
  }
3477
3494
  if (SQLCODE < 0)
3478
3495
  raise_ifx_extended();
@@ -3484,19 +3501,20 @@ each(VALUE self, VALUE type, int bang)
3484
3501
  /*
3485
3502
  * EXEC SQL fetch :cid using descriptor output;
3486
3503
  */
3487
- #line 2740 "informix.ec"
3504
+ #line 2689 "informixc.ec"
3488
3505
  {
3489
- #line 2740 "informix.ec"
3506
+ #line 2689 "informixc.ec"
3490
3507
  static _FetchSpec _FS0 = { 0, 1, 0 };
3491
3508
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, output, (char *)0, &_FS0);
3492
- #line 2740 "informix.ec"
3509
+ #line 2689 "informixc.ec"
3493
3510
  }
3494
3511
  if (SQLCODE < 0)
3495
3512
  raise_ifx_extended();
3496
3513
 
3497
3514
  if (SQLCODE == SQLNOTFOUND)
3498
3515
  return self;
3499
- RECORD(c, type, bang, record);
3516
+ c_bang = RTEST(bang);
3517
+ RECORD(c, type, c_bang, record);
3500
3518
  rb_yield(make_result(c, record));
3501
3519
  }
3502
3520
  }
@@ -3517,139 +3535,61 @@ each_by(VALUE self, VALUE n, VALUE type)
3517
3535
  }
3518
3536
  }
3519
3537
 
3520
- /*
3521
- * call-seq:
3522
- * cursor.each {|record| block } => cursor
3523
- *
3524
- * Iterates over the remaining records, passing each <i>record</i> to the
3525
- * <i>block</i> as an array.
3526
- *
3527
- * Returns __self__.
3528
- */
3529
- static VALUE
3530
- seqcur_each(VALUE self)
3531
- {
3532
- return each(self, T_ARRAY, 0);
3533
- }
3534
-
3535
- /*
3536
- * call-seq:
3537
- * cursor.each! {|record| block } => cursor
3538
- *
3539
- * Iterates over the remaining records, passing each <i>record</i> to the
3540
- * <i>block</i> as an array. No new Array objects are created for each record.
3541
- * The same Array object is reused in each call.
3542
- *
3543
- * Returns __self__.
3544
- */
3545
- static VALUE
3546
- seqcur_each_bang(VALUE self)
3547
- {
3548
- return each(self, T_ARRAY, 1);
3549
- }
3550
-
3551
- /*
3552
- * call-seq:
3553
- * cursor.each_hash {|record| block } => cursor
3554
- *
3555
- * Iterates over the remaining records, passing each <i>record</i> to the
3556
- * <i>block</i> as a hash.
3557
- *
3558
- * Returns __self__.
3559
- */
3560
- static VALUE
3561
- seqcur_each_hash(VALUE self)
3562
- {
3563
- return each(self, T_HASH, 0);
3564
- }
3565
-
3566
- /*
3567
- * call-seq:
3568
- * cursor.each_hash! {|record| block } => cursor
3569
- *
3570
- * Iterates over the remaining records, passing each <i>record</i> to the
3571
- * <i>block</i> as a hash. No new Hash objects are created for each record.
3572
- * The same Hash object is reused in each call.
3573
- *
3574
- * Returns __self__.
3575
- */
3576
- static VALUE
3577
- seqcur_each_hash_bang(VALUE self)
3578
- {
3579
- return each(self, T_HASH, 1);
3580
- }
3581
-
3582
- /*
3583
- * call-seq:
3584
- * cursor.each_by(n) {|records| block } => cursor
3585
- *
3586
- * Iterates over the remaining records, passing at most <i>n</i> <i>records</i>
3587
- * to the <i>block</i> as arrays.
3588
- *
3589
- * Returns __self__.
3590
- */
3591
- static VALUE
3592
- seqcur_each_by(VALUE self, VALUE n)
3593
- {
3594
- return each_by(self, n, T_ARRAY);
3595
- }
3596
-
3597
- /*
3598
- * call-seq:
3599
- * cursor.each_hash_by(n) {|records| block } => cursor
3600
- *
3601
- * Iterates over the remaining records, passing at most <i>n</i> <i>records</i>
3602
- * to the <i>block</i> as hashes.
3603
- *
3604
- * Returns __self__.
3605
- */
3606
- static VALUE
3607
- seqcur_each_hash_by(VALUE self, VALUE n)
3608
- {
3609
- return each_by(self, n, T_HASH);
3610
- }
3611
-
3612
- /* module InsertCursor --------------------------------------------------- */
3538
+ /* class InsertCursor ---------------------------------------------------- */
3613
3539
 
3614
3540
  /*
3615
3541
  * call-seq:
3616
3542
  * cursor.put(*params)
3617
3543
  *
3618
- * Binds <i>params</i> as input parameters and executes the insert statement.
3544
+ * Binds +params+ as input parameters and executes the insert statement.
3619
3545
  * The records are not written immediatly to disk, unless the insert buffer
3620
- * is full, the <code>flush</code> method is called, the cursor is closed or
3546
+ * is full, the +flush+ method is called, the cursor is closed or
3621
3547
  * the transaction is commited.
3548
+ *
3549
+ * Examples:
3550
+ *
3551
+ * A bulk insert using an insert cursor. Requires a transaction:
3552
+ * db.transaction do |db|
3553
+ * db.cursor('insert into stock values(?, ?, ?, ?, ?, ?)') |cur|
3554
+ * cur.open
3555
+ * # Loading a file separated by '|'
3556
+ * File.open(filename).each do |line|
3557
+ * fields = line.split('|')
3558
+ * cur.put(*fields)
3559
+ * end
3560
+ * end
3561
+ * end
3622
3562
  */
3623
3563
  static VALUE
3624
- inscur_put(int argc, VALUE *argv, VALUE self)
3564
+ rb_inscur_put(int argc, VALUE *argv, VALUE self)
3625
3565
  {
3626
3566
  struct sqlda *input;
3627
3567
  cursor_t *c;
3628
3568
  /*
3629
3569
  * EXEC SQL begin declare section;
3630
3570
  */
3631
- #line 2875 "informix.ec"
3632
- #line 2876 "informix.ec"
3571
+ #line 2747 "informixc.ec"
3572
+ #line 2748 "informixc.ec"
3633
3573
  char *cid, *did;
3634
3574
  /*
3635
3575
  * EXEC SQL end declare section;
3636
3576
  */
3637
- #line 2877 "informix.ec"
3577
+ #line 2749 "informixc.ec"
3638
3578
 
3639
3579
 
3640
3580
  Data_Get_Struct(self, cursor_t, c);
3641
3581
  if (!c->is_open)
3642
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3582
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3643
3583
 
3644
3584
  did = c->database_id;
3645
3585
  /*
3646
3586
  * EXEC SQL set connection :did;
3647
3587
  */
3648
- #line 2884 "informix.ec"
3588
+ #line 2756 "informixc.ec"
3649
3589
  {
3650
- #line 2884 "informix.ec"
3590
+ #line 2756 "informixc.ec"
3651
3591
  sqli_connect_set(0, did, 0);
3652
- #line 2884 "informix.ec"
3592
+ #line 2756 "informixc.ec"
3653
3593
  }
3654
3594
  if (SQLCODE < 0)
3655
3595
  raise_ifx_extended();
@@ -3665,11 +3605,11 @@ inscur_put(int argc, VALUE *argv, VALUE self)
3665
3605
  /*
3666
3606
  * EXEC SQL put :cid using descriptor input;
3667
3607
  */
3668
- #line 2896 "informix.ec"
3608
+ #line 2768 "informixc.ec"
3669
3609
  {
3670
- #line 2896 "informix.ec"
3610
+ #line 2768 "informixc.ec"
3671
3611
  sqli_curs_put(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), input, (char *)0);
3672
- #line 2896 "informix.ec"
3612
+ #line 2768 "informixc.ec"
3673
3613
  }
3674
3614
  clean_input_slots(c);
3675
3615
  if (SQLCODE < 0)
@@ -3688,34 +3628,34 @@ inscur_put(int argc, VALUE *argv, VALUE self)
3688
3628
  * Returns __self__.
3689
3629
  */
3690
3630
  static VALUE
3691
- inscur_flush(VALUE self)
3631
+ rb_inscur_flush(VALUE self)
3692
3632
  {
3693
3633
  cursor_t *c;
3694
3634
  /*
3695
3635
  * EXEC SQL begin declare section;
3696
3636
  */
3697
- #line 2917 "informix.ec"
3698
- #line 2918 "informix.ec"
3637
+ #line 2789 "informixc.ec"
3638
+ #line 2790 "informixc.ec"
3699
3639
  char *cid, *did;
3700
3640
  /*
3701
3641
  * EXEC SQL end declare section;
3702
3642
  */
3703
- #line 2919 "informix.ec"
3643
+ #line 2791 "informixc.ec"
3704
3644
 
3705
3645
 
3706
3646
  Data_Get_Struct(self, cursor_t, c);
3707
3647
  if (!c->is_open)
3708
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3648
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3709
3649
 
3710
3650
  did = c->database_id;
3711
3651
  /*
3712
3652
  * EXEC SQL set connection :did;
3713
3653
  */
3714
- #line 2926 "informix.ec"
3654
+ #line 2798 "informixc.ec"
3715
3655
  {
3716
- #line 2926 "informix.ec"
3656
+ #line 2798 "informixc.ec"
3717
3657
  sqli_connect_set(0, did, 0);
3718
- #line 2926 "informix.ec"
3658
+ #line 2798 "informixc.ec"
3719
3659
  }
3720
3660
  if (SQLCODE < 0)
3721
3661
  raise_ifx_extended();
@@ -3724,53 +3664,54 @@ inscur_flush(VALUE self)
3724
3664
  /*
3725
3665
  * EXEC SQL flush :cid;
3726
3666
  */
3727
- #line 2931 "informix.ec"
3667
+ #line 2803 "informixc.ec"
3728
3668
  {
3729
- #line 2931 "informix.ec"
3669
+ #line 2803 "informixc.ec"
3730
3670
  sqli_curs_flush(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256));
3731
- #line 2931 "informix.ec"
3671
+ #line 2803 "informixc.ec"
3732
3672
  }
3733
3673
  return self;
3734
3674
  }
3735
3675
 
3736
- /* module ScrollCursor --------------------------------------------------- */
3676
+ /* class ScrollCursor --------------------------------------------------- */
3737
3677
 
3738
3678
  /*
3739
3679
  * Provides the Array-like functionality for scroll cursors when using the
3740
3680
  * cursor[index] syntax
3741
3681
  */
3742
3682
  static VALUE
3743
- scrollcur_entry(VALUE self, VALUE index, VALUE type, int bang)
3683
+ rb_scrollcur_entry(VALUE self, VALUE index, VALUE type, VALUE bang)
3744
3684
  {
3745
3685
  cursor_t *c;
3746
3686
  struct sqlda *output;
3747
3687
  VALUE record;
3688
+ short c_bang;
3748
3689
  /*
3749
3690
  * EXEC SQL begin declare section;
3750
3691
  */
3751
- #line 2947 "informix.ec"
3752
- #line 2948 "informix.ec"
3692
+ #line 2820 "informixc.ec"
3693
+ #line 2821 "informixc.ec"
3753
3694
  char *cid, *did;
3754
3695
  long pos;
3755
3696
  /*
3756
3697
  * EXEC SQL end declare section;
3757
3698
  */
3758
- #line 2950 "informix.ec"
3699
+ #line 2823 "informixc.ec"
3759
3700
 
3760
3701
 
3761
3702
  Data_Get_Struct(self, cursor_t, c);
3762
3703
  if (!c->is_open)
3763
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3704
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
3764
3705
 
3765
3706
  did = c->database_id;
3766
3707
  /*
3767
3708
  * EXEC SQL set connection :did;
3768
3709
  */
3769
- #line 2957 "informix.ec"
3710
+ #line 2830 "informixc.ec"
3770
3711
  {
3771
- #line 2957 "informix.ec"
3712
+ #line 2830 "informixc.ec"
3772
3713
  sqli_connect_set(0, did, 0);
3773
- #line 2957 "informix.ec"
3714
+ #line 2830 "informixc.ec"
3774
3715
  }
3775
3716
  if (SQLCODE < 0)
3776
3717
  return Qnil;
@@ -3782,60 +3723,60 @@ long pos;
3782
3723
  /*
3783
3724
  * EXEC SQL fetch current :cid using descriptor output;
3784
3725
  */
3785
- #line 2965 "informix.ec"
3726
+ #line 2838 "informixc.ec"
3786
3727
  {
3787
- #line 2965 "informix.ec"
3728
+ #line 2838 "informixc.ec"
3788
3729
  static _FetchSpec _FS0 = { 0, 5, 0 };
3789
3730
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, output, (char *)0, &_FS0);
3790
- #line 2965 "informix.ec"
3731
+ #line 2838 "informixc.ec"
3791
3732
  }
3792
3733
  else if ((pos = NUM2LONG(index) + 1) > 0)
3793
3734
  /*
3794
3735
  * EXEC SQL fetch absolute :pos :cid using descriptor output;
3795
3736
  */
3796
- #line 2967 "informix.ec"
3737
+ #line 2840 "informixc.ec"
3797
3738
  {
3798
- #line 2967 "informix.ec"
3739
+ #line 2840 "informixc.ec"
3799
3740
  static ifx_sqlvar_t _sqibind[] =
3800
3741
  {
3801
3742
  { 103, sizeof(pos), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3802
- #line 2967 "informix.ec"
3743
+ #line 2840 "informixc.ec"
3803
3744
  };
3804
3745
  static ifx_sqlda_t _SD0 = { 1, _sqibind, {0}, 1, 0 };
3805
3746
  static _FetchSpec _FS1 = { 0, 6, 0 };
3806
- #line 2967 "informix.ec"
3747
+ #line 2840 "informixc.ec"
3807
3748
  _sqibind[0].sqldata = (char *) &pos;
3808
3749
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), &_SD0, output, (char *)0, &_FS1);
3809
- #line 2967 "informix.ec"
3750
+ #line 2840 "informixc.ec"
3810
3751
  }
3811
3752
  else {
3812
3753
  /*
3813
3754
  * EXEC SQL fetch last :cid;
3814
3755
  */
3815
- #line 2969 "informix.ec"
3756
+ #line 2842 "informixc.ec"
3816
3757
  {
3817
- #line 2969 "informix.ec"
3758
+ #line 2842 "informixc.ec"
3818
3759
  static _FetchSpec _FS0 = { 0, 4, 0 };
3819
3760
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, (ifx_sqlda_t *)0, (char *)0, &_FS0);
3820
- #line 2969 "informix.ec"
3761
+ #line 2842 "informixc.ec"
3821
3762
  }
3822
3763
  /*
3823
3764
  * EXEC SQL fetch relative :pos :cid using descriptor output;
3824
3765
  */
3825
- #line 2970 "informix.ec"
3766
+ #line 2843 "informixc.ec"
3826
3767
  {
3827
- #line 2970 "informix.ec"
3768
+ #line 2843 "informixc.ec"
3828
3769
  static ifx_sqlvar_t _sqibind[] =
3829
3770
  {
3830
3771
  { 103, sizeof(pos), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
3831
- #line 2970 "informix.ec"
3772
+ #line 2843 "informixc.ec"
3832
3773
  };
3833
3774
  static ifx_sqlda_t _SD0 = { 1, _sqibind, {0}, 1, 0 };
3834
3775
  static _FetchSpec _FS1 = { 0, 7, 0 };
3835
- #line 2970 "informix.ec"
3776
+ #line 2843 "informixc.ec"
3836
3777
  _sqibind[0].sqldata = (char *) &pos;
3837
3778
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), &_SD0, output, (char *)0, &_FS1);
3838
- #line 2970 "informix.ec"
3779
+ #line 2843 "informixc.ec"
3839
3780
  }
3840
3781
  }
3841
3782
 
@@ -3845,208 +3786,72 @@ long pos;
3845
3786
  if (SQLCODE < 0)
3846
3787
  raise_ifx_extended();
3847
3788
 
3848
- RECORD(c, type, bang, record);
3789
+ c_bang = RTEST(bang);
3790
+ RECORD(c, type, c_bang, record);
3849
3791
  return make_result(c, record);
3850
3792
  }
3851
3793
 
3852
- /*
3853
- * Provides the Array-like functionality for scroll cursors when using the
3854
- * cursor[start, length] syntax
3855
- */
3856
- static VALUE
3857
- scrollcur_subseq(VALUE self, VALUE start, VALUE length, VALUE type)
3858
- {
3859
- VALUE first, records;
3860
- /*
3861
- * EXEC SQL begin declare section;
3862
- */
3863
- #line 2991 "informix.ec"
3864
- #line 2992 "informix.ec"
3865
- long pos;
3866
- /*
3867
- * EXEC SQL end declare section;
3868
- */
3869
- #line 2993 "informix.ec"
3870
-
3871
-
3872
- first = scrollcur_entry(self, start, type, 0);
3873
- if (NIL_P(first))
3874
- return Qnil;
3875
-
3876
- pos = NUM2LONG(length) - 1;
3877
-
3878
- if (pos > 0) {
3879
- length = LONG2NUM(pos);
3880
- records = fetch_many(self, length, type);
3881
- }
3882
- else
3883
- records = rb_ary_new();
3884
-
3885
- rb_ary_unshift(records, first);
3886
-
3887
- return records;
3888
- }
3889
-
3890
- /*
3891
- * Base function for slice and slice_hash methods
3892
- */
3893
- static VALUE
3894
- slice(int argc, VALUE *argv, VALUE self, VALUE type)
3895
- {
3896
- if (argc == 2) {
3897
- if (NUM2LONG(argv[1]) <= 0)
3898
- rb_raise(rb_eArgError, "length must be positive");
3899
- return scrollcur_subseq(self, argv[0], argv[1], type);
3900
- }
3901
- if (argc != 1)
3902
- rb_scan_args(argc, argv, "11", 0, 0);
3903
-
3904
- return scrollcur_entry(self, argv[0], type, 0);
3905
- }
3906
-
3907
- /*
3908
- * call-seq:
3909
- * cursor[index] => array or nil
3910
- * cursor[start, length] => array or nil
3911
- * cursor.slice(index) => array or nil
3912
- * cursor.slice(start, length) => array or nil
3913
- *
3914
- * Returns the record at _index_, or returns a subarray starting at _start_
3915
- * and continuing for _length_ records. Negative indices count backward from
3916
- * the end of the cursor (-1 is the last element). Returns nil if the
3917
- * (starting) index is out of range.
3918
- *
3919
- * <b>Warning</b>: if the (starting) index is negative and out of range, the
3920
- * position in the cursor is set to the last record. Otherwise the current
3921
- * position in the cursor is preserved.
3922
- */
3923
- static VALUE
3924
- scrollcur_slice(int argc, VALUE *argv, VALUE self)
3925
- {
3926
- return slice(argc, argv, self, T_ARRAY);
3927
- }
3928
-
3929
- /*
3930
- * call-seq:
3931
- * cursor.slice!(index) => array or nil
3932
- *
3933
- * Returns the record at _index_. Negative indices count backward from
3934
- * the end of the cursor (-1 is the last element). Returns nil if the index
3935
- * is out of range.
3936
- *
3937
- * Stores the record fetched always in the same Array object.
3938
- *
3939
- * <b>Warning</b>: if the index is negative and out of range, the
3940
- * position in the cursor is set to the last record. Otherwise the current
3941
- * position in the cursor is preserved.
3942
- */
3943
- static VALUE
3944
- scrollcur_slice_bang(VALUE self, VALUE index)
3945
- {
3946
- return scrollcur_entry(self, index, T_ARRAY, 1);
3947
- }
3948
-
3949
- /*
3950
- * call-seq:
3951
- * cursor.slice_hash(index) => hash or nil
3952
- * cursor.slice_hash(start, length) => array or nil
3953
- *
3954
- * Returns the record at _index_, or returns a subarray starting at _start_
3955
- * and continuing for _length_ records. Negative indices count backward from
3956
- * the end of the cursor (-1 is the last element). Returns nil if the
3957
- * (starting) index is out of range.
3958
- *
3959
- * <b>Warning</b>: if the (starting) index is negative and out of range, the
3960
- * position in the cursor is set to the last record. Otherwise the current
3961
- * position in the cursor is preserved.
3962
- */
3963
- static VALUE
3964
- scrollcur_slice_hash(int argc, VALUE *argv, VALUE self)
3965
- {
3966
- return slice(argc, argv, self, T_HASH);
3967
- }
3968
-
3969
- /*
3970
- * call-seq:
3971
- * cursor.slice_hash!(index) => hash or nil
3972
- *
3973
- * Returns the record at _index_. Negative indices count backward from
3974
- * the end of the cursor (-1 is the last element). Returns nil if the index
3975
- * is out of range.
3976
- *
3977
- * Stores the record fetched always in the same Hash object.
3978
- *
3979
- * <b>Warning</b>: if the index is negative and out of range, the
3980
- * position in the cursor is set to the last record. Otherwise the current
3981
- * position in the cursor is preserved.
3982
- */
3983
- static VALUE
3984
- scrollcur_slice_hash_bang(VALUE self, VALUE index)
3985
- {
3986
- return scrollcur_entry(self, index, T_HASH, 1);
3987
- }
3988
-
3989
3794
  /*
3990
3795
  * Base function for prev* and next* methods
3991
3796
  */
3992
3797
  static VALUE
3993
- scrollcur_rel(int argc, VALUE *argv, VALUE self, int dir, VALUE type, int bang)
3798
+ rb_scrollcur_rel(VALUE self, VALUE offset, VALUE type, VALUE bang)
3994
3799
  {
3800
+ short c_bang;
3995
3801
  cursor_t *c;
3996
3802
  struct sqlda *output;
3997
- VALUE offset, record;
3803
+ VALUE record;
3998
3804
  /*
3999
3805
  * EXEC SQL begin declare section;
4000
3806
  */
4001
- #line 3121 "informix.ec"
4002
- #line 3122 "informix.ec"
3807
+ #line 2867 "informixc.ec"
3808
+ #line 2868 "informixc.ec"
4003
3809
  char *cid, *did;
4004
3810
  long pos;
4005
3811
  /*
4006
3812
  * EXEC SQL end declare section;
4007
3813
  */
4008
- #line 3124 "informix.ec"
3814
+ #line 2870 "informixc.ec"
4009
3815
 
4010
3816
 
4011
3817
  Data_Get_Struct(self, cursor_t, c);
4012
3818
  if (!c->is_open)
4013
- rb_raise(esyms.eProgrammingError, "Open the cursor object first");
3819
+ rb_raise(rb_eProgrammingError, "Open the cursor object first");
4014
3820
 
4015
3821
  did = c->database_id;
4016
3822
  /*
4017
3823
  * EXEC SQL set connection :did;
4018
3824
  */
4019
- #line 3131 "informix.ec"
3825
+ #line 2877 "informixc.ec"
4020
3826
  {
4021
- #line 3131 "informix.ec"
3827
+ #line 2877 "informixc.ec"
4022
3828
  sqli_connect_set(0, did, 0);
4023
- #line 3131 "informix.ec"
3829
+ #line 2877 "informixc.ec"
4024
3830
  }
4025
3831
  if (SQLCODE < 0)
4026
3832
  return Qnil;
4027
3833
 
4028
- rb_scan_args(argc, argv, "01", &offset);
4029
- pos = dir*(NIL_P(offset)? 1: NUM2LONG(offset));
3834
+ pos = NUM2LONG(offset);
4030
3835
 
4031
3836
  output = c->daOutput;
4032
3837
  cid = c->cursor_id;
4033
3838
  /*
4034
3839
  * EXEC SQL fetch relative :pos :cid using descriptor output;
4035
3840
  */
4036
- #line 3140 "informix.ec"
3841
+ #line 2885 "informixc.ec"
4037
3842
  {
4038
- #line 3140 "informix.ec"
3843
+ #line 2885 "informixc.ec"
4039
3844
  static ifx_sqlvar_t _sqibind[] =
4040
3845
  {
4041
3846
  { 103, sizeof(pos), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
4042
- #line 3140 "informix.ec"
3847
+ #line 2885 "informixc.ec"
4043
3848
  };
4044
3849
  static ifx_sqlda_t _SD0 = { 1, _sqibind, {0}, 1, 0 };
4045
3850
  static _FetchSpec _FS1 = { 0, 7, 0 };
4046
- #line 3140 "informix.ec"
3851
+ #line 2885 "informixc.ec"
4047
3852
  _sqibind[0].sqldata = (char *) &pos;
4048
3853
  sqli_curs_fetch(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), &_SD0, output, (char *)0, &_FS1);
4049
- #line 3140 "informix.ec"
3854
+ #line 2885 "informixc.ec"
4050
3855
  }
4051
3856
 
4052
3857
  if (SQLCODE == SQLNOTFOUND)
@@ -4055,435 +3860,296 @@ long pos;
4055
3860
  if (SQLCODE < 0)
4056
3861
  raise_ifx_extended();
4057
3862
 
4058
- RECORD(c, type, bang, record);
3863
+ c_bang = RTEST(bang);
3864
+ RECORD(c, type, c_bang, record);
4059
3865
  return make_result(c, record);
4060
3866
  }
4061
3867
 
4062
- /* call-seq:
4063
- * cursor.prev(offset = 1) => array or nil
4064
- *
4065
- * Returns the previous _offset_ th record. Negative indices count
4066
- * forward from the current position. Returns nil if the _offset_ is out of
4067
- * range.
4068
- */
4069
- static VALUE
4070
- scrollcur_prev(int argc, VALUE *argv, VALUE self)
4071
- {
4072
- return scrollcur_rel(argc, argv, self, -1, T_ARRAY, 0);
4073
- }
3868
+ /* class CursorBase ------------------------------------------------------ */
4074
3869
 
4075
- /* call-seq:
4076
- * cursor.prev!(offset = 1) => array or nil
4077
- *
4078
- * Returns the previous _offset_ th record. Negative indices count
4079
- * forward from the current position. Returns nil if the _offset_ is out of
4080
- * range.
4081
- *
4082
- * Stores the record fetched always in the same Array object.
4083
- */
4084
- static VALUE
4085
- scrollcur_prev_bang(int argc, VALUE *argv, VALUE self)
3870
+ static void
3871
+ cursorbase_close_or_free(cursor_t *c, short op)
4086
3872
  {
4087
- return scrollcur_rel(argc, argv, self, -1, T_ARRAY, 1);
4088
- }
4089
-
4090
- /* call-seq:
4091
- * cursor.prev_hash(offset = 1) => hash or nil
4092
- *
4093
- * Returns the previous _offset_ th record. Negative indices count
4094
- * forward from the current position. Returns nil if the _offset_ is out of
4095
- * range.
3873
+ /*
3874
+ * EXEC SQL begin declare section;
4096
3875
  */
4097
- static VALUE
4098
- scrollcur_prev_hash(int argc, VALUE *argv, VALUE self)
4099
- {
4100
- return scrollcur_rel(argc, argv, self, -1, T_HASH, 0);
4101
- }
4102
-
4103
- /* call-seq:
4104
- * cursor.prev_hash!(offset = 1) => hash or nil
4105
- *
4106
- * Returns the previous _offset_ th record. Negative indices count
4107
- * forward from the current position. Returns nil if the _offset_ is out of
4108
- * range.
4109
- *
4110
- * Stores the record fetched always in the same Hash object.
3876
+ #line 2903 "informixc.ec"
3877
+ #line 2904 "informixc.ec"
3878
+ char *cid, *sid, *did;
3879
+ /*
3880
+ * EXEC SQL end declare section;
4111
3881
  */
4112
- static VALUE
4113
- scrollcur_prev_hash_bang(int argc, VALUE *argv, VALUE self)
4114
- {
4115
- return scrollcur_rel(argc, argv, self, -1, T_HASH, 1);
4116
- }
3882
+ #line 2905 "informixc.ec"
4117
3883
 
4118
- /* call-seq:
4119
- * cursor.next(offset = 1) => array or nil
4120
- *
4121
- * Returns the next _offset_ th record. Negative indices count
4122
- * backward from the current position. Returns nil if the _offset_ is out of
4123
- * range.
3884
+
3885
+ if (op == 1 && !c->is_open)
3886
+ return;
3887
+
3888
+ c->is_open = 0;
3889
+
3890
+ switch(op) {
3891
+ case 1:
3892
+ clean_input_slots(c);
3893
+ case 2:
3894
+ did = c->database_id;
3895
+ /*
3896
+ * EXEC SQL set connection :did;
4124
3897
  */
4125
- static VALUE
4126
- scrollcur_next(int argc, VALUE *argv, VALUE self)
4127
- {
4128
- return scrollcur_rel(argc, argv, self, 1, T_ARRAY, 0);
3898
+ #line 2917 "informixc.ec"
3899
+ {
3900
+ #line 2917 "informixc.ec"
3901
+ sqli_connect_set(0, did, 0);
3902
+ #line 2917 "informixc.ec"
3903
+ }
3904
+ if (SQLCODE < 0)
3905
+ return;
3906
+ cid = c->cursor_id;
3907
+ /*
3908
+ * EXEC SQL close :cid;
3909
+ */
3910
+ #line 2921 "informixc.ec"
3911
+ {
3912
+ #line 2921 "informixc.ec"
3913
+ sqli_curs_close(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256));
3914
+ #line 2921 "informixc.ec"
3915
+ }
3916
+ if (op == 1)
3917
+ break;
3918
+ /*
3919
+ * EXEC SQL free :cid;
3920
+ */
3921
+ #line 2924 "informixc.ec"
3922
+ {
3923
+ #line 2924 "informixc.ec"
3924
+ sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 258));
3925
+ #line 2924 "informixc.ec"
3926
+ }
3927
+ st_free(c);
3928
+ break;
3929
+ }
4129
3930
  }
4130
3931
 
4131
- /* call-seq:
4132
- * cursor.next!(offset = 1) => array or nil
4133
- *
4134
- * Returns the next _offset_ th record. Negative indices count
4135
- * backward from the current position. Returns nil if the _offset_ is out of
4136
- * range.
4137
- *
4138
- * Stores the record fetched always in the same Array object.
4139
- */
4140
- static VALUE
4141
- scrollcur_next_bang(int argc, VALUE *argv, VALUE self)
3932
+ static void
3933
+ cursorbase_mark(cursor_t *c)
4142
3934
  {
4143
- return scrollcur_rel(argc, argv, self, 1, T_ARRAY, 1);
3935
+ rb_gc_mark(c->db);
3936
+ if (c->array)
3937
+ rb_gc_mark(c->array);
3938
+ if (c->hash)
3939
+ rb_gc_mark(c->hash);
3940
+ if (c->field_names)
3941
+ rb_gc_mark(c->field_names);
4144
3942
  }
4145
3943
 
4146
- /* call-seq:
4147
- * cursor.next_hash(offset = 1) => hash or nil
4148
- *
4149
- * Returns the next _offset_ th record. Negative indices count
4150
- * backward from the current position. Returns nil if the _offset_ is out of
4151
- * range.
4152
- */
4153
- static VALUE
4154
- scrollcur_next_hash(int argc, VALUE *argv, VALUE self)
3944
+ static void
3945
+ cursorbase_free(void *p)
4155
3946
  {
4156
- return scrollcur_rel(argc, argv, self, 1, T_HASH, 0);
3947
+ cursorbase_close_or_free(p, 2);
3948
+ xfree(p);
4157
3949
  }
4158
3950
 
4159
- /* call-seq:
4160
- * cursor.next_hash!(offset = 1) => hash or nil
4161
- *
4162
- * Returns the next _offset_ th record. Negative indices count
4163
- * backward from the current position. Returns nil if the _offset_ is out of
4164
- * range.
4165
- *
4166
- * Stores the record fetched always in the same Hash object.
4167
- */
4168
3951
  static VALUE
4169
- scrollcur_next_hash_bang(int argc, VALUE *argv, VALUE self)
3952
+ cursorbase_alloc(VALUE klass)
4170
3953
  {
4171
- return scrollcur_rel(argc, argv, self, 1, T_HASH, 1);
3954
+ cursor_t *c;
3955
+
3956
+ c = ALLOC(cursor_t);
3957
+ memset(c, 0, sizeof(cursor_t));
3958
+ return Data_Wrap_Struct(klass, cursorbase_mark, cursorbase_free, c);
4172
3959
  }
4173
3960
 
4174
3961
  /*
4175
3962
  * call-seq:
4176
- * cursor.first => array or nil
3963
+ * cursor.id => string
4177
3964
  *
4178
- * Returns the first record of the cursor. If the cursor is empty,
4179
- * returns nil.
3965
+ * Returns the cursor ID
4180
3966
  */
4181
3967
  static VALUE
4182
- scrollcur_first(VALUE self)
3968
+ rb_cursorbase_id(VALUE self)
4183
3969
  {
4184
- return scrollcur_entry(self, INT2FIX(0), T_ARRAY, 0);
3970
+ cursor_t *c;
3971
+
3972
+ Data_Get_Struct(self, cursor_t, c);
3973
+ return rb_str_new2(c->cursor_id);
4185
3974
  }
4186
3975
 
4187
3976
  /*
4188
3977
  * call-seq:
4189
- * cursor.first! => array or nil
3978
+ * cursor.open(*params) => cursor
4190
3979
  *
4191
- * Returns the first record of the cursor. If the cursor is empty,
4192
- * returns nil.
3980
+ * Executes the previously prepared select statement, binding <i>params</i> as
3981
+ * input parameters.
4193
3982
  *
4194
- * Stores the record fetched always in the same Array object.
3983
+ * Returns __self__.
4195
3984
  */
4196
3985
  static VALUE
4197
- scrollcur_first_bang(VALUE self)
4198
- {
4199
- return scrollcur_entry(self, INT2FIX(0), T_ARRAY, 1);
4200
- }
4201
-
4202
- /*
4203
- * call-seq:
4204
- * cursor.first_hash => hash or nil
4205
- *
4206
- * Returns the first record of the cursor. If the cursor is empty,
4207
- * returns nil.
4208
- */
4209
- static VALUE
4210
- scrollcur_first_hash(VALUE self)
4211
- {
4212
- return scrollcur_entry(self, INT2FIX(0), T_HASH, 0);
4213
- }
4214
-
4215
- /*
4216
- * call-seq:
4217
- * cursor.first_hash! => hash or nil
4218
- *
4219
- * Returns the first record of the cursor. If the cursor is empty,
4220
- * returns nil.
4221
- *
4222
- * Stores the record fetched always in the same Hash object.
4223
- */
4224
- static VALUE
4225
- scrollcur_first_hash_bang(VALUE self)
4226
- {
4227
- return scrollcur_entry(self, INT2FIX(0), T_HASH, 1);
4228
- }
4229
-
4230
- /*
4231
- * call-seq:
4232
- * cursor.last => array or nil
4233
- *
4234
- * Returns the last record of the cursor. If the cursor is empty,
4235
- * returns nil.
4236
- */
4237
- static VALUE
4238
- scrollcur_last(VALUE self)
4239
- {
4240
- return scrollcur_entry(self, INT2FIX(-1), T_ARRAY, 0);
4241
- }
4242
-
4243
- /*
4244
- * call-seq:
4245
- * cursor.last! => array or nil
4246
- *
4247
- * Returns the last record of the cursor. If the cursor is empty,
4248
- * returns nil.
4249
- *
4250
- * Stores the record fetched always in the same Array object.
4251
- */
4252
- static VALUE
4253
- scrollcur_last_bang(VALUE self)
4254
- {
4255
- return scrollcur_entry(self, INT2FIX(-1), T_ARRAY, 1);
4256
- }
4257
-
4258
- /*
4259
- * call-seq:
4260
- * cursor.last_hash => hash or nil
4261
- *
4262
- * Returns the last record of the cursor. If the cursor is empty,
4263
- * returns nil.
4264
- */
4265
- static VALUE
4266
- scrollcur_last_hash(VALUE self)
4267
- {
4268
- return scrollcur_entry(self, INT2FIX(-1), T_HASH, 0);
4269
- }
4270
-
4271
- /*
4272
- * call-seq:
4273
- * cursor.last_hash! => hash or nil
4274
- *
4275
- * Returns the last record of the cursor. If the cursor is empty,
4276
- * returns nil.
4277
- *
4278
- * Stores the record fetched always in the same Hash object.
4279
- */
4280
- static VALUE
4281
- scrollcur_last_hash_bang(VALUE self)
4282
- {
4283
- return scrollcur_entry(self, INT2FIX(-1), T_HASH, 1);
4284
- }
4285
-
4286
- /*
4287
- * call-seq:
4288
- * cursor.current => array or nil
4289
- *
4290
- * Returns the current record of the cursor. If the cursor is empty,
4291
- * returns nil.
4292
- */
4293
- static VALUE
4294
- scrollcur_current(VALUE self)
4295
- {
4296
- return scrollcur_entry(self, Qnil, T_ARRAY, 0);
4297
- }
4298
-
4299
- /*
4300
- * call-seq:
4301
- * cursor.current! => array or nil
4302
- *
4303
- * Returns the current record of the cursor. If the cursor is empty,
4304
- * returns nil.
4305
- *
4306
- * Stores the record fetched always in the same Array object.
4307
- */
4308
- static VALUE
4309
- scrollcur_current_bang(VALUE self)
4310
- {
4311
- return scrollcur_entry(self, Qnil, T_ARRAY, 1);
4312
- }
4313
-
4314
- /*
4315
- * call-seq:
4316
- * cursor.current_hash => hash or nil
4317
- *
4318
- * Returns the current record of the cursor. If the cursor is empty,
4319
- * returns nil.
4320
- */
4321
- static VALUE
4322
- scrollcur_current_hash(VALUE self)
4323
- {
4324
- return scrollcur_entry(self, Qnil, T_HASH, 0);
4325
- }
4326
-
4327
- /*
4328
- * call-seq:
4329
- * cursor.current_hash! => hash or nil
4330
- *
4331
- * Returns the current record of the cursor. If the cursor is empty,
4332
- * returns nil.
4333
- *
4334
- * Stores the record fetched always in the same Hash object.
4335
- */
4336
- static VALUE
4337
- scrollcur_current_hash_bang(VALUE self)
4338
- {
4339
- return scrollcur_entry(self, Qnil, T_HASH, 1);
4340
- }
4341
-
4342
- /* class Cursor ---------------------------------------------------------- */
4343
- static void
4344
- cursor_close_or_free(cursor_t *c, short op)
3986
+ rb_cursorbase_open(int argc, VALUE *argv, VALUE self)
4345
3987
  {
3988
+ struct sqlda *input;
3989
+ cursor_t *c;
4346
3990
  /*
4347
3991
  * EXEC SQL begin declare section;
4348
3992
  */
4349
- #line 3436 "informix.ec"
4350
- #line 3437 "informix.ec"
4351
- char *cid, *sid, *did;
3993
+ #line 2988 "informixc.ec"
3994
+ #line 2989 "informixc.ec"
3995
+ char *cid, *did;
4352
3996
  /*
4353
3997
  * EXEC SQL end declare section;
4354
3998
  */
4355
- #line 3438 "informix.ec"
3999
+ #line 2990 "informixc.ec"
4356
4000
 
4357
4001
 
4358
- if (op == 1 && !c->is_open)
4359
- return;
4002
+ Data_Get_Struct(self, cursor_t, c);
4360
4003
 
4361
- c->is_open = 0;
4362
- if (op == 1)
4363
- clean_input_slots(c);
4364
- else {
4365
- free_input_slots(c);
4366
- free_output_slots(c);
4367
- }
4004
+ if (c->is_open)
4005
+ return self;
4368
4006
 
4369
4007
  did = c->database_id;
4370
4008
  /*
4371
4009
  * EXEC SQL set connection :did;
4372
4010
  */
4373
- #line 3452 "informix.ec"
4011
+ #line 2998 "informixc.ec"
4374
4012
  {
4375
- #line 3452 "informix.ec"
4013
+ #line 2998 "informixc.ec"
4376
4014
  sqli_connect_set(0, did, 0);
4377
- #line 3452 "informix.ec"
4015
+ #line 2998 "informixc.ec"
4378
4016
  }
4379
4017
  if (SQLCODE < 0)
4380
- return;
4018
+ raise_ifx_extended();
4381
4019
 
4020
+ input = &c->daInput;
4382
4021
  cid = c->cursor_id;
4022
+
4023
+ if (c->is_select) {
4024
+ if (argc != input->sqld) {
4025
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
4026
+ argc, input->sqld);
4027
+ }
4028
+ if (argc) {
4029
+ bind_input_params(c, argv);
4383
4030
  /*
4384
- * EXEC SQL close :cid;
4031
+ * EXEC SQL open :cid using descriptor input
4032
+ * with reoptimization;
4385
4033
  */
4386
- #line 3457 "informix.ec"
4034
+ #line 3012 "informixc.ec"
4387
4035
  {
4388
- #line 3457 "informix.ec"
4389
- sqli_curs_close(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256));
4390
- #line 3457 "informix.ec"
4036
+ #line 3013 "informixc.ec"
4037
+ sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), input, (char *)0, (struct value *)0, 1, 1);
4038
+ #line 3013 "informixc.ec"
4391
4039
  }
4392
-
4393
- if (op == 2) {
4394
- sid = c->stmt_id;
4040
+ clean_input_slots(c);
4041
+ }
4042
+ else
4395
4043
  /*
4396
- * EXEC SQL free :cid;
4044
+ * EXEC SQL open :cid with reoptimization;
4397
4045
  */
4398
- #line 3461 "informix.ec"
4046
+ #line 3017 "informixc.ec"
4399
4047
  {
4400
- #line 3461 "informix.ec"
4401
- sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 258));
4402
- #line 3461 "informix.ec"
4048
+ #line 3017 "informixc.ec"
4049
+ sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0, 1);
4050
+ #line 3017 "informixc.ec"
4403
4051
  }
4052
+ }
4053
+ else
4404
4054
  /*
4405
- * EXEC SQL free :sid;
4055
+ * EXEC SQL open :cid;
4406
4056
  */
4407
- #line 3461 "informix.ec"
4057
+ #line 3020 "informixc.ec"
4408
4058
  {
4409
- #line 3461 "informix.ec"
4410
- sqli_curs_free(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 258));
4411
- #line 3461 "informix.ec"
4059
+ #line 3020 "informixc.ec"
4060
+ sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0, 0);
4061
+ #line 3020 "informixc.ec"
4412
4062
  }
4413
- }
4414
- }
4415
4063
 
4416
- static void
4417
- cursor_mark(cursor_t *c)
4418
- {
4419
- rb_gc_mark(c->db);
4420
- if (c->array)
4421
- rb_gc_mark(c->array);
4422
- if (c->hash)
4423
- rb_gc_mark(c->hash);
4424
- if (c->field_names)
4425
- rb_gc_mark(c->field_names);
4064
+ if (SQLCODE < 0)
4065
+ raise_ifx_extended();
4066
+
4067
+ c->is_open = 1;
4068
+ return self;
4426
4069
  }
4427
4070
 
4428
- static void
4429
- cursor_free(void *p)
4071
+ /*
4072
+ * call-seq:
4073
+ * cursor.close => cursor
4074
+ *
4075
+ * Closes the cursor and returns __self__.
4076
+ */
4077
+ static VALUE
4078
+ rb_cursorbase_close(VALUE self)
4430
4079
  {
4431
- cursor_close_or_free(p, 2);
4432
- xfree(p);
4080
+ cursor_t *c;
4081
+
4082
+ Data_Get_Struct(self, cursor_t, c);
4083
+ cursorbase_close_or_free(c, 1);
4084
+ return self;
4433
4085
  }
4434
4086
 
4087
+ /*
4088
+ * call-seq:
4089
+ * cursor.drop => nil
4090
+ *
4091
+ * Closes the cursor and frees the memory associated with it. The cursor
4092
+ * cannot be opened again.
4093
+ */
4435
4094
  static VALUE
4436
- cursor_alloc(VALUE klass)
4095
+ rb_cursorbase_drop(VALUE self)
4437
4096
  {
4438
4097
  cursor_t *c;
4439
4098
 
4440
- c = ALLOC(cursor_t);
4441
- memset(c, 0, sizeof(cursor_t));
4442
- return Data_Wrap_Struct(klass, cursor_mark, cursor_free, c);
4099
+ Data_Get_Struct(self, cursor_t, c);
4100
+ cursorbase_close_or_free(c, 2);
4101
+
4102
+ return Qnil;
4443
4103
  }
4444
4104
 
4105
+ /* module Cursor --------------------------------------------------------- */
4106
+
4107
+ /*
4108
+ * The underlying class method that prepares a cursor and creates
4109
+ * the respective cursor object.
4110
+ */
4445
4111
  static VALUE
4446
- cursor_initialize(int argc, VALUE *argv, VALUE self)
4112
+ rb_cursor_s_new0(int argc, VALUE *argv, VALUE self)
4447
4113
  {
4448
- VALUE db, query, options;
4114
+ VALUE db, query, options, ret;
4449
4115
  VALUE scroll, hold;
4450
4116
  struct sqlda *output;
4451
- cursor_t *c;
4117
+ cursor_t c, *cur;
4452
4118
  /*
4453
4119
  * EXEC SQL begin declare section;
4454
4120
  */
4455
- #line 3501 "informix.ec"
4456
- #line 3502 "informix.ec"
4121
+ #line 3076 "informixc.ec"
4122
+ #line 3077 "informixc.ec"
4457
4123
  char *c_query;
4458
4124
  char *cid, *sid, *did;
4459
4125
  /*
4460
4126
  * EXEC SQL end declare section;
4461
4127
  */
4462
- #line 3504 "informix.ec"
4128
+ #line 3079 "informixc.ec"
4463
4129
 
4464
4130
 
4131
+ memset(&c, 0, sizeof(c));
4465
4132
  rb_scan_args(argc, argv, "21", &db, &query, &options);
4466
4133
  Data_Get_Struct(db, char, did);
4467
4134
 
4468
4135
  /*
4469
4136
  * EXEC SQL set connection :did;
4470
4137
  */
4471
- #line 3509 "informix.ec"
4138
+ #line 3085 "informixc.ec"
4472
4139
  {
4473
- #line 3509 "informix.ec"
4140
+ #line 3085 "informixc.ec"
4474
4141
  sqli_connect_set(0, did, 0);
4475
- #line 3509 "informix.ec"
4142
+ #line 3085 "informixc.ec"
4476
4143
  }
4477
4144
  if (SQLCODE < 0)
4478
4145
  raise_ifx_extended();
4479
4146
 
4480
- Data_Get_Struct(self, cursor_t, c);
4481
- c->db = db;
4482
- c->database_id = did;
4147
+ c.db = db;
4148
+ c.database_id = did;
4483
4149
  scroll = hold = Qfalse;
4484
- snprintf(c->cursor_id, sizeof(c->cursor_id), "CUR%lX", self);
4485
- snprintf(c->stmt_id, sizeof(c->stmt_id), "STMT%lX", self);
4486
- cid = c->cursor_id; sid = c->stmt_id;
4150
+ snprintf(c.cursor_id, sizeof(c.cursor_id), "CUR%lX", self);
4151
+ snprintf(c.stmt_id, sizeof(c.stmt_id), "STMT%lX", self);
4152
+ cid = c.cursor_id; sid = c.stmt_id;
4487
4153
  c_query = StringValueCStr(query);
4488
4154
 
4489
4155
  if (!NIL_P(options)) {
@@ -4495,11 +4161,11 @@ cursor_initialize(int argc, VALUE *argv, VALUE self)
4495
4161
  /*
4496
4162
  * EXEC SQL prepare :sid from :c_query;
4497
4163
  */
4498
- #line 3528 "informix.ec"
4164
+ #line 3103 "informixc.ec"
4499
4165
  {
4500
- #line 3528 "informix.ec"
4166
+ #line 3103 "informixc.ec"
4501
4167
  sqli_prep(ESQLINTVERSION, sid, c_query,(ifx_literal_t *)0, (ifx_namelist_t *)0, -1, 0, 0 );
4502
- #line 3528 "informix.ec"
4168
+ #line 3103 "informixc.ec"
4503
4169
  }
4504
4170
  if (SQLCODE < 0)
4505
4171
  raise_ifx_extended();
@@ -4508,317 +4174,135 @@ cursor_initialize(int argc, VALUE *argv, VALUE self)
4508
4174
  /*
4509
4175
  * EXEC SQL declare :cid scroll cursor with hold for :sid;
4510
4176
  */
4511
- #line 3533 "informix.ec"
4177
+ #line 3108 "informixc.ec"
4512
4178
  {
4513
- #line 3533 "informix.ec"
4179
+ #line 3108 "informixc.ec"
4514
4180
  sqli_curs_decl_dynm(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 0), cid, sqli_curs_locate(ESQLINTVERSION, sid, 1), 4128, 0);
4515
- #line 3533 "informix.ec"
4181
+ #line 3108 "informixc.ec"
4516
4182
  }
4517
4183
  else if (RTEST(hold))
4518
4184
  /*
4519
4185
  * EXEC SQL declare :cid cursor with hold for :sid;
4520
4186
  */
4521
- #line 3535 "informix.ec"
4187
+ #line 3110 "informixc.ec"
4522
4188
  {
4523
- #line 3535 "informix.ec"
4189
+ #line 3110 "informixc.ec"
4524
4190
  sqli_curs_decl_dynm(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 0), cid, sqli_curs_locate(ESQLINTVERSION, sid, 1), 4096, 0);
4525
- #line 3535 "informix.ec"
4191
+ #line 3110 "informixc.ec"
4526
4192
  }
4527
4193
  else if (RTEST(scroll))
4528
4194
  /*
4529
4195
  * EXEC SQL declare :cid scroll cursor for :sid;
4530
4196
  */
4531
- #line 3537 "informix.ec"
4197
+ #line 3112 "informixc.ec"
4532
4198
  {
4533
- #line 3537 "informix.ec"
4199
+ #line 3112 "informixc.ec"
4534
4200
  sqli_curs_decl_dynm(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 0), cid, sqli_curs_locate(ESQLINTVERSION, sid, 1), 32, 0);
4535
- #line 3537 "informix.ec"
4201
+ #line 3112 "informixc.ec"
4536
4202
  }
4537
4203
  else
4538
4204
  /*
4539
4205
  * EXEC SQL declare :cid cursor for :sid;
4540
4206
  */
4541
- #line 3539 "informix.ec"
4207
+ #line 3114 "informixc.ec"
4542
4208
  {
4543
- #line 3539 "informix.ec"
4209
+ #line 3114 "informixc.ec"
4544
4210
  sqli_curs_decl_dynm(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 0), cid, sqli_curs_locate(ESQLINTVERSION, sid, 1), 0, 0);
4545
- #line 3539 "informix.ec"
4211
+ #line 3114 "informixc.ec"
4546
4212
  }
4547
4213
 
4548
4214
  if (SQLCODE < 0)
4549
4215
  raise_ifx_extended();
4550
4216
 
4551
- alloc_input_slots(c, c_query);
4217
+ alloc_input_slots(&c, c_query);
4552
4218
  /*
4553
4219
  * EXEC SQL describe :sid into output;
4554
4220
  */
4555
- #line 3545 "informix.ec"
4221
+ #line 3120 "informixc.ec"
4556
4222
  {
4557
- #line 3545 "informix.ec"
4223
+ #line 3120 "informixc.ec"
4558
4224
  sqli_describe_stmt(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, sid, 257), &output, 0);
4559
- #line 3545 "informix.ec"
4225
+ #line 3120 "informixc.ec"
4560
4226
  }
4561
- c->daOutput = output;
4227
+ c.daOutput = output;
4562
4228
 
4563
- c->is_select = (SQLCODE == 0 || SQLCODE == SQ_EXECPROC);
4229
+ c.is_select = (SQLCODE == 0 || SQLCODE == SQ_EXECPROC);
4564
4230
 
4565
- if (c->is_select) {
4566
- alloc_output_slots(c);
4567
- rb_extend_object(self, rb_mSequentialCursor);
4231
+ if (c.is_select) {
4232
+ alloc_output_slots(&c);
4568
4233
  if (scroll)
4569
- rb_extend_object(self, rb_mScrollCursor);
4234
+ ret = cursorbase_alloc(rb_cScrollCursor);
4235
+ else
4236
+ ret = cursorbase_alloc(rb_cSequentialCursor);
4570
4237
  }
4571
4238
  else {
4572
- xfree(c->daOutput);
4573
- c->daOutput = NULL;
4574
- rb_extend_object(self, rb_mInsertCursor);
4239
+ xfree(c.daOutput);
4240
+ c.daOutput = NULL;
4241
+ ret = cursorbase_alloc(rb_cInsertCursor);
4575
4242
  }
4576
- return self;
4577
- }
4578
-
4579
- static VALUE cursor_drop(VALUE self);
4580
- /*
4581
- * call-seq:
4582
- * Cursor.new(database, query, options) => cursor
4583
- * Cursor.new(database, query, options) {|cursor| block } => obj
4584
- *
4585
- * Creates a Cursor object based on <i>query</i> using <i>options</i>
4586
- * in the context of <i>database</i> but does not open it.
4587
- * In the first form the Cursor object is returned.
4588
- * In the second form the Cursor object is passed to the block and when it
4589
- * terminates, the Cursor object is dropped, returning the value of the block.
4590
- *
4591
- * <i>options</i> can be nil or a Hash object with the following possible keys:
4592
- *
4593
- * :scroll => true or false
4594
- * :hold => true or false
4595
- */
4596
- static VALUE
4597
- rb_cursor_s_new(int argc, VALUE *argv, VALUE klass)
4598
- {
4599
- VALUE cursor;
4600
-
4601
- cursor = rb_class_new_instance(argc, argv, klass);
4602
-
4603
- if (rb_block_given_p())
4604
- return rb_ensure(rb_yield, cursor, cursor_drop, cursor);
4605
-
4606
- return cursor;
4607
- }
4608
-
4609
- static VALUE cursor_open(int argc, VALUE *argv, VALUE self);
4610
- /*
4611
- * call-seq:
4612
- * Cursor.open(database, query, options) => cursor
4613
- * Cursor.open(database, query, options) {|cursor| block } => obj
4614
- *
4615
- * Creates and opens a Cursor object based on <i>query</i> using <i>options</i>
4616
- * in the context of <i>database</i>.
4617
- * In the first form the Cursor object is returned.
4618
- * In the second form the Cursor object is passed to the block and when it
4619
- * terminates, the Cursor object is dropped, returning the value of the block.
4620
- *
4621
- * <i>options</i> can be nil or a Hash object with the following possible keys:
4622
- *
4623
- * :scroll => true or false
4624
- * :hold => true or false
4625
- * :params => input parameters as an Array or nil
4626
- */
4627
- static VALUE
4628
- cursor_s_open(int argc, VALUE *argv, VALUE klass)
4629
- {
4630
- VALUE cursor, options, params;
4631
- int open_argc;
4632
-
4633
- rb_scan_args(argc, argv, "21", 0, 0, &options);
4634
- open_argc = 0; params = Qnil;
4635
-
4636
- if (!NIL_P(options)) {
4637
- Check_Type(options, T_HASH);
4638
- params = rb_hash_aref(options, sym_params);
4639
-
4640
- if (TYPE(params) == T_ARRAY)
4641
- open_argc = RARRAY(params)->len;
4642
- else if (params != Qnil)
4643
- rb_raise(rb_eArgError, "Parameters must be supplied as an Array");
4644
- }
4645
-
4646
- cursor = rb_class_new_instance(argc, argv, klass);
4647
- cursor_open(open_argc, &params, cursor);
4648
-
4649
- if (rb_block_given_p())
4650
- return rb_ensure(rb_yield, cursor, cursor_drop, cursor);
4651
-
4652
- return cursor;
4653
- }
4654
-
4655
- /*
4656
- * call-seq:
4657
- * cursor.id => string
4658
- *
4659
- * Returns the cursor ID
4660
- */
4661
- static VALUE
4662
- cursor_id(VALUE self)
4663
- {
4664
- cursor_t *c;
4665
-
4666
- Data_Get_Struct(self, cursor_t, c);
4667
- return rb_str_new2(c->cursor_id);
4668
- }
4669
-
4670
- /*
4671
- * call-seq:
4672
- * cursor.open(*params) => cursor
4673
- *
4674
- * Executes the previously prepared select statement, binding <i>params</i> as
4675
- * input parameters.
4676
- *
4677
- * Returns __self__.
4678
- */
4679
- static VALUE
4680
- cursor_open(int argc, VALUE *argv, VALUE self)
4681
- {
4682
- struct sqlda *input;
4683
- cursor_t *c;
4684
- /*
4685
- * EXEC SQL begin declare section;
4686
- */
4687
- #line 3669 "informix.ec"
4688
- #line 3670 "informix.ec"
4689
- char *cid, *did;
4690
- /*
4691
- * EXEC SQL end declare section;
4692
- */
4693
- #line 3671 "informix.ec"
4694
-
4695
-
4696
- Data_Get_Struct(self, cursor_t, c);
4697
-
4698
- if (c->is_open)
4699
- return self;
4700
-
4701
- did = c->database_id;
4702
- /*
4703
- * EXEC SQL set connection :did;
4704
- */
4705
- #line 3679 "informix.ec"
4706
- {
4707
- #line 3679 "informix.ec"
4708
- sqli_connect_set(0, did, 0);
4709
- #line 3679 "informix.ec"
4710
- }
4711
- if (SQLCODE < 0)
4712
- raise_ifx_extended();
4713
-
4714
- input = &c->daInput;
4715
- cid = c->cursor_id;
4716
-
4717
- if (c->is_select) {
4718
- if (argc != input->sqld) {
4719
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
4720
- argc, input->sqld);
4721
- }
4722
- if (argc) {
4723
- bind_input_params(c, argv);
4724
- /*
4725
- * EXEC SQL open :cid using descriptor input
4726
- * with reoptimization;
4727
- */
4728
- #line 3693 "informix.ec"
4729
- {
4730
- #line 3694 "informix.ec"
4731
- sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), input, (char *)0, (struct value *)0, 1, 1);
4732
- #line 3694 "informix.ec"
4733
- }
4734
- clean_input_slots(c);
4735
- }
4736
- else
4737
- /*
4738
- * EXEC SQL open :cid with reoptimization;
4739
- */
4740
- #line 3698 "informix.ec"
4741
- {
4742
- #line 3698 "informix.ec"
4743
- sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0, 1);
4744
- #line 3698 "informix.ec"
4745
- }
4746
- }
4747
- else
4748
- /*
4749
- * EXEC SQL open :cid;
4750
- */
4751
- #line 3701 "informix.ec"
4752
- {
4753
- #line 3701 "informix.ec"
4754
- sqli_curs_open(ESQLINTVERSION, sqli_curs_locate(ESQLINTVERSION, cid, 256), (ifx_sqlda_t *)0, (char *)0, (struct value *)0, 0, 0);
4755
- #line 3701 "informix.ec"
4756
- }
4757
-
4758
- if (SQLCODE < 0)
4759
- raise_ifx_extended();
4760
-
4761
- c->is_open = 1;
4762
- return self;
4763
- }
4764
-
4765
- /*
4766
- * call-seq:
4767
- * cursor.close => cursor
4768
- *
4769
- * Closes the cursor and returns __self__.
4770
- */
4771
- static VALUE
4772
- cursor_close(VALUE self)
4773
- {
4774
- cursor_t *c;
4775
-
4776
- Data_Get_Struct(self, cursor_t, c);
4777
- cursor_close_or_free(c, 1);
4778
- return self;
4779
- }
4780
-
4781
- /*
4782
- * call-seq:
4783
- * cursor.drop => nil
4784
- *
4785
- * Closes the cursor and frees the memory associated with it. The cursor
4786
- * cannot be opened again.
4787
- */
4788
- static VALUE
4789
- cursor_drop(VALUE self)
4790
- {
4791
- cursor_t *c;
4792
-
4793
- Data_Get_Struct(self, cursor_t, c);
4794
- cursor_close_or_free(c, 2);
4795
-
4796
- return Qnil;
4797
- }
4798
-
4799
- /* Entry point ------------------------------------------------------------ */
4800
-
4801
- void Init_informix(void)
4802
- {
4803
- /* module Informix ---------------------------------------------------- */
4243
+ Data_Get_Struct(ret, cursor_t, cur);
4244
+ memcpy(cur, &c, sizeof(cursor_t));
4245
+
4246
+ return ret;
4247
+ }
4248
+
4249
+ void Init_informixc(void)
4250
+ {
4251
+ /*
4252
+ * The +Informix+ module contains the mechanisms for connecting to and
4253
+ * taking advantage of an existing Informix database by means of a
4254
+ * simple model, similar to the one used in ESQL/C.
4255
+ *
4256
+ * The interaction with an Informix database is made basically through three
4257
+ * classes: +Database+, +Statement+ and +Cursor+.
4258
+ *
4259
+ * +Cursor+ is actually a module that works as a shortcut for creating three
4260
+ * kinds of cursors: +SequentialCursor+, +ScrollCursor+ and +InsertCursor+.
4261
+ *
4262
+ * There are other classes for supporting some data types not available in
4263
+ * Ruby: +Slob+, +SlobStat+ and +Interval+.
4264
+ *
4265
+ * Again, +Interval+ is actually a module that works as a shortcut for
4266
+ * creating two kinds of intervals: +IntervalYTM+ and +IntervalDTS+.
4267
+ */
4804
4268
  rb_mInformix = rb_define_module("Informix");
4805
- rb_mScrollCursor = rb_define_module_under(rb_mInformix, "ScrollCursor");
4806
- rb_mInsertCursor = rb_define_module_under(rb_mInformix, "InsertCursor");
4807
- rb_define_module_function(rb_mInformix, "connect", rb_informix_connect, -1);
4808
- rb_define_module_function(rb_mInformix, "version", rb_informix_version, 0);
4809
4269
 
4810
- /* class Slob --------------------------------------------------------- */
4270
+ /*
4271
+ * The +Slob+ class is the Ruby interface for handling Smart Large Objects.
4272
+ * It provides methods for every action applicable to an SLOB.
4273
+ *
4274
+ * Examples:
4275
+ *
4276
+ * # Storing BLOBs read from files
4277
+ * Slob = Informix::Slob
4278
+ * db.execute("create table album (filename varchar(30), picture blob)")
4279
+ * st = db.prepare("insert into album values(?, ?)")
4280
+ * Dir.glob("*jpg") do |filename|
4281
+ * slob = db.slob(Slob::BLOB)
4282
+ * slob.write(File.read(filename)) # same as slob <<File.read(filename)
4283
+ * slob.close
4284
+ * st.execute(filename, slob)
4285
+ * end
4286
+ *
4287
+ *
4288
+ * # Retrieving BLOBs and writing them to files
4289
+ * db.each_hash("select filename, picture from album") do |r|
4290
+ * slob = r['picture'].open
4291
+ * File.open(r['filename'], "w") do |f|
4292
+ * f.write r['picture'].read(r['picture'].size)
4293
+ * end
4294
+ * slob.close
4295
+ * end
4296
+ */
4811
4297
  rb_cSlob = rb_define_class_under(rb_mInformix, "Slob", rb_cObject);
4812
4298
  rb_define_alloc_func(rb_cSlob, slob_alloc);
4813
4299
  rb_define_method(rb_cSlob, "initialize", rb_slob_initialize, -1);
4814
- rb_define_singleton_method(rb_cSlob, "new", rb_slob_s_new, -1);
4815
4300
  rb_define_method(rb_cSlob, "open", rb_slob_open, -1);
4816
4301
  rb_define_method(rb_cSlob, "close", rb_slob_close, 0);
4817
4302
  rb_define_method(rb_cSlob, "read", rb_slob_read, 1);
4818
4303
  rb_define_method(rb_cSlob, "write", rb_slob_write, 1);
4819
4304
  rb_define_method(rb_cSlob, "seek", rb_slob_seek, 2);
4820
4305
  rb_define_method(rb_cSlob, "tell", rb_slob_tell, 0);
4821
- rb_define_alias(rb_cSlob, "pos", "tell");
4822
4306
  rb_define_method(rb_cSlob, "pos=", rb_slob_set_pos, 1);
4823
4307
  rb_define_method(rb_cSlob, "truncate", rb_slob_truncate, 1);
4824
4308
  rb_define_method(rb_cSlob, "stat", rb_slob_stat, 0);
@@ -4845,38 +4329,38 @@ void Init_informix(void)
4845
4329
  rb_define_const(rb_cSlob, "CLOB", INT2FIX(XID_CLOB));
4846
4330
  rb_define_const(rb_cSlob, "BLOB", INT2FIX(XID_BLOB));
4847
4331
 
4848
- #define DEF_SLOB_CONST(k) rb_define_const(rb_cSlob, #k, INT2FIX(LO_##k))
4849
-
4850
- /* Access modes */
4851
- DEF_SLOB_CONST(RDONLY);
4852
- DEF_SLOB_CONST(DIRTY_READ);
4853
- DEF_SLOB_CONST(WRONLY);
4854
- DEF_SLOB_CONST(APPEND);
4855
- DEF_SLOB_CONST(RDWR);
4856
- DEF_SLOB_CONST(BUFFER);
4857
- DEF_SLOB_CONST(NOBUFFER);
4858
- DEF_SLOB_CONST(LOCKALL);
4859
- DEF_SLOB_CONST(LOCKRANGE);
4860
- DEF_SLOB_CONST(SEEK_SET);
4861
- DEF_SLOB_CONST(SEEK_CUR);
4862
- DEF_SLOB_CONST(SEEK_END);
4332
+ /* Access modes */
4333
+ rb_define_const(rb_cSlob, "RDONLY", INT2FIX(LO_RDONLY));
4334
+ rb_define_const(rb_cSlob, "DIRTY_READ", INT2FIX(LO_DIRTY_READ));
4335
+ rb_define_const(rb_cSlob, "WRONLY", INT2FIX(LO_WRONLY));
4336
+ rb_define_const(rb_cSlob, "APPEND", INT2FIX(LO_APPEND));
4337
+ rb_define_const(rb_cSlob, "RDWR", INT2FIX(LO_RDWR));
4338
+ rb_define_const(rb_cSlob, "BUFFER", INT2FIX(LO_BUFFER));
4339
+ rb_define_const(rb_cSlob, "NOBUFFER", INT2FIX(LO_NOBUFFER));
4340
+ rb_define_const(rb_cSlob, "LOCKALL", INT2FIX(LO_LOCKALL));
4341
+ rb_define_const(rb_cSlob, "LOCKRANGE", INT2FIX(LO_LOCKRANGE));
4342
+ rb_define_const(rb_cSlob, "SEEK_SET", INT2FIX(LO_SEEK_SET));
4343
+ rb_define_const(rb_cSlob, "SEEK_CUR", INT2FIX(LO_SEEK_CUR));
4344
+ rb_define_const(rb_cSlob, "SEEK_END", INT2FIX(LO_SEEK_END));
4863
4345
 
4864
4346
  /* Creation-time flags */
4865
- DEF_SLOB_CONST(LOG);
4866
- DEF_SLOB_CONST(NOLOG);
4867
- DEF_SLOB_CONST(KEEP_LASTACCESS_TIME);
4868
- DEF_SLOB_CONST(NOKEEP_LASTACCESS_TIME);
4347
+ rb_define_const(rb_cSlob, "LOG", INT2FIX(LO_LOG));
4348
+ rb_define_const(rb_cSlob, "NOLOG", INT2FIX(LO_NOLOG));
4349
+ rb_define_const(rb_cSlob, "KEEP_LASTACCESS_TIME", INT2FIX(LO_KEEP_LASTACCESS_TIME));
4350
+ rb_define_const(rb_cSlob, "NOKEEP_LASTACCESS_TIME", INT2FIX(LO_NOKEEP_LASTACCESS_TIME));
4869
4351
 
4870
4352
  /* Ranges */
4871
- DEF_SLOB_CONST(CURRENT_END);
4872
- DEF_SLOB_CONST(MAX_END);
4353
+ rb_define_const(rb_cSlob, "CURRENT_END", INT2FIX(LO_CURRENT_END));
4354
+ rb_define_const(rb_cSlob, "MAX_END", INT2FIX(LO_MAX_END));
4873
4355
 
4874
4356
  /* Lock modes */
4875
- DEF_SLOB_CONST(SHARED_MODE);
4876
- DEF_SLOB_CONST(EXCLUSIVE_MODE);
4877
-
4878
- /* class Slob::Stat --------------------------------------------------- */
4357
+ rb_define_const(rb_cSlob, "SHARED_MODE", INT2FIX(LO_SHARED_MODE));
4358
+ rb_define_const(rb_cSlob, "EXCLUSIVE_MODE", INT2FIX(LO_EXCLUSIVE_MODE));
4879
4359
 
4360
+ /*
4361
+ * An instance of the <tt>Slob::Stat</tt> class is returned when an Slob
4362
+ * is queried about its status information (<tt>Slob#stat</tt>).
4363
+ */
4880
4364
  rb_cSlobStat = rb_define_class_under(rb_cSlob, "Stat", rb_cObject);
4881
4365
  rb_define_alloc_func(rb_cSlobStat, slobstat_alloc);
4882
4366
  rb_define_method(rb_cSlobStat, "initialize", rb_slobstat_initialize, 1);
@@ -4890,106 +4374,122 @@ void Init_informix(void)
4890
4374
  rb_define_method(rb_cSlobStat, "refcnt", rb_slobstat_refcnt, 0);
4891
4375
  rb_define_method(rb_cSlobStat, "size", rb_slobstat_size, 0);
4892
4376
 
4893
- /* class Database ----------------------------------------------------- */
4377
+ /*
4378
+ * The +Database+ class lets you open a connection to an existing database
4379
+ * (usually done with <tt>Informix.connect</tt>) and provides shortcuts for
4380
+ * creating +Cursor+, +Statement+ and +Slob+ objects, among other database
4381
+ * actions.
4382
+ */
4894
4383
  rb_cDatabase = rb_define_class_under(rb_mInformix, "Database", rb_cObject);
4895
4384
  rb_define_alloc_func(rb_cDatabase, database_alloc);
4896
4385
  rb_define_method(rb_cDatabase, "initialize", rb_database_initialize, -1);
4897
- rb_define_singleton_method(rb_cDatabase, "open", rb_database_s_open, -1);
4898
- rb_define_alias(rb_cDatabase, "new", "open");
4899
4386
  rb_define_method(rb_cDatabase, "close", rb_database_close, 0);
4900
- rb_define_alias(rb_cDatabase, "disconnect", "close");
4901
4387
  rb_define_method(rb_cDatabase, "immediate", rb_database_immediate, 1);
4902
- rb_define_alias(rb_cDatabase, "do", "immediate");
4903
- rb_define_alias(rb_cDatabase, "execute", "immediate");
4904
4388
  rb_define_method(rb_cDatabase, "rollback", rb_database_rollback, 0);
4905
4389
  rb_define_method(rb_cDatabase, "commit", rb_database_commit, 0);
4906
4390
  rb_define_method(rb_cDatabase, "transaction", rb_database_transaction, 0);
4907
- rb_define_method(rb_cDatabase, "prepare", rb_database_prepare, 1);
4908
4391
  rb_define_method(rb_cDatabase, "columns", rb_database_columns, 1);
4909
- rb_define_method(rb_cDatabase, "cursor", rb_database_cursor, -1);
4910
- rb_define_method(rb_cDatabase, "slob", rb_database_slob, -1);
4911
4392
 
4912
- /* class Statement ---------------------------------------------------- */
4913
- rb_cStatement = rb_define_class_under(rb_mInformix, "Statement", rb_cObject);
4393
+ rb_define_const(rb_cDatabase, "IfxVersion",
4394
+ rb_struct_define("IfxVersion", "server_type", "major",
4395
+ "minor", "level", "os", "full", NULL));
4396
+ rb_cIfxVersion = rb_const_get(rb_cDatabase, rb_intern("IfxVersion"));
4397
+
4398
+ /*
4399
+ * The +Statement+ class lets you prepare and execute any SQL statement,
4400
+ * (usually done with <tt>Database#prepare</tt>)
4401
+ * paremeterized or not, that does not return records. This includes
4402
+ * DDL (CREATE, DROP, ALTER), DCL (GRANT, REVOKE) and DML (INSERT, UPDATE,
4403
+ * DELETE) statements, and SELECTs that return <b>only one</b> record at
4404
+ * most.
4405
+ *
4406
+ * To retrieve more than one record, use a +Cursor+ instead.
4407
+ */
4408
+ rb_cStatement = rb_define_class_under(rb_mInformix, "Statement",rb_cObject);
4914
4409
  rb_define_alloc_func(rb_cStatement, statement_alloc);
4915
- rb_define_method(rb_cStatement, "initialize", statement_initialize, 2);
4916
- rb_define_singleton_method(rb_cStatement, "new", statement_s_new, -1);
4917
- rb_define_method(rb_cStatement, "[]", statement_call, -1);
4918
- rb_define_alias(rb_cStatement, "call", "[]");
4919
- rb_define_alias(rb_cStatement, "execute", "[]");
4920
- rb_define_method(rb_cStatement, "drop", statement_drop, 0);
4921
-
4922
- /* module SequentialCursor -------------------------------------------- */
4923
- rb_mSequentialCursor = rb_define_module_under(rb_mInformix, "SequentialCursor");
4924
- rb_define_method(rb_mSequentialCursor, "fetch", seqcur_fetch, 0);
4925
- rb_define_method(rb_mSequentialCursor, "fetch!", seqcur_fetch_bang, 0);
4926
- rb_define_method(rb_mSequentialCursor, "fetch_hash", seqcur_fetch_hash, 0);
4927
- rb_define_method(rb_mSequentialCursor, "fetch_hash!", seqcur_fetch_hash_bang, 0);
4928
- rb_define_method(rb_mSequentialCursor, "fetch_many", seqcur_fetch_many, 1);
4929
- rb_define_method(rb_mSequentialCursor, "fetch_hash_many", seqcur_fetch_hash_many, 1);
4930
- rb_define_method(rb_mSequentialCursor, "fetch_all", seqcur_fetch_all, 0);
4931
- rb_define_method(rb_mSequentialCursor, "fetch_hash_all", seqcur_fetch_hash_all, 0);
4932
- rb_define_method(rb_mSequentialCursor, "each", seqcur_each, 0);
4933
- rb_define_method(rb_mSequentialCursor, "each!", seqcur_each_bang, 0);
4934
- rb_define_method(rb_mSequentialCursor, "each_hash", seqcur_each_hash, 0);
4935
- rb_define_method(rb_mSequentialCursor, "each_hash!", seqcur_each_hash_bang, 0);
4936
- rb_define_method(rb_mSequentialCursor, "each_by", seqcur_each_by, 1);
4937
- rb_define_method(rb_mSequentialCursor, "each_hash_by", seqcur_each_hash_by, 1);
4938
-
4939
- /* InsertCursor ------------------------------------------------------- */
4940
- rb_define_method(rb_mInsertCursor, "put", inscur_put, -1);
4941
- rb_define_method(rb_mInsertCursor, "flush", inscur_flush, 0);
4942
-
4943
- /* ScrollCursor ------------------------------------------------------- */
4944
- rb_define_method(rb_mScrollCursor, "[]", scrollcur_slice, -1);
4945
- rb_define_alias(rb_mScrollCursor, "slice", "[]");
4946
- rb_define_method(rb_mScrollCursor, "slice!", scrollcur_slice_bang, 1);
4947
- rb_define_method(rb_mScrollCursor, "slice_hash", scrollcur_slice_hash, -1);
4948
- rb_define_method(rb_mScrollCursor, "slice_hash!", scrollcur_slice_hash_bang, 1);
4949
- rb_define_method(rb_mScrollCursor, "prev", scrollcur_prev, -1);
4950
- rb_define_method(rb_mScrollCursor, "prev!", scrollcur_prev_bang, -1);
4951
- rb_define_method(rb_mScrollCursor, "prev_hash", scrollcur_prev_hash, -1);
4952
- rb_define_method(rb_mScrollCursor, "prev_hash!", scrollcur_prev_hash_bang, -1);
4953
- rb_define_method(rb_mScrollCursor, "next", scrollcur_next, -1);
4954
- rb_define_method(rb_mScrollCursor, "next!", scrollcur_next_bang, -1);
4955
- rb_define_method(rb_mScrollCursor, "next_hash", scrollcur_next_hash, -1);
4956
- rb_define_method(rb_mScrollCursor, "next_hash!", scrollcur_next_hash_bang, -1);
4957
- rb_define_method(rb_mScrollCursor, "first", scrollcur_first, 0);
4958
- rb_define_method(rb_mScrollCursor, "first!", scrollcur_first_bang, 0);
4959
- rb_define_method(rb_mScrollCursor, "first_hash", scrollcur_first_hash, 0);
4960
- rb_define_method(rb_mScrollCursor, "first_hash!", scrollcur_first_hash_bang, 0);
4961
- rb_define_method(rb_mScrollCursor, "last", scrollcur_last, 0);
4962
- rb_define_method(rb_mScrollCursor, "last!", scrollcur_last_bang, 0);
4963
- rb_define_method(rb_mScrollCursor, "last_hash", scrollcur_last_hash, 0);
4964
- rb_define_method(rb_mScrollCursor, "last_hash!", scrollcur_last_hash_bang, 0);
4965
- rb_define_method(rb_mScrollCursor, "current", scrollcur_current, 0);
4966
- rb_define_method(rb_mScrollCursor, "current!", scrollcur_current_bang, 0);
4967
- rb_define_method(rb_mScrollCursor, "current_hash", scrollcur_current_hash, 0);
4968
- rb_define_method(rb_mScrollCursor, "current_hash!", scrollcur_current_hash_bang, 0);
4969
-
4970
- /* class Cursor ------------------------------------------------------- */
4971
- rb_cCursor = rb_define_class_under(rb_mInformix, "Cursor", rb_cObject);
4972
- rb_define_alloc_func(rb_cCursor, cursor_alloc);
4973
- rb_define_method(rb_cCursor, "initialize", cursor_initialize, -1);
4974
- rb_define_singleton_method(rb_cCursor, "new", rb_cursor_s_new, -1);
4975
- rb_define_singleton_method(rb_cCursor, "open", cursor_s_open, -1);
4976
- rb_define_method(rb_cCursor, "id", cursor_id, 0);
4977
- rb_define_method(rb_cCursor, "open", cursor_open, -1);
4978
- rb_define_method(rb_cCursor, "close", cursor_close, 0);
4979
- rb_define_method(rb_cCursor, "drop", cursor_drop, 0);
4410
+ rb_define_method(rb_cStatement, "initialize", rb_statement_initialize, 2);
4411
+ rb_define_method(rb_cStatement, "[]", rb_statement_call, -1);
4412
+ rb_define_method(rb_cStatement, "drop", rb_statement_drop, 0);
4413
+
4414
+ /*
4415
+ * The +CursorBase+ class provides the basic functionality for any cursor.
4416
+ */
4417
+ rb_cCursorBase=rb_define_class_under(rb_mInformix,"CursorBase",rb_cObject);
4418
+ rb_define_alloc_func(rb_cCursorBase, cursorbase_alloc);
4419
+ rb_define_method(rb_cCursorBase, "id", rb_cursorbase_id, 0);
4420
+ rb_define_method(rb_cCursorBase, "open", rb_cursorbase_open, -1);
4421
+ rb_define_method(rb_cCursorBase, "close", rb_cursorbase_close, 0);
4422
+ rb_define_method(rb_cCursorBase, "drop", rb_cursorbase_drop, 0);
4423
+
4424
+ /*
4425
+ * The +SequentialCursor+ class adds fetching capabilities and iterators
4426
+ * to the +CursorBase+ class.
4427
+ */
4428
+ rb_cSequentialCursor = rb_define_class_under(rb_mInformix, "SequentialCursor", rb_cCursorBase);
4429
+ rb_define_private_method(rb_cSequentialCursor, "fetch0", fetch, 2);
4430
+ rb_define_private_method(rb_cSequentialCursor, "fetch_many0", fetch_many,2);
4431
+ rb_define_private_method(rb_cSequentialCursor, "each0", each, 2);
4432
+ rb_define_private_method(rb_cSequentialCursor, "each_by0", each_by, 2);
4433
+
4434
+ /*
4435
+ * The +InsertCursor+ class adds insertion capabilities to the +CursorBase+
4436
+ * class.
4437
+ */
4438
+ rb_cInsertCursor = rb_define_class_under(rb_mInformix, "InsertCursor", rb_cCursorBase);
4439
+ rb_define_method(rb_cInsertCursor, "put", rb_inscur_put, -1);
4440
+ rb_define_method(rb_cInsertCursor, "flush", rb_inscur_flush, 0);
4441
+
4442
+ /*
4443
+ * The +ScrollCursor+ class adds +Array+-like capabilities to the
4444
+ * +SequentialCursor+ class
4445
+ */
4446
+ rb_cScrollCursor = rb_define_class_under(rb_mInformix, "ScrollCursor", rb_cSequentialCursor);
4447
+ rb_define_private_method(rb_cScrollCursor, "entry", rb_scrollcur_entry, 3);
4448
+ rb_define_private_method(rb_cScrollCursor, "rel", rb_scrollcur_rel, 3);
4449
+
4450
+ /*
4451
+ * The +Cursor+ module provides shortcuts for creating cursor objects that
4452
+ * lets you retrieve, update and insert records.
4453
+ *
4454
+ * Depending on the query and options given, one of three classes of
4455
+ * cursors is returned: +SequentialCursor+, +ScrollCursor+ or
4456
+ * +InsertCursor+.
4457
+ */
4458
+ rb_mCursor = rb_define_module_under(rb_mInformix, "Cursor");
4459
+ rb_define_singleton_method(rb_mCursor, "new0", rb_cursor_s_new0, -1);
4980
4460
 
4981
4461
  /* Global constants --------------------------------------------------- */
4462
+ rb_cArray = rb_const_get(rb_cObject, rb_intern("Array"));
4463
+
4982
4464
  rb_require("date");
4983
4465
  rb_cDate = rb_const_get(rb_cObject, rb_intern("Date"));
4466
+
4984
4467
  rb_require("bigdecimal");
4985
4468
  rb_cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal"));
4986
4469
 
4470
+ rb_cRational = rb_const_get(rb_cObject, rb_intern("Rational"));
4471
+
4472
+ rb_require("informix/exceptions");
4473
+ rb_eError = rb_const_get(rb_mInformix, rb_intern("Error"));
4474
+ rb_eWarning = rb_const_get(rb_mInformix, rb_intern("Warning"));
4475
+ rb_eInternalError = rb_const_get(rb_mInformix, rb_intern("InternalError"));
4476
+ rb_eProgrammingError = rb_const_get(rb_mInformix, rb_intern("ProgrammingError"));
4477
+ rb_eOperationalError = rb_const_get(rb_mInformix, rb_intern("OperationalError"));
4478
+ rb_eDatabaseError = rb_const_get(rb_mInformix, rb_intern("DatabaseError"));
4479
+
4480
+ rb_require("informix/interval");
4481
+ rb_mInterval = rb_const_get(rb_mInformix, rb_intern("Interval"));
4482
+
4987
4483
  /* Global symbols ----------------------------------------------------- */
4988
4484
  #define INTERN(sym) s_##sym = rb_intern(#sym)
4989
4485
  INTERN(read); INTERN(new);
4990
4486
  INTERN(utc); INTERN(day); INTERN(month); INTERN(year);
4991
4487
  INTERN(hour); INTERN(min); INTERN(sec); INTERN(usec);
4992
4488
  INTERN(to_s); INTERN(to_i);
4489
+ INTERN(add_info);
4490
+ INTERN(from_months); INTERN(from_seconds);
4491
+ s_add = rb_intern("+");
4492
+ s_mul = rb_intern("*");
4993
4493
 
4994
4494
  sym_name = ID2SYM(rb_intern("name"));
4995
4495
  sym_type = ID2SYM(rb_intern("type"));
@@ -5013,9 +4513,6 @@ void Init_informix(void)
5013
4513
  sym_maxbytes = ID2SYM(rb_intern("maxbytes"));
5014
4514
 
5015
4515
  sym_params = ID2SYM(rb_intern("params"));
5016
-
5017
- /* Initialize ifx_except module */
5018
- rbifx_except_init(rb_mInformix, &esyms);
5019
4516
  }
5020
4517
 
5021
- #line 3964 "informix.ec"
4518
+ #line 3410 "informixc.ec"