]> granicus.if.org Git - php/commitdiff
Improve FR #31021 implementation (pg_last_notice() is needed to get all notice messages).
authorYasuo Ohgaki <yohgaki@php.net>
Fri, 18 Dec 2015 04:04:34 +0000 (13:04 +0900)
committerYasuo Ohgaki <yohgaki@php.net>
Fri, 18 Dec 2015 04:04:34 +0000 (13:04 +0900)
Now pg_last_notice() can clear stored notices.

UPGRADING
ext/pgsql/pgsql.c
ext/pgsql/tests/09notice.phpt

index e7a6856744e35c91ef97794249353c4236806f4f..b77d8aa7ba2ffc04edeb9d8a1372f018f8badaf9 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -46,9 +46,12 @@ PHP 7.1 UPGRADE NOTES
   current environment variables will be returned as an associative array
   when omitted.
 - long2ip() accepts integer as parameter now
-- pg_last_notice() accepts optional 2nd bool parameter to get all notices and
-  returns empty string or array on successful calls. It returned FALSE for
-  empty notice previously.
+- pg_last_notice() accepts optional long parameter to specify operation.
+  PGSQL_NOTICE_LAST - Get last notice (Default)
+  PGSQL_NOTICE_ALL - Get all stored notices
+  PGSQL_NOTICE_CLEAR - Remove all stored notices
+  It returns empty string or array on successful PGSQL_NOTICE_LAST/ALL calls.
+  It returned FALSE for empty notice previously.
 - pg_fetch_all() accepts optional 2nd bool parameter to get numerically indexed
   rows.
 - pg_select() accepts PGSQL_FETCH_NUM option to get numerically indexed rows.
@@ -73,6 +76,11 @@ PHP 7.1 UPGRADE NOTES
 10. New Global Constants
 ========================================
 
+- Pgsql:
+  PGSQL_NOTICE_LAST
+  PGSQL_NOTICE_ALL
+  PGSQL_NOTICE_CLEAR
+
 ========================================
 11. Changes to INI File Handling
 ========================================
index 812a2d5fc0d1e621644df564713316ca90d28b11..173998c57fc6d8ba44fe27e32ebd0e44d0cc60b9 100644 (file)
 #define InvalidOid ((Oid) 0)
 #endif
 
-#define PGSQL_ASSOC            1<<0
-#define PGSQL_NUM              1<<1
-#define PGSQL_BOTH             (PGSQL_ASSOC|PGSQL_NUM)
+#define PGSQL_ASSOC           1<<0
+#define PGSQL_NUM             1<<1
+#define PGSQL_BOTH            (PGSQL_ASSOC|PGSQL_NUM)
+
+#define PGSQL_NOTICE_LAST     1  /* Get the last notice */
+#define PGSQL_NOTICE_ALL      2  /* Get all notices */
+#define PGSQL_NOTICE_CLEAR    3  /* Remove notices */
 
 #define PGSQL_STATUS_LONG     1
 #define PGSQL_STATUS_STRING   2
@@ -208,7 +212,7 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_last_notice, 0, 0, 1)
        ZEND_ARG_INFO(0, connection)
-       ZEND_ARG_INFO(0, all_notices)
+       ZEND_ARG_INFO(0, option)
 ZEND_END_ARG_INFO()
 
 #ifdef HAVE_PQFTABLE
@@ -1120,6 +1124,10 @@ PHP_MINIT_FUNCTION(pgsql)
        REGISTER_LONG_CONSTANT("PGSQL_ASSOC", PGSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT);
