Added lastInsertId() method for retrieving last insert id.

Made affectedRows() work for MySQL.
Populate error value in MySQL on error.
This commit is contained in:
Ilia Alshanetsky 2004-05-19 17:35:39 +00:00
parent 5a4c3234b9
commit 074ba3fbc0
6 changed files with 84 additions and 24 deletions

View File

@ -287,10 +287,31 @@ static PHP_METHOD(PDO, affectedRows)
RETURN_FALSE;
}
RETURN_LONG(dbh->affected_rows);
if (!dbh->methods->affected) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver affected rows retrieval.");
} else {
RETURN_LONG(dbh->methods->affected(dbh));
}
}
/* }}} */
/* {{{ proto int PDO::lastInsertId()
Returns the number id of rows that we affected by the last call to PDO::exec(). Not always meaningful. */
static PHP_METHOD(PDO, lastInsertId)
{
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
if (ZEND_NUM_ARGS()) {
RETURN_FALSE;
}
if (!dbh->methods->last_id) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This driver last inserted id retrieval.");
} else {
RETURN_LONG(dbh->methods->last_id(dbh));
}
}
/* }}} */
function_entry pdo_dbh_functions[] = {
PHP_ME(PDO, prepare, NULL, ZEND_ACC_PUBLIC)
@ -300,6 +321,7 @@ function_entry pdo_dbh_functions[] = {
PHP_ME(PDO, setAttribute, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, exec, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, affectedRows, NULL, ZEND_ACC_PUBLIC)
PHP_ME(PDO, lastInsertId, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};

View File

@ -1,5 +1,5 @@
/* Generated by re2c 0.5 on Tue May 18 12:42:13 2004 */
#line 1 "/home/george/src/pecl/pdo/pdo_sql_parser.re"
/* Generated by re2c 0.5 on Tue May 18 15:32:50 2004 */
#line 1 "/home/rei/php5/ext/pdo/pdo_sql_parser.re"
/*
+----------------------------------------------------------------------+
| PHP Version 5 |

View File

@ -114,7 +114,7 @@ typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh TSRMLS_DC);
typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, const char *sql, long sql_len, pdo_stmt_t *stmt, long options, zval *driver_options TSRMLS_DC);
/* execute a statement (that does not return a result set) */
typedef int (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, int sql_len TSRMLS_DC);
typedef int (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC);
/* quote a string */
typedef int (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC);
@ -125,6 +125,12 @@ typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
/* setting and getting of attributes */
typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
/* return affected rows */
typedef long (*pdo_dbh_affected_func)(pdo_dbh_t *dbh TSRMLS_DC);
/* return last insert id */
typedef long (*pdo_dbh_last_id_func)(pdo_dbh_t *dbh TSRMLS_DC);
struct pdo_dbh_methods {
pdo_dbh_close_func closer;
pdo_dbh_prepare_func preparer;
@ -134,6 +140,8 @@ struct pdo_dbh_methods {
pdo_dbh_txn_func commit;
pdo_dbh_txn_func rollback;
pdo_dbh_set_attr_func set_attribute;
pdo_dbh_affected_func affected;
pdo_dbh_last_id_func last_id;
};
/* }}} */
@ -231,10 +239,6 @@ struct _pdo_dbh_t {
const char *data_source;
unsigned long data_source_len;
/* the number of rows affected by last $dbh->exec(). Not always
* meaningful */
int affected_rows;
/* the global error code. */
enum pdo_error_type error_code;
#if 0

View File

@ -55,6 +55,10 @@ static int mysql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
mysql_close(H->server);
H->server = NULL;
}
if (H->mysql_error) {
efree(H->mysql_error);
H->mysql_error = NULL;
}
return 0;
}
/* }}} */
@ -71,11 +75,31 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, long sql_len,
return 1;
}
static int mysql_handle_doer(pdo_dbh_t *dbh, const char *sql TSRMLS_DC)
static int mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRMLS_DC)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
return 0;
if (mysql_real_query(H->server, sql, sql_len)) {
pdo_mysql_error(H);
return 0;
} else {
return 1;
}
}
static long pdo_mysql_affected_rows(pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
my_ulonglong afr = mysql_affected_rows(H->server);
return afr == (my_ulonglong) - 1 ? 0 : (long) afr;
}
static long pdo_mysql_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
return (long) mysql_insert_id(H->server);
}
static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen TSRMLS_DC)
@ -95,7 +119,13 @@ static struct pdo_dbh_methods mysql_methods = {
mysql_handle_closer,
mysql_handle_preparer,
mysql_handle_doer,
mysql_handle_quoter
mysql_handle_quoter,
NULL,
NULL,
NULL,
NULL,
pdo_mysql_affected_rows,
pdo_mysql_last_insert_id
};
static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC) /* {{{ */
@ -120,7 +150,8 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
/* allocate an environment */
/* handle for the server */
dbh->driver_data = H->server = mysql_init(NULL);
H->server = mysql_init(NULL);
dbh->driver_data = H;
if(vars[2].optval && strcmp("localhost", vars[2].optval)) {
host = vars[2].optval;
port = atoi(vars[3].optval);
@ -131,8 +162,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
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);
pdo_mysql_error(H);
goto cleanup;
}
@ -154,10 +184,6 @@ cleanup:
}
}
if (!ret) {
mysql_handle_closer(dbh TSRMLS_CC);
}
return ret;
}
/* }}} */

View File

@ -65,13 +65,11 @@ static int mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
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);
pdo_mysql_error(H);
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);
pdo_mysql_error(H);
return 0;
}
if(!stmt->executed) {
@ -94,6 +92,7 @@ static int mysql_stmt_fetch(pdo_stmt_t *stmt TSRMLS_DC)
if((S->current_data = mysql_fetch_row(S->result)) == NULL) {
/* there seems to be no way of distinguishing 'no data' from 'error' */
pdo_mysql_error(S->H);
return 0;
}
S->current_lengths = mysql_fetch_lengths(S->result);
@ -137,7 +136,7 @@ static int mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsigned
}
if(colno >= mysql_num_fields(S->result)) {
/* error invalid column */
pdo_mysql_error("invalid column", 0);
pdo_mysql_error(S->H);
return 0;
}
*ptr = estrndup(S->current_data[colno], S->current_lengths[colno] +1);

View File

@ -27,6 +27,8 @@
typedef struct {
MYSQL *server;
int last_err;
unsigned int mysql_errno;
char *mysql_error;
unsigned attached:1;
unsigned _reserved:31;
} pdo_mysql_db_handle;
@ -54,7 +56,14 @@ typedef struct {
extern pdo_driver_t pdo_mysql_driver;
extern int _pdo_mysql_error(char *what, int mysql_errno, const char *file, int line TSRMLS_DC);
#define pdo_mysql_error(w,s) _pdo_mysql_error(w, s, __FILE__, __LINE__ TSRMLS_CC)
#define pdo_mysql_error(s) \
s->mysql_errno = mysql_errno(s->server); \
if (s->mysql_error) { \
efree(s->mysql_error); \
} \
s->mysql_error = estrdup(mysql_error(s->server));
extern int mysql_handle_error(pdo_dbh_t *dbh, pdo_mysql_db_handle *H, int errcode);
extern struct pdo_stmt_methods mysql_stmt_methods;