]> granicus.if.org Git - php/commitdiff
Fix bug #50755 & Enable multiple rowsets [DOC]
authorStanley Sufficool <ssufficool@php.net>
Mon, 31 May 2010 18:38:22 +0000 (18:38 +0000)
committerStanley Sufficool <ssufficool@php.net>
Mon, 31 May 2010 18:38:22 +0000 (18:38 +0000)
ext/pdo_dblib/dblib_stmt.c
ext/pdo_dblib/php_pdo_dblib_int.h

index a9f8cf2f0c6d5f2efd932098dd070f2928b04353..e57682e27ded6c2cdf053068417d40d343583a7b 100644 (file)
 #include "php_pdo_dblib_int.h"
 #include "zend_exceptions.h"
 
-static void free_rows(pdo_dblib_stmt *S TSRMLS_DC)
+static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
 {
-       int i, j;
+       pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+       pdo_dblib_db_handle *H = S->H;
+
+       /* Cancel any pending results */
+       dbcancel(H->link);
+
+       efree(stmt->columns);
+       stmt->columns = NULL;
        
-       for (i = 0; i < S->nrows; i++) {
-               for (j = 0; j < S->ncols; j++) {
-                       pdo_dblib_colval *val = &S->rows[i] + j;
-                       if (val->data) {
-                               efree(val->data);
-                               val->data = NULL;
-                       }
-               }
-       }
-       efree(S->rows);
-       S->rows = NULL;
-       S->nrows = 0;
+       return 1;
 }
 
 static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
 {
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
 
-       if (S->rows) {
-               free_rows(S TSRMLS_CC);
-       }
-       if (S->cols) {
-               efree(S->cols);
-       }
+       dblib_dblib_stmt_cursor_closer(stmt);
+
        efree(S);
+               
+       return 1;
+}
 
+static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt)
+{
+       pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+       pdo_dblib_db_handle *H = S->H;
+       RETCODE ret;
+       
+       ret = dbresults(H->link);
+       
+       if (ret == FAIL || ret == NO_MORE_RESULTS) {
+               return 0;
+       }
+       
+       stmt->row_count = DBCOUNT(H->link);
+       stmt->column_count = dbnumcols(H->link);
+       
        return 1;
 }
 
@@ -70,180 +80,59 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
        pdo_dbh_t *dbh = stmt->dbh;
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
        pdo_dblib_db_handle *H = S->H;
-       RETCODE resret, ret;
-       int i, j;
-       int arows;
-       unsigned int size;
+       RETCODE ret;
+       
+       dbsetuserdata(H->link, (BYTE*) &S->err);
        
-       dbsetuserdata(H->link, &S->err);
-
-       if (S->rows) {
-               /* clean them up */
-               free_rows(S TSRMLS_CC);
-       }
-
        if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
                return 0;
        }
+       
        if (FAIL == dbsqlexec(H->link)) {
                return 0;
        }
        
