mirror of
https://github.com/php/php-src.git
synced 2024-11-28 04:14:26 +08:00
ODBC (v3 ish) driver for PDO.
Will not build under unix yet.
This commit is contained in:
parent
1b1ced539b
commit
d6c4dee168
2
ext/pdo_odbc/CREDITS
Executable file
2
ext/pdo_odbc/CREDITS
Executable file
@ -0,0 +1,2 @@
|
||||
ODBC driver for PDO
|
||||
Wez Furlong
|
0
ext/pdo_odbc/EXPERIMENTAL
Normal file
0
ext/pdo_odbc/EXPERIMENTAL
Normal file
9
ext/pdo_odbc/config.m4
Executable file
9
ext/pdo_odbc/config.m4
Executable file
@ -0,0 +1,9 @@
|
||||
dnl $Id$
|
||||
dnl config.m4 for extension pdo_odbc
|
||||
|
||||
PHP_ARG_WITH(pdo_odbc, for pdo_odbc support,
|
||||
[ --with-pdo_odbc Include pdo_odbc support])
|
||||
|
||||
if test "$PHP_PDO_ODBC" != "no"; then
|
||||
PHP_NEW_EXTENSION(pdo_odbc, pdo_odbc.c odbc_driver.c odbc_stmt.c, $ext_shared)
|
||||
fi
|
15
ext/pdo_odbc/config.w32
Executable file
15
ext/pdo_odbc/config.w32
Executable file
@ -0,0 +1,15 @@
|
||||
// $Id$
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("pdo-odbc", "ODBC support for PDO", "no");
|
||||
|
||||
if (PHP_PDO_ODBC != "no") {
|
||||
if (CHECK_LIB("odbc32.lib", "pdo_odbc") && CHECK_LIB("odbccp32.lib", "pdo_odbc")) {
|
||||
EXTENSION("pdo_odbc", "pdo_odbc.c odbc_driver.c odbc_stmt.c");
|
||||
CHECK_HEADER_ADD_INCLUDE('sql.h', 'CFLAGS_PDO_ODBC');
|
||||
CHECK_HEADER_ADD_INCLUDE('sqlext.h', 'CFLAGS_PDO_ODBC');
|
||||
ADD_FLAG('CFLAGS_PDO_ODBC', "/I ..\\pecl");
|
||||
}
|
||||
ADD_EXTENSION_DEP('pdo_odbc', 'pdo');
|
||||
}
|
||||
|
248
ext/pdo_odbc/odbc_driver.c
Executable file
248
ext/pdo_odbc/odbc_driver.c
Executable file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 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> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $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_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
void _odbc_error(pdo_dbh_t *dbh, char *what, PDO_ODBC_HSTMT stmt, const char *file, int line TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
RETCODE rc;
|
||||
SWORD errmsgsize;
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
|
||||
|
||||
rc = SQLError(H->env, H->dbc, stmt, H->last_state, &H->last_error,
|
||||
H->last_err_msg, sizeof(H->last_err_msg)-1, &errmsgsize);
|
||||
|
||||
H->last_err_msg[errmsgsize] = '\0';
|
||||
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s:%d) %s: %d %s [SQL State %s]",
|
||||
file, line, what, H->last_error, H->last_err_msg, H->last_state);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int odbc_handle_closer(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle*)dbh->driver_data;
|
||||
|
||||
if (H->dbc != SQL_NULL_HANDLE) {
|
||||
SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_ROLLBACK);
|
||||
}
|
||||
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, H->dbc);
|
||||
SQLFreeHandle(SQL_HANDLE_ENV, H->env);
|
||||
pefree(H, dbh->is_persistent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
RETCODE rc;
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
pdo_odbc_stmt *S = ecalloc(1, sizeof(*S));
|
||||
|
||||
S->H = H;
|
||||
|
||||
rc = SQLAllocHandle(SQL_HANDLE_STMT, H->dbc, &S->stmt);
|
||||
|
||||
if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) {
|
||||
efree(S);
|
||||
odbc_error(dbh, "SQLAllocStmt", SQL_NULL_HSTMT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = SQLPrepare(S->stmt, (char*)sql, SQL_NTS);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
odbc_error(dbh, "SQLPrepare", S->stmt);
|
||||
}
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
stmt->driver_data = S;
|
||||
stmt->methods = &odbc_stmt_methods;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_handle_doer(pdo_dbh_t *dbh, const char *sql TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, char **quoted, int *quotedlen TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_handle_begin(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
/* with ODBC, there is nothing special to be done */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_handle_commit(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_COMMIT);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
odbc_error(dbh, "SQLEndTran: Commit", SQL_NULL_HSTMT);
|
||||
|
||||
if (rc != SQL_SUCCESS_WITH_INFO) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_handle_rollback(pdo_dbh_t *dbh TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLEndTran(SQL_HANDLE_DBC, H->dbc, SQL_ROLLBACK);
|
||||
|
||||
if (rc != SQL_SUCCESS) {
|
||||
odbc_error(dbh, "SQLEndTran: Rollback", SQL_NULL_HSTMT);
|
||||
|
||||
if (rc != SQL_SUCCESS_WITH_INFO) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct pdo_dbh_methods odbc_methods = {
|
||||
odbc_handle_closer,
|
||||
odbc_handle_preparer,
|
||||
odbc_handle_doer,
|
||||
odbc_handle_quoter,
|
||||
odbc_handle_begin,
|
||||
odbc_handle_commit,
|
||||
odbc_handle_rollback,
|
||||
};
|
||||
|
||||
static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
pdo_odbc_db_handle *H;
|
||||
RETCODE rc;
|
||||
int use_direct = 0;
|
||||
|
||||
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
|
||||
|
||||
dbh->driver_data = H;
|
||||
|
||||
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &H->env);
|
||||
rc = SQLSetEnvAttr(H->env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
odbc_error(dbh, "SQLSetEnvAttr: ODBC3", SQL_NULL_HSTMT);
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = SQLAllocHandle(SQL_HANDLE_DBC, H->env, &H->dbc);
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
odbc_error(dbh, "SQLAllocHandle (DBC)", SQL_NULL_HSTMT);
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dbh->auto_commit) {
|
||||
rc = SQLSetConnectAttr(H->dbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
|
||||
if (rc != SQL_SUCCESS) {
|
||||
odbc_error(dbh, "SQLSetConnectAttr AUTOCOMMIT = OFF", SQL_NULL_HSTMT);
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(dbh->data_source, ';')) {
|
||||
char dsnbuf[1024];
|
||||
short dsnbuflen;
|
||||
|
||||
use_direct = 1;
|
||||
|
||||
/* Force UID and PWD to be set in the DSN */
|
||||
if (*dbh->username && !strstr(dbh->data_source, "uid") && !strstr(dbh->data_source, "UID")) {
|
||||
char *dsn = pemalloc(strlen(dbh->data_source) + strlen(dbh->username) + strlen(dbh->password) + sizeof(";UID=;PWD="), dbh->is_persistent);
|
||||
sprintf(dsn, "%s;UID=%s;PWD=%s", dbh->data_source, dbh->username, dbh->password);
|
||||
pefree((char*)dbh->data_source, dbh->is_persistent);
|
||||
dbh->data_source = dsn;
|
||||
}
|
||||
|
||||
rc = SQLDriverConnect(H->dbc, NULL, (char*)dbh->data_source, strlen(dbh->data_source),
|
||||
dsnbuf, sizeof(dsnbuf)-1, &dsnbuflen, SQL_DRIVER_NOPROMPT);
|
||||
}
|
||||
if (!use_direct) {
|
||||
rc = SQLConnect(H->dbc, (char*)dbh->data_source, SQL_NTS, dbh->username, SQL_NTS, dbh->password, SQL_NTS);
|
||||
}
|
||||
|
||||
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
|
||||
odbc_error(dbh, use_direct ? "SQLDriverConnect" : "SQLConnect", SQL_NULL_HSTMT);
|
||||
odbc_handle_closer(dbh TSRMLS_CC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: if we want to play nicely, we should check to see if the driver supports ODBC v3 or not */
|
||||
|
||||
dbh->methods = &odbc_methods;
|
||||
dbh->alloc_own_columns = 1;
|
||||
dbh->supports_placeholders = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
pdo_driver_t pdo_odbc_driver = {
|
||||
PDO_DRIVER_HEADER(odbc),
|
||||
pdo_odbc_handle_factory
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
231
ext/pdo_odbc/odbc_stmt.c
Executable file
231
ext/pdo_odbc/odbc_stmt.c
Executable file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 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> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $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_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
static int odbc_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
int i;
|
||||
|
||||
if (S->stmt != SQL_NULL_HANDLE) {
|
||||
if (stmt->executed) {
|
||||
SQLCancel(S->stmt);
|
||||
}
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, S->stmt);
|
||||
S->stmt = SQL_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (S->cols) {
|
||||
for (i = 0; i < stmt->column_count; i++) {
|
||||
if (S->cols[i].data) {
|
||||
efree(S->cols[i].data);
|
||||
}
|
||||
}
|
||||
efree(S->cols);
|
||||
S->cols = NULL;
|
||||
}
|
||||
efree(S);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
RETCODE rc;
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
|
||||
if (stmt->executed) {
|
||||
SQLCancel(S->stmt);
|
||||
}
|
||||
|
||||
rc = SQLExecute(S->stmt);
|
||||
|
||||
switch (rc) {
|
||||
case SQL_SUCCESS:
|
||||
break;
|
||||
case SQL_NO_DATA_FOUND:
|
||||
case SQL_SUCCESS_WITH_INFO:
|
||||
odbc_error(stmt->dbh, "SQLExecute", S->stmt);
|
||||
break;
|
||||
|
||||
default:
|
||||
odbc_error(stmt->dbh, "SQLExecute", S->stmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!stmt->executed) {
|
||||
/* do first-time-only definition of bind/mapping stuff */
|
||||
SQLSMALLINT colcount;
|
||||
|
||||
/* how many columns do we have ? */
|
||||
SQLNumResultCols(S->stmt, &colcount);
|
||||
|
||||
stmt->column_count = (int)colcount;
|
||||
|
||||
S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
|
||||
enum pdo_param_event event_type TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
RETCODE rc;
|
||||
SWORD sqltype, ctype, scale, nullable;
|
||||
UDWORD precision;
|
||||
|
||||
/* we're only interested in parameters for prepared SQL right now */
|
||||
if (param->is_param) {
|
||||
|
||||
switch (event_type) {
|
||||
case PDO_PARAM_EVT_ALLOC:
|
||||
|
||||
/* figure out what we're doing */
|
||||
switch (param->param_type) {
|
||||
case PDO_PARAM_LOB:
|
||||
case PDO_PARAM_STMT:
|
||||
return 0;
|
||||
|
||||
case PDO_PARAM_STR:
|
||||
default:
|
||||
convert_to_string(param->parameter);
|
||||
}
|
||||
|
||||
SQLDescribeParam(S->stmt, param->paramno+1, &sqltype, &precision, &scale, &nullable);
|
||||
if (sqltype == SQL_BINARY || sqltype == SQL_VARBINARY || sqltype == SQL_LONGVARBINARY) {
|
||||
ctype = SQL_C_BINARY;
|
||||
} else {
|
||||
ctype = SQL_C_CHAR;
|
||||
}
|
||||
|
||||
rc = SQLBindParameter(S->stmt, param->paramno+1,
|
||||
SQL_PARAM_INPUT, ctype, sqltype, precision, scale,
|
||||
Z_STRVAL_P(param->parameter), 0, &Z_STRLEN_P(param->parameter)
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
RETCODE rc;
|
||||
|
||||
rc = SQLFetch(S->stmt);
|
||||
|
||||
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (rc == SQL_NO_DATA) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
odbc_error(stmt->dbh, "SQLFetch", S->stmt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int odbc_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
struct pdo_column_data *col = &stmt->columns[colno];
|
||||
zend_bool dyn = FALSE;
|
||||
RETCODE rc;
|
||||
SWORD colnamelen;
|
||||
SDWORD colsize;
|
||||
|
||||
rc = SQLDescribeCol(S->stmt, colno+1, S->cols[colno].colname,
|
||||
sizeof(S->cols[colno].colname)-1, &colnamelen,
|
||||
&S->cols[colno].coltype, &colsize, NULL, NULL);
|
||||
|
||||
col->maxlen = S->cols[colno].datalen = colsize;
|
||||
col->namelen = colnamelen;
|
||||
col->name = S->cols[colno].colname;
|
||||
|
||||
S->cols[colno].data = emalloc(colsize+1);
|
||||
|
||||
/* returning data as a string */
|
||||
col->param_type = PDO_PARAM_STR;
|
||||
|
||||
/* tell ODBC to put it straight into our buffer */
|
||||
rc = SQLBindCol(S->stmt, colno+1, SQL_C_CHAR, S->cols[colno].data,
|
||||
S->cols[colno].datalen, &S->cols[colno].fetched_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC)
|
||||
{
|
||||
pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
|
||||
pdo_odbc_column *C = &S->cols[colno];
|
||||
|
||||
/* check the indicator to ensure that the data is intact */
|
||||
if (C->fetched_len == SQL_NULL_DATA) {
|
||||
/* A NULL value */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 1;
|
||||
} else if (C->fetched_len >= 0) {
|
||||
/* it was stored perfectly */
|
||||
*ptr = C->data;
|
||||
*len = C->fetched_len;
|
||||
return 1;
|
||||
} else {
|
||||
/* no data? */
|
||||
*ptr = NULL;
|
||||
*len = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct pdo_stmt_methods odbc_stmt_methods = {
|
||||
odbc_stmt_dtor,
|
||||
odbc_stmt_execute,
|
||||
odbc_stmt_fetch,
|
||||
odbc_stmt_describe,
|
||||
odbc_stmt_get_col,
|
||||
odbc_stmt_param_hook
|
||||
};
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
102
ext/pdo_odbc/pdo_odbc.c
Executable file
102
ext/pdo_odbc/pdo_odbc.c
Executable file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 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> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $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_odbc.h"
|
||||
#include "php_pdo_odbc_int.h"
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
# define PDO_ODBC_TYPE "Win32"
|
||||
#endif
|
||||
|
||||
#ifndef PDO_ODBC_TYPE
|
||||
# warning Please fix configure to give your ODBC libraries a name
|
||||
# define PDO_ODBC_TYPE "Unknown"
|
||||
#endif
|
||||
|
||||
/* {{{ pdo_odbc_functions[] */
|
||||
function_entry pdo_odbc_functions[] = {
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ pdo_odbc_module_entry */
|
||||
zend_module_entry pdo_odbc_module_entry = {
|
||||
STANDARD_MODULE_HEADER,
|
||||
"pdo_odbc",
|
||||
pdo_odbc_functions,
|
||||
PHP_MINIT(pdo_odbc),
|
||||
PHP_MSHUTDOWN(pdo_odbc),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(pdo_odbc),
|
||||
"0.1",
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_PDO_ODBC
|
||||
ZEND_GET_MODULE(pdo_odbc)
|
||||
#endif
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION */
|
||||
PHP_MINIT_FUNCTION(pdo_odbc)
|
||||
{
|
||||
php_pdo_register_driver(&pdo_odbc_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_odbc)
|
||||
{
|
||||
php_pdo_unregister_driver(&pdo_odbc_driver);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(pdo_odbc)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "PDO Driver for ODBC (" PDO_ODBC_TYPE ")" , "enabled");
|
||||
php_info_print_table_end();
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
81
ext/pdo_odbc/php_pdo_odbc.h
Normal file
81
ext/pdo_odbc/php_pdo_odbc.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 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: |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef PHP_PDO_ODBC_H
|
||||
#define PHP_PDO_ODBC_H
|
||||
|
||||
extern zend_module_entry pdo_odbc_module_entry;
|
||||
#define phpext_pdo_odbc_ptr &pdo_odbc_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_PDO_ODBC_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_PDO_ODBC_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
PHP_MINIT_FUNCTION(pdo_odbc);
|
||||
PHP_MSHUTDOWN_FUNCTION(pdo_odbc);
|
||||
PHP_RINIT_FUNCTION(pdo_odbc);
|
||||
PHP_RSHUTDOWN_FUNCTION(pdo_odbc);
|
||||
PHP_MINFO_FUNCTION(pdo_odbc);
|
||||
|
||||
PHP_FUNCTION(confirm_pdo_odbc_compiled); /* For testing, remove later. */
|
||||
|
||||
/*
|
||||
Declare any global variables you may need between the BEGIN
|
||||
and END macros here:
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(pdo_odbc)
|
||||
long global_value;
|
||||
char *global_string;
|
||||
ZEND_END_MODULE_GLOBALS(pdo_odbc)
|
||||
*/
|
||||
|
||||
/* In every utility function you add that needs to use variables
|
||||
in php_pdo_odbc_globals, call TSRMLS_FETCH(); after declaring other
|
||||
variables used by that function, or better yet, pass in TSRMLS_CC
|
||||
after the last function argument and declare your utility function
|
||||
with TSRMLS_DC after the last declared argument. Always refer to
|
||||
the globals in your function as PDO_ODBC_G(variable). You are
|
||||
encouraged to rename these macros something shorter, see
|
||||
examples in any other php module directory.
|
||||
*/
|
||||
|
||||
#ifdef ZTS
|
||||
#define PDO_ODBC_G(v) TSRMG(pdo_odbc_globals_id, zend_pdo_odbc_globals *, v)
|
||||
#else
|
||||
#define PDO_ODBC_G(v) (pdo_odbc_globals.v)
|
||||
#endif
|
||||
|
||||
#endif /* PHP_PDO_ODBC_H */
|
||||
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
143
ext/pdo_odbc/php_pdo_odbc_int.h
Executable file
143
ext/pdo_odbc/php_pdo_odbc_int.h
Executable file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2004 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> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/* {{{ Roll a dice, pick a header at random... */
|
||||
#if HAVE_ODBC_H
|
||||
# include <odbc.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_IODBC_H
|
||||
# include <iodbc.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLUNIX_H && !defined(PHP_WIN32)
|
||||
# include <sqlunix.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLTYPES_H
|
||||
# include <sqltypes.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLUCODE_H
|
||||
# include <sqlucode.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQL_H
|
||||
# include <sql.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ISQL_H
|
||||
# include <isql.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLEXT_H
|
||||
# include <sqlext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_ISQLEXT_H
|
||||
# include <isqlext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UDBCEXT_H
|
||||
# include <udbcext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SQLCLI1_H
|
||||
# include <sqlcli1.h>
|
||||
# if defined(DB268K) && HAVE_LIBRARYMANAGER_H
|
||||
# include <LibraryManager.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0CORE_H
|
||||
# include <cli0core.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0EXT1_H
|
||||
# include <cli0ext.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0CLI_H
|
||||
# include <cli0cli.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0DEFS_H
|
||||
# include <cli0defs.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_CLI0ENV_H
|
||||
# include <cli0env.h>
|
||||
#endif
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Figure out the type for handles */
|
||||
#if !defined(HENV) && !defined(SQLHENV) && defined(SQLHANDLE)
|
||||
# define PDO_ODBC_HENV SQLHANDLE
|
||||
# define PDO_ODBC_HDBC SQLHANDLE
|
||||
# define PDO_ODBC_HSTMT SQLHANDLE
|
||||
#elif !defined(HENV) && defined(SQLHENV)
|
||||
# define PDO_ODBC_HENV SQLHENV
|
||||
# define PDO_ODBC_HDBC SQLHDBC
|
||||
# define PDO_ODBC_HSTMT SQLHSTMT
|
||||
#else
|
||||
# define PDO_ODBC_HENV HENV
|
||||
# define PDO_ODBC_HDBC HDBC
|
||||
# define PDO_ODBC_HSTMT HSTMT
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
typedef struct {
|
||||
PDO_ODBC_HENV env;
|
||||
PDO_ODBC_HDBC dbc;
|
||||
|
||||
char last_state[6];
|
||||
char last_err_msg[SQL_MAX_MESSAGE_LENGTH];
|
||||
SDWORD last_error;
|
||||
} pdo_odbc_db_handle;
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
unsigned long datalen;
|
||||
long fetched_len;
|
||||
SWORD coltype;
|
||||
char colname[32];
|
||||
} pdo_odbc_column;
|
||||
|
||||
typedef struct {
|
||||
PDO_ODBC_HSTMT stmt;
|
||||
pdo_odbc_column *cols;
|
||||
pdo_odbc_db_handle *H;
|
||||
} pdo_odbc_stmt;
|
||||
|
||||
extern pdo_driver_t pdo_odbc_driver;
|
||||
extern struct pdo_stmt_methods odbc_stmt_methods;
|
||||
|
||||
void _odbc_error(pdo_dbh_t *dbh, char *what, PDO_ODBC_HSTMT stmt, const char *file, int line TSRMLS_DC);
|
||||
#define odbc_error(dbh, what, stmt) _odbc_error(dbh, what, stmt, __FILE__, __LINE__ TSRMLS_CC)
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* End:
|
||||
* vim600: noet sw=4 ts=4 fdm=marker
|
||||
* vim<600: noet sw=4 ts=4
|
||||
*/
|
Loading…
Reference in New Issue
Block a user