ruby-odbc 0.99991 → 0.99992

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,6 +1,21 @@
1
1
  ODBC binding for Ruby
2
2
  ---------------------
3
3
 
4
+ Thu Sep 16 2010 version 0.99992 released
5
+
6
+ * ODBC::Statement.each/each_hash now output arrays when
7
+ invoked without block
8
+ * column keys in result hashes now are cached/recycled Ruby strings
9
+ * added ODBC::Database methods use_time/use_utc to directly
10
+ output Ruby Time/Date objects
11
+ * added encoding support in the UTF8 variant for Ruby >= 1.9
12
+ * added module constant ODBC::UTF8 to indicate variant of module
13
+ * fixes for M$SQL server reporting zero column sizes
14
+ and unknown data types for varchar(strmax) columns
15
+ * eliminated compiler warnings
16
+ * use StringValueCStr instead of STR2CSTR (Ruby >= 1.9.1)
17
+ * small change for decision when to use SQLGetData() loop
18
+
4
19
  Sun Apr 25 2010 version 0.99991 released
5
20
 
6
21
  * detect HAVE_LONG_LONG for builds with unixODBC
data/README CHANGED
@@ -1,6 +1,6 @@
1
- # $Id: README,v 1.38 2010/04/25 12:27:18 chw Exp chw $
1
+ # $Id: README,v 1.39 2010/09/16 06:54:01 chw Exp chw $
2
2
 
3
- ruby-odbc-0.99991
3
+ ruby-odbc-0.99992
4
4
 
5
5
  This is an ODBC binding for Ruby. So far it has been tested with
6
6
 
data/doc/odbc.html CHANGED
@@ -27,7 +27,7 @@
27
27
  <body>
28
28
  <h1><a name="reference">Ruby ODBC Reference</a></h1>
29
29
  <div class = "lastmodifed">
30
- Last update: Fri, 15 January 2010
30
+ Last update: Thu, 16 September 2010
31
31
  </div>
32
32
  <hr>
33
33
  <div>
@@ -101,6 +101,12 @@
101
101
  </dl>
102
102
  </dl>
103
103
  <h3>constants:</h3>
104
+ <p>
105
+ The boolean constant <var>UTF8</var> reports the character encoding
106
+ of the module. If it is <code>true</code>, the UTF-8 variant of
107
+ the module is in use, and string data is automatically converted
108
+ to/from Unicode.
109
+ </p>
104
110
  <p>
105
111
  Some constants of the ODBC API are defined in order to set connection
106
112
  options, to deal with SQL data types, and to obtain database meta data.
@@ -687,6 +693,19 @@ aproc.statement.drop</pre>
687
693
  <dd>Releases the resources of all open
688
694
  <a href="#ODBC::Statement">ODBC::Statement</a>s in this
689
695
  database connection.
696
+ <dt><a name="use_time"><code>use_time[=<var>bool</var>]</code></a>
697
+ <dd>Sets or queries the mapping of SQL_DATE, SQL_TIME, and
698
+ SQL_TIMESTAMP data types to Ruby objects. When true,
699
+ SQL_DATE is mapped to Ruby Date objects, SQL_TIME and
700
+ SQL_TIMESTAMP are mapped to Ruby Time objects. Otherwise (default)
701
+ <a href="#ODBC::Date">ODBC::Date</a>,
702
+ <a href="#ODBC::Time">ODBC::Time</a>, and
703
+ <a href="#ODBC::Time">ODBC::TimeStamp</a> are used.
704
+ <dt><a name="use_utc"><code>use_utc[=<var>bool</var>]</code></a>
705
+ <dd>Sets or queries the timezone applied on SQL_DATE, SQL_TIME, and
706
+ SQL_TIMESTAMP data types to Ruby objects. When true,
707
+ Ruby Date and Time objects are represented in UTC, when
708
+ false (default) in the local timezone.
690
709
  </dl>
691
710
  <h3>singleton methods:</h3>
692
711
  <dl>
@@ -738,11 +757,17 @@ aproc.statement.drop</pre>
738
757
  <td>T_FIXNUM, T_BIGNUM</td></tr>
739
758
  <tr><td>SQL_FLOAT, SQL_DOUBLE, SQL_REAL</td><td>T_FLOAT</td></tr>
740
759
  <tr><td>SQL_DATE, SQL_TYPE_DATE</td>
741
- <td><a href="#ODBC::Date">ODBC::Date</a></td></tr>
760
+ <td><a href="#ODBC::Date">ODBC::Date</a> or Date,
761
+ see <a href="#use_time">ODBC::Database.use_time</a>
762
+ </td></tr>
742
763
  <tr><td>SQL_TIME, SQL_TYPE_TIME</td>
743
- <td><a href="#ODBC::Time">ODBC::Time</a></td></tr>
764
+ <td><a href="#ODBC::Time">ODBC::Time</a> or Time,
765
+ see <a href="#use_time">ODBC::Database.use_time</a>
766
+ </td></tr>
744
767
  <tr><td>SQL_TIMESTAMP, SQL_TYPE_TIMESTAMP</td>
745
- <td><a href="#ODBC::TimeStamp">ODBC::TimeStamp</a></td></tr>
768
+ <td><a href="#ODBC::TimeStamp">ODBC::TimeStamp</a> or Time,
769
+ see <a href="#use_time">ODBC::Database.use_time</a>
770
+ </td></tr>
746
771
  <tr><td>all others</td><td>T_STRING</td></tr>
747
772
  </table>
748
773
  <h3>super class:</h3>
data/ext/extconf.rb CHANGED
@@ -28,7 +28,7 @@ have_header("sqlext.h") || begin
28
28
  puts "ERROR: sqlext.h not found"
29
29
  exit 1
30
30
  end
31
- testdlopen = enable_config("dlopen", true)
31
+ testdlopen = enable_config("dlopen", false)
32
32
  begin
33
33
  if PLATFORM !~ /(mingw|cygwin)/ then
34
34
  header = "sqltypes.h"
data/ext/odbc.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * ODBC-Ruby binding
3
- * Copyright (c) 2001-2009 Christian Werner <chw@ch-werner.de>
3
+ * Copyright (c) 2001-2010 Christian Werner <chw@ch-werner.de>
4
4
  * Portions copyright (c) 2004 Ryszard Niewisiewicz <micz@fibernet.pl>
5
5
  * Portions copyright (c) 2006 Carl Blakeley <cblakeley@openlinksw.co.uk>
6
6
  *
@@ -8,7 +8,7 @@
8
8
  * and redistribution of this file and for a
9
9
  * DISCLAIMER OF ALL WARRANTIES.
10
10
  *
11
- * $Id: odbc.c,v 1.62 2010/04/25 12:26:37 chw Exp chw $
11
+ * $Id: odbc.c,v 1.70 2010/09/16 06:52:23 chw Exp chw $
12
12
  */
13
13
 
14
14
  #undef ODBCVER
@@ -55,6 +55,10 @@ typedef SQLCHAR SQLTCHAR;
55
55
  #define SQLULEN SQLUINTEGER
56
56
  #endif
57
57
 
58
+ #if (RUBY_VERSION_MAJOR <= 1) && (RUBY_VERSION_MINOR < 9)
59
+ #define TIME_USE_USEC 1
60
+ #endif
61
+
58
62
  /*
59
63
  * Conditionally undefine aliases of ODBC installer UNICODE functions.
60
64
  */
@@ -73,7 +77,7 @@ typedef SQLCHAR SQLTCHAR;
73
77
  #endif
74
78
 
75
79
  #if defined(UNICODE) && defined(USE_DLOPEN_FOR_ODBC_LIBS)
76
- extern int ruby_odbc_have_func(char *name, void *addr);
80
+ extern int ruby_odbc_have_func(const char *name, void *addr);
77
81
  #endif
78
82
 
79
83
  #ifdef UNICODE
@@ -94,6 +98,14 @@ BOOL INSTAPI SQLReadFileDSNW(LPWSTR, LPWSTR, LPWSTR, LPWSTR, WORD, WORD *);
94
98
  #ifndef HAVE_SQLWRITEFILEDSNW
95
99
  BOOL INSTAPI SQLWriteFileDSNW(LPWSTR, LPWSTR, LPWSTR, LPWSTR);
96
100
  #endif
101
+
102
+ #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
103
+ #define USE_RB_ENC 1
104
+ #include "ruby/encoding.h"
105
+ static rb_encoding *rb_enc = NULL;
106
+ static VALUE rb_encv = Qnil;
107
+ #endif
108
+
97
109
  #endif /* UNICODE */
98
110
 
99
111
  #ifndef HAVE_RB_DEFINE_ALLOC_FUNC
@@ -109,11 +121,16 @@ BOOL INSTAPI SQLWriteFileDSNW(LPWSTR, LPWSTR, LPWSTR, LPWSTR);
109
121
  #define CVAR_SET(x, y, z) rb_cvar_set(x, y, z)
110
122
  #endif
111
123
 
124
+ #ifndef STR2CSTR
125
+ #define STR2CSTR(x) StringValueCStr(x)
126
+ #define NO_RB_STR2CSTR 1
127
+ #endif
128
+
112
129
  #ifdef TRACING
113
130
  static int tracing = 0;
114
131
  #define tracemsg(t, x) {if (tracing & t) { x }}
115
132
  static SQLRETURN tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt,
116
- SQLRETURN ret, char *m);
133
+ SQLRETURN ret, const char *m);
117
134
  #else
118
135
  #define tracemsg(t, x)
119
136
  #define tracesql(a, b, c, d, e) d
@@ -148,6 +165,8 @@ typedef struct dbc {
148
165
  struct env *envp;
149
166
  LINK stmts;
150
167
  SQLHDBC hdbc;
168
+ VALUE rbtime;
169
+ VALUE gmtime;
151
170
  int upc;
152
171
  } DBC;
153
172
 
@@ -163,12 +182,12 @@ typedef struct {
163
182
  #ifdef UNICODE
164
183
  SQLWCHAR *tofree;
165
184
  #endif
166
- char buffer[sizeof (double) * 4];
185
+ char buffer[sizeof (double) * 4 + sizeof (TIMESTAMP_STRUCT)];
167
186
  SQLSMALLINT ctype;
168
187
  SQLSMALLINT outtype;
169
188
  int outsize;
170
189
  char *outbuf;
171
- } PINFO;
190
+ } PARAMINFO;
172
191
 
173
192
  typedef struct {
174
193
  int type;
@@ -182,10 +201,11 @@ typedef struct stmt {
182
201
  struct dbc *dbcp;
183
202
  SQLHSTMT hstmt;
184
203
  int nump;
185
- PINFO *pinfo;
204
+ PARAMINFO *paraminfo;
186
205
  int ncols;
187
206
  COLTYPE *coltypes;
188
207
  char **colnames;
208
+ VALUE *colvals;
189
209
  char **dbufs;
190
210
  int fetchc;
191
211
  int upc;
@@ -217,6 +237,8 @@ static ID IDday;
217
237
  static ID IDmonth;
218
238
  static ID IDyear;
219
239
  static ID IDmday;
240
+ static ID IDnsec;
241
+ static ID IDusec;
220
242
  static ID IDsec;
221
243
  static ID IDmin;
222
244
  static ID IDhour;
@@ -248,6 +270,12 @@ static ID IDreturn_output_param;
248
270
  static ID IDattrs;
249
271
  static ID IDNULL;
250
272
  static ID IDdefault;
273
+ #ifdef USE_RB_ENC
274
+ static ID IDencode;
275
+ #endif
276
+ static ID IDparse;
277
+ static ID IDutc;
278
+ static ID IDlocal;
251
279
 
252
280
  /*
253
281
  * Modes for dbc_info
@@ -299,7 +327,7 @@ static ID IDdefault;
299
327
  */
300
328
 
301
329
  static SQLRETURN callsql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt,
302
- SQLRETURN ret, char *m);
330
+ SQLRETURN ret, const char *m);
303
331
 
304
332
  static VALUE stmt_exec(int argc, VALUE *argv, VALUE self);
305
333
  static VALUE stmt_each(VALUE self);
@@ -421,6 +449,9 @@ uc_tainted_str_new(SQLWCHAR *str, int len)
421
449
  ulen = mkutf(cp, str, len);
422
450
  }
423
451
  v = rb_tainted_str_new((cp != NULL) ? cp : "", ulen);
452
+ #ifdef USE_RB_ENC
453
+ rb_enc_associate(v, rb_enc);
454
+ #endif
424
455
  if (cp != NULL) {
425
456
  xfree(cp);
426
457
  }
@@ -443,7 +474,11 @@ uc_str_new(SQLWCHAR *str, int len)
443
474
  if ((cp != NULL) && (str != NULL)) {
444
475
  ulen = mkutf(cp, str, len);
445
476
  }
477
+ #ifdef USE_RB_ENC
478
+ v = rb_enc_str_new((cp != NULL) ? cp : "", ulen, rb_enc);
479
+ #else
446
480
  v = rb_str_new((cp != NULL) ? cp : "", ulen);
481
+ #endif
447
482
  if (cp != NULL) {
448
483
  xfree(cp);
449
484
  }
