summaryrefslogtreecommitdiff
path: root/ext/pdo_odbc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_odbc')
-rw-r--r--ext/pdo_odbc/odbc_driver.c78
-rw-r--r--ext/pdo_odbc/odbc_stmt.c103
2 files changed, 77 insertions, 104 deletions
diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c
index 76b981e2c2..790ee87851 100644
--- a/ext/pdo_odbc/odbc_driver.c
+++ b/ext/pdo_odbc/odbc_driver.c
@@ -27,7 +27,7 @@
#include "php_pdo_odbc_int.h"
#include "zend_exceptions.h"
-static int pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
+static void pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
pdo_odbc_errinfo *einfo = &H->einfo;
@@ -47,8 +47,6 @@ static int pdo_odbc_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *inf
add_next_index_long(info, einfo->last_error);
add_next_index_str(info, message);
add_next_index_string(info, einfo->last_state);
-
- return 1;
}
@@ -120,7 +118,7 @@ void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement,
}
/* }}} */
-static int odbc_handle_closer(pdo_dbh_t *dbh)
+static void odbc_handle_closer(pdo_dbh_t *dbh)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
@@ -134,19 +132,16 @@ static int odbc_handle_closer(pdo_dbh_t *dbh)
H->env = NULL;
pefree(H, dbh->is_persistent);
dbh->driver_data = NULL;
-
- return 0;
}
-static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options)
+static bool odbc_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options)
{
RETCODE rc;
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
pdo_odbc_stmt *S = ecalloc(1, sizeof(*S));
enum pdo_cursor_type cursor_type = PDO_CURSOR_FWDONLY;
int ret;
- char *nsql = NULL;
- size_t nsql_len = 0;
+ zend_string *nsql = NULL;
S->H = H;
S->assume_utf8 = H->assume_utf8;
@@ -154,7 +149,7 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
/* before we prepare, we need to peek at the query; if it uses named parameters,
* we want PDO to rewrite them for us */
stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL;
- ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len);
+ ret = pdo_parse_params(stmt, sql, &nsql);
if (ret == 1) {
/* query was re-written */
@@ -163,7 +158,7 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
/* couldn't grok it */
strcpy(dbh->error_code, stmt->error_code);
efree(S);
- return 0;
+ return false;
}
rc = SQLAllocHandle(SQL_HANDLE_STMT, H->dbc, &S->stmt);
@@ -171,10 +166,10 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) {
efree(S);
if (nsql) {
- efree(nsql);
+ zend_string_release(nsql);
}
pdo_odbc_drv_error("SQLAllocStmt");
- return 0;
+ return false;
}
stmt->driver_data = S;
@@ -186,15 +181,15 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
pdo_odbc_stmt_error("SQLSetStmtAttr: SQL_ATTR_CURSOR_SCROLLABLE");
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
if (nsql) {
- efree(nsql);
+ zend_string_release(nsql);
}
- return 0;
+ return false;
}
}
- rc = SQLPrepare(S->stmt, (SQLCHAR *) sql, SQL_NTS);
+ rc = SQLPrepare(S->stmt, (SQLCHAR *) ZSTR_VAL(sql), SQL_NTS);
if (nsql) {
- efree(nsql);
+ zend_string_release(nsql);
}
stmt->methods = &odbc_stmt_methods;
@@ -212,12 +207,12 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len,
}
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len)
+static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const zend_string *sql)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
RETCODE rc;
@@ -230,7 +225,7 @@ static zend_long odbc_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_le
return -1;
}
- rc = SQLExecDirect(stmt, (SQLCHAR *) sql, sql_len);
+ rc = SQLExecDirect(stmt, (SQLCHAR *) ZSTR_VAL(sql), ZSTR_LEN(sql));
if (rc == SQL_NO_DATA) {
/* If SQLExecDirect executes a searched update or delete statement that
@@ -267,7 +262,7 @@ static int odbc_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquo
}
*/
-static int odbc_handle_begin(pdo_dbh_t *dbh)
+static bool odbc_handle_begin(pdo_dbh_t *dbh)
{
if (dbh->auto_commit) {
/* we need to disable auto-commit now, to be able to initiate a transaction */
@@ -277,13 +272,13 @@ static int odbc_handle_begin(pdo_dbh_t *dbh)
rc = SQLSetConnectAttr(H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
if (rc != SQL_SUCCESS) {
pdo_odbc_drv_error("SQLSetConnectAttr AUTOCOMMIT = OFF");
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
-static int odbc_handle_commit(pdo_dbh_t *dbh)
+static bool odbc_handle_commit(pdo_dbh_t *dbh)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
RETCODE rc;
@@ -294,7 +289,7 @@ static int odbc_handle_commit(pdo_dbh_t *dbh)
pdo_odbc_drv_error("SQLEndTran: Commit");
if (rc != SQL_SUCCESS_WITH_INFO) {
- return 0;
+ return false;
}
}
@@ -303,13 +298,13 @@ static int odbc_handle_commit(pdo_dbh_t *dbh)
rc = SQLSetConnectAttr(H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
if (rc != SQL_SUCCESS) {
pdo_odbc_drv_error("SQLSetConnectAttr AUTOCOMMIT = ON");
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
-static int odbc_handle_rollback(pdo_dbh_t *dbh)
+static bool odbc_handle_rollback(pdo_dbh_t *dbh)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
RETCODE rc;
@@ -320,7 +315,7 @@ static int odbc_handle_rollback(pdo_dbh_t *dbh)
pdo_odbc_drv_error("SQLEndTran: Rollback");
if (rc != SQL_SUCCESS_WITH_INFO) {
- return 0;
+ return false;
}
}
if (dbh->auto_commit && H->dbc) {
@@ -328,25 +323,30 @@ static int odbc_handle_rollback(pdo_dbh_t *dbh)
rc = SQLSetConnectAttr(H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
if (rc != SQL_SUCCESS) {
pdo_odbc_drv_error("SQLSetConnectAttr AUTOCOMMIT = ON");
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
-static int odbc_handle_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
+static bool odbc_handle_set_attr(pdo_dbh_t *dbh, zend_long attr, zval *val)
{
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
+ bool bval;
+
switch (attr) {
case PDO_ODBC_ATTR_ASSUME_UTF8:
- H->assume_utf8 = zval_is_true(val);
- return 1;
+ if (!pdo_get_bool_param(&bval, val)) {
+ return false;
+ }
+ H->assume_utf8 = bval;
+ return true;
default:
strcpy(H->einfo.last_err_msg, "Unknown Attribute");
H->einfo.what = "setAttribute";
strcpy(H->einfo.last_state, "IM001");
- return 0;
+ return false;
}
}
@@ -384,7 +384,11 @@ static const struct pdo_dbh_methods odbc_methods = {
NULL, /* last id */
pdo_odbc_fetch_error_func,
odbc_handle_get_attr, /* get attr */
- NULL, /* check_liveness */
+ NULL, /* check_liveness */
+ NULL, /* get_driver_methods */
+ NULL, /* request_shutdown */
+ NULL, /* in transaction, use PDO's internal tracking mechanism */
+ NULL /* get_gc */
};
static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c
index 5e882fbcc9..c1f4b5f497 100644
--- a/ext/pdo_odbc/odbc_stmt.c
+++ b/ext/pdo_odbc/odbc_stmt.c
@@ -88,31 +88,28 @@ static int pdo_odbc_utf82ucs2(pdo_stmt_t *stmt, int is_unicode, const char *buf,
return PDO_ODBC_CONV_NOT_REQUIRED;
}
-static int pdo_odbc_ucs22utf8(pdo_stmt_t *stmt, int is_unicode, const char *buf,
- zend_ulong buflen, zend_ulong *outlen)
+static int pdo_odbc_ucs22utf8(pdo_stmt_t *stmt, int is_unicode, zval *result)
{
#ifdef PHP_WIN32
- if (is_unicode && buflen) {
+ ZEND_ASSERT(Z_TYPE_P(result) == IS_STRING);
+ if (is_unicode && Z_STRLEN_P(result) != 0) {
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
DWORD ret;
- ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)buf, buflen/sizeof(WCHAR), NULL, 0, NULL, NULL);
+ ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) Z_STRVAL_P(result), Z_STRLEN_P(result)/sizeof(WCHAR), NULL, 0, NULL, NULL);
if (ret == 0) {
return PDO_ODBC_CONV_FAIL;
}
- if (S->convbufsize <= ret) {
- S->convbufsize = ret + 1;
- S->convbuf = erealloc(S->convbuf, S->convbufsize);
- }
-
- ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)buf, buflen/sizeof(WCHAR), S->convbuf, S->convbufsize, NULL, NULL);
+ zend_string *str = zend_string_alloc(ret, 0);
+ ret = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) Z_STRVAL_P(result), Z_STRLEN_P(result)/sizeof(WCHAR), ZSTR_VAL(str), ZSTR_LEN(str), NULL, NULL);
if (ret == 0) {
return PDO_ODBC_CONV_FAIL;
}
- *outlen = ret;
- S->convbuf[*outlen] = '\0';
+ ZSTR_VAL(str)[ret] = '\0';
+ zval_ptr_dtor_str(result);
+ ZVAL_STR(result, str);
return PDO_ODBC_CONV_OK;
}
#endif
@@ -480,38 +477,27 @@ static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *p
P = param->driver_data;
if (P->outbuf) {
- zend_ulong ulen;
- char *srcbuf;
- zend_ulong srclen = 0;
-
if (Z_ISREF(param->parameter)) {
parameter = Z_REFVAL(param->parameter);
} else {
parameter = &param->parameter;
}
zval_ptr_dtor(parameter);
- ZVAL_NULL(parameter);
switch (P->len) {
case SQL_NULL_DATA:
+ ZVAL_NULL(parameter);
break;
default:
- switch (pdo_odbc_ucs22utf8(stmt, P->is_unicode, P->outbuf, P->len, &ulen)) {
+ ZVAL_STRINGL(parameter, P->outbuf, P->len);
+ switch (pdo_odbc_ucs22utf8(stmt, P->is_unicode, parameter)) {
case PDO_ODBC_CONV_FAIL:
/* something fishy, but allow it to come back as binary */
case PDO_ODBC_CONV_NOT_REQUIRED:
- srcbuf = P->outbuf;
- srclen = P->len;
break;
case PDO_ODBC_CONV_OK:
- srcbuf = S->convbuf;
- srclen = ulen;
break;
}
-
- ZVAL_NEW_STR(parameter, zend_string_alloc(srclen, 0));
- memcpy(Z_STRVAL_P(parameter), srcbuf, srclen);
- Z_STRVAL_P(parameter)[Z_STRLEN_P(parameter)] = '\0';
}
}
return 1;
@@ -612,9 +598,6 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno)
col->name = zend_string_init(S->cols[colno].colname, colnamelen, 0);
S->cols[colno].is_unicode = pdo_odbc_sqltype_is_unicode(S, S->cols[colno].coltype);
- /* returning data as a string */
- col->param_type = PDO_PARAM_STR;
-
/* tell ODBC to put it straight into our buffer, but only if it
* isn't "long" data, and only if we haven't already bound a long
* column. */
@@ -642,17 +625,21 @@ static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno)
return 1;
}
-static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong *len, int *caller_frees)
+static int odbc_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *return_value)
+{
+ array_init(return_value);
+ add_assoc_long(return_value, "pdo_type", PDO_PARAM_STR);
+ return 1;
+}
+
+static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo_param_type *type)
{
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
pdo_odbc_column *C = &S->cols[colno];
- zend_ulong ulen;
/* if it is a column containing "long" data, perform late binding now */
if (C->is_long) {
SQLLEN orig_fetched_len = SQL_NULL_DATA;
- zend_ulong used = 0;
- char *buf;
RETCODE rc;
/* fetch it into C->data, which is allocated with a length
@@ -679,11 +666,9 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
this loop has to work whether or not SQLGetData() provides the total column length.
calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read
for that size would be slower except maybe for extremely long columns.*/
- char *buf2;
-
- buf2 = emalloc(256);
- buf = estrndup(C->data, 256);
- used = 255; /* not 256; the driver NUL terminated the buffer */
+ char *buf2 = emalloc(256);
+ zend_string *str = zend_string_init(C->data, 256, 0);
+ size_t used = 255; /* not 256; the driver NUL terminated the buffer */
do {
C->fetched_len = 0;
@@ -702,12 +687,12 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
/* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx
states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size)
(if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */
- buf = erealloc(buf, used + 255+1);
- memcpy(buf + used, buf2, 255);
+ str = zend_string_realloc(str, used + 256, 0);
+ memcpy(ZSTR_VAL(str) + used, buf2, 256);
used = used + 255;
} else if (rc==SQL_SUCCESS) {
- buf = erealloc(buf, used + C->fetched_len+1);
- memcpy(buf + used, buf2, C->fetched_len);
+ str = zend_string_realloc(str, used + C->fetched_len, 0);
+ memcpy(ZSTR_VAL(str) + used, buf2, C->fetched_len);
used = used + C->fetched_len;
} else {
/* includes SQL_NO_DATA */
@@ -719,11 +704,8 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
efree(buf2);
/* NULL terminate the buffer once, when finished, for use with the rest of PHP */
- buf[used] = '\0';
-
- *ptr = buf;
- *caller_frees = 1;
- *len = used;
+ ZSTR_VAL(str)[used] = '\0';
+ ZVAL_STR(result, str);
if (C->is_unicode) {
goto unicode_conv;
}
@@ -731,8 +713,6 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong
}
/* something went caca */
- *ptr = NULL;
- *len = 0;
return 1;
}
@@ -740,40 +720,29 @@ in_data:
/* check the indicator to ensure that the data is intact */
if (C->fetched_len == SQL_NULL_DATA) {
/* A NULL value */
- *ptr = NULL;
- *len = 0;
+ ZVAL_NULL(result);
return 1;
} else if (C->fetched_len >= 0) {
/* it was stored perfectly */
- *ptr = C->data;
- *len = C->fetched_len;
+ ZVAL_STRINGL_FAST(result, C->data, C->fetched_len);
if (C->is_unicode) {
goto unicode_conv;
}
return 1;
} else {
/* no data? */
- *ptr = NULL;
- *len = 0;
+ ZVAL_NULL(result);
return 1;
}
- unicode_conv:
- switch (pdo_odbc_ucs22utf8(stmt, C->is_unicode, *ptr, *len, &ulen)) {
+unicode_conv:
+ switch (pdo_odbc_ucs22utf8(stmt, C->is_unicode, result)) {
case PDO_ODBC_CONV_FAIL:
/* oh well. They can have the binary version of it */
case PDO_ODBC_CONV_NOT_REQUIRED:
/* shouldn't happen... */
return 1;
-
case PDO_ODBC_CONV_OK:
- if (*caller_frees) {
- efree(*ptr);
- }
- *ptr = emalloc(ulen + 1);
- *len = ulen;
- memcpy(*ptr, S->convbuf, ulen+1);
- *caller_frees = 1;
return 1;
}
return 1;
@@ -883,8 +852,8 @@ const struct pdo_stmt_methods odbc_stmt_methods = {
odbc_stmt_get_col,
odbc_stmt_param_hook,
odbc_stmt_set_param,
- odbc_stmt_get_attr, /* get attr */
- NULL, /* get column meta */
+ odbc_stmt_get_attr,
+ odbc_stmt_get_column_meta,
odbc_stmt_next_rowset,
odbc_stmt_close_cursor
};