guard against uninitialized property write, too
[m6w6/ext-pq] / src / php_pqconn.c
index 4378404eb98ba3a9fcd6d8788f672473ff5bc7ba..c4d6c806341de53295bfec4bc1a2578144a732be 100644 (file)
@@ -219,7 +219,7 @@ static void php_pqconn_object_write_encoding(zval *object, void *o, zval *value
        }
 
        if (0 > PQsetClientEncoding(obj->intern->conn, Z_STRVAL_P(zenc))) {
        }
 
        if (0 > PQsetClientEncoding(obj->intern->conn, Z_STRVAL_P(zenc))) {
-               zend_error(E_NOTICE, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc));
+               php_error(E_NOTICE, "Unrecognized encoding '%s'", Z_STRVAL_P(zenc));
        }
 
        if (zenc != value) {
        }
 
        if (zenc != value) {
@@ -372,7 +372,7 @@ static void php_pqconn_object_write_def_fetch_type(zval *object, void *o, zval *
                }
        }
 
                }
        }
 
-       obj->intern->default_fetch_type = Z_LVAL_P(zft) & 0x2; /* two bits only */
+       obj->intern->default_fetch_type = Z_LVAL_P(zft) & 0x3; /* two bits only */
 
        if (zft != value) {
                zval_ptr_dtor(&zft);
 
        if (zft != value) {
                zval_ptr_dtor(&zft);
@@ -402,7 +402,7 @@ static void php_pqconn_object_write_def_txn_isolation(zval *object, void *o, zva
                }
        }
 
                }
        }
 
-       obj->intern->default_txn_isolation = Z_LVAL_P(zti) & 0x2; /* two bits only */
+       obj->intern->default_txn_isolation = Z_LVAL_P(zti) & 0x3; /* two bits only */
 
        if (zti != value) {
                zval_ptr_dtor(&zti);
 
        if (zti != value) {
                zval_ptr_dtor(&zti);
@@ -435,6 +435,36 @@ static void php_pqconn_object_write_def_txn_deferrable(zval *object, void *o, zv
        obj->intern->default_txn_deferrable = zend_is_true(value);
 }
 
        obj->intern->default_txn_deferrable = zend_is_true(value);
 }
 
+static void php_pqconn_object_read_def_auto_conv(zval *object, void *o, zval *return_value TSRMLS_DC)
+{
+       php_pqconn_object_t *obj = o;
+
+       RETVAL_LONG(obj->intern->default_auto_convert);
+}
+static void php_pqconn_object_write_def_auto_conv(zval*object, void *o, zval *value TSRMLS_DC)
+{
+       php_pqconn_object_t *obj = o;
+       zval *zac = value;
+
+       if (Z_TYPE_P(zac) != IS_LONG) {
+               if (Z_REFCOUNT_P(zac) > 1) {
+                       zval *tmp;
+                       MAKE_STD_ZVAL(tmp);
+                       ZVAL_ZVAL(tmp, zac, 1, 0);
+                       convert_to_long(tmp);
+                       zac = tmp;
+               } else {
+                       convert_to_long_ex(&zac);
+               }
+       }
+
+       obj->intern->default_auto_convert = Z_LVAL_P(zac) & 0xff;
+
+       if (zac != value) {
+               zval_ptr_dtor(&zac);
+       }
+}
+
 static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC)
 {
        zval *zsocket, zmember;
 static STATUS php_pqconn_update_socket(zval *this_ptr, php_pqconn_object_t *obj TSRMLS_DC)
 {
        zval *zsocket, zmember;
@@ -511,7 +541,12 @@ php_resource_factory_ops_t *php_pqconn_get_resource_factory_ops(void)
 
 static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC)
 {
 
 static void php_pqconn_wakeup(php_persistent_handle_factory_t *f, void **handle TSRMLS_DC)
 {
-       // FIXME: ping server
+       PGresult *res = PQexec(*handle, "");
+       PHP_PQclear(res);
+
+       if (CONNECTION_OK != PQstatus(*handle)) {
+               PQreset(*handle);
+       }
 }
 
 static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len TSRMLS_DC)
 }
 
 static inline PGresult *unlisten(PGconn *conn, const char *channel_str, size_t channel_len TSRMLS_DC)
@@ -590,7 +625,6 @@ static void php_pqconn_retire(php_persistent_handle_factory_t *f, void **handle
                zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj);
 
                /* release instance data */
                zend_hash_apply_with_arguments(&evdata->obj->intern->listeners TSRMLS_CC, apply_unlisten, 1, evdata->obj);
 
                /* release instance data */
-               //memset(evdata, 0, sizeof(*evdata));
                efree(evdata);
        }
 }
                efree(evdata);
        }
 }
@@ -621,6 +655,8 @@ static PHP_METHOD(pqconn, __construct) {
 
                        obj->intern = ecalloc(1, sizeof(*obj->intern));
 
 
                        obj->intern = ecalloc(1, sizeof(*obj->intern));
 
+                       obj->intern->default_auto_convert = PHP_PQRES_CONV_ALL;
+
                        zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
                        zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0);
                        zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
                        zend_hash_init(&obj->intern->listeners, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
                        zend_hash_init(&obj->intern->converters, 0, NULL, ZVAL_PTR_DTOR, 0);
                        zend_hash_init(&obj->intern->eventhandlers, 0, NULL, (dtor_func_t) zend_hash_destroy, 0);
@@ -2020,6 +2056,12 @@ PHP_MINIT_FUNCTION(pqconn)
        zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL);
        ph.write = NULL;
 
        zend_hash_add(&php_pqconn_object_prophandlers, "defaultTransactionDeferrable", sizeof("defaultTransactionDeferrable"), (void *) &ph, sizeof(ph), NULL);
        ph.write = NULL;
 
+       zend_declare_property_long(php_pqconn_class_entry, ZEND_STRL("defaultAutoConvert"), PHP_PQRES_CONV_ALL, ZEND_ACC_PUBLIC TSRMLS_CC);
+       ph.read = php_pqconn_object_read_def_auto_conv;
+       ph.write = php_pqconn_object_write_def_auto_conv;
+       zend_hash_add(&php_pqconn_object_prophandlers, "defaultAutoConvert", sizeof("defaultAutoConvert"), (void *) &ph, sizeof(ph), NULL);
+       ph.write = NULL;
+
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC);
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC);
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC);
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("OK"), CONNECTION_OK TSRMLS_CC);
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("BAD"), CONNECTION_BAD TSRMLS_CC);
        zend_declare_class_constant_long(php_pqconn_class_entry, ZEND_STRL("STARTED"), CONNECTION_STARTED TSRMLS_CC);