@@ -494,7 +529,7 @@ uc_from_utf(unsigned char *str, int len)
494
529
  if (c < 0x80) {
495
530
  uc[i++] = c;
496
531
  ++str;
497
- } else if (c <= 0xc1 || (c >= 0xf5 && c <= 0xff)) {
532
+ } else if ((c <= 0xc1) || (c >= 0xf5)) {
498
533
  /* illegal, ignored */
499
534
  ++str;
500
535
  } else if (c < 0xe0) {
@@ -767,16 +802,16 @@ free_dbc(DBC *p)
767
802
  static void
768
803
  free_stmt_sub(STMT *q)
769
804
  {
770
- if (q->pinfo != NULL) {
805
+ if (q->paraminfo != NULL) {
771
806
  int i;
772
807
 
773
808
  for (i = 0; i < q->nump; i++) {
774
- if (q->pinfo[i].outbuf != NULL) {
775
- xfree(q->pinfo[i].outbuf);
809
+ if (q->paraminfo[i].outbuf != NULL) {
810
+ xfree(q->paraminfo[i].outbuf);
776
811
  }
777
812
  }
778
- xfree(q->pinfo);
779
- q->pinfo = NULL;
813
+ xfree(q->paraminfo);
814
+ q->paraminfo = NULL;
780
815
  }
781
816
  q->nump = 0;
782
817
  q->ncols = 0;
@@ -788,6 +823,10 @@ free_stmt_sub(STMT *q)
788
823
  xfree(q->colnames);
789
824
  q->colnames = NULL;
790
825
  }
826
+ if (q->colvals != NULL) {
827
+ xfree(q->colvals);
828
+ q->colvals = NULL;
829
+ }
791
830
  if (q->dbufs != NULL) {
792
831
  xfree(q->dbufs);
793
832
  q->dbufs = NULL;
@@ -803,6 +842,10 @@ free_stmt_sub(STMT *q)
803
842
  if (v != Qnil) {
804
843
  rb_iv_set(q->self, "@_h", rb_hash_new());
805
844
  }
845
+ v = rb_iv_get(q->self, "@_c");
846
+ if (v != Qnil) {
847
+ rb_iv_set(q->self, "@_c", rb_hash_new());
848
+ }
806
849
  }
807
850
  }
808
851
 
@@ -882,11 +925,14 @@ mark_stmt(STMT *q)
882
925
  */
883
926
 
884
927
  static char *
885
- set_err(char *msg, int warn)
928
+ set_err(const char *msg, int warn)
886
929
  {
887
930
  VALUE a, v = rb_str_new2("INTERN (0) [RubyODBC]");
888
931
 
889
932
  v = rb_str_cat2(v, msg);
933
+ #ifdef USE_RB_ENC
934
+ rb_enc_associate(v, rb_enc);
935
+ #endif
890
936
  a = rb_ary_new2(1);
891
937
  rb_ary_push(a, rb_obj_taint(v));
892
938
  CVAR_SET(Cobj, warn ? IDatatinfo : IDataterror, a);
@@ -1031,6 +1077,9 @@ get_installer_err()
1031
1077
  v = rb_str_new2(buf);
1032
1078
  #ifdef UNICODE
1033
1079
  if (have_w) {
1080
+ #ifdef USE_RB_ENC
1081
+ rb_enc_associate(v, rb_enc);
1082
+ #endif
1034
1083
  v = uc_str_cat(v, msg, len);
1035
1084
  } else {
1036
1085
  v = rb_str_cat(v, (char *) msg, len);
@@ -1078,7 +1127,8 @@ get_err(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt)
1078
1127
  static void
1079
1128
  trace_sql_ret(SQLRETURN ret)
1080
1129
  {
1081
- char msg[32], *p;
1130
+ char msg[32];
1131
+ const char *p;
1082
1132
 
1083
1133
  switch (ret) {
1084
1134
  case SQL_SUCCESS:
@@ -1105,7 +1155,8 @@ trace_sql_ret(SQLRETURN ret)
1105
1155
  }
1106
1156
 
1107
1157
  static SQLRETURN
1108
- tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret, char *m)
1158
+ tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1159
+ const char *m)
1109
1160
  {
1110
1161
  if (tracing & 1) {
1111
1162
  fprintf(stderr, "SQLCall: %s", m);
@@ -1118,7 +1169,8 @@ tracesql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret, char *m)
1118
1169
  #endif
1119
1170
 
1120
1171
  static SQLRETURN
1121
- callsql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret, char *m)
1172
+ callsql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1173
+ const char *m)
1122
1174
  {
1123
1175
  SQLRETURN err;
1124
1176
 
@@ -1176,7 +1228,7 @@ succeeded_common(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1176
1228
 
1177
1229
  static int
1178
1230
  succeeded(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1179
- char **msgp, char *m, ...)
1231
+ char **msgp, const char *m, ...)
1180
1232
  {
1181
1233
  #ifdef TRACING
1182
1234
  va_list args;
@@ -1196,7 +1248,7 @@ succeeded(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1196
1248
 
1197
1249
  static int
1198
1250
  succeeded_nodata(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLRETURN ret,
1199
- char **msgp, char *m, ...)
1251
+ char **msgp, const char *m, ...)
1200
1252
  {
1201
1253
  #ifdef TRACING
1202
1254
  va_list args;
@@ -1235,7 +1287,7 @@ env_of(VALUE self)
1235
1287
  Data_Get_Struct(self, STMT, q);
1236
1288
  self = q->dbc;
1237
1289
  if (self == Qnil) {
1238
- rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
1290
+ rb_raise(Cerror, "%s", set_err("Stale ODBC::Statement", 0));
1239
1291
  }
1240
1292
  }
1241
1293
  if (rb_obj_is_kind_of(self, Cdbc) == Qtrue) {
@@ -1244,7 +1296,7 @@ env_of(VALUE self)
1244
1296
  Data_Get_Struct(self, DBC, p);
1245
1297
  self = p->env;
1246
1298
  if (self == Qnil) {
1247
- rb_raise(Cerror, set_err("Stale ODBC::Database", 0));
1299
+ rb_raise(Cerror, "%s", set_err("Stale ODBC::Database", 0));
1248
1300
  }
1249
1301
  }
1250
1302
  return self;
@@ -1278,7 +1330,7 @@ get_dbc(VALUE self)
1278
1330
  Data_Get_Struct(self, STMT, q);
1279
1331
  self = q->dbc;
1280
1332
  if (self == Qnil) {
1281
- rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
1333
+ rb_raise(Cerror, "%s", set_err("Stale ODBC::Statement", 0));
1282
1334
  }
1283
1335
  }
1284
1336
  Data_Get_Struct(self, DBC, p);
@@ -1338,7 +1390,7 @@ env_new(VALUE self)
1338
1390
  self = Cenv;
1339
1391
  }
1340
1392
  if ((!SQL_SUCCEEDED(SQLAllocEnv(&henv))) || (henv == SQL_NULL_HENV)) {
1341
- rb_raise(Cerror, set_err("Cannot allocate SQLHENV", 0));
1393
+ rb_raise(Cerror, "%s", set_err("Cannot allocate SQLHENV", 0));
1342
1394
  }
1343
1395
  obj = Data_Make_Struct(self, ENV, NULL, free_env, e);
1344
1396
  tracemsg(2, fprintf(stderr, "ObjAlloc: ENV %p\n", e););
@@ -1390,14 +1442,16 @@ dbc_dsns(VALUE self)
1390
1442
  VALUE odsn = rb_obj_alloc(Cdsn);
1391
1443
 
1392
1444
  #ifdef UNICODE
1393
- dsnLen = (dsnLen == 0) ? uc_strlen(dsn) : (dsnLen / sizeof (SQLWCHAR));
1445
+ dsnLen = (dsnLen == 0) ? (SQLSMALLINT) uc_strlen(dsn) :
1446
+ (SQLSMALLINT) (dsnLen / sizeof (SQLWCHAR));
1394
1447
  descrLen = (descrLen == 0) ?
1395
- uc_strlen(descr) : (descrLen / sizeof (SQLWCHAR));
1448
+ (SQLSMALLINT) uc_strlen(descr) :
1449
+ (SQLSMALLINT) (descrLen / sizeof (SQLWCHAR));
1396
1450
  rb_iv_set(odsn, "@name", uc_tainted_str_new(dsn, dsnLen));
1397
1451
  rb_iv_set(odsn, "@descr", uc_tainted_str_new(descr, descrLen));
1398
1452
  #else
1399
- dsnLen = (dsnLen == 0) ? strlen(dsn) : dsnLen;
1400
- descrLen = (descrLen == 0) ? strlen(descr) : descrLen;
1453
+ dsnLen = (dsnLen == 0) ? (SQLSMALLINT) strlen(dsn) : dsnLen;
1454
+ descrLen = (descrLen == 0) ? (SQLSMALLINT) strlen(descr) : descrLen;
1401
1455
  rb_iv_set(odsn, "@name", rb_tainted_str_new(dsn, dsnLen));
1402
1456
  rb_iv_set(odsn, "@descr", rb_tainted_str_new(descr, descrLen));
1403
1457
  #endif
@@ -1447,7 +1501,8 @@ dbc_drivers(VALUE self)
1447
1501
 
1448
1502
  #ifdef UNICODE
1449
1503
  driverLen = (driverLen == 0) ?
1450
- uc_strlen(driver) : (driverLen / sizeof (SQLWCHAR));
1504
+ (SQLSMALLINT) uc_strlen(driver) :
1505
+ (SQLSMALLINT) (driverLen / sizeof (SQLWCHAR));
1451
1506
  rb_iv_set(odrv, "@name", uc_tainted_str_new(driver, driverLen));
1452
1507
  for (attr = attrs; *attr; attr += uc_strlen(attr) + 1) {
1453
1508
  SQLWCHAR *p = uc_strchr(attr, (SQLWCHAR) '=');
@@ -1461,7 +1516,7 @@ dbc_drivers(VALUE self)
1461
1516
  }
1462
1517
  }
1463
1518
  #else
1464
- driverLen = (driverLen == 0) ? strlen(driver) : driverLen;
1519
+ driverLen = (driverLen == 0) ? (SQLSMALLINT) strlen(driver) : driverLen;
1465
1520
  rb_iv_set(odrv, "@name", rb_tainted_str_new(driver, driverLen));
1466
1521
  for (attr = attrs; *attr; attr += strlen(attr) + 1) {
1467
1522
  char *p = strchr(attr, '=');
@@ -1547,12 +1602,16 @@ conf_dsn(int argc, VALUE *argv, VALUE self, int op)
1547
1602
  have_w = ruby_odbc_have_func("SQLConfigDataSourceW", SQLConfigDataSourceW);
1548
1603
  #endif
1549
1604
  if (have_w) {
1605
+ #ifdef USE_RB_ENC
1606
+ drv = rb_funcall(drv, IDencode, 1, rb_encv);
1607
+ astr = rb_funcall(astr, IDencode, 1, rb_encv);
1608
+ #endif
1550
1609
  sdrv = uc_from_utf((unsigned char *) STR2CSTR(drv), -1);
1551
1610
  sastr = uc_from_utf((unsigned char *) STR2CSTR(astr), -1);
1552
1611
  if ((sdrv == NULL) || (sastr == NULL)) {
1553
1612
  uc_free(sdrv);
1554
1613
  uc_free(sastr);
1555
- rb_raise(Cerror, set_err("Out of memory", 0));
1614
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
1556
1615
  }
1557
1616
  if (SQLConfigDataSourceW(NULL, (WORD) op,
1558
1617
  (LPWSTR) sdrv, (LPWSTR) sastr)) {
@@ -1578,9 +1637,9 @@ conf_dsn(int argc, VALUE *argv, VALUE self, int op)
1578
1637
  }
1579
1638
  #endif
1580
1639
  #if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1581
- rb_raise(Cerror, set_err(get_installer_err(), 0));
1640
+ rb_raise(Cerror, "%s", set_err(get_installer_err(), 0));
1582
1641
  #else
1583
- rb_raise(Cerror, set_err("DSN configuration error", 0));
1642
+ rb_raise(Cerror, "%s", set_err("DSN configuration error", 0));
1584
1643
  #endif
1585
1644
  return Qnil;
1586
1645
  }
@@ -1592,7 +1651,7 @@ dbc_adddsn(int argc, VALUE *argv, VALUE self)
1592
1651
  #ifdef HAVE_ODBCINST_H
1593
1652
  return conf_dsn(argc, argv, self, ODBC_ADD_DSN);
1594
1653
  #else
1595
- rb_raise(Cerror, set_err("ODBC::add_dsn not supported", 0));
1654
+ rb_raise(Cerror, "%s", set_err("ODBC::add_dsn not supported", 0));
1596
1655
  return Qnil;
1597
1656
  #endif
1598
1657
  }
@@ -1603,7 +1662,7 @@ dbc_confdsn(int argc, VALUE *argv, VALUE self)
1603
1662
  #ifdef HAVE_ODBCINST_H
1604
1663
  return conf_dsn(argc, argv, self, ODBC_CONFIG_DSN);
1605
1664
  #else
1606
- rb_raise(Cerror, set_err("ODBC::config_dsn not supported", 0));
1665
+ rb_raise(Cerror, "%s", set_err("ODBC::config_dsn not supported", 0));
1607
1666
  return Qnil;
1608
1667
  #endif
1609
1668
  }
@@ -1614,7 +1673,7 @@ dbc_deldsn(int argc, VALUE *argv, VALUE self)
1614
1673
  #ifdef HAVE_ODBCINST_H
1615
1674
  return conf_dsn(argc, argv, self, ODBC_REMOVE_DSN);
1616
1675
  #else
1617
- rb_raise(Cerror, set_err("ODBC::del_dsn not supported", 0));
1676
+ rb_raise(Cerror, "%s", set_err("ODBC::del_dsn not supported", 0));
1618
1677
  return Qnil;
1619
1678
  #endif
1620
1679
  }
@@ -1649,6 +1708,14 @@ dbc_wfdsn(int argc, VALUE *argv, VALUE self)
1649
1708
  if (have_w) {
1650
1709
  BOOL rc;
1651
1710
 
1711
+ #ifdef USE_RB_ENC
1712
+ fname = rb_funcall(fname, IDencode, 1, rb_encv);
1713
+ aname = rb_funcall(aname, IDencode, 1, rb_encv);
1714
+ kname = rb_funcall(kname, IDencode, 1, rb_encv);
1715
+ if (val != Qnil) {
1716
+ val = rb_funcall(val, IDencode, 1, rb_encv);
1717
+ }
1718
+ #endif
1652
1719
  sfname = uc_from_utf((unsigned char *) STR2CSTR(fname), -1);
1653
1720
  saname = uc_from_utf((unsigned char *) STR2CSTR(aname), -1);
1654
1721
  skname = uc_from_utf((unsigned char *) STR2CSTR(kname), -1);
@@ -1657,7 +1724,7 @@ nomem:
1657
1724
  uc_free(sfname);
1658
1725
  uc_free(saname);
1659
1726
  uc_free(skname);
1660
- rb_raise(Cerror, set_err("Out of memory", 0));
1727
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
1661
1728
  }
1662
1729
  if (val != Qnil) {
1663
1730
  sval = uc_from_utf((unsigned char *) STR2CSTR(val), -1);
@@ -1697,12 +1764,12 @@ nomem:
1697
1764
  }
1698
1765
  #endif
1699
1766
  #if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1700
- rb_raise(Cerror, set_err(get_installer_err(), 0));
1767
+ rb_raise(Cerror, "%s", set_err(get_installer_err(), 0));
1701
1768
  #else
1702
- rb_raise(Cerror, set_err("File DSN configuration error", 0));
1769
+ rb_raise(Cerror, "%s", set_err("File DSN configuration error", 0));
1703
1770
  #endif
1704
1771
  #else
1705
- rb_raise(Cerror, set_err("ODBC::write_file_dsn not supported", 0));
1772
+ rb_raise(Cerror, "%s", set_err("ODBC::write_file_dsn not supported", 0));
1706
1773
  #endif
1707
1774
  return Qnil;
1708
1775
  }
@@ -1734,6 +1801,11 @@ dbc_rfdsn(int argc, VALUE *argv, VALUE self)
1734
1801
  if (have_w) {
1735
1802
  BOOL rc;
1736
1803
 
1804
+ #ifdef USE_RB_ENC
1805
+ fname = rb_funcall(fname, IDencode, 1, rb_encv);
1806
+ aname = rb_funcall(aname, IDencode, 1, rb_encv);
1807
+ kname = rb_funcall(kname, IDencode, 1, rb_encv);
1808
+ #endif
1737
1809
  sfname = uc_from_utf((unsigned char *) STR2CSTR(fname), -1);
1738
1810
  saname = uc_from_utf((unsigned char *) STR2CSTR(aname), -1);
1739
1811
  skname = uc_from_utf((unsigned char *) STR2CSTR(kname), -1);
@@ -1742,7 +1814,7 @@ dbc_rfdsn(int argc, VALUE *argv, VALUE self)
1742
1814
  uc_free(sfname);
1743
1815
  uc_free(saname);
1744
1816
  uc_free(skname);
1745
- rb_raise(Cerror, set_err("Out of memory", 0));
1817
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
1746
1818
  }
1747
1819
  rc = SQLReadFileDSNW(sfname, saname, skname, valbuf,
1748
1820
  sizeof (valbuf), NULL);
@@ -1774,12 +1846,12 @@ dbc_rfdsn(int argc, VALUE *argv, VALUE self)
1774
1846
  }
1775
1847
  #endif
1776
1848
  #if defined(HAVE_SQLINSTALLERERROR) || (defined(UNICODE) && defined(HAVE_SQLINSTALLERERRORW))
1777
- rb_raise(Cerror, set_err(get_installer_err(), 0));
1849
+ rb_raise(Cerror, "%s", set_err(get_installer_err(), 0));
1778
1850
  #else
1779
- rb_raise(Cerror, set_err("File DSN configuration error", 0));
1851
+ rb_raise(Cerror, "%s", set_err("File DSN configuration error", 0));
1780
1852
  #endif
1781
1853
  #else
1782
- rb_raise(Cerror, set_err("ODBC::read_file_dsn not supported", 0));
1854
+ rb_raise(Cerror, "%s", set_err("ODBC::read_file_dsn not supported", 0));
1783
1855
  return Qnil;
1784
1856
  #endif
1785
1857
  }
