ruby-odbc 0.99991 → 0.99992

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/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;