Annotation of embedaddon/php/ext/pdo_dblib/dblib_stmt.c, revision 1.1.1.3

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
1.1.1.3 ! misho       5:   | Copyright (c) 1997-2013 The PHP Group                                |
1.1       misho       6:   +----------------------------------------------------------------------+
                      7:   | This source file is subject to version 3.01 of the PHP license,      |
                      8:   | that is bundled with this package in the file LICENSE, and is        |
                      9:   | available through the world-wide-web at the following url:           |
                     10:   | http://www.php.net/license/3_01.txt                                  |
                     11:   | If you did not receive a copy of the PHP license and are unable to   |
                     12:   | obtain it through the world-wide-web, please send a note to          |
                     13:   | license@php.net so we can mail you a copy immediately.               |
                     14:   +----------------------------------------------------------------------+
                     15:   | Author: Wez Furlong <wez@php.net>                                    |
                     16:   |         Frank M. Kromann <frank@kromann.info>                        |
                     17:   +----------------------------------------------------------------------+
                     18: */
                     19: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: # include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #include "php_ini.h"
                     28: #include "ext/standard/php_string.h"
                     29: #include "ext/standard/info.h"
                     30: #include "pdo/php_pdo.h"
                     31: #include "pdo/php_pdo_driver.h"
                     32: #include "php_pdo_dblib.h"
                     33: #include "php_pdo_dblib_int.h"
                     34: #include "zend_exceptions.h"
                     35: 
1.1.1.2   misho      36: 
                     37: /* {{{ pdo_dblib_get_field_name
                     38:  * 
1.1.1.3 ! misho      39:  * Return the data type name for a given TDS number
1.1.1.2   misho      40:  * 
                     41:  */
                     42: static char *pdo_dblib_get_field_name(int type)
1.1       misho      43: {
1.1.1.3 ! misho      44:        /* 
        !            45:         * I don't return dbprtype(type) because it does not fully describe the type 
        !            46:         * (example: varchar is reported as char by dbprtype)
        !            47:         * 
        !            48:         * FIX ME: Cache datatypes from server systypes table in pdo_dblib_handle_factory()
        !            49:         *                 to make this future proof.
        !            50:         */
        !            51:         
1.1.1.2   misho      52:        switch (type) {
1.1.1.3 ! misho      53:                case 31: return "nvarchar";
1.1.1.2   misho      54:                case 34: return "image";
                     55:                case 35: return "text";
                     56:                case 36: return "uniqueidentifier";
1.1.1.3 ! misho      57:                case 37: return "varbinary"; /* & timestamp - Sybase AS12 */
        !            58:                case 38: return "bigint"; /* & bigintn - Sybase AS12 */
        !            59:                case 39: return "varchar"; /* & sysname & nvarchar - Sybase AS12 */
1.1.1.2   misho      60:                case 40: return "date";
                     61:                case 41: return "time";
                     62:                case 42: return "datetime2";
                     63:                case 43: return "datetimeoffset";
1.1.1.3 ! misho      64:                case 45: return "binary"; /* Sybase AS12 */
        !            65:                case 47: return "char"; /* & nchar & uniqueidentifierstr Sybase AS12 */
1.1.1.2   misho      66:                case 48: return "tinyint";
1.1.1.3 ! misho      67:                case 50: return "bit"; /* Sybase AS12 */
1.1.1.2   misho      68:                case 52: return "smallint";
1.1.1.3 ! misho      69:                case 55: return "decimal"; /* Sybase AS12 */
1.1.1.2   misho      70:                case 56: return "int";
                     71:                case 58: return "smalldatetime";
                     72:                case 59: return "real";
                     73:                case 60: return "money";
                     74:                case 61: return "datetime";
                     75:                case 62: return "float";
1.1.1.3 ! misho      76:                case 63: return "numeric"; /* or uint, ubigint, usmallint Sybase AS12 */
1.1.1.2   misho      77:                case 98: return "sql_variant";
                     78:                case 99: return "ntext";
                     79:                case 104: return "bit";
1.1.1.3 ! misho      80:                case 106: return "decimal"; /* decimal n on sybase */
        !            81:                case 108: return "numeric"; /* numeric n on sybase */
1.1.1.2   misho      82:                case 122: return "smallmoney";
                     83:                case 127: return "bigint";
                     84:                case 165: return "varbinary";
                     85:                case 167: return "varchar";
                     86:                case 173: return "binary";
                     87:                case 175: return "char";
                     88:                case 189: return "timestamp";
                     89:                case 231: return "nvarchar";
                     90:                case 239: return "nchar";
1.1.1.3 ! misho      91:                case 240: return "geometry";
1.1.1.2   misho      92:                case 241: return "xml";
1.1.1.3 ! misho      93:                default: return "unknown";
1.1       misho      94:        }
1.1.1.2   misho      95: }
                     96: /* }}} */
                     97: 
