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

1.1       misho       1: /*
                      2:   +----------------------------------------------------------------------+
                      3:   | PHP Version 5                                                        |
                      4:   +----------------------------------------------------------------------+
                      5:   | Copyright (c) 1997-2012 The PHP Group                                |
                      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: 
                     20: /* $Id: dblib_stmt.c 321634 2012-01-01 13:15:04Z felipe $ */
                     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: 
                     36: static void free_rows(pdo_dblib_stmt *S TSRMLS_DC)
                     37: {
                     38:        int i, j;
                     39:        
                     40:        for (i = 0; i < S->nrows; i++) {
                     41:                for (j = 0; j < S->ncols; j++) {
                     42:                        pdo_dblib_colval *val = &S->rows[i*S->ncols] + j;
                     43:                        if (val->data) {
                     44:                                efree(val->data);
                     45:                                val->data = NULL;
                     46:                        }
                     47:                }
                     48:        }
                     49:        efree(S->rows);
                     50:        S->rows = NULL;
                     51:        S->nrows = 0;
                     52: }
                     53: 
                     54: static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
                     55: {
                     56:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                     57: 
                     58:        if (S->rows) {
                     59:                free_rows(S TSRMLS_CC);
                     60:        }
                     61:        if (S->cols) {
                     62:                efree(S->cols);
                     63:        }
                     64:        efree(S);
                     65: 
                     66:        return 1;
                     67: }
                     68: 
                     69: static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
                     70: {
                     71:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                     72:        pdo_dblib_db_handle *H = S->H;
                     73:        RETCODE resret, ret;
                     74:        int i, j;
                     75:        int arows;
                     76:        unsigned int size;
                     77:        
                     78:        dbsetuserdata(H->link, &S->err);
                     79: 
                     80:        if (S->rows) {
                     81:                /* clean them up */
                     82:                free_rows(S TSRMLS_CC);
                     83:        }
                     84: 
                     85:        if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
                     86:                return 0;
                     87:        }
                     88:        if (FAIL == dbsqlexec(H->link)) {
                     89:                return 0;
                     90:        }
                     91:        
                     92:        resret = dbresults(H->link);
                     93:        if (resret == FAIL) {
                     94:                return 0;
                     95:        }
                     96: 
                     97:        ret = dbnextrow(H->link);
                     98: 
                     99:        stmt->row_count = DBCOUNT(H->link);
                    100: 
                    101:     if (ret == NO_MORE_ROWS) {
                    102:        return 1;
                    103:     }
                    104:     
                    105:        if (!S->cols) {
                    106:                S->ncols = dbnumcols(H->link);
                    107: 
                    108:                if (S->ncols <= 0) {
                    109:                        return 1;
                    110:                }
                    111: 
                    112:                S->cols = ecalloc(S->ncols, sizeof(pdo_dblib_col));
                    113:                stmt->column_count = S->ncols;
                    114:        
                    115:                for (i = 0, j = 0; i < S->ncols; i++) {
                    116:                        char *tmp = NULL;
                    117: 
                    118:                        S->cols[i].coltype = dbcoltype(H->link, i+1);
                    119:                        S->cols[i].name = (char*)dbcolname(H->link, i+1);
                    120: 
                    121:                        if (!strlen(S->cols[i].name)) {
                    122:                                if (j) {
                    123:                                        spprintf(&tmp, 0, "computed%d", j++);
                    124:                                        strlcpy(S->cols[i].name, tmp, strlen(tmp)+1);
                    125:                                        efree(tmp);
                    126:                                } else {
                    127:                                        S->cols[i].name = "computed";
                    128:                                        j++;
                    129:                                }
                    130:                        }
                    131: 
                    132:                        S->cols[i].source = (char*)dbcolsource(H->link, i+1);
                    133:                        tmp = estrdup(S->cols[i].source ? S->cols[i].source : "");
                    134:                        S->cols[i].source = tmp;
                    135:                        efree(tmp);
                    136: 
                    137:                        S->cols[i].maxlen = dbcollen(H->link, i+1);
                    138:                }
                    139:        }
                    140: 
                    141:        arows = 100;
                    142:        size = S->ncols * sizeof(pdo_dblib_colval);
                    143:        S->rows = safe_emalloc(arows, size, 0);
                    144: 
                    145:        /* let's fetch all the data */
                    146:        do {
                    147:                if (S->nrows >= arows) {
                    148:                        arows *= 2;
                    149:                        S->rows = erealloc(S->rows, arows * size);
                    150:                }
                    151:                for (i = 0; i < S->ncols; i++) {
                    152:                        pdo_dblib_colval *val = &S->rows[S->nrows * S->ncols + i];
                    153: 
                    154:                        if (dbdatlen(H->link, i+1) == 0 && dbdata(H->link, i+1) == NULL) {
                    155:                                val->len = 0;
                    156:                                val->data = NULL;
                    157:                        } else {
                    158:                                switch (S->cols[i].coltype) {
                    159:                                        case SQLCHAR:
                    160:                                        case SQLTEXT:
                    161:                                        case SQLVARBINARY:
                    162:                                        case SQLBINARY:
                    163:                                        case SQLIMAGE:
                    164:                                                val->len = dbdatlen(H->link, i+1);
                    165:                                                val->data = emalloc(val->len + 1);
                    166:                                                memcpy(val->data, dbdata(H->link, i+1), val->len);
                    167:                                                val->data[val->len] = '\0';
                    168:                                                break;
                    169:                                        case SQLMONEY:
                    170:                                        case SQLMONEY4:
                    171:                                        case SQLMONEYN: {
                    172:                                                DBFLT8 money_value;
                    173:                                                dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLFLT8, (LPBYTE)&money_value, 8);
                    174:                                                val->len = spprintf(&val->data, 0, "%.4f", money_value);
                    175:                                                }
                    176:                                                break;
                    177: #ifdef SQLUNIQUE
                    178:                                        case SQLUNIQUE: {
                    179: #else
                    180:                                        case 36: { /* FreeTDS hack, also used by ext/mssql */
                    181: #endif
                    182:                                                val->len = 36+1;
                    183:                                                val->data = emalloc(val->len + 1);
                    184: 
                    185:                                                /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
                    186: #ifdef SQLUNIQUE
                    187:                                                val->len = dbconvert(NULL, SQLUNIQUE, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
                    188: #else
                    189:                                                val->len = dbconvert(NULL, 36, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
                    190: #endif
                    191:                                                php_strtoupper(val->data, val->len);
                    192:                                                break;
                    193:                                                }
                    194:                                        default:
                    195:                                                if (dbwillconvert(S->cols[i].coltype, SQLCHAR)) {
                    196:                                                        val->len = 32 + (2 * dbdatlen(H->link, i+1));
                    197:                                                        val->data = emalloc(val->len);
                    198: 
                    199:                                                        val->len = dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1),
                    200:                                                                        dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
                    201: 
                    202:                                                        if (val->len >= 0) {
                    203:                                                                val->data[val->len] = '\0';
                    204:                                                        }
                    205:                                                } else {
                    206:                                                        val->len = 0;
                    207:                                                        val->data = NULL;
                    208:                                                }
                    209:                                }
                    210:                        }
                    211:                }
                    212: 
                    213:                S->nrows++;
                    214: 
                    215:                ret = dbnextrow(H->link);
                    216: 
                    217:                if (ret == BUF_FULL) {
                    218:                        dbclrbuf(H->link, DBLASTROW(H->link)-1);
                    219:                }
                    220:        } while (ret != FAIL && ret != NO_MORE_ROWS);
                    221: 
                    222:        if (resret != NO_MORE_RESULTS) {
                    223:                /* there are additional result sets available */
                    224:                dbresults(H->link);
                    225:                /* cancel pending rows */
                    226:                dbcanquery(H->link);
                    227: 
                    228:                /* TODO: figure out a sane solution */
                    229:        }
                    230: 
                    231:        S->current = -1;
                    232:                
                    233:        return 1;       
                    234: }
                    235: 
                    236: static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
                    237:        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
                    238: {
                    239:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    240: 
                    241:        if (!S->rows) {
                    242:                return 0;
                    243:        }
                    244:        
                    245:        if (++S->current < S->nrows) {
                    246:                return 1;
                    247:        }
                    248: 
                    249:        return 0;
                    250: }
                    251: 
                    252: static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
                    253: {
                    254:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    255:        struct pdo_column_data *col = &stmt->columns[colno];
                    256: 
                    257:        if (!S->rows) {
                    258:                return 0;
                    259:        }
                    260: 
                    261:        col->maxlen = S->cols[colno].maxlen;    
                    262:        col->namelen = strlen(S->cols[colno].name);     
                    263:        col->name = estrdup(S->cols[colno].name);
                    264:        col->param_type = PDO_PARAM_STR;
                    265:                
                    266:        return 1;
                    267: }
                    268: 
                    269: static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
                    270:         unsigned long *len, int *caller_frees TSRMLS_DC)
                    271: {
                    272:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    273:        pdo_dblib_colval *val = &S->rows[S->current * S->ncols + colno];
                    274: 
                    275:        *ptr = val->data;
                    276:        *len = val->len;
                    277:        return 1;
                    278: }
                    279: 
                    280: static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
                    281:                enum pdo_param_event event_type TSRMLS_DC)
                    282: {
                    283:        return 1;
                    284: }
                    285: 
                    286: static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
                    287: {
                    288:        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
                    289: 
                    290:        if (S->rows) {
                    291:                free_rows(S TSRMLS_CC);
                    292:                S->rows = NULL;
                    293:        }
                    294: 
                    295:        return 1;
                    296: }
                    297: 
                    298: struct pdo_stmt_methods dblib_stmt_methods = {
                    299:        pdo_dblib_stmt_dtor,
                    300:        pdo_dblib_stmt_execute,
                    301:        pdo_dblib_stmt_fetch,
                    302:        pdo_dblib_stmt_describe,
                    303:        pdo_dblib_stmt_get_col,
                    304:        pdo_dblib_stmt_param_hook,
                    305:        NULL, /* set attr */
                    306:        NULL, /* get attr */
                    307:        NULL, /* meta */
                    308:        NULL, /* nextrow */
                    309:        dblib_dblib_stmt_cursor_closer
                    310: };
                    311: 

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