44 message =
strpprintf(0,
"%s (%s[%ld] at %s:%d)",
58 SQLSMALLINT errmsgsize = 0;
60 SQLSMALLINT htype, recno = 1;
73 if (statement == SQL_NULL_HSTMT &&
S) {
78 htype = SQL_HANDLE_STMT;
81 htype = SQL_HANDLE_DBC;
84 htype = SQL_HANDLE_ENV;
91 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
112 while (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
116 rc = SQLGetDiagRec(htype, eh, recno++, discard_state, &code,
117 discard_buf,
sizeof(discard_buf)-1, &errmsgsize);
123static void odbc_handle_closer(
pdo_dbh_t *dbh)
127 if (
H->dbc != SQL_NULL_HANDLE) {
128 SQLEndTran(SQL_HANDLE_DBC,
H->dbc, SQL_ROLLBACK);
129 SQLDisconnect(
H->dbc);
130 SQLFreeHandle(SQL_HANDLE_DBC,
H->dbc);
133 SQLFreeHandle(SQL_HANDLE_ENV,
H->env);
136 dbh->driver_data =
NULL;
149 S->assume_utf8 =
H->assume_utf8;
159 }
else if (
ret == -1) {
161 strcpy(dbh->error_code, stmt->error_code);
166 rc = SQLAllocHandle(SQL_HANDLE_STMT,
H->dbc, &
S->stmt);
168 if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) {
171 zend_string_release(nsql);
177 stmt->driver_data =
S;
181 rc = SQLSetStmtAttr(
S->stmt, SQL_ATTR_CURSOR_SCROLLABLE, (
void*)SQL_SCROLLABLE, 0);
182 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
184 SQLFreeHandle(SQL_HANDLE_STMT,
S->stmt);
186 zend_string_release(nsql);
194 zend_string_release(nsql);
199 if (rc != SQL_SUCCESS) {
201 if (rc != SQL_SUCCESS_WITH_INFO) {
203 strcpy(
H->einfo.last_err_msg,
S->einfo.last_err_msg);
204 H->einfo.file =
S->einfo.file;
205 H->einfo.line =
S->einfo.line;
206 H->einfo.what =
S->einfo.what;
207 strcpy(dbh->error_code, stmt->error_code);
211 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
221 SQLLEN row_count = -1;
224 rc = SQLAllocHandle(SQL_HANDLE_STMT,
H->dbc, &stmt);
225 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
232 if (rc == SQL_NO_DATA) {
240 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
245 rc = SQLRowCount(stmt, &row_count);
246 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
250 if (row_count == -1) {
254 SQLFreeHandle(SQL_HANDLE_STMT, stmt);
267static bool odbc_handle_begin(
pdo_dbh_t *dbh)
274 rc = SQLSetConnectAttr(
H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER);
275 if (rc != SQL_SUCCESS) {
283static bool odbc_handle_commit(
pdo_dbh_t *dbh)
288 rc = SQLEndTran(SQL_HANDLE_DBC,
H->dbc, SQL_COMMIT);
290 if (rc != SQL_SUCCESS) {
293 if (rc != SQL_SUCCESS_WITH_INFO) {
300 rc = SQLSetConnectAttr(
H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
301 if (rc != SQL_SUCCESS) {
309static bool odbc_handle_rollback(
pdo_dbh_t *dbh)
314 rc = SQLEndTran(SQL_HANDLE_DBC,
H->dbc, SQL_ROLLBACK);
316 if (rc != SQL_SUCCESS) {
319 if (rc != SQL_SUCCESS_WITH_INFO) {
325 rc = SQLSetConnectAttr(
H->dbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_INTEGER);
326 if (rc != SQL_SUCCESS) {
345 H->assume_utf8 = bval;
357 RETCODE rc = SQLSetConnectAttr(
360 dbh->
auto_commit ? (SQLPOINTER) SQL_AUTOCOMMIT_ON : (SQLPOINTER) SQL_AUTOCOMMIT_OFF,
363 if (rc != SQL_SUCCESS) {
365 dbh->
auto_commit ?
"SQLSetConnectAttr AUTOCOMMIT = ON" :
"SQLSetConnectAttr AUTOCOMMIT = OFF"
372 strcpy(
H->einfo.last_err_msg,
"Unknown Attribute");
373 H->einfo.what =
"setAttribute";
374 strcpy(
H->einfo.last_state,
"IM001");
385 rc = SQLGetInfo(
H->dbc,
type, (SQLPOINTER)
buf,
sizeof(
buf), &out_len);
387 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
403 return pdo_odbc_get_info_string(dbh, SQL_DBMS_VER,
val);
405 return pdo_odbc_get_info_string(dbh, SQL_DBMS_NAME,
val);
425 SQLUINTEGER dead = SQL_CD_FALSE;
428 ret = SQLGetConnectAttr(
H->dbc, SQL_ATTR_CONNECTION_DEAD, &dead, 0,
NULL);
429 if (
ret == SQL_SUCCESS && dead == SQL_CD_TRUE) {
439 ret = SQLGetInfo(
H->dbc, SQL_DATA_SOURCE_READ_ONLY, d_name,
440 sizeof(d_name), &
len);
442 if (
ret != SQL_SUCCESS ||
len == 0) {
450 odbc_handle_preparer,
455 odbc_handle_rollback,
456 odbc_handle_set_attr,
458 pdo_odbc_fetch_error_func,
459 odbc_handle_get_attr,
460 odbc_handle_check_liveness,
468static int pdo_odbc_handle_factory(
pdo_dbh_t *dbh,
zval *driver_options)
479 rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &
H->env);
480 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
485 rc = SQLSetEnvAttr(
H->env, SQL_ATTR_ODBC_VERSION, (
void*)SQL_OV_ODBC3, 0);
487 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
492#ifdef SQL_ATTR_CONNECTION_POOLING
493 if (pdo_odbc_pool_on != SQL_CP_OFF) {
494 rc = SQLSetEnvAttr(
H->env, SQL_ATTR_CP_MATCH, (
void*)pdo_odbc_pool_mode, 0);
495 if (rc != SQL_SUCCESS) {
502 rc = SQLAllocHandle(SQL_HANDLE_DBC,
H->env, &
H->dbc);
503 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
508 rc = SQLSetConnectAttr(
H->dbc, SQL_ATTR_AUTOCOMMIT,
509 (SQLPOINTER)(intptr_t)(dbh->
auto_commit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF), SQL_IS_INTEGER);
510 if (rc != SQL_SUCCESS) {
517 rc = SQLSetConnectAttr(
H->dbc,
SQL_ODBC_CURSORS, (
void*)cursor_lib, SQL_IS_INTEGER);
526 SQLSMALLINT dsnbuflen;
534 if (use_uid_arg || use_pwd_arg) {
535 char *db = (
char*)
emalloc(db_len + 1);
537 char *db_end = db + db_len;
539 if ((
unsigned char)*(db_end) ==
';') {
544 bool should_quote_uid, should_quote_pwd;
549 if (should_quote_uid) {
551 uid =
emalloc(estimated_length);
560 snprintf(dsn, new_dsn_size,
"%s;UID=%s;", db, uid);
566 if (should_quote_pwd) {
568 pwd =
emalloc(estimated_length);
577 snprintf(dsn, new_dsn_size,
"%s;PWD=%s;", db, pwd);
581 if (use_uid_arg && use_pwd_arg) {
584 +
strlen(
";UID=;PWD=;") + 1;
586 snprintf(dsn, new_dsn_size,
"%s;UID=%s;PWD=%s;", db, uid, pwd);
591 if (uid && should_quote_uid) {
594 if (pwd && should_quote_pwd) {
601 dsnbuf,
sizeof(dsnbuf)-1, &dsnbuflen, SQL_DRIVER_NOPROMPT);
607 if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
627 pdo_odbc_handle_factory
file(string $filename, int $flags=0, $context=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
zend_ffi_ctype_name_buf buf
const SQL_CUR_USE_IF_NEEDED
const pdo_driver_t pdo_odbc_driver
void pdo_odbc_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, PDO_ODBC_HSTMT statement, char *what, const char *file, int line)
const struct pdo_stmt_methods odbc_stmt_methods
PDO_API zend_class_entry * php_pdo_get_exception(void)
void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, pdo_error_type sqlstate, const char *supp)
PDO_API bool pdo_get_bool_param(bool *bval, zval *value)
PHPAPI size_t php_odbc_connstr_estimate_quote_length(const char *in_str)
PHPAPI bool php_odbc_connstr_is_quoted(const char *str)
PHPAPI size_t php_odbc_connstr_quote(char *out_str, const char *in_str, size_t out_str_size)
PHPAPI bool php_odbc_connstr_should_quote(const char *str)
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery)
struct _pdo_dbh_t pdo_dbh_t
#define PDO_DRIVER_HEADER(name)
struct _pdo_stmt_t pdo_stmt_t
@ PDO_PLACEHOLDER_POSITIONAL
@ PDO_ATTR_CONNECTION_STATUS
@ PDO_ATTR_SERVER_VERSION
@ PDO_ATTR_CLIENT_VERSION
@ PDO_ODBC_ATTR_ASSUME_UTF8
@ PDO_ODBC_ATTR_USE_CURSOR_LIBRARY
#define pdo_odbc_doer_error(what)
#define pdo_odbc_stmt_error(what)
#define pdo_odbc_drv_error(what)
pdo_error_type error_code
unsigned alloc_own_columns
const struct pdo_dbh_methods * methods
pdo_error_type error_code
char last_err_msg[SQL_MAX_MESSAGE_LENGTH]
ZEND_API zend_result add_next_index_long(zval *arg, zend_long n)
ZEND_API zend_result add_next_index_string(zval *arg, const char *str)
ZEND_API zend_result add_next_index_str(zval *arg, zend_string *str)
#define ZVAL_STRING(z, s)
#define ZVAL_STRINGL(z, s, l)
#define ecalloc(nmemb, size)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
#define pecalloc(nmemb, size, persistent)
ZEND_API ZEND_COLD zend_object * zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format,...)
struct _zend_string zend_string
ZEND_RESULT_CODE zend_result