-       resret = dbresults(H->link);
-       if (resret == FAIL) {
+       ret = pdo_dblib_stmt_next_rowset(stmt);
+       
+       if (ret == 0) {
                return 0;
        }
-
-       ret = dbnextrow(H->link);
-
+       
        stmt->row_count = DBCOUNT(H->link);
-
-    if (ret == NO_MORE_ROWS) {
-       return 1;
-    }
-    
-       if (!S->cols) {
-               S->ncols = dbnumcols(H->link);
-
-               if (S->ncols <= 0) {
-                       return 1;
-               }
-
-               S->cols = ecalloc(S->ncols, sizeof(pdo_dblib_col));
-               stmt->column_count = S->ncols;
+       stmt->column_count = dbnumcols(H->link);
        
-               for (i = 0, j = 0; i < S->ncols; i++) {
-                       char *tmp = NULL;
-
-                       S->cols[i].coltype = dbcoltype(H->link, i+1);
-                       S->cols[i].name = (char*)dbcolname(H->link, i+1);
-
-                       if (!strlen(S->cols[i].name)) {
-                               if (j) {
-                                       spprintf(&tmp, 0, "computed%d", j++);
-                                       strlcpy(S->cols[i].name, tmp, strlen(tmp)+1);
-                                       efree(tmp);
-                               } else {
-                                       S->cols[i].name = "computed";
-                                       j++;
-                               }
-                       }
-
-                       S->cols[i].source = (char*)dbcolsource(H->link, i+1);
-                       tmp = estrdup(S->cols[i].source ? S->cols[i].source : "");
-                       S->cols[i].source = tmp;
-                       efree(tmp);
-
-                       S->cols[i].maxlen = dbcollen(H->link, i+1);
-               }
-       }
-
-       arows = 100;
-       size = S->ncols * sizeof(pdo_dblib_colval);
-       S->rows = safe_emalloc(arows, size, 0);
-
-       /* let's fetch all the data */
-       do {
-               if (S->nrows >= arows) {
-                       arows *= 2;
-                       S->rows = erealloc(S->rows, arows * size);
-               }
-               for (i = 0; i < S->ncols; i++) {
-                       pdo_dblib_colval *val = &S->rows[S->nrows * S->ncols + i];
-
-                       if (dbdatlen(H->link, i+1) == 0 && dbdata(H->link, i+1) == NULL) {
-                               val->len = 0;
-                               val->data = NULL;
-                       } else {
-                               switch (S->cols[i].coltype) {
-                                       case SQLCHAR:
-                                       case SQLTEXT:
-                                       case SQLVARBINARY:
-                                       case SQLBINARY:
-                                       case SQLIMAGE:
-                                               val->len = dbdatlen(H->link, i+1);
-                                               val->data = emalloc(val->len + 1);
-                                               memcpy(val->data, dbdata(H->link, i+1), val->len);
-                                               val->data[val->len] = '\0';
-                                               break;
-                                       case SQLMONEY:
-                                       case SQLMONEY4:
-                                       case SQLMONEYN: {
-                                               DBFLT8 money_value;
-                                               dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLFLT8, (LPBYTE)&money_value, val->len);
-                                               val->len = spprintf(val->data, 0, "%.4f", money_value);
-                                               }
-                                               break;
-                                       default:
-                                               if (dbwillconvert(S->cols[i].coltype, SQLCHAR)) {
-                                                       val->len = 32 + (2 * dbdatlen(H->link, i+1));
-                                                       val->data = emalloc(val->len);
-
-                                                       val->len = dbconvert(NULL, S->cols[i].coltype, dbdata(H->link, i+1),
-                                                                       dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
-
-                                                       if (val->len >= 0) {
-                                                               val->data[val->len] = '\0';
-                                                       }
-                                               } else {
-                                                       val->len = 0;
-                                                       val->data = NULL;
-                                               }
-                               }
-                       }
-               }
-
-               S->nrows++;
-
-               ret = dbnextrow(H->link);
-
-               if (ret == BUF_FULL) {
-                       dbclrbuf(H->link, DBLASTROW(H->link)-1);
-               }
-       } while (ret != FAIL && ret != NO_MORE_ROWS);
-
-       if (resret != NO_MORE_RESULTS) {
-               /* there are additional result sets available */
-               dbresults(H->link);
-               /* cancel pending rows */
-               dbcanquery(H->link);
-
-               /* TODO: figure out a sane solution */
-       }
-
-       S->current = -1;
-               
-       return 1;       
+       return 1;
 }
 
 static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
        enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
 {
+       
+       RETCODE ret;
+       int i;
+       
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
-
-       if (!S->rows) {
+       pdo_dblib_db_handle *H = S->H;
+       
+       ret = dbnextrow(H->link);
+       
+       if (ret == FAIL || ret == NO_MORE_ROWS) {
                return 0;
        }
        
-       if (++S->current < S->nrows) {
-               return 1;
-       }
-
-       return 0;
+       return 1;       
 }
 
 static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
 {
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+       pdo_dblib_db_handle *H = S->H;
+       
        struct pdo_column_data *col = &stmt->columns[colno];
-
-       if (!S->rows) {
-               return 0;
-       }
-
-       col->maxlen = S->cols[colno].maxlen;    
-       col->namelen = strlen(S->cols[colno].name);     
-       col->name = estrdup(S->cols[colno].name);
+       
+       col->name = (char*)dbcolname(H->link, colno+1);
+       col->maxlen = dbcollen(H->link, colno+1);
+       col->namelen = strlen(col->name);
        col->param_type = PDO_PARAM_STR;
                
        return 1;
@@ -252,11 +141,65 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
 static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
         unsigned long *len, int *caller_frees TSRMLS_DC)
 {
+       
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
-       pdo_dblib_colval *val = &S->rows[S->current * S->ncols + colno];
+       pdo_dblib_db_handle *H = S->H;
+       
+       int coltype;
+       unsigned int tmp_len;
+       char *tmp_ptr = NULL;
+       
+       coltype = dbcoltype(H->link, colno+1);
+       
+       *len = dbdatlen(H->link, colno+1);
+       *ptr = dbdata(H->link, colno+1);
+       
+       if (*len == 0 && *ptr == NULL) {
+               return 1;
+       }
+       
+       switch (coltype) {
+               case SQLCHAR:
+               case SQLTEXT:
+               case SQLVARBINARY:
+               case SQLBINARY:
+               case SQLIMAGE:
+               case SQLVARCHAR:
+                       tmp_ptr = emalloc(*len + 1);
+                       memcpy(tmp_ptr, *ptr, *len);
+                       tmp_ptr[*len] = '\0';
+                       *ptr = tmp_ptr;
+                       ++(*len);
+                       break;
+               case SQLMONEY:
+               case SQLMONEY4:
+               case SQLMONEYN: {
+                       DBFLT8 money_value;
+                       dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, tmp_len);
+                       *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
+                       *ptr = tmp_ptr;
+                       break;
+               }
+               default:
+                       if (dbwillconvert(coltype, SQLCHAR)) {
+                               tmp_len = 32 + (2 * (*len));
+                               tmp_ptr = emalloc(tmp_len);
+
+                               *len = dbconvert(NULL, coltype, *ptr, *len, SQLCHAR, tmp_ptr, tmp_len);
+
+                               if (*len >= 0) {
+                                       tmp_ptr[*len] = '\0';
+                               }
+                               *ptr = tmp_ptr;
+                               *len = tmp_len;
+               } else {
+                       *len = 0;
+                       *ptr = NULL;
+               }
+       }
+
+       *caller_frees = 1;
 
-       *ptr = val->data;
-       *len = val->len;
        return 1;
 }
 
