return n_matches;
}
-
+
+static const char digit_vec[] = "0123456789";
+PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC)
+{
+ char buffer[65];
+ char outbuf[65] = "";
+ register char *p;
+ long long_val;
+ char *dst = outbuf;
+
+ if (i64 < 0) {
+ i64 = -i64;
+ *dst++ = '-';
+ }
+
+ if (i64 == 0) {
+ *dst++ = '0';
+ *dst++ = '\0';
+ return estrdup(outbuf);
+ }
+
+ p = &buffer[sizeof(buffer)-1];
+ *p = '\0';
+
+ while ((pdo_uint64_t)i64 > (pdo_uint64_t)LONG_MAX) {
+ pdo_uint64_t quo = (pdo_uint64_t)i64 / (unsigned int)10;
+ unsigned int rem = (unsigned int)(i64 - quo*10U);
+ *--p = digit_vec[rem];
+ i64 = (pdo_int64_t)quo;
+ }
+ long_val = (long)i64;
+ while (long_val != 0) {
+ long quo = long_val / 10;
+ *--p = digit_vec[(unsigned int)(long_val - quo * 10)];
+ long_val = quo;
+ }
+ while ((*dst++ = *p++) != 0)
+ ;
+ *dst = '\0';
+ return estrdup(outbuf);
+}
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(pdo)
/* }}} */
-/* {{{ proto int PDO::lastInsertId()
- Returns the number id of rows that we affected by the last call to PDO::exec(). Not always meaningful. */
+/* {{{ proto string PDO::lastInsertId([string seqname])
+ Returns the id of the last row that we affected on this connection. Some databases require a sequence or table name to be passed in. Not always meaningful. */
static PHP_METHOD(PDO, lastInsertId)
{
pdo_dbh_t *dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ char *name = NULL;
+ int namelen;
- if (ZEND_NUM_ARGS()) {
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &name, &namelen)) {
RETURN_FALSE;
}
pdo_raise_impl_error(dbh, NULL, "IM001", "driver does not support lastInsertId()" TSRMLS_CC);
RETURN_FALSE;
} else {
- RETURN_LONG(dbh->methods->last_id(dbh TSRMLS_CC));
+ Z_STRVAL_P(return_value) = dbh->methods->last_id(dbh, name, &Z_STRLEN_P(return_value) TSRMLS_CC);
+ if (!Z_STRVAL_P(return_value)) {
+ PDO_HANDLE_DBH_ERR();
+ RETURN_FALSE;
+ } else {
+ Z_TYPE_P(return_value) = IS_STRING;
+ }
}
}
/* }}} */
typedef struct _pdo_stmt_t pdo_stmt_t;
struct pdo_bound_param_data;
+#ifdef PHP_WIN32
+typedef __int64 pdo_int64_t;
+typedef unsigned __int64 pdo_uint64_t;
+#else
+typedef long long int pdo_int64_t;
+typedef unsigned long long int pdo_uint64_t;
+#endif
+PDO_API char *php_pdo_int64_to_str(pdo_int64_t i64 TSRMLS_DC);
+
#ifndef TRUE
# define TRUE 1
#endif
# define FALSE 0
#endif
-#define PDO_DRIVER_API 20050222
+#define PDO_DRIVER_API 20050226
enum pdo_param_type {
PDO_PARAM_NULL,
/* setting of attributes */
typedef int (*pdo_dbh_set_attr_func)(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);
-/* return last insert id */
-typedef long (*pdo_dbh_last_id_func)(pdo_dbh_t *dbh TSRMLS_DC);
+/* return last insert id. NULL indicates error condition, otherwise, the return value
+ * MUST be an emalloc'd NULL terminated string. */
+typedef char *(*pdo_dbh_last_id_func)(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC);
/* fetch error information. if stmt is not null, fetch information pertaining
* to the statement, otherwise fetch global error information. The driver
enum pdo_param_type param_type;
unsigned long precision;
- /* don't touch the following fields unless your name is dbdo */
- char *native_type_name;
- int abstract_type;
- int abstract_flags;
+ /* don't touch this unless your name is dbdo */
+ void *dbdo_stuff;
};
/* describes a bound parameter */
}
}
-static long pdo_mysql_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
+static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len, TSRMLS_DC)
{
pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data;
+ char *id = NULL;
- return (long) mysql_insert_id(H->server);
+ *len = spprintf(&id, 0, "%ld", mysql_insert_id(H->server));
+ return id;
}
static int mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquotedlen, char **quoted, int *quotedlen, enum pdo_param_type paramtype TSRMLS_DC)
return 1;
}
-static long pdo_pgsql_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
+static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ char *id = NULL;
if (H->pgoid == InvalidOid) {
- return -1;
+ return NULL;
}
- return (long) H->pgoid;
+ /* TODO: if name != NULL, pull out last value for that sequence/column */
+
+ *len = spprintf(&id, 0, "%ld", H->pgoid);
+ return id;
}
static int pdo_pgsql_get_attribute(pdo_dbh_t *dbh, long attr, zval *return_value TSRMLS_DC)
}
}
-static long pdo_sqlite_last_insert_id(pdo_dbh_t *dbh TSRMLS_DC)
+static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, unsigned int *len TSRMLS_DC)
{
pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data;
-
- return (long) sqlite3_last_insert_rowid(H->db);
+ char *id;
+
+ id = php_pdo_int64_to_str(sqlite3_last_insert_rowid(H->db) TSRMLS_CC);
+ *len = strlen(id);
+ return id;
}
/* NB: doesn't handle binary strings... use prepared stmts for that */