+       /* For pg_last_notice() */
+       REGISTER_LONG_CONSTANT("PGSQL_NOTICE_LAST", PGSQL_NOTICE_LAST, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("PGSQL_NOTICE_ALL", PGSQL_NOTICE_ALL, CONST_CS | CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("PGSQL_NOTICE_CLEAR", PGSQL_NOTICE_CLEAR, CONST_CS | CONST_PERSISTENT);
        /* For pg_connection_status() */
        REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT);
@@ -2304,16 +2312,16 @@ PHP_FUNCTION(pg_affected_rows)
 /* }}} */
 #endif
 
-/* {{{ proto mixed pg_last_notice(resource connection [, bool all_notices])
+/* {{{ proto mixed pg_last_notice(resource connection [, long option])
    Returns the last notice set by the backend */
 PHP_FUNCTION(pg_last_notice)
 {
        zval *pgsql_link = NULL;
        zval *notice, *notices;
        PGconn *pg_link;
-       zend_bool all_notices = 0;
+       long option = PGSQL_NOTICE_LAST;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|b", &pgsql_link, &all_notices) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &pgsql_link, &option) == FAILURE) {
                return;
        }
 
@@ -2322,26 +2330,37 @@ PHP_FUNCTION(pg_last_notice)
                RETURN_FALSE;
        }
 
-       /* PHP 7.0 and earlier returns FALSE for empty notice.
-          PHP 7.1> returns empty array or string */
        notices = zend_hash_index_find(&PGG(notices), (zend_ulong)Z_RES_HANDLE_P(pgsql_link));
-       if (all_notices) {
-               if (notices) {
-                       RETURN_ZVAL(notices, 1, 0);
-               } else {
-                       array_init(return_value);
-               }
-       } else {
-               if (notices) {
-                       zend_hash_internal_pointer_end(Z_ARRVAL_P(notices));
-                       if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) {
+       switch (option) {
+               case PGSQL_NOTICE_LAST:
+                       if (notices) {
+                               zend_hash_internal_pointer_end(Z_ARRVAL_P(notices));
+                               if ((notice = zend_hash_get_current_data(Z_ARRVAL_P(notices))) == NULL) {
+                                       RETURN_EMPTY_STRING();
+                               }
+                               RETURN_ZVAL(notice, 1, 0);
+                       } else {
                                RETURN_EMPTY_STRING();
                        }
-                       RETURN_ZVAL(notice, 1, 0);
-               } else {
-                       RETURN_EMPTY_STRING();
-               }
+                       break;
+               case PGSQL_NOTICE_ALL:
+                       if (notices) {
+                               RETURN_ZVAL(notices, 1, 0);
+                       } else {
+                               array_init(return_value);
+                               return;
+                       }
+                       break;
+               case PGSQL_NOTICE_CLEAR:
+                       if (notices) {
+                               zend_hash_clean(&PGG(notices));
+                       }
+                       RETURN_TRUE;
+                       break;
+               default:
+                       php_error_docref(NULL, E_WARNING, "Invalid option specified (%d)", option);
        }
+       RETURN_FALSE;
 }
 /* }}} */
 
index c5f9b1df9e0316ae7096eed832bc3a65fabfaccb..fb5dc8325c33476075968ff6a8ac6449d9ce44fc 100644 (file)
@@ -26,7 +26,7 @@ var_dump($res);
 
 // Get empty notice
 var_dump(pg_last_notice($db));
-var_dump(pg_last_notice($db, TRUE));
+var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL));
 
 pg_query($db, "BEGIN;");
 pg_query($db, "BEGIN;");
@@ -35,7 +35,15 @@ pg_query($db, "BEGIN;");
 
 // Get notices
 var_dump(pg_last_notice($db));
-var_dump(pg_last_notice($db, TRUE));
+var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL));
+
+// Clear and get notices
+var_dump(pg_last_notice($db, PGSQL_NOTICE_CLEAR));
+var_dump(pg_last_notice($db, PGSQL_NOTICE_LAST));
+var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL));
+
+// Invalid option
+var_dump(pg_last_notice($db, 99));
 ?>
 --EXPECTF--
 resource(%d) of type (pgsql result)
@@ -57,3 +65,10 @@ array(3) {
   [2]=>
   string(52) "WARNING:  there is already a transaction in progress"
 }
+bool(true)
+string(0) ""
+array(0) {
+}
+
+Warning: pg_last_notice(): Invalid option specified (99) in %s/09notice.php on line %d
+bool(false)