Made affectedRows() work for MySQL.
Populate error value in MySQL on error.
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)
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}
};
-/* 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 |
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);
/* 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;
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;
};
/* }}} */
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
mysql_close(H->server);
H->server = NULL;
}
+ if (H->mysql_error) {
+ efree(H->mysql_error);
+ H->mysql_error = NULL;
+ }
return 0;
}
/* }}} */
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)
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) /* {{{ */
/* 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);
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;
}
}
}
- if (!ret) {
- mysql_handle_closer(dbh TSRMLS_CC);
- }
-
return ret;
}
/* }}} */
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) {
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);
}
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);
typedef struct {
MYSQL *server;
int last_err;
+ unsigned int mysql_errno;
+ char *mysql_error;
unsigned attached:1;
unsigned _reserved:31;
} pdo_mysql_db_handle;
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;