@@ -266,17 +209,6 @@ static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
        return 1;
 }
 
-static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
-{
-       pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
-
-       if (S->rows) {
-               free_rows(S TSRMLS_CC);
-               S->rows = NULL;
-       }
-
-       return 1;
-}
 
 struct pdo_stmt_methods dblib_stmt_methods = {
        pdo_dblib_stmt_dtor,
@@ -288,7 +220,7 @@ struct pdo_stmt_methods dblib_stmt_methods = {
        NULL, /* set attr */
        NULL, /* get attr */
        NULL, /* meta */
-       NULL, /* nextrow */
+       pdo_dblib_stmt_next_rowset, /* nextrow */
        dblib_dblib_stmt_cursor_closer
 };
 
index fbecbd1b8415cfdad17002d5966eb98d29eed8c8..cb52e47bd73a5be1f8960323c957a1aa2acc7f3f 100644 (file)
@@ -113,29 +113,8 @@ typedef struct {
        pdo_dblib_err err;
 } pdo_dblib_db_handle;
 
-typedef struct {
-       int coltype;
-       char *name;
-       int maxlen;
-       char *source;
-} pdo_dblib_col;
-
-typedef struct {
-       unsigned long len;
-       char *data;
-} pdo_dblib_colval;
-
 typedef struct {
        pdo_dblib_db_handle *H;
-
-       int ncols;
-       pdo_dblib_col *cols;
-
-       pdo_dblib_colval *rows;
-       int nrows;
-
-       int current;
-       
        pdo_dblib_err err;
 } pdo_dblib_stmt;