summaryrefslogtreecommitdiff
path: root/ext/pdo_dblib/dblib_stmt.c
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2005-01-17 01:15:14 (GMT)
committerWez Furlong <wez@php.net>2005-01-17 01:15:14 (GMT)
commitca988059354fcee51c6306ff5056fe16b3081f58 (patch)
tree5e95571838b75ca5fe5c77db424b92b2700a7a2b /ext/pdo_dblib/dblib_stmt.c
parentf3d39ff406787514bb36927c0b97979c066f5d5d (diff)
downloadphp-ca988059354fcee51c6306ff5056fe16b3081f58.tar.gz
Add a PDO driver for Sybase style DB-lib (including MS SQL).
Only the basics are here right now.
Diffstat (limited to 'ext/pdo_dblib/dblib_stmt.c')
-rw-r--r--ext/pdo_dblib/dblib_stmt.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
new file mode 100644
index 0000000..e552c71
--- /dev/null
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -0,0 +1,252 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2005 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_0.txt. |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Wez Furlong <wez@php.net> |
+ | Frank M. Kromann <frank@kromann.info> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "pdo/php_pdo.h"
+#include "pdo/php_pdo_driver.h"
+#include "php_pdo_dblib.h"
+#include "php_pdo_dblib_int.h"
+#include "zend_exceptions.h"
+
+static void free_rows(pdo_dblib_stmt *S TSRMLS_DC)
+{
+ int i, j;
+
+ 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;
+}
+
+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);
+
+ return 1;
+}
+
+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;
+
+ 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) {
+ return 0;
+ }
+
+ ret = dbnextrow(H->link);
+
+ 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;
+
+ for (i = 0, j = 0; i < S->ncols; i++) {
+ S->cols[i].coltype = dbcoltype(H->link, i+1);
+ S->cols[i].name = dbcolname(H->link, i+1);
+ if (S->cols[i].name) {
+ S->cols[i].name = estrdup(S->cols[i].name);
+ } else if (j) {
+ spprintf(&S->cols[i].name, 0, "computed%d", j++);
+ } else {
+ S->cols[i].name = estrdup("computed");
+ j++;
+ }
+ S->cols[i].source = dbcolsource(H->link, i+1);
+ S->cols[i].source = estrdup(S->cols[i].source ? S->cols[i].source : "");
+ S->cols[i].maxlen = dbcollen(H->link, i+1);
+ }
+ }
+
+ arows = 100;
+ size = S->ncols * sizeof(pdo_dblib_colval);
+ S->rows = emalloc(arows * size);
+
+ /* 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] + i;
+
+ 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;
+
+ default:
+ if (dbwillconvert(S->cols[i].coltype, SYBCHAR)) {
+ 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;
+}
+
+static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
+ enum pdo_fetch_orientation ori, long offset TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+
+ if (!S->rows) {
+ return 0;
+ }
+
+ if (++S->current < S->nrows) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ 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->param_type = PDO_PARAM_STR;
+
+ return 1;
+}
+
+static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
+ unsigned long *len TSRMLS_DC)
+{
+ pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
+ pdo_dblib_colval *val = &S->rows[S->current] + colno;
+
+ *ptr = val->data;
+ *len = val->len;
+ return 1;
+}
+
+static int pdo_dblib_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
+ enum pdo_param_event event_type TSRMLS_DC)
+{
+ return 1;
+}
+
+
+struct pdo_stmt_methods dblib_stmt_methods = {
+ pdo_dblib_stmt_dtor,
+ pdo_dblib_stmt_execute,
+ pdo_dblib_stmt_fetch,
+ pdo_dblib_stmt_describe,
+ pdo_dblib_stmt_get_col,
+ pdo_dblib_stmt_param_hook,
+ NULL, /* set attr */
+ NULL, /* get attr */
+ NULL, /* meta */
+};
+