@@ -1834,6 +1906,8 @@ dbc_alloc(VALUE self)
1834
1906
  p->envp = NULL;
1835
1907
  list_init(&p->stmts, offsetof(STMT, link));
1836
1908
  p->hdbc = SQL_NULL_HDBC;
1909
+ p->rbtime = Qfalse;
1910
+ p->gmtime = Qfalse;
1837
1911
  return obj;
1838
1912
  }
1839
1913
  #endif
@@ -1918,7 +1992,7 @@ dbc_connect(int argc, VALUE *argv, VALUE self)
1918
1992
  }
1919
1993
  p = get_dbc(self);
1920
1994
  if (p->hdbc != SQL_NULL_HDBC) {
1921
- rb_raise(Cerror, set_err("Already connected", 0));
1995
+ rb_raise(Cerror, "%s", set_err("Already connected", 0));
1922
1996
  }
1923
1997
  if (p->env == Qnil) {
1924
1998
  p->env = env_new(Cenv);
@@ -1932,11 +2006,20 @@ dbc_connect(int argc, VALUE *argv, VALUE self)
1932
2006
  }
1933
2007
  #ifdef UNICODE
1934
2008
  if (user != Qnil) {
2009
+ #ifdef USE_RB_ENC
2010
+ user = rb_funcall(user, IDencode, 1, rb_encv);
2011
+ #endif
1935
2012
  suser = uc_from_utf((unsigned char *) STR2CSTR(user), -1);
1936
2013
  }
1937
2014
  if (passwd != Qnil) {
2015
+ #ifdef USE_RB_ENC
2016
+ passwd = rb_funcall(passwd, IDencode, 1, rb_encv);
2017
+ #endif
1938
2018
  spasswd = uc_from_utf((unsigned char *) STR2CSTR(passwd), -1);
1939
2019
  }
2020
+ #ifdef USE_RB_ENC
2021
+ dsn = rb_funcall(dsn, IDencode, 1, rb_encv);
2022
+ #endif
1940
2023
  sdsn = uc_from_utf((unsigned char *) STR2CSTR(dsn), -1);
1941
2024
  if (((suser == NULL) && (user != Qnil)) ||
1942
2025
  ((spasswd == NULL) && (passwd != Qnil)) ||
@@ -1944,7 +2027,7 @@ dbc_connect(int argc, VALUE *argv, VALUE self)
1944
2027
  uc_free(sdsn);
1945
2028
  uc_free(suser);
1946
2029
  uc_free(spasswd);
1947
- rb_raise(Cerror, set_err("Out of memory", 0));
2030
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
1948
2031
  }
1949
2032
  #else
1950
2033
  if (user != Qnil) {
@@ -2021,7 +2104,7 @@ dbc_drvconnect(VALUE self, VALUE drv)
2021
2104
  Check_Type(drv, T_STRING);
2022
2105
  p = get_dbc(self);
2023
2106
  if (p->hdbc != SQL_NULL_HDBC) {
2024
- rb_raise(Cerror, set_err("Already connected", 0));
2107
+ rb_raise(Cerror, "%s", set_err("Already connected", 0));
2025
2108
  }
2026
2109
  if (p->env == Qnil) {
2027
2110
  p->env = env_new(Cenv);
@@ -2031,9 +2114,12 @@ dbc_drvconnect(VALUE self, VALUE drv)
2031
2114
  e = get_env(p->env);
2032
2115
  }
2033
2116
  #ifdef UNICODE
2117
+ #ifdef USE_RB_ENC
2118
+ drv = rb_funcall(drv, IDencode, 1, rb_encv);
2119
+ #endif
2034
2120
  sdrv = uc_from_utf((unsigned char *) STR2CSTR(drv), -1);
2035
2121
  if (sdrv == NULL) {
2036
- rb_raise(Cerror, set_err("Out of memory", 0));
2122
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
2037
2123
  }
2038
2124
  #else
2039
2125
  sdrv = STR2CSTR(drv);
@@ -2070,6 +2156,32 @@ dbc_connected(VALUE self)
2070
2156
 
2071
2157
  return (p->hdbc == SQL_NULL_HDBC) ? Qfalse : Qtrue;
2072
2158
  }
2159
+
2160
+ static VALUE
2161
+ dbc_timefmt(int argc, VALUE *argv, VALUE self)
2162
+ {
2163
+ DBC *p = get_dbc(self);
2164
+ VALUE val;
2165
+
2166
+ if (argc > 0) {
2167
+ rb_scan_args(argc, argv, "1", &val);
2168
+ p->rbtime = (val != Qnil && val != Qfalse) ? Qtrue : Qfalse;
2169
+ }
2170
+ return p->rbtime;
2171
+ }
2172
+
2173
+ static VALUE
2174
+ dbc_timeutc(int argc, VALUE *argv, VALUE self)
2175
+ {
2176
+ DBC *p = get_dbc(self);
2177
+ VALUE val;
2178
+
2179
+ if (argc > 0) {
2180
+ rb_scan_args(argc, argv, "1", &val);
2181
+ p->gmtime = (val != Qnil && val != Qfalse) ? Qtrue : Qfalse;
2182
+ }
2183
+ return p->gmtime;
2184
+ }
2073
2185
 
2074
2186
  /*
2075
2187
  *----------------------------------------------------------------------
@@ -2912,16 +3024,19 @@ static VALUE
2912
3024
  dbc_getinfo(int argc, VALUE *argv, VALUE self)
2913
3025
  {
2914
3026
  DBC *p = get_dbc(self);
2915
- VALUE which, vtype;
3027
+ VALUE which, vtype, vstr;
2916
3028
  SQLRETURN ret;
2917
3029
  int i, k, info = -1, maptype = -1, info_found = 0;
2918
- char buffer[513], *string = NULL;
2919
- SQLSMALLINT len_in = sizeof (buffer) - 1, len_out;
3030
+ SQLUSMALLINT sbuffer;
3031
+ SQLUINTEGER lbuffer;
3032
+ SQLSMALLINT len_in, len_out;
3033
+ char *string = NULL, buffer[513];
2920
3034
 
2921
3035
  rb_scan_args(argc, argv, "11", &which, &vtype);
2922
3036
  switch (TYPE(which)) {
2923
3037
  default:
2924
- string = STR2CSTR(rb_any_to_s(which));
3038
+ vstr = rb_any_to_s(which);
3039
+ string = STR2CSTR(vstr);
2925
3040
  goto doString;
2926
3041
  case T_STRING:
2927
3042
  string = STR2CSTR(which);
@@ -2956,7 +3071,7 @@ dbc_getinfo(int argc, VALUE *argv, VALUE self)
2956
3071
  }
2957
3072
  switch (info_found) {
2958
3073
  case 0:
2959
- rb_raise(Cerror,
3074
+ rb_raise(Cerror, "%s",
2960
3075
  set_err("Invalid info type for ODBC::Connection.get_info",
2961
3076
  0));
2962
3077
  return Qnil;
@@ -3006,18 +3121,36 @@ dbc_getinfo(int argc, VALUE *argv, VALUE self)
3006
3121
  break;
3007
3122
  }
3008
3123
  }
3009
- memset(buffer, 0, sizeof (buffer));
3010
- ret = SQLGetInfo(p->hdbc, (SQLUSMALLINT) info,
3011
- (SQLPOINTER) buffer, len_in, &len_out);
3124
+ switch (maptype) {
3125
+ case SQL_C_SHORT:
3126
+ len_in = sizeof (sbuffer);
3127
+ sbuffer = 0;
3128
+ ret = SQLGetInfo(p->hdbc, (SQLUSMALLINT) info,
3129
+ (SQLPOINTER) &sbuffer, len_in, &len_out);
3130
+ break;
3131
+ case SQL_C_LONG:
3132
+ len_in = sizeof (lbuffer);
3133
+ lbuffer = 0;
3134
+ ret = SQLGetInfo(p->hdbc, (SQLUSMALLINT) info,
3135
+ (SQLPOINTER) &lbuffer, len_in, &len_out);
3136
+ break;
3137
+ default:
3138
+ case SQL_C_CHAR:
3139
+ len_in = sizeof (buffer) - 1;
3140
+ memset(buffer, 0, sizeof (buffer));
3141
+ ret = SQLGetInfo(p->hdbc, (SQLUSMALLINT) info,
3142
+ (SQLPOINTER) buffer, len_in, &len_out);
3143
+ break;
3144
+ }
3012
3145
  if (!SQL_SUCCEEDED(ret)) {
3013
3146
  rb_raise(Cerror, "%s",
3014
3147
  get_err(SQL_NULL_HENV, p->hdbc, SQL_NULL_HSTMT));
3015
3148
  }
3016
3149
  switch (maptype) {
3017
3150
  case SQL_C_SHORT:
3018
- return INT2NUM(*((SQLUSMALLINT *) buffer));
3151
+ return INT2NUM(sbuffer);
3019
3152
  case SQL_C_LONG:
3020
- return INT2NUM(*((SQLUINTEGER *) buffer));
3153
+ return INT2NUM(lbuffer);
3021
3154
  default:
3022
3155
  case SQL_C_CHAR:
3023
3156
  return rb_str_new(buffer, len_out);
@@ -3153,6 +3286,9 @@ make_coltypes(SQLHSTMT hstmt, int ncols, char **msgp)
3153
3286
  break;
3154
3287
  #endif
3155
3288
  default:
3289
+ if ((size == 0) || (size > SEGSIZE)) {
3290
+ size = SQL_NO_TOTAL;
3291
+ }
3156
3292
  #ifdef UNICODE
3157
3293
  type = SQL_C_WCHAR;
3158
3294
  if (size != SQL_NO_TOTAL) {
@@ -3181,64 +3317,73 @@ make_coltypes(SQLHSTMT hstmt, int ncols, char **msgp)
3181
3317
  *----------------------------------------------------------------------
3182
3318
  */
3183
3319
 
3184
- static PINFO *
3185
- make_pinfo(SQLHSTMT hstmt, int nump, char **msgp)
3320
+ static PARAMINFO *
3321
+ make_paraminfo(SQLHSTMT hstmt, int nump, char **msgp)
3186
3322
  {
3187
3323
  int i;
3188
- PINFO *pinfo = NULL;
3324
+ PARAMINFO *paraminfo = NULL;
3189
3325
 
3190
- pinfo = ALLOC_N(PINFO, nump);
3191
- if (pinfo == NULL) {
3326
+ paraminfo = ALLOC_N(PARAMINFO, nump);
3327
+ if (paraminfo == NULL) {
3192
3328
  if (msgp != NULL) {
3193
3329
  *msgp = set_err("Out of memory", 0);
3194
3330
  }
3195
3331
  return NULL;
3196
3332
  }
3197
3333
  for (i = 0; i < nump; i++) {
3198
- pinfo[i].iotype = SQL_PARAM_INPUT;
3199
- pinfo[i].outsize = 0;
3200
- pinfo[i].outbuf = NULL;
3201
- pinfo[i].rlen = SQL_NULL_DATA;
3202
- pinfo[i].ctype = SQL_C_CHAR;
3203
- pinfo[i].outtype = SQL_CHAR;
3204
- pinfo[i].coldef_max = 0;
3334
+ paraminfo[i].iotype = SQL_PARAM_INPUT;
3335
+ paraminfo[i].outsize = 0;
3336
+ paraminfo[i].outbuf = NULL;
3337
+ paraminfo[i].rlen = SQL_NULL_DATA;
3338
+ paraminfo[i].ctype = SQL_C_CHAR;
3339
+ #ifdef UNICODE
3340
+ paraminfo[i].outtype = SQL_WCHAR;
3341
+ #else
3342
+ paraminfo[i].outtype = SQL_WCHAR;
3343
+ #endif
3344
+ paraminfo[i].coldef_max = 0;
3205
3345
  if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3206
3346
  SQLDescribeParam(hstmt, (SQLUSMALLINT) (i + 1),
3207
- &pinfo[i].type, &pinfo[i].coldef,
3208
- &pinfo[i].scale,
3209
- &pinfo[i].nullable),
3347
+ &paraminfo[i].type,
3348
+ &paraminfo[i].coldef,
3349
+ &paraminfo[i].scale,
3350
+ &paraminfo[i].nullable),
3210
3351
  NULL, "SQLDescribeParam")) {
3211
- pinfo[i].type = SQL_VARCHAR;
3212
- pinfo[i].coldef = 0;
3213
- pinfo[i].scale = 0;
3214
- pinfo[i].nullable = SQL_NULLABLE_UNKNOWN;
3215
- pinfo[i].override = 0;
3352
+ #ifdef UNICODE
3353
+ paraminfo[i].type = SQL_WVARCHAR;
3354
+ #else
3355
+ paraminfo[i].type = SQL_VARCHAR;
3356
+ #endif
3357
+ paraminfo[i].coldef = 0;
3358
+ paraminfo[i].scale = 0;
3359
+ paraminfo[i].nullable = SQL_NULLABLE_UNKNOWN;
3360
+ paraminfo[i].override = 0;
3216
3361
  }
3217
3362
  }
3218
- return pinfo;
3363
+ return paraminfo;
3219
3364
  }
3220
3365
 
3221
3366
  static void
