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