1.1.1.3 ! misho      98: static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
1.1.1.2   misho      99: {
                    100:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    101:        pdo_dblib_db_handle *H = S->H;
                    102: 
                    103:        /* Cancel any pending results */
                    104:        dbcancel(H->link);
1.1.1.3 ! misho     105:        
        !           106:        efree(stmt->columns); 
1.1.1.2   misho     107:        stmt->columns = NULL;
                    108:        
                    109:        return 1;
1.1       misho     110: }
                    111: 
                    112: static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
                    113: {
                    114:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    115: 
1.1.1.3 ! misho     116:        efree(stmt->columns); 
        !           117:        stmt->columns = NULL;
1.1       misho     118: 
1.1.1.2   misho     119:        efree(S);
                    120:                
1.1       misho     121:        return 1;
                    122: }
                    123: 
1.1.1.2   misho     124: static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
1.1       misho     125: {
                    126:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    127:        pdo_dblib_db_handle *H = S->H;
1.1.1.2   misho     128:        RETCODE ret;
                    129:        
                    130:        ret = dbresults(H->link);
                    131:        
1.1.1.3 ! misho     132:        if (FAIL == ret) {
        !           133:                pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbresults() returned FAIL" TSRMLS_CC);               
        !           134:                return 0;
        !           135:        }
        !           136:                
        !           137:        if(NO_MORE_RESULTS == ret) {
1.1.1.2   misho     138:                return 0;
1.1       misho     139:        }
1.1.1.2   misho     140:        
                    141:        stmt->row_count = DBCOUNT(H->link);
                    142:        stmt->column_count = dbnumcols(H->link);
                    143:        
                    144:        return 1;
                    145: }
1.1       misho     146: 
1.1.1.2   misho     147: static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
                    148: {
                    149:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    150:        pdo_dblib_db_handle *H = S->H;
                    151:        RETCODE ret;
                    152:        
                    153:        dbsetuserdata(H->link, (BYTE*) &S->err);
                    154:        
1.1.1.3 ! misho     155:        pdo_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
        !           156:        
1.1       misho     157:        if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
                    158:                return 0;
                    159:        }
1.1.1.2   misho     160:        
1.1       misho     161:        if (FAIL == dbsqlexec(H->link)) {
                    162:                return 0;
                    163:        }
                    164:        
1.1.1.2   misho     165:        ret = pdo_dblib_stmt_next_rowset(stmt TSRMLS_CC);
                    166:        
1.1       misho     167:        stmt->row_count = DBCOUNT(H->link);
1.1.1.2   misho     168:        stmt->column_count = dbnumcols(H->link);
1.1       misho     169:        
1.1.1.2   misho     170:        return 1;
1.1       misho     171: }
                    172: 
                    173: static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
                    174:        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
                    175: {
1.1.1.2   misho     176:        
                    177:        RETCODE ret;
                    178:        
1.1       misho     179:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2   misho     180:        pdo_dblib_db_handle *H = S->H;
                    181:        
                    182:        ret = dbnextrow(H->link);
                    183:        
1.1.1.3 ! misho     184:        if (FAIL == ret) {
        !           185:                pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "PDO_DBLIB: dbnextrow() returned FAIL" TSRMLS_CC);
        !           186:                return 0;
        !           187:        }
        !           188:                
        !           189:        if(NO_MORE_ROWS == ret) {
1.1       misho     190:                return 0;
                    191:        }
                    192:        