3222
- retain_pinfo_override(STMT *q, int nump, PINFO *pinfo)
3367
+ retain_paraminfo_override(STMT *q, int nump, PARAMINFO *paraminfo)
3223
3368
  {
3224
- if ((q->pinfo != NULL) && (q->nump == nump)) {
3369
+ if ((q->paraminfo != NULL) && (q->nump == nump)) {
3225
3370
  int i;
3226
3371
 
3227
3372
  for (i = 0; i < nump; i++) {
3228
- pinfo[i].iotype = q->pinfo[i].iotype;
3229
- pinfo[i].rlen = q->pinfo[i].rlen;
3230
- pinfo[i].ctype = q->pinfo[i].ctype;
3231
- pinfo[i].outtype = q->pinfo[i].outtype;
3232
- pinfo[i].outsize = q->pinfo[i].outsize;
3233
- if (q->pinfo[i].outbuf != NULL) {
3234
- pinfo[i].outbuf = q->pinfo[i].outbuf;
3235
- q->pinfo[i].outbuf = NULL;
3373
+ paraminfo[i].iotype = q->paraminfo[i].iotype;
3374
+ paraminfo[i].rlen = q->paraminfo[i].rlen;
3375
+ paraminfo[i].ctype = q->paraminfo[i].ctype;
3376
+ paraminfo[i].outtype = q->paraminfo[i].outtype;
3377
+ paraminfo[i].outsize = q->paraminfo[i].outsize;
3378
+ if (q->paraminfo[i].outbuf != NULL) {
3379
+ paraminfo[i].outbuf = q->paraminfo[i].outbuf;
3380
+ q->paraminfo[i].outbuf = NULL;
3236
3381
  }
3237
- if (q->pinfo[i].override) {
3238
- pinfo[i].override = q->pinfo[i].override;
3239
- pinfo[i].type = q->pinfo[i].type;
3240
- pinfo[i].coldef = q->pinfo[i].coldef;
3241
- pinfo[i].scale = q->pinfo[i].scale;
3382
+ if (q->paraminfo[i].override) {
3383
+ paraminfo[i].override = q->paraminfo[i].override;
3384
+ paraminfo[i].type = q->paraminfo[i].type;
3385
+ paraminfo[i].coldef = q->paraminfo[i].coldef;
3386
+ paraminfo[i].scale = q->paraminfo[i].scale;
3242
3387
  }
3243
3388
  }
3244
3389
  }
@@ -3265,15 +3410,21 @@ wrap_stmt(VALUE dbc, DBC *p, SQLHSTMT hstmt, STMT **qp)
3265
3410
  q->hstmt = hstmt;
3266
3411
  q->dbc = dbc;
3267
3412
  q->dbcp = NULL;
3268
- q->pinfo = NULL;
3413
+ q->paraminfo = NULL;
3269
3414
  q->coltypes = NULL;
3270
3415
  q->colnames = q->dbufs = NULL;
3416
+ q->colvals = NULL;
3271
3417
  q->fetchc = 0;
3272
3418
  q->upc = p->upc;
3273
3419
  q->usef = 0;
3274
3420
  rb_iv_set(q->self, "@_a", rb_ary_new());
3275
3421
  rb_iv_set(q->self, "@_h", rb_hash_new());
3276
- link_stmt(q, p);
3422
+ rb_iv_set(q->self, "@_c", rb_hash_new());
3423
+ if (hstmt != SQL_NULL_HSTMT) {
3424
+ link_stmt(q, p);
3425
+ } else {
3426
+ q->dbc = Qnil;
3427
+ }
3277
3428
  if (qp != NULL) {
3278
3429
  *qp = q;
3279
3430
  }
@@ -3295,21 +3446,23 @@ make_result(VALUE dbc, SQLHSTMT hstmt, VALUE result, int mode)
3295
3446
  STMT *q;
3296
3447
  SQLSMALLINT cols = 0, nump;
3297
3448
  COLTYPE *coltypes = NULL;
3298
- PINFO *pinfo = NULL;
3449
+ PARAMINFO *paraminfo = NULL;
3299
3450
  char *msg = NULL;
3300
3451
 
3301
3452
  Data_Get_Struct(dbc, DBC, p);
3302
- if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3453
+ if ((hstmt == SQL_NULL_HSTMT) ||
3454
+ !succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3303
3455
  SQLNumParams(hstmt, &nump), NULL, "SQLNumParams")) {
3304
3456
  nump = 0;
3305
3457
  }
3306
3458
  if (nump > 0) {
3307
- pinfo = make_pinfo(hstmt, nump, &msg);
3308
- if (pinfo == NULL) {
3459
+ paraminfo = make_paraminfo(hstmt, nump, &msg);
3460
+ if (paraminfo == NULL) {
3309
3461
  goto error;
3310
3462
  }
3311
3463
  }
3312
3464
  if ((mode & MAKERES_PREPARE) ||
3465
+ (hstmt == SQL_NULL_HSTMT) ||
3313
3466
  (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
3314
3467
  SQLNumResultCols(hstmt, &cols), NULL,
3315
3468
  "SQLNumResultCols"))) {
@@ -3325,17 +3478,19 @@ make_result(VALUE dbc, SQLHSTMT hstmt, VALUE result, int mode)
3325
3478
  result = wrap_stmt(dbc, p, hstmt, &q);
3326
3479
  } else {
3327
3480
  Data_Get_Struct(result, STMT, q);
3328
- retain_pinfo_override(q, nump, pinfo);
3481
+ retain_paraminfo_override(q, nump, paraminfo);
3329
3482
  free_stmt_sub(q);
3330
3483
  if (q->dbc != dbc) {
3331
3484
  unlink_stmt(q);
3332
3485
  q->dbc = dbc;
3333
- link_stmt(q, p);
3486
+ if (hstmt != SQL_NULL_HSTMT) {
3487
+ link_stmt(q, p);
3488
+ }
3334
3489
  }
3335
3490
  q->hstmt = hstmt;
3336
3491
  }
3337
3492
  q->nump = nump;
3338
- q->pinfo = pinfo;
3493
+ q->paraminfo = paraminfo;
3339
3494
  q->ncols = cols;
3340
3495
  q->coltypes = coltypes;
3341
3496
  if ((mode & MAKERES_BLOCK) && rb_block_given_p()) {
@@ -3355,8 +3510,8 @@ error:
3355
3510
  unlink_stmt(q);
3356
3511
  }
3357
3512
  }
3358
- if (pinfo != NULL) {
3359
- xfree(pinfo);
3513
+ if (paraminfo != NULL) {
3514
+ xfree(paraminfo);
3360
3515
  }
3361
3516
  if (coltypes != NULL) {
3362
3517
  xfree(coltypes);
@@ -3395,7 +3550,7 @@ upcase_if(char *string, int upc)
3395
3550
  */
3396
3551
 
3397
3552
  static VALUE
3398
- make_col(SQLHSTMT hstmt, int i, int upc)
3553
+ make_column(SQLHSTMT hstmt, int i, int upc)
3399
3554
  {
3400
3555
  VALUE obj, v;
3401
3556
  SQLUSMALLINT ic = i + 1;
@@ -3417,7 +3572,7 @@ make_col(SQLHSTMT hstmt, int i, int upc)
3417
3572
  rb_raise(Cerror, "%s", msg);
3418
3573
  }
3419
3574
  obj = rb_obj_alloc(Ccolumn);
3420
- if (name_len >= sizeof (name)) {
3575
+ if (name_len >= (SQLSMALLINT) sizeof (name)) {
3421
3576
  name_len = sizeof (name) - 1;
3422
3577
  }
3423
3578
  if (name_len > 0) {
@@ -3428,13 +3583,18 @@ make_col(SQLHSTMT hstmt, int i, int upc)
3428
3583
  int len = uc_strlen(name);
3429
3584
  char tmpbuf[1];
3430
3585
  char *tmp = xmalloc(len);
3586
+ VALUE v;
3431
3587
 
3432
3588
  if (tmp == NULL) {
3433
3589
  tmp = tmpbuf;
3434
3590
  len = 0;
3435
3591
  }
3436
3592
  mkutf(tmp, name, len);
3437
- rb_iv_set(obj, "@name", rb_tainted_str_new2(upcase_if(tmp, 1)));
3593
+ v = rb_tainted_str_new2(upcase_if(tmp, 1));
3594
+ #ifdef USE_RB_ENC
3595
+ rb_enc_associate(v, rb_enc);
3596
+ #endif
3597
+ rb_iv_set(obj, "@name", v);
3438
3598
  if ((tmp != NULL) && (tmp != tmpbuf)) {
3439
3599
  xfree(tmp);
3440
3600
  }
@@ -3451,7 +3611,7 @@ make_col(SQLHSTMT hstmt, int i, int upc)
3451
3611
  (SQLSMALLINT) sizeof (name),
3452
3612
  &name_len, NULL),
3453
3613
  NULL, "SQLColAttributes(SQL_COLUMN_TABLE_NAME)")) {
3454
- if (name_len > sizeof (name)) {
3614
+ if (name_len > (SQLSMALLINT) sizeof (name)) {
3455
3615
  name_len = sizeof (name) - 1;
3456
3616
  }
3457
3617
  if (name_len > 0) {
@@ -3560,25 +3720,33 @@ make_col(SQLHSTMT hstmt, int i, int upc)
3560
3720
  */
3561
3721
 
3562
3722
  static VALUE
3563
- make_par(STMT *q, int i)
3723
+ make_param(STMT *q, int i)
3564
3724
  {
3565
3725
  VALUE obj;
3566
3726
  int v;
3567
3727
 
3568
3728
  obj = rb_obj_alloc(Cparam);
3569
- v = q->pinfo ? q->pinfo[i].type : SQL_VARCHAR;
3729
+ #ifdef UNICODE
3730
+ v = q->paraminfo ? q->paraminfo[i].type : SQL_VARCHAR;
3731
+ #else
3732
+ v = q->paraminfo ? q->paraminfo[i].type : SQL_WVARCHAR;
3733
+ #endif
3570
3734
  rb_iv_set(obj, "@type", INT2NUM(v));
3571
- v = q->pinfo ? q->pinfo[i].coldef : 0;
3735
+ v = q->paraminfo ? q->paraminfo[i].coldef : 0;
3572
3736
  rb_iv_set(obj, "@precision", INT2NUM(v));
3573
- v = q->pinfo ? q->pinfo[i].scale : 0;
3737
+ v = q->paraminfo ? q->paraminfo[i].scale : 0;
3574
3738
  rb_iv_set(obj, "@scale", INT2NUM(v));
3575
- v = q->pinfo ? q->pinfo[i].nullable : SQL_NULLABLE_UNKNOWN;
3739
+ v = q->paraminfo ? q->paraminfo[i].nullable : SQL_NULLABLE_UNKNOWN;
3576
3740
  rb_iv_set(obj, "@nullable", INT2NUM(v));
3577
- v = q->pinfo ? q->pinfo[i].iotype : SQL_PARAM_INPUT;
3741
+ v = q->paraminfo ? q->paraminfo[i].iotype : SQL_PARAM_INPUT;
3578
3742
  rb_iv_set(obj, "@iotype", INT2NUM(v));
3579
- v = q->pinfo ? q->pinfo[i].outsize : 0;
3743
+ v = q->paraminfo ? q->paraminfo[i].outsize : 0;
3580
3744
  rb_iv_set(obj, "@output_size", INT2NUM(v));
3581
- v = q->pinfo ? q->pinfo[i].outtype : SQL_CHAR;
3745
+ #ifdef UNICODE
3746
+ v = q->paraminfo ? q->paraminfo[i].outtype : SQL_WCHAR;
3747
+ #else
3748
+ v = q->paraminfo ? q->paraminfo[i].outtype : SQL_CHAR;
3749
+ #endif
3582
3750
  rb_iv_set(obj, "@output_type", INT2NUM(v));
3583
3751
  return obj;
3584
3752
  }
@@ -3601,13 +3769,14 @@ dbc_info(int argc, VALUE *argv, VALUE self, int mode)
3601
3769
  #else
3602
3770
  SQLCHAR *swhich = NULL, *swhich2 = NULL;
3603
3771
  #endif
3604
- char *msg, *argspec = NULL;
3772
+ char *msg;
3773
+ const char *argspec = NULL;
3605
3774
  SQLHSTMT hstmt;
3606
3775
  int needstr = 1, itype = SQL_ALL_TYPES;
3607
3776
  int iid = SQL_BEST_ROWID, iscope = SQL_SCOPE_CURROW;
3608
3777
 
3609
3778
  if (p->hdbc == SQL_NULL_HDBC) {
3610
- rb_raise(Cerror, set_err("No connection", 0));
3779
+ rb_raise(Cerror, "%s", set_err("No connection", 0));
3611
3780
  }
3612
3781
  switch (mode) {
3613
3782
  case INFO_TYPES:
@@ -3631,7 +3800,7 @@ dbc_info(int argc, VALUE *argv, VALUE self, int mode)
3631
3800
  argspec = "12";
3632
3801
  break;
3633
3802
  default:
3634
- rb_raise(Cerror, set_err("Invalid info mode", 0));
3803
+ rb_raise(Cerror, "%s", set_err("Invalid info mode", 0));
3635
3804
  break;
3636
3805
  }
3637
3806
  rb_scan_args(argc, argv, argspec, &which, &which2, &which3);
@@ -3661,16 +3830,26 @@ dbc_info(int argc, VALUE *argv, VALUE self, int mode)
3661
3830
  }
3662
3831
  #ifdef UNICODE
3663
3832
  if (swhich != NULL) {
3664
- swhich = uc_from_utf((unsigned char *) STR2CSTR((VALUE) swhich), -1);
3833
+ VALUE val = (VALUE) swhich;
3834
+
3835
+ #ifdef USE_RB_ENC
3836
+ val = rb_funcall(val, IDencode, 1, rb_encv);
3837
+ #endif
3838
+ swhich = uc_from_utf((unsigned char *) STR2CSTR(val), -1);
3665
3839
  if (swhich == NULL) {
3666
- rb_raise(Cerror, set_err("Out of memory", 0));
3840
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
3667
3841
  }
3668
3842
  }
3669
3843
  if (swhich2 != NULL) {
3670
- swhich2 = uc_from_utf((unsigned char *) STR2CSTR((VALUE) swhich2), -1);
3844
+ VALUE val = (VALUE) swhich2;
3845
+
3846
+ #ifdef USE_RB_ENC
3847
+ val = rb_funcall(val, IDencode, 1, rb_encv);
3848
+ #endif
3849
+ swhich2 = uc_from_utf((unsigned char *) STR2CSTR(val), -1);
3671
3850
  if (swhich2 == NULL) {
3672
3851
  uc_free(swhich);
3673
- rb_raise(Cerror, set_err("Out of memory", 0));
3852
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
3674
3853
  }
3675
3854
  }
3676
3855
  #endif
@@ -3999,7 +4178,7 @@ env_cpooling(int argc, VALUE *argv, VALUE self)
3999
4178
  #if (ODBCVER >= 0x0300)
4000
4179
  return do_attr(argc, argv, self, SQL_ATTR_CONNECTION_POOLING);
4001
4180
  #else
4002
- rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4181
+ rb_raise(Cerror, "%s", set_err("Unsupported in ODBC < 3.0", 0));
4003
4182
  return Qnil;
4004
4183
  #endif
4005
4184
  }
@@ -4010,7 +4189,7 @@ env_cpmatch(int argc, VALUE *argv, VALUE self)
4010
4189
  #if (ODBCVER >= 0x0300)
4011
4190
  return do_attr(argc, argv, self, SQL_ATTR_CP_MATCH);
4012
4191
  #else
4013
- rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4192
+ rb_raise(Cerror, "%s", set_err("Unsupported in ODBC < 3.0", 0));
4014
4193
  return Qnil;
4015
4194
  #endif
4016
4195
  }
@@ -4027,7 +4206,7 @@ env_odbcver(int argc, VALUE *argv, VALUE self)
4027
4206
  if (val == Qnil) {
4028
4207
  return rb_int2inum(ODBCVER >> 8);
4029
4208
  }
4030
- rb_raise(Cerror, set_err("Unsupported in ODBC < 3.0", 0));
4209
+ rb_raise(Cerror, "%s", set_err("Unsupported in ODBC < 3.0", 0));
4031
4210
  #endif
4032
4211
  }
4033
4212
 
@@ -4056,7 +4235,7 @@ env_odbcver(int argc, VALUE *argv, VALUE self)
4056
4235
  #define OPT_CONST_INT(x, level) { #x, x, level }
4057
4236
  #define OPT_CONST_END { NULL, -1 }
4058
4237
  static struct {
4059
- char *name;
4238
+ const char *name;
4060
4239
  int option;
4061
4240
  int level;
4062
4241
  } option_map[] = {
@@ -4080,7 +4259,7 @@ do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4080
4259
  {
4081
4260
  DBC *p = NULL;
4082
4261
  STMT *q = NULL;
4083
- VALUE val, val2;
4262
+ VALUE val, val2, vstr;
4084
4263
  SQLINTEGER v;
4085
4264
  char *msg;
4086
4265
  int level = isstmt ? OPT_LEVEL_STMT : OPT_LEVEL_DBC;
@@ -4089,15 +4268,15 @@ do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4089
4268
  if (isstmt) {
4090
4269
  Data_Get_Struct(self, STMT, q);
4091
4270
  if (q->dbc == Qnil) {
4092
- rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
4271
+ rb_raise(Cerror, "%s", set_err("Stale ODBC::Statement", 0));
4093
4272
  }
4094
4273
  if (q->hstmt == SQL_NULL_HSTMT) {
4095
- rb_raise(Cerror, set_err("No statement", 0));
4274
+ rb_raise(Cerror, "%s", set_err("No statement", 0));
4096
4275
  }
4097
4276
  } else {
4098
4277
  p = get_dbc(self);
4099
4278
  if (p->hdbc == SQL_NULL_HDBC) {
4100
- rb_raise(Cerror, set_err("No connection", 0));
4279
+ rb_raise(Cerror, "%s", set_err("No connection", 0));
4101
4280
  }
4102
4281
  }
4103
4282
  if (op == -1) {
@@ -4106,7 +4285,8 @@ do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4106
4285
 
4107
4286
  switch (TYPE(val)) {
4108
4287
  default:
4109
- string = STR2CSTR(rb_any_to_s(val));
4288
+ vstr = rb_any_to_s(val);
4289
+ string = STR2CSTR(vstr);
4110
4290
  goto doString;
4111
4291
  case T_STRING:
4112
4292
  string = STR2CSTR(val);
@@ -4138,14 +4318,15 @@ do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4138
4318
  break;
4139
4319
  }
4140
4320
  if (!op_found) {
4141
- rb_raise(Cerror, set_err("Unknown option", 0));
4321
+ rb_raise(Cerror, "%s", set_err("Unknown option", 0));
4142
4322
  return Qnil;
4143
4323
  }
4144
4324
  val = val2;
4145
4325
  }
4146
4326
  if ((isstmt && (!(level & OPT_LEVEL_STMT))) ||
4147
4327
  (!isstmt && (!(level & OPT_LEVEL_DBC)))) {
4148
- rb_raise(Cerror, set_err("Invalid option type for this level", 0));
4328
+ rb_raise(Cerror, "%s",
4329
+ set_err("Invalid option type for this level", 0));
4149
4330
  return Qnil;
4150
4331
  }
4151
4332
  if (val == Qnil) {
@@ -4197,7 +4378,7 @@ do_option(int argc, VALUE *argv, VALUE self, int isstmt, int op)
4197
4378
  Check_Type(val, T_FIXNUM);
4198
4379
  v = FIX2INT(val);
4199
4380
  if (op == SQL_ROWSET_SIZE) {
4200
- rb_raise(Cerror, set_err("Read only attribute", 0));
4381
+ rb_raise(Cerror, "%s", set_err("Read only attribute", 0));
4201
4382
  }
4202
4383
  break;
4203
4384
  }
@@ -4370,7 +4551,7 @@ scan_dtts(VALUE str, int do_d, int do_t, TIMESTAMP_STRUCT *ts)
4370
4551
  i = sscanf(cstr, "%d-%d-%d %d:%d:%d%c%d",
4371
4552
  &yy, &mm, &dd, &hh, &mmm, &ss, &c, &ff);
4372
4553
  if (i >= 5) {
4373
- if ((i > 6) && (strchr(". \t", c) == NULL)) {
4554
+ if ((i > 6) && (c != 0) && (strchr(". \t", c) == NULL)) {
4374
4555
  goto next;
4375
4556
  }
4376
4557
  ts->year = yy;
@@ -5294,7 +5475,7 @@ static VALUE
5294
5475
  stmt_nrows(VALUE self)
5295
5476
  {
5296
5477
  STMT *q;
5297
- SQLLEN rows = 0;
5478
+ SQLLEN rows = -1;
5298
5479
  char *msg;
5299
5480
 
5300
5481
  Data_Get_Struct(self, STMT, q);
@@ -5316,13 +5497,13 @@ stmt_nparams(VALUE self)
5316
5497
  }
5317
5498
 
5318
5499
  static int
5319
- param_num_check(STMT *q, VALUE pnum, int mkpinfo, int needout)
5500
+ param_num_check(STMT *q, VALUE pnum, int mkparaminfo, int needout)
5320
5501
  {
5321
5502
  int vnum;
5322
5503
 
5323
5504
  Check_Type(pnum, T_FIXNUM);
5324
5505
  vnum = NUM2INT(pnum);
5325
- if (mkpinfo && (q->pinfo == NULL)) {
5506
+ if (mkparaminfo && (q->paraminfo == NULL)) {
5326
5507
  char *msg = NULL;
5327
5508
  SQLSMALLINT nump = 0;
5328
5509
 
@@ -5331,23 +5512,23 @@ param_num_check(STMT *q, VALUE pnum, int mkpinfo, int needout)
5331
5512
  nump = 0;
5332
5513
  }
5333
5514
  if (nump > 0) {
5334
- PINFO *pinfo = make_pinfo(q->hstmt, nump, &msg);
5515
+ PARAMINFO *paraminfo = make_paraminfo(q->hstmt, nump, &msg);
5335
5516
 
5336
- if (pinfo == NULL) {
5517
+ if (paraminfo == NULL) {
5337
5518
  rb_raise(Cerror, "%s", msg);
5338
5519
  }
5339
- q->pinfo = pinfo;
5340
- if (q->pinfo != NULL) {
5520
+ q->paraminfo = paraminfo;
5521
+ if (q->paraminfo != NULL) {
5341
5522
  q->nump = nump;
5342
5523
  }
5343
5524
  }
5344
5525
  }
5345
- if ((q->pinfo == NULL) || (vnum < 0) || (vnum >= q->nump)) {
5526
+ if ((q->paraminfo == NULL) || (vnum < 0) || (vnum >= q->nump)) {
5346
5527
  rb_raise(rb_eArgError, "parameter number out of bounds");
5347
5528
  }
5348
5529
  if (needout) {
5349
- if ((q->pinfo[vnum].iotype != SQL_PARAM_OUTPUT) &&
5350
- (q->pinfo[vnum].iotype != SQL_PARAM_INPUT_OUTPUT)) {
5530
+ if ((q->paraminfo[vnum].iotype != SQL_PARAM_OUTPUT) &&
5531
+ (q->paraminfo[vnum].iotype != SQL_PARAM_INPUT_OUTPUT)) {
5351
5532
  rb_raise(Cerror, "not an output parameter");
5352
5533
  }
5353
5534
  }
@@ -5375,15 +5556,15 @@ stmt_param_type(int argc, VALUE *argv, VALUE self)
5375
5556
  if (argc > 3) {
5376
5557
  Check_Type(pscale, T_FIXNUM);
5377
5558
  vscale = NUM2INT(pscale);
5378
- q->pinfo[vnum].scale = vscale;
5559
+ q->paraminfo[vnum].scale = vscale;
5379
5560
  }
5380
- q->pinfo[vnum].coldef = vcoldef;
5561
+ q->paraminfo[vnum].coldef = vcoldef;
5381
5562
  }
5382
- q->pinfo[vnum].type = vtype;
5383
- q->pinfo[vnum].override = 1;
5563
+ q->paraminfo[vnum].type = vtype;
5564
+ q->paraminfo[vnum].override = 1;
5384
5565
  return Qnil;
5385
5566
  }
5386
- return INT2NUM(q->pinfo[vnum].type);
5567
+ return INT2NUM(q->paraminfo[vnum].type);
5387
5568
  }
5388
5569
 
5389
5570
  static VALUE
@@ -5403,11 +5584,11 @@ stmt_param_iotype(int argc, VALUE *argv, VALUE self)
5403
5584
  case SQL_PARAM_INPUT:
5404
5585
  case SQL_PARAM_INPUT_OUTPUT:
5405
5586
  case SQL_PARAM_OUTPUT:
5406
- q->pinfo[vnum].iotype = viotype;
5587
+ q->paraminfo[vnum].iotype = viotype;
5407
5588
  break;
5408
5589
  }
5409
5590
  }
5410
- return INT2NUM(q->pinfo[vnum].iotype);
5591
+ return INT2NUM(q->paraminfo[vnum].iotype);
5411
5592
  }
5412
5593
 
5413
5594
  static VALUE
@@ -5421,52 +5602,101 @@ stmt_param_output_value(int argc, VALUE *argv, VALUE self)
5421
5602
  Data_Get_Struct(self, STMT, q);
5422
5603
  vnum = param_num_check(q, pnum, 0, 1);
5423
5604
  v = Qnil;
5424
- if (q->pinfo[vnum].rlen == SQL_NULL_DATA) {
5605
+ if (q->paraminfo[vnum].rlen == SQL_NULL_DATA) {
5425
5606
  return v;
5426
5607
  }
5427
- if (q->pinfo[vnum].outbuf == NULL) {
5608
+ if (q->paraminfo[vnum].outbuf == NULL) {
5428
5609
  rb_raise(Cerror, "no output value available");
5429
5610
  }
5430
- switch (q->pinfo[vnum].ctype) {
5611
+ switch (q->paraminfo[vnum].ctype) {
5431
5612
  case SQL_C_LONG:
5432
- v = INT2NUM(*((SQLINTEGER *) q->pinfo[vnum].outbuf));
5613
+ v = INT2NUM(*((SQLINTEGER *) q->paraminfo[vnum].outbuf));
5433
5614
  break;
5434
5615
  case SQL_C_DOUBLE:
5435
- v = rb_float_new(*((double *) q->pinfo[vnum].outbuf));
5616
+ v = rb_float_new(*((double *) q->paraminfo[vnum].outbuf));
5436
5617
  break;
5437
5618
  case SQL_C_DATE:
5438
5619
  {
5439
5620
  DATE_STRUCT *date;
5440
5621
 
5441
- v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree, date);
5442
- *date = *((DATE_STRUCT *) q->pinfo[vnum].outbuf);
5622
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
5623
+ const char *p;
5624
+ char buffer[128];
5625
+ VALUE d;
5626
+
5627
+ date = (DATE_STRUCT *) q->paraminfo[vnum].outbuf;
5628
+ p = (q->dbcp->gmtime == Qtrue) ? "+00:00" : "";
5629
+ sprintf(buffer, "%d-%d-%dT00:00:00%s",
5630
+ date->year, date->month, date->day, p);
5631
+ d = rb_str_new2(buffer);
5632
+ v = rb_funcall(rb_cDate, IDparse, 1, d);
5633
+ } else {
5634
+ v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree, date);
5635
+ *date = *((DATE_STRUCT *) q->paraminfo[vnum].outbuf);
5636
+ }
5443
5637
  }
5444
5638
  break;
5445
5639
  case SQL_C_TIME:
5446
5640
  {
5447
5641
  TIME_STRUCT *time;
5448
5642
 
5449
- v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree, time);
5450
- *time = *((TIME_STRUCT *) q->pinfo[vnum].outbuf);
5643
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
5644
+ VALUE now, frac;
5645
+
5646
+ time = (TIME_STRUCT *) q->paraminfo[vnum].outbuf;
5647
+ frac = rb_float_new(0.0);
5648
+ now = rb_funcall(rb_cTime, IDnow, 0, NULL);
5649
+ v = rb_funcall(rb_cTime,
5650
+ (q->dbcp->gmtime == Qtrue) ? IDutc : IDlocal,
5651
+ 7,
5652
+ rb_funcall(now, IDyear, 0, NULL),
5653
+ rb_funcall(now, IDmonth, 0, NULL),
5654
+ rb_funcall(now, IDday, 0, NULL),
5655
+ INT2NUM(time->hour),
5656
+ INT2NUM(time->minute),
5657
+ INT2NUM(time->second),
5658
+ frac);
5659
+ } else {
5660
+ v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree, time);
5661
+ *time = *((TIME_STRUCT *) q->paraminfo[vnum].outbuf);
5662
+ }
5451
5663
  }
5452
5664
  break;
5453
5665
  case SQL_C_TIMESTAMP:
5454
5666
  {
5455
5667
  TIMESTAMP_STRUCT *ts;
5456
5668
 
5457
- v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
5458
- 0, xfree, ts);
5459
- *ts = *((TIMESTAMP_STRUCT *) q->pinfo[vnum].outbuf);
5669
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
5670
+ VALUE frac;
5671
+
5672
+ ts = (TIMESTAMP_STRUCT *) q->paraminfo[vnum].outbuf;
5673
+ frac = rb_float_new((double) 1.0e-3 * ts->fraction);
5674
+ v = rb_funcall(rb_cTime,
5675
+ (q->dbcp->gmtime == Qtrue) ? IDutc : IDlocal,
5676
+ 7,
5677
+ INT2NUM(ts->year),
5678
+ INT2NUM(ts->month),
5679
+ INT2NUM(ts->day),
5680
+ INT2NUM(ts->hour),
5681
+ INT2NUM(ts->minute),
5682
+ INT2NUM(ts->second),
5683
+ frac);
5684
+ } else {
5685
+ v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
5686
+ 0, xfree, ts);
5687
+ *ts = *((TIMESTAMP_STRUCT *) q->paraminfo[vnum].outbuf);
5688
+ }
5460
5689
  }
