]> granicus.if.org Git - php/commitdiff
Alan: moved your fields away, but reserved you a pointer.
authorWez Furlong <wez@php.net>
Sat, 26 Feb 2005 17:27:51 +0000 (17:27 +0000)
committerWez Furlong <wez@php.net>
Sat, 26 Feb 2005 17:27:51 +0000 (17:27 +0000)
Changed PDO::lastInsertId() to have following proto:

string PDO::lastInsertId([string name])

this allows arbitrary unique identitifers to be returned from the driver.

The optional name parameter is for databases that require additional contextual
information to be able to return the correct identifier.  None currently use
it, but pgsql will be on the list of drivers that do.

ext/pdo/pdo.c
ext/pdo/pdo_dbh.c
ext/pdo/php_pdo_driver.h
ext/pdo_mysql/mysql_driver.c
ext/pdo_pgsql/pgsql_driver.c
ext/pdo_sqlite/sqlite_driver.c

index 36dbd2bd5ca1b81eae8200d2503c86c485bb1ba0..795f8f1e599293a36dffe50fe1b04ea46bdb9e0d 100755 (executable)
@@ -203,7 +203,47 @@ PDO_API int php_pdo_parse_data_source(const char *data_source,
 
        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)
index e979cc06ac8fe88b30d8c7812f675c4992dc7e38..61979b15f63cc913ef28b764997a82052fa37239 100755 (executable)
@@ -752,13 +752,15 @@ static PHP_METHOD(PDO, exec)
 /* }}} */
 
 
-/* {{{ 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;
        }
 
@@ -767,7 +769,13 @@ static PHP_METHOD(PDO, lastInsertId)
                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;
+               }
        }
 }
 /* }}} */
index b0937a3e3f84ae9a63244ba6009487ba801bcaa3..6348349dca4a15fc9d58bffe3b95286349bf368b 100755 (executable)
@@ -28,6 +28,15 @@ typedef struct _pdo_dbh_t    pdo_dbh_t;
 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
@@ -35,7 +44,7 @@ struct pdo_bound_param_data;
 # define FALSE 0
 #endif
 
-#define PDO_DRIVER_API 20050222
+#define PDO_DRIVER_API 20050226
 
 enum pdo_param_type {
        PDO_PARAM_NULL,
@@ -231,8 +240,9 @@ typedef int (*pdo_dbh_txn_func)(pdo_dbh_t *dbh TSRMLS_DC);
 /* 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
@@ -460,10 +470,8 @@ struct pdo_column_data {
        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 */
index fe61f55081fddb4812b811d5ee71a0fd0ee95b95..cd1c8f0b296d14e758311d52bde355f3e229e1d4 100755 (executable)
@@ -160,11 +160,13 @@ static long mysql_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSRM
        }
 }
 
-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)
index 9134ee769a4f1d605f79cac32de1cb1a6a30b339..72b6781f2dfcabcf00994e1ddc7f05f68e58688e 100644 (file)
@@ -197,15 +197,19 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, int unquote
        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)
index 4810cd0da37a5f2297378eb0a888a827d0eb50a6..3fe9426e3c18e55d15ac55a87e4a8f771da878ac 100644 (file)
@@ -156,11 +156,14 @@ static long sqlite_handle_doer(pdo_dbh_t *dbh, const char *sql, long sql_len TSR
        }
 }
 
-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 */