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