From: George Schlossnagle Date: Tue, 18 May 2004 18:01:52 +0000 (+0000) Subject: initial import of mysql 3.x pdo driver X-Git-Tag: RELEASE_0_1~143 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=71728cc2b24c4053aa7794a4f27b6403868dbd85;p=php initial import of mysql 3.x pdo driver --- diff --git a/ext/pdo_mysql/config.m4 b/ext/pdo_mysql/config.m4 new file mode 100755 index 0000000000..7348e5fd97 --- /dev/null +++ b/ext/pdo_mysql/config.m4 @@ -0,0 +1,93 @@ +dnl +dnl $Id$ +dnl + +AC_DEFUN(MYSQL_LIB_CHK, [ + str="$MYSQL_DIR/$1/libmysqlclient.*" + for j in `echo $str`; do + if test -r $j; then + MYSQL_LIB_DIR=$MYSQL_DIR/$1 + break 2 + fi + done +]) + +PHP_ARG_WITH(pdo_mysql, for MySQL support, +[ --with-pdo_mysql[=DIR] Include MySQL support. DIR is the MySQL base directory.]) + +if test "$PHP_PDO_MYSQL" != "no"; then + AC_DEFINE(HAVE_MYSQL, 1, [Whether you have MySQL]) + + AC_MSG_CHECKING([for MySQL UNIX socket location]) + if test "$PHP_MYSQL_SOCK" != "no" && test "$PHP_MYSQL_SOCK" != "yes"; then + MYSQL_SOCK=$PHP_MYSQL_SOCK + AC_DEFINE_UNQUOTED(MYSQL_UNIX_ADDR, "$MYSQL_SOCK", [ ]) + AC_MSG_RESULT([$MYSQL_SOCK]) + elif test "$PHP_MYSQL" = "yes" || test "$PHP_MYSQL_SOCK" = "yes"; then + PHP_MYSQL_SOCKET_SEARCH + else + AC_MSG_RESULT([no]) + fi + + for i in $PHP_MYSQL /usr/local /usr; do + if test -r $i/include/mysql/mysql.h; then + MYSQL_DIR=$i + MYSQL_INC_DIR=$i/include/mysql + break + elif test -r $i/include/mysql.h; then + MYSQL_DIR=$i + MYSQL_INC_DIR=$i/include + break + fi + done + + if test -z "$MYSQL_DIR"; then + AC_MSG_ERROR([Cannot find MySQL header files under $PHP_MYSQL. +Note that the MySQL client library is not bundled anymore.]) + fi + + for i in lib lib/mysql; do + MYSQL_LIB_CHK($i) + done + + if test -z "$MYSQL_LIB_DIR"; then + AC_MSG_ERROR([Cannot find libmysqlclient under $MYSQL_DIR. +Note that the MySQL client library is not bundled anymore.]) + fi + + PHP_CHECK_LIBRARY(mysqlclient, mysql_close, [ ], + [ + if test "$PHP_ZLIB_DIR" != "no"; then + PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR, PDO_MYSQL_SHARED_LIBADD) + PHP_CHECK_LIBRARY(mysqlclient, mysql_error, [], [ + AC_MSG_ERROR([mysql configure failed. Please check config.log for more information.]) + ], [ + -L$PHP_ZLIB_DIR/lib -L$MYSQL_LIB_DIR + ]) + MYSQL_LIBS="-L$PHP_ZLIB_DIR/lib -lz" + else + PHP_ADD_LIBRARY(z,, PDO_MYSQL_SHARED_LIBADD) + PHP_CHECK_LIBRARY(mysqlclient, mysql_errno, [], [ + AC_MSG_ERROR([Try adding --with-zlib-dir=. Please check config.log for more information.]) + ], [ + -L$MYSQL_LIB_DIR + ]) + MYSQL_LIBS="-lz" + fi + ], [ + -L$MYSQL_LIB_DIR + ]) + + PHP_ADD_LIBRARY_WITH_PATH(mysqlclient, $MYSQL_LIB_DIR, PDO_MYSQL_SHARED_LIBADD) + PHP_ADD_INCLUDE($MYSQL_INC_DIR) + + PHP_NEW_EXTENSION(pdo_mysql, pdo_mysql.c mysql_driver.c mysql_statement.c, $ext_shared) + PDO_MYSQL_MODULE_TYPE=external + PDO_MYSQL_LIBS="-L$MYSQL_LIB_DIR -lmysqlclient $MYSQL_LIBS" + PDO_MYSQL_INCLUDE=-I$MYSQL_INC_DIR + + PHP_SUBST(PDO_MYSQL_SHARED_LIBADD) + PHP_SUBST_OLD(PDO_MYSQL_MODULE_TYPE) + PHP_SUBST_OLD(PDO_MYSQL_LIBS) + PHP_SUBST_OLD(PDO_MYSQL_INCLUDE) +fi diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c new file mode 100755 index 0000000000..e217654933 --- /dev/null +++ b/ext/pdo_mysql/mysql_driver.c @@ -0,0 +1,179 @@ +/* + +----------------------------------------------------------------------+ + | 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: George Schlossnagle | + +----------------------------------------------------------------------+ +*/ + +/* $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_mysql.h" +#include "php_pdo_mysql_int.h" + +int _mysql_error(char *what, int errno, const char *file, int line TSRMLS_DC) /* {{{ */ +{ + switch (errno) { + default: + php_error_docref(NULL TSRMLS_CC, E_WARNING, "(%s:%d) %s: %d", file, line, what, errno); + break; + } + return errno; +} +/* }}} */ + +int mysql_handle_error(pdo_dbh_t *dbh, pdo_mysql_db_handle *H, int errcode) /* {{{ */ +{ + return 0; +} +/* }}} */ + +static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */ +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + + if (H->server) { + mysql_close(H->server); + H->server = NULL; + } + return 0; +} +/* }}} */ + +static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt TSRMLS_DC) +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + pdo_mysql_stmt *S = ecalloc(1, sizeof(pdo_mysql_stmt)); + + S->H = H; + stmt->driver_data = S; + stmt->methods = &mysql_stmt_methods; + + return 1; +} + +static int mysql_handle_doer(pdo_dbh_t *dbh, const char *sql TSRMLS_DC) +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + + return 0; +} + +static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC) +{ + pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; + *quoted = emalloc(2*unquotedlen + 3); + (*quoted)[0] = '"'; + *quotedlen = mysql_real_escape_string(H->server, *quoted + 1, + unquoted, unquotedlen); + (*quoted)[*quotedlen + 1] = '"'; + (*quoted)[*quotedlen + 2] = '\0'; + *quotedlen += 2; + return 1; +} + + +static struct pdo_dbh_methods mysql_methods = { + mysql_handle_closer, + mysql_handle_preparer, + mysql_handle_doer, + mysql_handle_quoter +}; + +static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */ +{ + pdo_mysql_db_handle *H; + int i, ret = 0; + char *host = NULL, *unix_socket = NULL; + unsigned int port; + char *dbname; + struct pdo_data_src_parser vars[] = { + { "charset", NULL, 0 }, + { "dbname", "", 0 }, + { "host", "localhost", 0 }, + { "port", "3306", 0 }, + { "unix_socket", "/var/tmp/mysql.sock", 0 }, + }; + + php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 4); + + H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent); + + /* allocate an environment */ + + /* handle for the server */ + H->server = mysql_init(NULL); + if(vars[2].optval && strcmp("localhost", vars[2].optval)) { + host = vars[2].optval; + port = atoi(vars[3].optval); + } else { + host = NULL; + unix_socket = vars[4].optval; + } + dbname = vars[1].optval; + if(mysql_real_connect(H->server, host, dbh->username, dbh->password, dbname, port, unix_socket, 0) == NULL) + { + H->last_err = mysql_errno(H->server); + pdo_mysql_error("pdo_mysql_handle_factory", H->last_err); + goto cleanup; + } + + H->attached = 1; + + dbh->driver_data = H; + dbh->methods = &mysql_methods; + dbh->alloc_own_columns = 1; + dbh->supports_placeholders = 1; + dbh->emulate_prepare = 1; + dbh->placeholders_can_be_strings = 1; + dbh->max_escaped_char_length = 2; + + ret = 1; + +cleanup: + for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) { + if (vars[i].freeme) { + efree(vars[i].optval); + } + } + + if (!ret) { + mysql_handle_closer(dbh TSRMLS_CC); + } + + return ret; +} +/* }}} */ + +pdo_driver_t pdo_mysql_driver = { + PDO_DRIVER_HEADER(mysql), + pdo_mysql_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 + */ diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c new file mode 100755 index 0000000000..0bd3cb31a6 --- /dev/null +++ b/ext/pdo_mysql/mysql_statement.c @@ -0,0 +1,164 @@ +/* + +----------------------------------------------------------------------+ + | 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: George Schlossnagle | + +----------------------------------------------------------------------+ +*/ + +/* $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_mysql.h" +#include "php_pdo_mysql_int.h" + + +static int mysql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC) +{ + pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data; + int i; + + if (S->result) { + /* free the resource */ + mysql_free_result(S->result); + S->result = NULL; + } + if(S->cols) { + efree(S->cols); + S->cols = NULL; + } + efree(S); + return 1; +} + +static int mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) +{ + pdo_dbh_t *dbh = stmt->dbh; + pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data; + pdo_mysql_db_handle *H = S->H; + + if (stmt->executed) { + /* ensure that we free any previous unfetched results */ + if(S->result) { + mysql_free_result(S->result); + S->result = NULL; + } + } + if(mysql_real_query(H->server, stmt->active_query_string, + stmt->active_query_stringlen) != 0) + { + H->last_err = S->last_err = mysql_errno(H->server); + pdo_mysql_error("execute failed", S->last_err); + return 0; + } + if((S->result = mysql_use_result(H->server)) == NULL) { + H->last_err = S->last_err = mysql_errno(H->server); + pdo_mysql_error("mysql_use_result() failed", S->last_err); + return 0; + } + if(!stmt->executed) { + stmt->column_count = (int) mysql_num_fields(S->result); + S->cols = ecalloc(stmt->column_count, sizeof(pdo_mysql_column)); + } + stmt->row_count = (long)mysql_num_rows(S->result); + return 1; +} + +static int mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, + enum pdo_param_event event_type TSRMLS_DC) +{ + return 1; +} + +static int mysql_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC) +{ + pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data; + + if((S->current_data = mysql_fetch_row(S->result)) == NULL) { + /* there seems to be no way of distinguishing 'no data' from 'error' */ + return 0; + } + S->current_lengths = mysql_fetch_lengths(S->result); + return 1; +} + +static int mysql_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) +{ + pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data; + MYSQL_RES *R = S->result; + MYSQL_FIELD *F; + struct pdo_column_data *cols = stmt->columns; + unsigned int num_fields, i; + + /* fetch all on demand, this seems easiest + ** if we've been here before bail out + */ + if(cols[0].name) { + return 1; + } + num_fields = mysql_num_fields(R); + F = mysql_fetch_fields(R); + for(i=0; i < num_fields; i++) { + int namelen; + namelen = strlen(F[i].name); + cols[i].precision = F[i].decimals; + cols[i].maxlen = F[i].length; + cols[i].namelen = namelen; + /* FIXME where does this get freed? */ + cols[i].name = estrndup(F[i].name, namelen + 1); + cols[i].param_type = PDO_PARAM_STR; + } + return 1; +} + +static int mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned long *len TSRMLS_DC) +{ + pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data; + if(S->current_data == NULL) { + return 0; + } + if(colno >= mysql_num_fields(S->result)) { + /* error invalid column */ + pdo_mysql_error("invalid column", 0); + return 0; + } + *ptr = estrndup(S->current_data[colno], S->current_lengths[colno] +1); + *len = S->current_lengths[colno]; + return 1; +} + +struct pdo_stmt_methods mysql_stmt_methods = { + mysql_stmt_dtor, + mysql_stmt_execute, + mysql_stmt_fetch, + mysql_stmt_describe, + mysql_stmt_get_col, + mysql_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 + */ diff --git a/ext/pdo_mysql/package.xml b/ext/pdo_mysql/package.xml new file mode 100644 index 0000000000..87deda8523 --- /dev/null +++ b/ext/pdo_mysql/package.xml @@ -0,0 +1,42 @@ + + + + pdo_oci + Oracle Call Interface driver for PDO + + + gschlossnagle + George Schlossnagle + george@omniti.com + lead + + + + This extension provides a Mysql 3.x driver for PDO. + + PHP + + alpha + 0.1dev + 2004-05-18 + + + Hope it works! + + + + + + + + + + + + + + + + + + diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c new file mode 100755 index 0000000000..a830f5ecf3 --- /dev/null +++ b/ext/pdo_mysql/pdo_mysql.c @@ -0,0 +1,95 @@ +/* + +----------------------------------------------------------------------+ + | 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: George Schlossnagle | + +----------------------------------------------------------------------+ +*/ + +/* $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_mysql.h" +#include "php_pdo_mysql_int.h" + +/* {{{ pdo_mysql_functions[] */ +function_entry pdo_mysql_functions[] = { + {NULL, NULL, NULL} +}; +/* }}} */ + +/* {{{ pdo_mysql_module_entry */ +zend_module_entry pdo_mysql_module_entry = { + STANDARD_MODULE_HEADER, + "pdo_mysql", + pdo_mysql_functions, + PHP_MINIT(pdo_mysql), + PHP_MSHUTDOWN(pdo_mysql), + NULL, + NULL, + PHP_MINFO(pdo_mysql), + "0.1", + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + +#ifdef COMPILE_DL_PDO_MYSQL +ZEND_GET_MODULE(pdo_mysql) +#endif + +/* true global environment */ + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(pdo_mysql) +{ + php_pdo_register_driver(&pdo_mysql_driver); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(pdo_mysql) +{ + php_pdo_unregister_driver(&pdo_mysql_driver); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(pdo_mysql) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "PDO Driver for MySQL 3.x Client Libraries", "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 + */ diff --git a/ext/pdo_mysql/php_pdo_mysql.h b/ext/pdo_mysql/php_pdo_mysql.h new file mode 100755 index 0000000000..4394f407ba --- /dev/null +++ b/ext/pdo_mysql/php_pdo_mysql.h @@ -0,0 +1,53 @@ +/* + +----------------------------------------------------------------------+ + | 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: George Schlossnagle | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_PDO_MYSQL_H +#define PHP_PDO_MYSQL_H + +extern zend_module_entry pdo_mysql_module_entry; +#define phpext_pdo_mysql_ptr &pdo_mysql_module_entry + +#ifdef PHP_WIN32 +#define PHP_PDO_MYSQL_API __declspec(dllexport) +#else +#define PHP_PDO_MYSQL_API +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + +PHP_MINIT_FUNCTION(pdo_mysql); +PHP_MSHUTDOWN_FUNCTION(pdo_mysql); +PHP_RINIT_FUNCTION(pdo_mysql); +PHP_RSHUTDOWN_FUNCTION(pdo_mysql); +PHP_MINFO_FUNCTION(pdo_mysql); + +#endif /* PHP_PDO_OCI_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 + */ diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h new file mode 100755 index 0000000000..92a988e957 --- /dev/null +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -0,0 +1,61 @@ +/* + +----------------------------------------------------------------------+ + | 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: George Schlossnagle | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_PDO_MYSQL_INT_H +#define PHP_PDO_MYSQL_INT_H + +#include + +/* stuff we use in an OCI database handle */ +typedef struct { + MYSQL *server; + unsigned int last_err; + unsigned attached:1; + unsigned _reserved:31; +} pdo_mysql_db_handle; + +typedef struct { + MYSQL_FIELD *def; +} pdo_mysql_column; + +typedef struct { + pdo_mysql_db_handle *H; + MYSQL_RES *result; + MYSQL_ROW current_data; + long *current_lengths; + unsigned int last_err; + pdo_mysql_column *cols; +} pdo_mysql_stmt; + +typedef struct { + char *repr; + long repr_len; + int mysql_type; + void *thing; /* for LOBS, REFCURSORS etc. */ +} pdo_mysql_bound_param; + +extern pdo_driver_t pdo_mysql_driver; + +int _mysql_error(char *what, int errno, const char *file, int line TSRMLS_DC); +#define pdo_mysql_error(w,s) _mysql_error(w, s, __FILE__, __LINE__ TSRMLS_CC) +int mysql_handle_error(pdo_dbh_t *dbh, pdo_mysql_db_handle *H, int errcode); + +extern struct pdo_stmt_methods mysql_stmt_methods; +#endif