5461
5690
  break;
5462
5691
  #ifdef UNICODE
5463
5692
  case SQL_C_WCHAR:
5464
- v = uc_tainted_str_new((SQLWCHAR *) q->pinfo[vnum].outbuf,
5465
- q->pinfo[vnum].rlen / sizeof (SQLWCHAR));
5693
+ v = uc_tainted_str_new((SQLWCHAR *) q->paraminfo[vnum].outbuf,
5694
+ q->paraminfo[vnum].rlen / sizeof (SQLWCHAR));
5466
5695
  break;
5467
5696
  #endif
5468
5697
  case SQL_C_CHAR:
5469
- v = rb_tainted_str_new(q->pinfo[vnum].outbuf, q->pinfo[vnum].rlen);
5698
+ v = rb_tainted_str_new(q->paraminfo[vnum].outbuf,
5699
+ q->paraminfo[vnum].rlen);
5470
5700
  break;
5471
5701
  }
5472
5702
  return v;
@@ -5485,12 +5715,12 @@ stmt_param_output_size(int argc, VALUE *argv, VALUE self)
5485
5715
  if (argc > 1) {
5486
5716
  Check_Type(psize, T_FIXNUM);
5487
5717
  vsize = NUM2INT(psize);
5488
- if ((vsize > 0) && (vsize < 4 * sizeof (double))) {
5718
+ if ((vsize > 0) && (vsize < (int) (4 * sizeof (double)))) {
5489
5719
  vsize = 4 * sizeof (double);
5490
5720
  }
5491
- q->pinfo[vnum].outsize = (vsize > 0) ? vsize : 0;
5721
+ q->paraminfo[vnum].outsize = (vsize > 0) ? vsize : 0;
5492
5722
  }
5493
- return INT2NUM(q->pinfo[vnum].outsize);
5723
+ return INT2NUM(q->paraminfo[vnum].outsize);
5494
5724
  }
5495
5725
 
5496
5726
  static VALUE
@@ -5506,9 +5736,9 @@ stmt_param_output_type(int argc, VALUE *argv, VALUE self)
5506
5736
  if (argc > 1) {
5507
5737
  Check_Type(ptype, T_FIXNUM);
5508
5738
  vtype = NUM2INT(ptype);
5509
- q->pinfo[vnum].outtype = vtype;
5739
+ q->paraminfo[vnum].outtype = vtype;
5510
5740
  }
5511
- return INT2NUM(q->pinfo[vnum].outtype);
5741
+ return INT2NUM(q->paraminfo[vnum].outtype);
5512
5742
  }
5513
5743
 
5514
5744
  static VALUE
@@ -5536,10 +5766,11 @@ stmt_cursorname(int argc, VALUE *argv, VALUE self)
5536
5766
  rb_raise(Cerror, "%s", msg);
5537
5767
  }
5538
5768
  #ifdef UNICODE
5539
- cnLen = (cnLen == 0) ? uc_strlen(cname) : (cnLen / sizeof (SQLWCHAR));
5769
+ cnLen = (cnLen == 0) ? (SQLSMALLINT) uc_strlen(cname) :
5770
+ (SQLSMALLINT) (cnLen / sizeof (SQLWCHAR));
5540
5771
  return uc_tainted_str_new(cname, cnLen);
5541
5772
  #else
5542
- cnLen = (cnLen == 0) ? strlen((char *) cname) : cnLen;
5773
+ cnLen = (cnLen == 0) ? (SQLSMALLINT) strlen((char *) cname) : cnLen;
5543
5774
  return rb_tainted_str_new((char *) cname, cnLen);
5544
5775
  #endif
5545
5776
  }
@@ -5547,9 +5778,12 @@ stmt_cursorname(int argc, VALUE *argv, VALUE self)
5547
5778
  cn = rb_any_to_s(cn);
5548
5779
  }
5549
5780
  #ifdef UNICODE
