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 +15 -0
- data/README +2 -2
- data/doc/odbc.html +29 -4
- data/ext/extconf.rb +1 -1
- data/ext/odbc.c +800 -294
- data/ext/utf8/extconf.rb +2 -1
- data/ext/utf8/odbc.c +4 -2
- data/ruby-odbc.gemspec +1 -1
- metadata +2 -2
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
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:
|
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
|
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
|
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
|
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
data/ext/odbc.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* ODBC-Ruby binding
|
3
|
-
* Copyright (c) 2001-
|
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.
|
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
|
-
}
|
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
|
-
|
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
|
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->
|
805
|
+
if (q->paraminfo != NULL) {
|
771
806
|
int i;
|
772
807
|
|
773
808
|
for (i = 0; i < q->nump; i++) {
|
774
|
-
if (q->
|
775
|
-
xfree(q->
|
809
|
+
if (q->paraminfo[i].outbuf != NULL) {
|
810
|
+
xfree(q->paraminfo[i].outbuf);
|
776
811
|
}
|
777
812
|
}
|
778
|
-
xfree(q->
|
779
|
-
q->
|
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]
|
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,
|
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,
|
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) :
|
1445
|
+
dsnLen = (dsnLen == 0) ? (SQLSMALLINT) uc_strlen(dsn) :
|
1446
|
+
(SQLSMALLINT) (dsnLen / sizeof (SQLWCHAR));
|
1394
1447
|
descrLen = (descrLen == 0) ?
|
1395
|
-
uc_strlen(descr) :
|
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) :
|
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
|
-
|
2919
|
-
|
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
|
-
|
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
|
-
|
3010
|
-
|
3011
|
-
|
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(
|
3151
|
+
return INT2NUM(sbuffer);
|
3019
3152
|
case SQL_C_LONG:
|
3020
|
-
return INT2NUM(
|
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
|
3185
|
-
|
3320
|
+
static PARAMINFO *
|
3321
|
+
make_paraminfo(SQLHSTMT hstmt, int nump, char **msgp)
|
3186
3322
|
{
|
3187
3323
|
int i;
|
3188
|
-
|
3324
|
+
PARAMINFO *paraminfo = NULL;
|
3189
3325
|
|
3190
|
-
|
3191
|
-
if (
|
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
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
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
|
-
&
|
3208
|
-
&
|
3209
|
-
&
|
3347
|
+
¶minfo[i].type,
|
3348
|
+
¶minfo[i].coldef,
|
3349
|
+
¶minfo[i].scale,
|
3350
|
+
¶minfo[i].nullable),
|
3210
3351
|
NULL, "SQLDescribeParam")) {
|
3211
|
-
|
3212
|
-
|
3213
|
-
|
3214
|
-
|
3215
|
-
|
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
|
3363
|
+
return paraminfo;
|
3219
3364
|
}
|
3220
3365
|
|
3221
3366
|
static void
|
3222
|
-
|
3367
|
+
retain_paraminfo_override(STMT *q, int nump, PARAMINFO *paraminfo)
|
3223
3368
|
{
|
3224
|
-
if ((q->
|
3369
|
+
if ((q->paraminfo != NULL) && (q->nump == nump)) {
|
3225
3370
|
int i;
|
3226
3371
|
|
3227
3372
|
for (i = 0; i < nump; i++) {
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3233
|
-
if (q->
|
3234
|
-
|
3235
|
-
q->
|
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->
|
3238
|
-
|
3239
|
-
|
3240
|
-
|
3241
|
-
|
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->
|
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
|
-
|
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
|
-
|
3449
|
+
PARAMINFO *paraminfo = NULL;
|
3299
3450
|
char *msg = NULL;
|
3300
3451
|
|
3301
3452
|
Data_Get_Struct(dbc, DBC, p);
|
3302
|
-
if (
|
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
|
-
|
3308
|
-
if (
|
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
|
-
|
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
|
-
|
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->
|
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 (
|
3359
|
-
xfree(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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->
|
3735
|
+
v = q->paraminfo ? q->paraminfo[i].coldef : 0;
|
3572
3736
|
rb_iv_set(obj, "@precision", INT2NUM(v));
|
3573
|
-
v = q->
|
3737
|
+
v = q->paraminfo ? q->paraminfo[i].scale : 0;
|
3574
3738
|
rb_iv_set(obj, "@scale", INT2NUM(v));
|
3575
|
-
v = q->
|
3739
|
+
v = q->paraminfo ? q->paraminfo[i].nullable : SQL_NULLABLE_UNKNOWN;
|
3576
3740
|
rb_iv_set(obj, "@nullable", INT2NUM(v));
|
3577
|
-
v = q->
|
3741
|
+
v = q->paraminfo ? q->paraminfo[i].iotype : SQL_PARAM_INPUT;
|
3578
3742
|
rb_iv_set(obj, "@iotype", INT2NUM(v));
|
3579
|
-
v = q->
|
3743
|
+
v = q->paraminfo ? q->paraminfo[i].outsize : 0;
|
3580
3744
|
rb_iv_set(obj, "@output_size", INT2NUM(v));
|
3581
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
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 =
|
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
|
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 (
|
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
|
-
|
5515
|
+
PARAMINFO *paraminfo = make_paraminfo(q->hstmt, nump, &msg);
|
5335
5516
|
|
5336
|
-
if (
|
5517
|
+
if (paraminfo == NULL) {
|
5337
5518
|
rb_raise(Cerror, "%s", msg);
|
5338
5519
|
}
|
5339
|
-
q->
|
5340
|
-
if (q->
|
5520
|
+
q->paraminfo = paraminfo;
|
5521
|
+
if (q->paraminfo != NULL) {
|
5341
5522
|
q->nump = nump;
|
5342
5523
|
}
|
5343
5524
|
}
|
5344
5525
|
}
|
5345
|
-
if ((q->
|
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->
|
5350
|
-
(q->
|
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->
|
5559
|
+
q->paraminfo[vnum].scale = vscale;
|
5379
5560
|
}
|
5380
|
-
q->
|
5561
|
+
q->paraminfo[vnum].coldef = vcoldef;
|
5381
5562
|
}
|
5382
|
-
q->
|
5383
|
-
q->
|
5563
|
+
q->paraminfo[vnum].type = vtype;
|
5564
|
+
q->paraminfo[vnum].override = 1;
|
5384
5565
|
return Qnil;
|
5385
5566
|
}
|
5386
|
-
return INT2NUM(q->
|
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->
|
5587
|
+
q->paraminfo[vnum].iotype = viotype;
|
5407
5588
|
break;
|
5408
5589
|
}
|
5409
5590
|
}
|
5410
|
-
return INT2NUM(q->
|
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->
|
5605
|
+
if (q->paraminfo[vnum].rlen == SQL_NULL_DATA) {
|
5425
5606
|
return v;
|
5426
5607
|
}
|
5427
|
-
if (q->
|
5608
|
+
if (q->paraminfo[vnum].outbuf == NULL) {
|
5428
5609
|
rb_raise(Cerror, "no output value available");
|
5429
5610
|
}
|
5430
|
-
switch (q->
|
5611
|
+
switch (q->paraminfo[vnum].ctype) {
|
5431
5612
|
case SQL_C_LONG:
|
5432
|
-
v = INT2NUM(*((SQLINTEGER *) q->
|
5613
|
+
v = INT2NUM(*((SQLINTEGER *) q->paraminfo[vnum].outbuf));
|
5433
5614
|
break;
|
5434
5615
|
case SQL_C_DOUBLE:
|
5435
|
-
v = rb_float_new(*((double *) q->
|
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
|
-
|
5442
|
-
|
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
|
-
|
5450
|
-
|
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
|
-
|
5458
|
-
|
5459
|
-
|
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->
|
5465
|
-
q->
|
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->
|
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->
|
5721
|
+
q->paraminfo[vnum].outsize = (vsize > 0) ? vsize : 0;
|
5492
5722
|
}
|
5493
|
-
return INT2NUM(q->
|
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->
|
5739
|
+
q->paraminfo[vnum].outtype = vtype;
|
5510
5740
|
}
|
5511
|
-
return INT2NUM(q->
|
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) :
|
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
|
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(
|
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 =
|
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
|
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(
|
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 =
|
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
|
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)) :
|
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
|
-
|
5983
|
-
|
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
|
-
|
5991
|
-
|
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
|
-
|
5999
|
-
|
6000
|
-
|
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
|
6023
|
-
|
6024
|
-
name
|
6025
|
-
|
6026
|
-
|
6027
|
-
|
6028
|
-
|
6029
|
-
|
6030
|
-
|
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
|
6039
|
-
|
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
|
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
|
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
|
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
|
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
|
-
|
6450
|
-
|
6451
|
-
|
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
|
-
|
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
|
-
|
6499
|
-
|
6500
|
-
|
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
|
-
|
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
|
-
|
6593
|
-
|
6594
|
-
|
6595
|
-
|
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->
|
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->
|
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->
|
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->
|
6739
|
-
coldef = q->
|
6740
|
-
q->
|
6741
|
-
q->
|
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->
|
6776
|
-
(q->
|
6777
|
-
if (q->
|
6778
|
-
q->
|
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->
|
6782
|
-
q->
|
7265
|
+
if (vlen > (SQLINTEGER) q->paraminfo[pnum].coldef_max) {
|
7266
|
+
q->paraminfo[pnum].coldef_max = vlen;
|
6783
7267
|
}
|
6784
7268
|
}
|
6785
|
-
coldef = q->
|
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->
|
6793
|
-
(q->
|
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->
|
6796
|
-
if (q->
|
6797
|
-
xfree(q->
|
7279
|
+
if (q->paraminfo[pnum].outsize > 0) {
|
7280
|
+
if (q->paraminfo[pnum].outbuf != NULL) {
|
7281
|
+
xfree(q->paraminfo[pnum].outbuf);
|
6798
7282
|
}
|
6799
|
-
q->
|
6800
|
-
if (q->
|
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->
|
7287
|
+
ctype = q->paraminfo[pnum].ctype = q->paraminfo[pnum].outtype;
|
6804
7288
|
outpp[0]++;
|
6805
|
-
valp = q->
|
6806
|
-
vlen = q->
|
7289
|
+
valp = q->paraminfo[pnum].outbuf;
|
7290
|
+
vlen = q->paraminfo[pnum].outsize;
|
6807
7291
|
}
|
6808
7292
|
} else {
|
6809
|
-
if (q->
|
6810
|
-
xfree(q->
|
7293
|
+
if (q->paraminfo[pnum].outbuf != NULL) {
|
7294
|
+
xfree(q->paraminfo[pnum].outbuf);
|
6811
7295
|
}
|
6812
|
-
q->
|
6813
|
-
if (q->
|
7296
|
+
q->paraminfo[pnum].outbuf = xmalloc(vlen);
|
7297
|
+
if (q->paraminfo[pnum].outbuf == NULL) {
|
6814
7298
|
oom:
|
6815
7299
|
#ifdef UNICODE
|
6816
|
-
if (q->
|
6817
|
-
uc_free(q->
|
6818
|
-
q->
|
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->
|
7310
|
+
memcpy(q->paraminfo[pnum].outbuf, *(SQLWCHAR **) valp, vlen);
|
6827
7311
|
} else
|
6828
7312
|
#endif
|
6829
|
-
memcpy(q->
|
7313
|
+
memcpy(q->paraminfo[pnum].outbuf, valp, vlen);
|
6830
7314
|
#ifdef UNICODE
|
6831
7315
|
if (ctype == SQL_C_WCHAR) {
|
6832
|
-
*(SQLWCHAR **) valp = (SQLWCHAR *) q->
|
7316
|
+
*(SQLWCHAR **) valp = (SQLWCHAR *) q->paraminfo[pnum].outbuf;
|
6833
7317
|
} else
|
6834
7318
|
#endif
|
6835
|
-
valp = q->
|
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->
|
7327
|
+
q->paraminfo[pnum].iotype,
|
6844
7328
|
ctype, stype, coldef,
|
6845
|
-
q->
|
7329
|
+
q->paraminfo[pnum].scale,
|
6846
7330
|
(ctype == SQL_C_WCHAR) ?
|
6847
7331
|
*(SQLWCHAR **) valp : valp,
|
6848
|
-
vlen, &q->
|
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->
|
7337
|
+
q->paraminfo[pnum].iotype,
|
6854
7338
|
ctype, stype, coldef,
|
6855
|
-
q->
|
6856
|
-
valp, vlen, &q->
|
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->
|
6923
|
-
uc_free(q->
|
6924
|
-
q->
|
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->
|
6937
|
-
uc_free(q->
|
6938
|
-
q->
|
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;
|