1.1.1.2   misho     193:        return 1;       
1.1       misho     194: }
                    195: 
                    196: static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
                    197: {
                    198:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2   misho     199:        pdo_dblib_db_handle *H = S->H;
                    200:        
1.1.1.3 ! misho     201:        if(colno >= stmt->column_count || colno < 0)  {
        !           202:                return FAILURE;
        !           203:        }
        !           204:        
1.1       misho     205:        struct pdo_column_data *col = &stmt->columns[colno];
1.1.1.2   misho     206:        
                    207:        col->name = (char*)dbcolname(H->link, colno+1);
                    208:        col->maxlen = dbcollen(H->link, colno+1);
                    209:        col->namelen = strlen(col->name);
1.1       misho     210:        col->param_type = PDO_PARAM_STR;
                    211:                
                    212:        return 1;
                    213: }
                    214: 
                    215: static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
                    216:         unsigned long *len, int *caller_frees TSRMLS_DC)
                    217: {
1.1.1.2   misho     218:        
1.1       misho     219:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2   misho     220:        pdo_dblib_db_handle *H = S->H;
                    221:        
                    222:        int coltype;
                    223:        unsigned int tmp_len;
                    224:        char *tmp_ptr = NULL;
                    225:        
                    226:        coltype = dbcoltype(H->link, colno+1);
                    227:        
                    228:        *len = dbdatlen(H->link, colno+1);
                    229:        *ptr = dbdata(H->link, colno+1);
                    230:        
                    231:        if (*len == 0 && *ptr == NULL) {
                    232:                return 1;
                    233:        }
                    234:        
                    235:        switch (coltype) {
                    236:                case SQLVARBINARY:
                    237:                case SQLBINARY:
                    238:                case SQLIMAGE:
1.1.1.3 ! misho     239:                case SQLTEXT:
        !           240:                        /* FIXME: Above types should be returned as a stream as they can be VERY large */
        !           241:                case SQLCHAR:
1.1.1.2   misho     242:                case SQLVARCHAR:
                    243:                        tmp_ptr = emalloc(*len + 1);
                    244:                        memcpy(tmp_ptr, *ptr, *len);
                    245:                        tmp_ptr[*len] = '\0';
                    246:                        *ptr = tmp_ptr;
                    247:                        break;
                    248:                case SQLMONEY:
                    249:                case SQLMONEY4:
                    250:                case SQLMONEYN: {
                    251:                        DBFLT8 money_value;
                    252:                        dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
                    253:                        *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
                    254:                        *ptr = tmp_ptr;
                    255:                        break;
                    256:                }
                    257:                case SQLUNIQUE: {
                    258:                        *len = 36+1;
                    259:                        tmp_ptr = emalloc(*len + 1);
                    260: 
                    261:                        /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
                    262:                        *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
                    263:                        php_strtoupper(tmp_ptr, *len);
                    264:                        *ptr = tmp_ptr;
                    265:                        break;
                    266:                }
                    267:                default:
                    268:                        if (dbwillconvert(coltype, SQLCHAR)) {
1.1.1.3 ! misho     269:                                tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
1.1.1.2   misho     270:                                tmp_ptr = emalloc(tmp_len);
                    271:                                *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, -1);
                    272:                                *ptr = tmp_ptr;
1.1.1.3 ! misho     273:                        } else {
        !           274:                                *len = 0; /* FIXME: Silently fails and returns null on conversion errors */
        !           275:                                *ptr = NULL;
        !           276:                        }
1.1.1.2   misho     277:        }
                    278: 
                    279:        *caller_frees = 1;
1.1       misho     280: 
                    281:        return 1;
                    282: }
                    283: 
                    284: static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
                    285:                enum pdo_param_event event_type TSRMLS_DC)
                    286: {
                    287:        return 1;
                    288: }
                    289: 
1.1.1.2   misho     290: static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *return_value TSRMLS_DC)
1.1       misho     291: {
                    292:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
1.1.1.2   misho     293:        pdo_dblib_db_handle *H = S->H;
1.1.1.3 ! misho     294:        DBTYPEINFO* dbtypeinfo;
        !           295: 
        !           296:        if(colno >= stmt->column_count || colno < 0)  {
        !           297:                return FAILURE;
        !           298:        }
        !           299: 
1.1.1.2   misho     300:        array_init(return_value);
1.1       misho     301: 
1.1.1.2   misho     302:        dbtypeinfo = dbcoltypeinfo(H->link, colno+1);
1.1.1.3 ! misho     303:        
        !           304:        if(!dbtypeinfo) return FAILURE;
1.1.1.2   misho     305:                
                    306:        add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
                    307:        add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
                    308:        add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );
                    309:        add_assoc_string(return_value, "column_source", dbcolsource(H->link, colno+1), 1);
                    310:        add_assoc_string(return_value, "native_type", pdo_dblib_get_field_name(dbcoltype(H->link, colno+1)), 1);
1.1.1.3 ! misho     311:        add_assoc_long(return_value, "native_type_id", dbcoltype(H->link, colno+1));
        !           312:        add_assoc_long(return_value, "native_usertype_id", dbcolutype(H->link, colno+1));
1.1       misho     313: 
                    314:        return 1;
                    315: }
                    316: 
1.1.1.2   misho     317: 
1.1       misho     318: struct pdo_stmt_methods dblib_stmt_methods = {
                    319:        pdo_dblib_stmt_dtor,
                    320:        pdo_dblib_stmt_execute,
                    321:        pdo_dblib_stmt_fetch,
                    322:        pdo_dblib_stmt_describe,
                    323:        pdo_dblib_stmt_get_col,
                    324:        pdo_dblib_stmt_param_hook,
                    325:        NULL, /* set attr */
                    326:        NULL, /* get attr */
1.1.1.2   misho     327:        pdo_dblib_stmt_get_column_meta, /* meta */
                    328:        pdo_dblib_stmt_next_rowset, /* nextrow */
1.1.1.3 ! misho     329:        pdo_dblib_stmt_cursor_closer
1.1       misho     330: };
                    331: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>