5781
+ #ifdef USE_RB_ENC
5782
+ cn = rb_funcall(cn, IDencode, 1, rb_encv);
5783
+ #endif
5550
5784
  cp = uc_from_utf((unsigned char *) STR2CSTR(cn), -1);
5551
5785
  if (cp == NULL) {
5552
- rb_raise(Cerror, set_err("Out of memory", 0));
5786
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
5553
5787
  }
5554
5788
  #else
5555
5789
  cp = (SQLCHAR *) STR2CSTR(cn);
@@ -5578,7 +5812,7 @@ stmt_column(int argc, VALUE *argv, VALUE self)
5578
5812
  Check_Type(col, T_FIXNUM);
5579
5813
  Data_Get_Struct(self, STMT, q);
5580
5814
  check_ncols(q);
5581
- return make_col(q->hstmt, FIX2INT(col), q->upc);
5815
+ return make_column(q->hstmt, FIX2INT(col), q->upc);
5582
5816
  }
5583
5817
 
5584
5818
  static VALUE
@@ -5593,7 +5827,7 @@ stmt_columns(int argc, VALUE *argv, VALUE self)
5593
5827
  check_ncols(q);
5594
5828
  if (rb_block_given_p()) {
5595
5829
  for (i = 0; i < q->ncols; i++) {
5596
- rb_yield(make_col(q->hstmt, i, q->upc));
5830
+ rb_yield(make_column(q->hstmt, i, q->upc));
5597
5831
  }
5598
5832
  return self;
5599
5833
  }
@@ -5605,7 +5839,7 @@ stmt_columns(int argc, VALUE *argv, VALUE self)
5605
5839
  for (i = 0; i < q->ncols; i++) {
5606
5840
  VALUE obj;
5607
5841
 
5608
- obj = make_col(q->hstmt, i, q->upc);
5842
+ obj = make_column(q->hstmt, i, q->upc);
5609
5843
  if (RTEST(as_ary)) {
5610
5844
  rb_ary_store(res, i, obj);
5611
5845
  } else {
@@ -5636,9 +5870,9 @@ stmt_param(int argc, VALUE *argv, VALUE self)
5636
5870
  Data_Get_Struct(self, STMT, q);
5637
5871
  i = FIX2INT(par);
5638
5872
  if ((i < 0) || (i >= q->nump)) {
5639
- rb_raise(Cerror, set_err("Parameter out of bounds", 0));
5873
+ rb_raise(Cerror, "%s", set_err("Parameter out of bounds", 0));
5640
5874
  }
5641
- return make_par(q, i);
5875
+ return make_param(q, i);
5642
5876
  }
5643
5877
 
5644
5878
  static VALUE
@@ -5651,7 +5885,7 @@ stmt_params(VALUE self)
5651
5885
  Data_Get_Struct(self, STMT, q);
5652
5886
  if (rb_block_given_p()) {
5653
5887
  for (i = 0; i < q->nump; i++) {
5654
- rb_yield(make_par(q, i));
5888
+ rb_yield(make_param(q, i));
5655
5889
  }
5656
5890
  return self;
5657
5891
  }
@@ -5659,7 +5893,7 @@ stmt_params(VALUE self)
5659
5893
  for (i = 0; i < q->nump; i++) {
5660
5894
  VALUE obj;
5661
5895
 
5662
- obj = make_par(q, i);
5896
+ obj = make_param(q, i);
5663
5897
  rb_ary_store(res, i, obj);
5664
5898
  }
5665
5899
  return res;
@@ -5673,7 +5907,7 @@ do_fetch(STMT *q, int mode)
5673
5907
  VALUE res;
5674
5908
 
5675
5909
  if (q->ncols <= 0) {
5676
- rb_raise(Cerror, set_err("No columns in result set", 0));
5910
+ rb_raise(Cerror, "%s", set_err("No columns in result set", 0));
5677
5911
  }
5678
5912
  if (++q->fetchc >= 500) {
5679
5913
  q->fetchc = 0;
@@ -5693,7 +5927,7 @@ do_fetch(STMT *q, int mode)
5693
5927
  }
5694
5928
  p = ALLOC_N(char, need);
5695
5929
  if (p == NULL) {
5696
- rb_raise(Cerror, set_err("Out of memory", 0));
5930
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
5697
5931
  }
5698
5932
  q->dbufs = bufs = (char **) p;
5699
5933
  p += needp;
@@ -5739,7 +5973,7 @@ do_fetch(STMT *q, int mode)
5739
5973
  "SQLColAttributes(SQL_COLUMN_TABLE_NAME)")) {
5740
5974
  rb_raise(Cerror, "%s", msg);
5741
5975
  }
5742
- if (name_len >= sizeof (name)) {
5976
+ if (name_len >= (SQLSMALLINT) sizeof (name)) {
5743
5977
  name_len = sizeof (name) - 1;
5744
5978
  }
5745
5979
  if (name_len > 0) {
@@ -5764,7 +5998,7 @@ do_fetch(STMT *q, int mode)
5764
5998
  &msg, "SQLColAttributes(SQL_COLUMN_LABEL)")) {
5765
5999
  rb_raise(Cerror, "%s", msg);
5766
6000
  }
5767
- if (name_len >= sizeof (name)) {
6001
+ if (name_len >= (SQLSMALLINT) sizeof (name)) {
5768
6002
  name_len = sizeof (name) - 1;
5769
6003
  }
5770
6004
  if (name_len > 0) {
@@ -5783,7 +6017,7 @@ do_fetch(STMT *q, int mode)
5783
6017
  need += max_len[0] + max_len[1] + 32;
5784
6018
  p = ALLOC_N(char, need);
5785
6019
  if (p == NULL) {
5786
- rb_raise(Cerror, set_err("Out of memory", 0));
6020
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
5787
6021
  }
5788
6022
  na = (char **) p;
5789
6023
  p += sizeof (char *) * 4 * q->ncols + sizeof (char *);
@@ -5796,7 +6030,7 @@ do_fetch(STMT *q, int mode)
5796
6030
  SQL_COLUMN_TABLE_NAME, name,
5797
6031
  sizeof (name), &name_len, NULL),
5798
6032
  "SQLColAttributes(SQL_COLUMN_TABLE_NAME)");
5799
- if (name_len >= sizeof (name)) {
6033
+ if (name_len >= (SQLSMALLINT) sizeof (name)) {
5800
6034
  name_len = sizeof (name) - 1;
5801
6035
  }
5802
6036
  if (name_len > 0) {
@@ -5817,7 +6051,7 @@ do_fetch(STMT *q, int mode)
5817
6051
  SQL_COLUMN_LABEL, name,
5818
6052
  sizeof (name), &name_len, NULL),
5819
6053
  "SQLColAttributes(SQL_COLUMN_LABEL)");
5820
- if (name_len >= sizeof (name)) {
6054
+ if (name_len >= (SQLSMALLINT) sizeof (name)) {
5821
6055
  name_len = sizeof (name) - 1;
5822
6056
  }
5823
6057
  if (name_len > 0) {
@@ -5839,6 +6073,42 @@ do_fetch(STMT *q, int mode)
5839
6073
  /* reserved space for later adjustments */
5840
6074
  na[4 * q->ncols] = p;
5841
6075
  q->colnames = na;
6076
+ if (q->colvals == NULL) {
6077
+ q->colvals = ALLOC_N(VALUE, 4 * q->ncols);
6078
+ if (q->colvals != NULL) {
6079
+ VALUE cname;
6080
+
6081
+ for (i = 0; i < 4 * q->ncols; i++) {
6082
+ q->colvals[i] = Qnil;
6083
+ }
6084
+ res = rb_iv_get(q->self, "@_c");
6085
+ if (res == Qnil) {
6086
+ res = rb_hash_new();
6087
+ rb_iv_set(q->self, "@_c", res);
6088
+ }
6089
+ for (i = 0; i < 4 * q->ncols; i++) {
6090
+ cname = rb_tainted_str_new2(q->colnames[i]);
6091
+ #ifdef USE_RB_ENC
6092
+ rb_enc_associate(cname, rb_enc);
6093
+ #endif
6094
+ q->colvals[i] = cname;
6095
+ if (rb_funcall(res, IDkeyp, 1, cname) == Qtrue) {
6096
+ char *p;
6097
+
6098
+ cname = rb_tainted_str_new2(q->colnames[i]);
6099
+ #ifdef USE_RB_ENC
6100
+ rb_enc_associate(cname, rb_enc);
6101
+ #endif
6102
+ p = q->colnames[4 * q->ncols];
6103
+ sprintf(p, "#%d", i);
6104
+ cname = rb_str_cat2(cname, p);
6105
+ q->colvals[i] = cname;
6106
+ }
6107
+ rb_obj_freeze(cname);
6108
+ rb_hash_aset(res, cname, Qtrue);
6109
+ }
6110
+ }
6111
+ }
5842
6112
  }
5843
6113
  /* FALL THRU */
5844
6114
  case DOFETCH_HASHN:
@@ -5866,15 +6136,21 @@ do_fetch(STMT *q, int mode)
5866
6136
  }
5867
6137
  }
5868
6138
  offc = q->upc ? (2 * q->ncols) : 0;
6139
+ switch (mode & DOFETCH_MODES) {
6140
+ case DOFETCH_HASHK2:
6141
+ case DOFETCH_HASH2:
6142
+ offc += q->ncols;
6143
+ break;
6144
+ }
5869
6145
  for (i = 0; i < q->ncols; i++) {
5870
- SQLLEN curlen, totlen;
6146
+ SQLLEN totlen;
6147
+ SQLLEN curlen = q->coltypes[i].size;
5871
6148
  SQLSMALLINT type = q->coltypes[i].type;
5872
6149
  VALUE v, name;
5873
6150
  char *valp, *freep = NULL;
5874
6151
 
5875
- curlen = q->coltypes[i].size;
5876
6152
  if (curlen == SQL_NO_TOTAL) {
5877
- SQLLEN chunksize = SEGSIZE;
6153
+ SQLLEN chunksize = SEGSIZE;
5878
6154
 
5879
6155
  totlen = 0;
5880
6156
  #ifdef UNICODE
@@ -5891,7 +6167,8 @@ do_fetch(STMT *q, int mode)
5891
6167
  type, (SQLPOINTER) (valp + totlen),
5892
6168
  #ifdef UNICODE
5893
6169
  ((type == SQL_C_CHAR) || (type == SQL_C_WCHAR)) ?
5894
- (chunksize + sizeof (SQLWCHAR)) : chunksize,
6170
+ (chunksize + (int) sizeof (SQLWCHAR)) :
6171
+ chunksize,
5895
6172
  #else
5896
6173
  (type == SQL_C_CHAR) ?
5897
6174
  (chunksize + 1) : chunksize,
@@ -5930,7 +6207,7 @@ do_fetch(STMT *q, int mode)
5930
6207
  if (freep != NULL) {
5931
6208
  xfree(freep);
5932
6209
  }
5933
- rb_raise(Cerror, set_err("Out of memory", 0));
6210
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
5934
6211
  }
5935
6212
  freep = valp;
5936
6213
  }
@@ -5979,25 +6256,77 @@ do_fetch(STMT *q, int mode)
5979
6256
  {
5980
6257
  DATE_STRUCT *date;
5981
6258
 
5982
- v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree, date);
5983
- *date = *(DATE_STRUCT *) valp;
6259
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
6260
+ const char *p;
6261
+ char buffer[128];
6262
+ VALUE d;
6263
+
6264
+ date = (DATE_STRUCT *) valp;
6265
+ p = (q->dbcp->gmtime == Qtrue) ? "+00:00" : "";
6266
+ sprintf(buffer, "%d-%d-%dT00:00:00%s",
6267
+ date->year, date->month, date->day, p);
6268
+ d = rb_str_new2(buffer);
6269
+ v = rb_funcall(rb_cDate, IDparse, 1, d);
6270
+ } else {
6271
+ v = Data_Make_Struct(Cdate, DATE_STRUCT, 0, xfree,
6272
+ date);
6273
+ *date = *(DATE_STRUCT *) valp;
6274
+ }
5984
6275
  }
5985
6276
  break;
5986
6277
  case SQL_C_TIME:
5987
6278
  {
5988
6279
  TIME_STRUCT *time;
5989
6280
 
5990
- v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree, time);
5991
- *time = *(TIME_STRUCT *) valp;
6281
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
6282
+ VALUE now, frac;
6283
+
6284
+ time = (TIME_STRUCT *) valp;
6285
+ frac = rb_float_new(0.0);
6286
+ now = rb_funcall(rb_cTime, IDnow, 0, NULL);
6287
+ v = rb_funcall(rb_cTime,
6288
+ (q->dbcp->gmtime == Qtrue) ?
6289
+ IDutc : IDlocal,
6290
+ 7,
6291
+ rb_funcall(now, IDyear, 0, NULL),
6292
+ rb_funcall(now, IDmonth, 0, NULL),
6293
+ rb_funcall(now, IDday, 0, NULL),
6294
+ INT2NUM(time->hour),
6295
+ INT2NUM(time->minute),
6296
+ INT2NUM(time->second),
6297
+ frac);
6298
+ } else {
6299
+ v = Data_Make_Struct(Ctime, TIME_STRUCT, 0, xfree,
6300
+ time);
6301
+ *time = *(TIME_STRUCT *) valp;
6302
+ }
5992
6303
  }
5993
6304
  break;
5994
6305
  case SQL_C_TIMESTAMP:
5995
6306
  {
5996
6307
  TIMESTAMP_STRUCT *ts;
5997
6308
 
5998
- v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
5999
- 0, xfree, ts);
6000
- *ts = *(TIMESTAMP_STRUCT *) valp;
6309
+ if (q->dbcp != NULL && q->dbcp->rbtime == Qtrue) {
6310
+ VALUE frac;
6311
+
6312
+ ts = (TIMESTAMP_STRUCT *) valp;
6313
+ frac = rb_float_new((double) 1.0e-3 * ts->fraction);
6314
+ v = rb_funcall(rb_cTime,
6315
+ (q->dbcp->gmtime == Qtrue) ?
6316
+ IDutc : IDlocal,
6317
+ 7,
6318
+ INT2NUM(ts->year),
6319
+ INT2NUM(ts->month),
6320
+ INT2NUM(ts->day),
6321
+ INT2NUM(ts->hour),
6322
+ INT2NUM(ts->minute),
6323
+ INT2NUM(ts->second),
6324
+ frac);
6325
+ } else {
6326
+ v = Data_Make_Struct(Ctimestamp, TIMESTAMP_STRUCT,
6327
+ 0, xfree, ts);
6328
+ *ts = *(TIMESTAMP_STRUCT *) valp;
6329
+ }
6001
6330
  }
6002
6331
  break;
6003
6332
  #ifdef UNICODE
@@ -6016,34 +6345,46 @@ do_fetch(STMT *q, int mode)
6016
6345
  }
6017
6346
  switch (mode & DOFETCH_MODES) {
6018
6347
  case DOFETCH_HASH:
6019
- valp = q->colnames[i + offc];
6020
- goto doaset;
6021
6348
  case DOFETCH_HASH2:
6022
- valp = q->colnames[i + offc + q->ncols];
6023
- doaset:
6024
- name = rb_tainted_str_new2(valp);
6025
- if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
6026
- char *p;
6027
-
6028
- p = q->colnames[4 * q->ncols];
6029
- sprintf(p, "#%d", i);
6030
- name = rb_str_cat2(name, p);
6349
+ valp = q->colnames[i + offc];
6350
+ name = (q->colvals == NULL) ? Qnil : q->colvals[i + offc];
6351
+ if (name == Qnil) {
6352
+ name = rb_tainted_str_new2(valp);
6353
+ #ifdef USE_RB_ENC
6354
+ rb_enc_associate(name, rb_enc);
6355
+ #endif
6356
+ if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
6357
+ char *p;
6358
+
6359
+ name = rb_tainted_str_new2(valp);
6360
+ #ifdef USE_RB_ENC
6361
+ rb_enc_associate(name, rb_enc);
6362
+ #endif
6363
+ p = q->colnames[4 * q->ncols];
6364
+ sprintf(p, "#%d", i);
6365
+ name = rb_str_cat2(name, p);
6366
+ }
6031
6367
  }
