434 lines
10 KiB
Diff
434 lines
10 KiB
Diff
diff -up php5.3-201105121030/ext/pdo_dblib/dblib_stmt.c.50755 php5.3-201105121030/ext/pdo_dblib/dblib_stmt.c
|
|
--- php5.3-201105121030/ext/pdo_dblib/dblib_stmt.c.50755 2011-03-17 14:35:50.000000000 +0100
|
|
+++ php5.3-201105121030/ext/pdo_dblib/dblib_stmt.c 2011-05-13 18:56:02.329918378 +0200
|
|
@@ -33,234 +33,105 @@
|
|
#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*S->ncols] + 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);
|
|
- }
|
|
- efree(S);
|
|
+ dblib_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
|
|
|
|
+ efree(S);
|
|
+
|
|
return 1;
|
|
}
|
|
|
|
-static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
|
+static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
|
|
{
|
|
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;
|
|
-
|
|
- dbsetuserdata(H->link, &S->err);
|
|
-
|
|
- if (S->rows) {
|
|
- /* clean them up */
|
|
- free_rows(S TSRMLS_CC);
|
|
+ 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;
|
|
+}
|
|
|
|
+static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
|
+{
|
|
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
|
|
+ pdo_dblib_db_handle *H = S->H;
|
|
+ RETCODE ret;
|
|
+
|
|
+ dbsetuserdata(H->link, (BYTE*) &S->err);
|
|
+
|
|
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 TSRMLS_CC);
|
|
+
|
|
+ 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, 8);
|
|
- val->len = spprintf(&val->data, 0, "%.4f", money_value);
|
|
- }
|
|
- break;
|
|
-#ifdef SQLUNIQUE
|
|
- case SQLUNIQUE: {
|
|
-#else
|
|
- case 36: { /* FreeTDS hack, also used by ext/mssql */
|
|
-#endif
|
|
- val->len = 36+1;
|
|
- val->data = emalloc(val->len + 1);
|
|
-
|
|
- /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
|
|
-#ifdef SQLUNIQUE
|
|
- val->len = dbconvert(NULL, SQLUNIQUE, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
|
|
-#else
|
|
- val->len = dbconvert(NULL, 36, dbdata(H->link, i+1), dbdatlen(H->link, i+1), SQLCHAR, val->data, val->len);
|
|
-#endif
|
|
- php_strtoupper(val->data, val->len);
|
|
- 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;
|
|
+
|
|
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;
|
|
@@ -269,11 +140,76 @@ static int pdo_dblib_stmt_describe(pdo_s
|
|
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;
|
|
+ break;
|
|
+ case SQLMONEY:
|
|
+ case SQLMONEY4:
|
|
+ case SQLMONEYN: {
|
|
+ DBFLT8 money_value;
|
|
+ dbconvert(NULL, coltype, *ptr, *len, SQLFLT8, (LPBYTE)&money_value, 8);
|
|
+ *len = spprintf(&tmp_ptr, 0, "%.4f", money_value);
|
|
+ *ptr = tmp_ptr;
|
|
+ break;
|
|
+ }
|
|
+#ifdef SQLUNIQUE
|
|
+ case SQLUNIQUE: {
|
|
+#else
|
|
+ case 36: { /* FreeTDS hack, also used by ext/mssql */
|
|
+#endif
|
|
+ *len = 36+1;
|
|
+ tmp_ptr = emalloc(*len + 1);
|
|
+
|
|
+ /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
|
|
+#ifdef SQLUNIQUE
|
|
+ *len = dbconvert(NULL, SQLUNIQUE, ptr, *len, SQLCHAR, tmp_ptr, *len);
|
|
+#else
|
|
+ *len = dbconvert(NULL, 36, ptr, *len, SQLCHAR, tmp_ptr, *len);
|
|
+#endif
|
|
+ php_strtoupper(tmp_ptr, *len);
|
|
+ *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, -1);
|
|
+ *ptr = tmp_ptr;
|
|
+ } else {
|
|
+ *len = 0;
|
|
+ *ptr = NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *caller_frees = 1;
|
|
|
|
- *ptr = val->data;
|
|
- *len = val->len;
|
|
return 1;
|
|
}
|
|
|
|
@@ -283,17 +219,6 @@ static int pdo_dblib_stmt_param_hook(pdo
|
|
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,
|
|
@@ -305,7 +230,7 @@ struct pdo_stmt_methods dblib_stmt_metho
|
|
NULL, /* set attr */
|
|
NULL, /* get attr */
|
|
NULL, /* meta */
|
|
- NULL, /* nextrow */
|
|
+ pdo_dblib_stmt_next_rowset, /* nextrow */
|
|
dblib_dblib_stmt_cursor_closer
|
|
};
|
|
|
|
diff -up php5.3-201105121030/ext/pdo_dblib/php_pdo_dblib_int.h.50755 php5.3-201105121030/ext/pdo_dblib/php_pdo_dblib_int.h
|
|
--- php5.3-201105121030/ext/pdo_dblib/php_pdo_dblib_int.h.50755 2011-01-01 04:37:16.000000000 +0100
|
|
+++ php5.3-201105121030/ext/pdo_dblib/php_pdo_dblib_int.h 2011-05-13 18:49:33.325783259 +0200
|
|
@@ -114,28 +114,7 @@ typedef struct {
|
|
} 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;
|
|
|