6032
6368
  rb_hash_aset(res, name, v);
6033
6369
  break;
6034
6370
  case DOFETCH_HASHK:
6035
- valp = q->colnames[i + offc];
6036
- goto dokset;
6037
6371
  case DOFETCH_HASHK2:
6038
- valp = q->colnames[i + offc + q->ncols];
6039
- dokset:
6372
+ valp = q->colnames[i + offc];
6373
+ #ifdef USE_RB_ENC
6374
+ name = ID2SYM(rb_intern3(valp, strlen(valp), rb_enc));
6375
+ #else
6040
6376
  name = ID2SYM(rb_intern(valp));
6377
+ #endif
6041
6378
  if (rb_funcall(res, IDkeyp, 1, name) == Qtrue) {
6042
6379
  char *p;
6043
6380
 
6044
6381
  p = q->colnames[4 * q->ncols];
6045
6382
  sprintf(p, "%s#%d", valp, i);
6383
+ #ifdef USE_RB_ENC
6384
+ name = ID2SYM(rb_intern3(p, strlen(p), rb_enc));
6385
+ #else
6046
6386
  name = ID2SYM(rb_intern(p));
6387
+ #endif
6047
6388
  }
6048
6389
  rb_hash_aset(res, name, v);
6049
6390
  break;
@@ -6063,7 +6404,8 @@ stmt_fetch1(VALUE self, int bang)
6063
6404
  {
6064
6405
  STMT *q;
6065
6406
  SQLRETURN ret;
6066
- char *msg, *err;
6407
+ const char *msg;
6408
+ char *err;
6067
6409
  #if (ODBCVER < 0x0300)
6068
6410
  SQLUINTEGER nRows;
6069
6411
  SQLUSMALLINT rowStat[1];
@@ -6134,7 +6476,8 @@ stmt_fetch_first1(VALUE self, int bang, int nopos)
6134
6476
  {
6135
6477
  STMT *q;
6136
6478
  SQLRETURN ret;
6137
- char *msg, *err;
6479
+ const char *msg;
6480
+ char *err;
6138
6481
  #if (ODBCVER < 0x0300)
6139
6482
  SQLUINTEGER nRows;
6140
6483
  SQLUSMALLINT rowStat[1];
@@ -6304,7 +6647,8 @@ stmt_fetch_hash1(int argc, VALUE *argv, VALUE self, int bang)
6304
6647
  STMT *q;
6305
6648
  SQLRETURN ret;
6306
6649
  int mode = stmt_hash_mode(argc, argv, self);
6307
- char *msg, *err;
6650
+ const char *msg;
6651
+ char *err;
6308
6652
  #if (ODBCVER < 0x0300)
6309
6653
  SQLUINTEGER nRows;
6310
6654
  SQLUSMALLINT rowStat[1];
@@ -6376,7 +6720,8 @@ stmt_fetch_first_hash1(int argc, VALUE *argv, VALUE self, int bang, int nopos)
6376
6720
  STMT *q;
6377
6721
  SQLRETURN ret;
6378
6722
  int mode = stmt_hash_mode(argc, argv, self);
6379
- char *msg, *err;
6723
+ const char *msg;
6724
+ char *err;
6380
6725
  #if (ODBCVER < 0x0300)
6381
6726
  SQLUINTEGER nRows;
6382
6727
  SQLUSMALLINT rowStat[1];
@@ -6417,7 +6762,7 @@ stmt_fetch_first_hash(int argc, VALUE *argv, VALUE self)
6417
6762
  static VALUE
6418
6763
  stmt_each(VALUE self)
6419
6764
  {
6420
- VALUE row;
6765
+ VALUE row, res = Qnil;
6421
6766
  STMT *q;
6422
6767
  #if (ODBCVER < 0x0300)
6423
6768
  SQLUINTEGER nRows;
@@ -6446,17 +6791,27 @@ stmt_each(VALUE self)
6446
6791
  default:
6447
6792
  row = stmt_fetch1(self, 0);
6448
6793
  }
6449
- while (row != Qnil) {
6450
- rb_yield(row);
6451
- row = stmt_fetch1(self, 0);
6794
+ if (rb_block_given_p()) {
6795
+ while (row != Qnil) {
6796
+ rb_yield(row);
6797
+ row = stmt_fetch1(self, 0);
6798
+ }
6799
+ return self;
6452
6800
  }
6453
- return self;
6801
+ if (row != Qnil) {
6802
+ res = rb_ary_new();
6803
+ while (row != Qnil) {
6804
+ rb_ary_push(res, row);
6805
+ row = stmt_fetch1(self, 0);
6806
+ }
6807
+ }
6808
+ return res;
6454
6809
  }
6455
6810
 
6456
6811
  static VALUE
6457
6812
  stmt_each_hash(int argc, VALUE *argv, VALUE self)
6458
6813
  {
6459
- VALUE row, withtab[2];
6814
+ VALUE row, res = Qnil, withtab[2];
6460
6815
  STMT *q;
6461
6816
  int mode = stmt_hash_mode(argc, argv, self);
6462
6817
  #if (ODBCVER < 0x0300)
@@ -6495,11 +6850,21 @@ stmt_each_hash(int argc, VALUE *argv, VALUE self)
6495
6850
  default:
6496
6851
  row = stmt_fetch_hash1(2, withtab, self, 0);
6497
6852
  }
6498
- while (row != Qnil) {
6499
- rb_yield(row);
6500
- row = stmt_fetch_hash1(2, withtab, self, 0);
6853
+ if (rb_block_given_p()) {
6854
+ while (row != Qnil) {
6855
+ rb_yield(row);
6856
+ row = stmt_fetch_hash1(2, withtab, self, 0);
6857
+ }
6858
+ return self;
6501
6859
  }
6502
- return self;
6860
+ if (row != Qnil) {
6861
+ res = rb_ary_new();
6862
+ while (row != Qnil) {
6863
+ rb_ary_push(res, row);
6864
+ row = stmt_fetch_hash1(2, withtab, self, 0);
6865
+ }
6866
+ }
6867
+ return res;
6503
6868
  }
6504
6869
 
6505
6870
  static VALUE
@@ -6571,10 +6936,13 @@ stmt_prep_int(int argc, VALUE *argv, VALUE self, int mode)
6571
6936
  rb_scan_args(argc, argv, "1", &sql);
6572
6937
  Check_Type(sql, T_STRING);
6573
6938
  #ifdef UNICODE
6939
+ #ifdef USE_RB_ENC
6940
+ sql = rb_funcall(sql, IDencode, 1, rb_encv);
6941
+ #endif
6574
6942
  csql = STR2CSTR(sql);
6575
6943
  ssql = uc_from_utf((unsigned char *) csql, -1);
6576
6944
  if (ssql == NULL) {
6577
- rb_raise(Cerror, set_err("Out of memory", 0));
6945
+ rb_raise(Cerror, "%s", set_err("Out of memory", 0));
6578
6946
  }
6579
6947
  #else
6580
6948
  csql = STR2CSTR(sql);
@@ -6589,10 +6957,13 @@ stmt_prep_int(int argc, VALUE *argv, VALUE self, int mode)
6589
6957
  goto sqlerr;
6590
6958
  }
6591
6959
  if (ret == SQL_NO_DATA) {
6592
- #ifdef UNICODE
6593
- uc_free(ssql);
6594
- #endif
6595
- return Qnil;
6960
+ callsql(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
6961
+ SQLFreeStmt(hstmt, SQL_CLOSE), "SQLFreeStmt(SQL_DROP)");
6962
+ if (q != NULL) {
6963
+ q->hstmt = SQL_NULL_HSTMT;
6964
+ unlink_stmt(q);
6965
+ }
6966
+ hstmt = SQL_NULL_HSTMT;
6596
6967
  }
6597
6968
  } else if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, hstmt,
6598
6969
  SQLPrepare(hstmt, ssql, SQL_NTS),
@@ -6626,29 +6997,52 @@ stmt_prep(int argc, VALUE *argv, VALUE self)
6626
6997
  static int
6627
6998
  bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
6628
6999
  {
6629
- SQLPOINTER valp = (SQLPOINTER) &q->pinfo[pnum].buffer;
7000
+ SQLPOINTER valp = (SQLPOINTER) &q->paraminfo[pnum].buffer;
6630
7001
  SQLSMALLINT ctype, stype;
6631
7002
  SQLINTEGER vlen, rlen;
6632
7003
  SQLUINTEGER coldef;
7004
+ #ifdef NO_RB_STR2CSTR
7005
+ VALUE val;
7006
+ #endif
6633
7007
  long llen;
6634
7008
  int retry = 1;
6635
7009
  #ifdef UNICODE
6636
7010
  SQLWCHAR *up;
6637
7011
 
6638
- q->pinfo[pnum].tofree = NULL;
7012
+ q->paraminfo[pnum].tofree = NULL;
6639
7013
  #endif
6640
7014
  switch (TYPE(arg)) {
6641
7015
  case T_STRING:
6642
7016
  #ifdef UNICODE
6643
7017
  ctype = SQL_C_WCHAR;
7018
+ #ifdef USE_RB_ENC
7019
+ arg = rb_funcall(arg, IDencode, 1, rb_encv);
7020
+ #endif
7021
+ #ifndef NO_RB_STR2CSTR
6644
7022
  up = (SQLWCHAR *) rb_str2cstr(arg, &llen);
6645
- if (llen != strlen((char *) up)) {
7023
+ if (llen != (long) strlen((char *) up)) {
6646
7024
  ctype = SQL_C_BINARY;
6647
7025
  valp = (SQLPOINTER) up;
6648
7026
  rlen = llen;
6649
7027
  vlen = rlen + 1;
6650
7028
  break;
6651
7029
  }
7030
+ #else
7031
+ val = rb_string_value(&arg);
7032
+ up = (SQLWCHAR *) RSTRING_PTR(val);
7033
+ llen = RSTRING_LEN(val);
7034
+ if (up == NULL) {
7035
+ goto oom;
7036
+ }
7037
+ if (memchr((char *) up, 0, llen)) {
7038
+ ctype = SQL_C_BINARY;
7039
+ valp = (SQLPOINTER) up;
7040
+ rlen = llen;
7041
+ vlen = rlen + 1;
7042
+ break;
7043
+ }
7044
+ up = (SQLWCHAR *) rb_string_value_cstr(&arg);
7045
+ #endif
6652
7046
  up = uc_from_utf((unsigned char *) up, llen);
6653
7047
  if (up == NULL) {
6654
7048
  goto oom;
@@ -6656,15 +7050,31 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
6656
7050
  *(SQLWCHAR **) valp = up;
6657
7051
  rlen = uc_strlen(up) * sizeof (SQLWCHAR);
6658
7052
  vlen = rlen + sizeof (SQLWCHAR);
6659
- q->pinfo[pnum].tofree = up;
7053
+ q->paraminfo[pnum].tofree = up;
6660
7054
  #else
6661
7055
  ctype = SQL_C_CHAR;
7056
+ #ifndef NO_RB_STR2CSTR
6662
7057
  valp = (SQLPOINTER) rb_str2cstr(arg, &llen);
6663
7058
  rlen = llen;
6664
- if (rlen != strlen((char *) valp)) {
7059
+ if (rlen != (SQLINTEGER) strlen((char *) valp)) {
6665
7060
  ctype = SQL_C_BINARY;
6666
7061
  }
6667
7062
  vlen = rlen + 1;
7063
+ #else
7064
+ val = rb_string_value(&arg);
7065
+ valp = (SQLPOINTER) RSTRING_PTR(val);
7066
+ llen = RSTRING_LEN(val);
7067
+ if (valp == NULL) {
7068
+ goto oom;
7069
+ }
7070
+ rlen = llen;
7071
+ vlen = rlen + 1;
7072
+ if (memchr((char *) valp, 0, llen)) {
7073
+ ctype = SQL_C_BINARY;
7074
+ break;
7075
+ }
7076
+ valp = (SQLPOINTER) rb_string_value_cstr(&arg);
7077
+ #endif
6668
7078
  #endif
6669
7079
  break;
6670
7080
  case T_FIXNUM:
@@ -6726,19 +7136,93 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
6726
7136
  vlen = sizeof (TIMESTAMP_STRUCT);
6727
7137
  break;
6728
7138
  }
7139
+ if (rb_obj_is_kind_of(arg, rb_cTime) == Qtrue) {
7140
+ if (q->paraminfo[pnum].type == SQL_TIME) {
7141
+ TIME_STRUCT *time;
7142
+
7143
+ ctype = SQL_C_TIME;
7144
+ time = (TIME_STRUCT *) valp;
7145
+ memset(time, 0, sizeof (TIME_STRUCT));
7146
+ time->hour = rb_funcall(arg, IDhour, 0, NULL);
7147
+ time->minute = rb_funcall(arg, IDmin, 0, NULL);
7148
+ time->second = rb_funcall(arg, IDsec, 0, NULL);
7149
+ rlen = 1;
7150
+ vlen = sizeof (TIME_STRUCT);
7151
+ } else if (q->paraminfo[pnum].type == SQL_DATE) {
7152
+ DATE_STRUCT *date;
7153
+
7154
+ ctype = SQL_C_DATE;
7155
+ date = (DATE_STRUCT *) valp;
7156
+ memset(date, 0, sizeof (DATE_STRUCT));
7157
+ date->year = rb_funcall(arg, IDyear, 0, NULL);
7158
+ date->month = rb_funcall(arg, IDmonth, 0, NULL);
7159
+ date->day = rb_funcall(arg, IDday, 0, NULL);
7160
+ rlen = 1;
7161
+ vlen = sizeof (TIMESTAMP_STRUCT);
7162
+ } else {
7163
+ TIMESTAMP_STRUCT *ts;
7164
+
7165
+ ctype = SQL_C_TIMESTAMP;
7166
+ ts = (TIMESTAMP_STRUCT *) valp;
7167
+ memset(ts, 0, sizeof (TIMESTAMP_STRUCT));
7168
+ ts->year = rb_funcall(arg, IDyear, 0, NULL);
7169
+ ts->month = rb_funcall(arg, IDmonth, 0, NULL);
7170
+ ts->day = rb_funcall(arg, IDday, 0, NULL);
7171
+ ts->hour = rb_funcall(arg, IDhour, 0, NULL);
7172
+ ts->minute = rb_funcall(arg, IDmin, 0, NULL);
7173
+ ts->second = rb_funcall(arg, IDsec, 0, NULL);
7174
+ #ifdef TIME_USE_USEC
7175
+ ts->fraction = rb_funcall(arg, IDusec, 0, NULL) * 1000;
7176
+ #else
7177
+ ts->fraction = rb_funcall(arg, IDnsec, 0, NULL);
7178
+ #endif
7179
+ rlen = 1;
7180
+ vlen = sizeof (TIMESTAMP_STRUCT);
7181
+ }
7182
+ break;
7183
+ }
7184
+ if (rb_obj_is_kind_of(arg, rb_cDate) == Qtrue) {
7185
+ DATE_STRUCT *date;
7186
+
7187
+ ctype = SQL_C_DATE;
7188
+ date = (DATE_STRUCT *) valp;
7189
+ memset(date, 0, sizeof (DATE_STRUCT));
7190
+ date->year = rb_funcall(arg, IDyear, 0, NULL);
7191
+ date->month = rb_funcall(arg, IDmonth, 0, NULL);
7192
+ date->day = rb_funcall(arg, IDmday, 0, NULL);
7193
+ rlen = 1;
7194
+ vlen = sizeof (DATE_STRUCT);
7195
+ break;
7196
+ }
6729
7197
  ctype = SQL_C_CHAR;
7198
+ #ifndef NO_RB_STR2CSTR
6730
7199
  valp = (SQLPOINTER *) rb_str2cstr(rb_str_to_str(arg), &llen);
6731
7200
  rlen = llen;
6732
- if (rlen != strlen((char *) valp)) {
7201
+ if (rlen != (SQLINTEGER) strlen((char *) valp)) {
6733
7202
  ctype = SQL_C_BINARY;
6734
7203
  }
6735
7204
  vlen = rlen + 1;
7205
+ #else
7206
+ val = rb_string_value(&arg);
7207
+ valp = (SQLPOINTER) RSTRING_PTR(val);
7208
+ llen = RSTRING_LEN(val);
7209
+ if (valp == NULL) {
7210
+ goto oom;
7211
+ }
7212
+ rlen = llen;
7213
+ vlen = rlen + 1;
7214
+ if (memchr((char *) valp, 0, llen)) {
7215
+ ctype = SQL_C_BINARY;
7216
+ break;
7217
+ }
7218
+ valp = (SQLPOINTER) rb_string_value_cstr(&arg);
7219
+ #endif
6736
7220
  break;
6737
7221
  }
6738
- stype = q->pinfo[pnum].type;
6739
- coldef = q->pinfo[pnum].coldef;
6740
- q->pinfo[pnum].rlen = rlen;
6741
- q->pinfo[pnum].ctype = ctype;
7222
+ stype = q->paraminfo[pnum].type;
7223
+ coldef = q->paraminfo[pnum].coldef;
7224
+ q->paraminfo[pnum].rlen = rlen;
7225
+ q->paraminfo[pnum].ctype = ctype;
6742
7226
  if (coldef == 0) {
6743
7227
  switch (ctype) {
6744
7228
  case SQL_C_LONG:
@@ -6772,50 +7256,50 @@ bind_one_param(int pnum, VALUE arg, STMT *q, char **msgp, int *outpp)
6772
7256
  * TBD: the default for this should be a tunable parameter.
6773
7257
  */
6774
7258
  if ((stype == SQL_VARCHAR) &&
6775
- (q->pinfo[pnum].iotype != SQL_PARAM_INPUT_OUTPUT) &&
6776
- (q->pinfo[pnum].iotype != SQL_PARAM_OUTPUT)) {
6777
- if (q->pinfo[pnum].coldef_max == 0) {
6778
- q->pinfo[pnum].coldef_max = (vlen > 128) ? vlen : 128;
7259
+ (q->paraminfo[pnum].iotype != SQL_PARAM_INPUT_OUTPUT) &&
7260
+ (q->paraminfo[pnum].iotype != SQL_PARAM_OUTPUT)) {
7261
+ if (q->paraminfo[pnum].coldef_max == 0) {
7262
+ q->paraminfo[pnum].coldef_max = (vlen > 128) ? vlen : 128;
6779
7263
  } else {
6780
7264
  /* bump up max, if needed */
6781
- if (vlen > q->pinfo[pnum].coldef_max) {
6782
- q->pinfo[pnum].coldef_max = vlen;
7265
+ if (vlen > (SQLINTEGER) q->paraminfo[pnum].coldef_max) {
7266
+ q->paraminfo[pnum].coldef_max = vlen;
6783
7267
  }
6784
7268
  }
6785
- coldef = q->pinfo[pnum].coldef_max;
7269
+ coldef = q->paraminfo[pnum].coldef_max;
6786
7270
  } else {
6787
7271
  coldef = vlen;
6788
7272
  }
6789
7273
  break;
6790
7274
  }
6791
7275
  }
6792
- if ((q->pinfo[pnum].iotype == SQL_PARAM_INPUT_OUTPUT) ||
6793
- (q->pinfo[pnum].iotype == SQL_PARAM_OUTPUT)) {
7276
+ if ((q->paraminfo[pnum].iotype == SQL_PARAM_INPUT_OUTPUT) ||
7277
+ (q->paraminfo[pnum].iotype == SQL_PARAM_OUTPUT)) {
6794
7278
  if (valp == NULL) {
6795
- if (q->pinfo[pnum].outsize > 0) {
6796
- if (q->pinfo[pnum].outbuf != NULL) {
6797
- xfree(q->pinfo[pnum].outbuf);
7279
+ if (q->paraminfo[pnum].outsize > 0) {
7280
+ if (q->paraminfo[pnum].outbuf != NULL) {
7281
+ xfree(q->paraminfo[pnum].outbuf);
6798
7282
  }
6799
- q->pinfo[pnum].outbuf = xmalloc(q->pinfo[pnum].outsize);
6800
- if (q->pinfo[pnum].outbuf == NULL) {
7283
+ q->paraminfo[pnum].outbuf = xmalloc(q->paraminfo[pnum].outsize);
7284
+ if (q->paraminfo[pnum].outbuf == NULL) {
6801
7285
  goto oom;
6802
7286
  }
6803
- ctype = q->pinfo[pnum].ctype = q->pinfo[pnum].outtype;
7287
+ ctype = q->paraminfo[pnum].ctype = q->paraminfo[pnum].outtype;
6804
7288
  outpp[0]++;
6805
- valp = q->pinfo[pnum].outbuf;
6806
- vlen = q->pinfo[pnum].outsize;
7289
+ valp = q->paraminfo[pnum].outbuf;
7290
+ vlen = q->paraminfo[pnum].outsize;
6807
7291
  }
6808
7292
  } else {
6809
- if (q->pinfo[pnum].outbuf != NULL) {
6810
- xfree(q->pinfo[pnum].outbuf);
7293
+ if (q->paraminfo[pnum].outbuf != NULL) {
7294
+ xfree(q->paraminfo[pnum].outbuf);
6811
7295
  }
6812
- q->pinfo[pnum].outbuf = xmalloc(vlen);
6813
- if (q->pinfo[pnum].outbuf == NULL) {
7296
+ q->paraminfo[pnum].outbuf = xmalloc(vlen);
7297
+ if (q->paraminfo[pnum].outbuf == NULL) {
6814
7298
  oom:
6815
7299
  #ifdef UNICODE
6816
- if (q->pinfo[pnum].tofree != NULL) {
6817
- uc_free(q->pinfo[pnum].tofree);
6818
- q->pinfo[pnum].tofree = NULL;
7300
+ if (q->paraminfo[pnum].tofree != NULL) {
7301
+ uc_free(q->paraminfo[pnum].tofree);
7302
+ q->paraminfo[pnum].tofree = NULL;
6819
7303
  }
6820
7304
  #endif
6821
7305
  *msgp = set_err("Out of memory", 0);
@@ -6823,16 +7307,16 @@ oom:
6823
7307
  }
6824
7308
  #ifdef UNICODE
6825
7309
  if (ctype == SQL_C_WCHAR) {
6826
- memcpy(q->pinfo[pnum].outbuf, *(SQLWCHAR **) valp, vlen);
7310
+ memcpy(q->paraminfo[pnum].outbuf, *(SQLWCHAR **) valp, vlen);
6827
7311
  } else
6828
7312
  #endif
6829
- memcpy(q->pinfo[pnum].outbuf, valp, vlen);
7313
+ memcpy(q->paraminfo[pnum].outbuf, valp, vlen);
6830
7314
  #ifdef UNICODE
6831
7315
  if (ctype == SQL_C_WCHAR) {
6832
- *(SQLWCHAR **) valp = (SQLWCHAR *) q->pinfo[pnum].outbuf;
7316
+ *(SQLWCHAR **) valp = (SQLWCHAR *) q->paraminfo[pnum].outbuf;
6833
7317
  } else
6834
7318
  #endif
6835
- valp = q->pinfo[pnum].outbuf;
7319
+ valp = q->paraminfo[pnum].outbuf;
6836
7320
  outpp[0]++;
6837
7321
  }
6838
7322
  }
@@ -6840,20 +7324,20 @@ retry:
6840
7324
  #ifdef UNICODE
6841
7325
  if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6842
7326
  SQLBindParameter(q->hstmt, (SQLUSMALLINT) (pnum + 1),
6843
- q->pinfo[pnum].iotype,
7327
+ q->paraminfo[pnum].iotype,
6844
7328
  ctype, stype, coldef,
6845
- q->pinfo[pnum].scale,
7329
+ q->paraminfo[pnum].scale,
6846
7330
  (ctype == SQL_C_WCHAR) ?
6847
7331
  *(SQLWCHAR **) valp : valp,
6848
- vlen, &q->pinfo[pnum].rlen),
7332
+ vlen, &q->paraminfo[pnum].rlen),
6849
7333
  msgp, "SQLBindParameter(%d)", pnum + 1))
6850
7334
  #else
6851
7335
  if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6852
7336
  SQLBindParameter(q->hstmt, (SQLUSMALLINT) (pnum + 1),
6853
- q->pinfo[pnum].iotype,
7337
+ q->paraminfo[pnum].iotype,
6854
7338
  ctype, stype, coldef,
6855
- q->pinfo[pnum].scale,
6856
- valp, vlen, &q->pinfo[pnum].rlen),
7339
+ q->paraminfo[pnum].scale,
7340
+ valp, vlen, &q->paraminfo[pnum].rlen),
6857
7341
  msgp, "SQLBindParameter(%d)", pnum + 1))
6858
7342
  #endif
6859
7343
  {
@@ -6885,11 +7369,11 @@ stmt_exec_int(int argc, VALUE *argv, VALUE self, int mode)
6885
7369
  SQLRETURN ret;
6886
7370
 
6887
7371
  Data_Get_Struct(self, STMT, q);
6888
- if (argc > q->nump - (EXEC_PARMXOUT(mode) < 0 ? 0 : 1)) {
6889
- rb_raise(Cerror, set_err("Too much parameters", 0));
7372
+ if (argc > q->nump - ((EXEC_PARMXOUT(mode) < 0) ? 0 : 1)) {
7373
+ rb_raise(Cerror, "%s", set_err("Too much parameters", 0));
6890
7374
  }
6891
7375
  if (q->hstmt == SQL_NULL_HSTMT) {
6892
- rb_raise(Cerror, set_err("Stale ODBC::Statement", 0));
7376
+ rb_raise(Cerror, "%s", set_err("Stale ODBC::Statement", 0));
6893
7377
  }
6894
7378
  if (!succeeded(SQL_NULL_HENV, SQL_NULL_HDBC, q->hstmt,
6895
7379
  SQLFreeStmt(q->hstmt, SQL_CLOSE),
@@ -6908,7 +7392,7 @@ stmt_exec_int(int argc, VALUE *argv, VALUE self, int mode)
6908
7392
  }
6909
7393
  continue;
6910
7394
  }
6911
- arg = argnum < argc ? argv[argnum++] : Qnil;
7395
+ arg = (argnum < argc) ? argv[argnum++] : Qnil;
6912
7396
  if (bind_one_param(i, arg, q, &msg, &has_out_parms) < 0) {
6913
7397
  goto error;
6914
7398
  }
@@ -6919,9 +7403,9 @@ stmt_exec_int(int argc, VALUE *argv, VALUE self, int mode)
6919
7403
  error:
6920
7404
  #ifdef UNICODE
6921
7405
  for (i = 0; i < q->nump; i++) {
6922
- if (q->pinfo[i].tofree != NULL) {
6923
- uc_free(q->pinfo[i].tofree);
6924
- q->pinfo[i].tofree = NULL;
7406
+ if (q->paraminfo[i].tofree != NULL) {
7407
+ uc_free(q->paraminfo[i].tofree);
7408
+ q->paraminfo[i].tofree = NULL;
6925
7409
  }
6926
7410
  }
6927
7411
  #endif
@@ -6933,9 +7417,9 @@ error:
6933
7417
  }
6934
7418
  #ifdef UNICODE
6935
7419
  for (i = 0; i < q->nump; i++) {
6936
- if (q->pinfo[i].tofree != NULL) {
6937
- uc_free(q->pinfo[i].tofree);
6938
- q->pinfo[i].tofree = NULL;
7420
+ if (q->paraminfo[i].tofree != NULL) {
7421
+ uc_free(q->paraminfo[i].tofree);
7422
+ q->paraminfo[i].tofree = NULL;
6939
7423
  }
6940
7424
  }
6941
7425
  #endif
@@ -7523,6 +8007,8 @@ static struct {
7523
8007
  { &IDmonth, "month" },
7524
8008
  { &IDyear, "year" },
7525
8009
  { &IDmday, "mday" },
8010
+ { &IDnsec, "nsec" },
8011
+ { &IDusec, "usec" },
7526
8012
  { &IDsec, "sec" },
7527
8013
  { &IDmin, "min" },
7528
8014
  { &IDhour, "hour" },
@@ -7553,7 +8039,13 @@ static struct {
7553
8039
  { &IDreturn_output_param, "return_output_param" },
7554
8040
  { &IDattrs, "attrs" },
7555
8041
  { &IDNULL, "NULL" },
7556
- { &IDdefault, "default" }
8042
+ { &IDdefault, "default" },
8043
+ #ifdef USE_RB_ENC
8044
+ { &IDencode, "encode" },
8045
+ #endif
8046
+ { &IDparse, "parse" },
8047
+ { &IDutc, "utc" },
8048
+ { &IDlocal, "local" }
7557
8049
  };
7558
8050
 
7559
8051
  /*
@@ -7572,7 +8064,7 @@ Init_odbc()
7572
8064
  #endif
7573
8065
  {
7574
8066
  int i;
7575
- char *modname = "ODBC";
8067
+ const char *modname = "ODBC";
7576
8068
  ID modid = rb_intern(modname);
7577
8069
  VALUE v = Qnil;
7578
8070
 
@@ -7593,7 +8085,7 @@ Init_odbc()
7593
8085
  #endif
7594
8086
  }
7595
8087
 
7596
- for (i = 0; i < sizeof (ids) / sizeof (ids[0]); i++) {
8088
+ for (i = 0; i < (int) (sizeof (ids) / sizeof (ids[0])); i++) {
7597
8089
  *(ids[i].idp) = rb_intern(ids[i].str);
7598
8090
  }
7599
8091
 
@@ -7728,6 +8220,10 @@ Init_odbc()
7728
8220
  rb_define_method(Cdbc, "run", stmt_run, -1);
7729
8221
  rb_define_method(Cdbc, "do", stmt_do, -1);
7730
8222
  rb_define_method(Cdbc, "proc", stmt_proc, -1);
8223
+ rb_define_method(Cdbc, "use_time", dbc_timefmt, -1);
8224
+ rb_define_method(Cdbc, "use_time=", dbc_timefmt, -1);
8225
+ rb_define_method(Cdbc, "use_utc", dbc_timeutc, -1);
8226
+ rb_define_method(Cdbc, "use_utc=", dbc_timeutc, -1);
7731
8227
 
7732
8228
  /* connection options */
7733
8229
  rb_define_method(Cdbc, "get_option", dbc_getsetoption, -1);
@@ -7900,6 +8396,16 @@ Init_odbc()
7900
8396
  INT2NUM(option_map[i].option));
7901
8397
  }
7902
8398
 
8399
+ #ifdef UNICODE
8400
+ rb_define_const(Modbc, "UTF8", Qtrue);
8401
+ #ifdef USE_RB_ENC
8402
+ rb_enc = rb_utf8_encoding();
8403
+ rb_encv = rb_enc_from_encoding(rb_enc);
8404
+ #endif
8405
+ #else
8406
+ rb_define_const(Modbc, "UTF8", Qfalse);
8407
+ #endif
8408
+
7903
8409
  #ifdef TRACING
7904
8410
  if (ruby_verbose) {
7905
8411
  tracing = -1;