diff --git a/swoole_postgresql_coro.cc b/swoole_postgresql_coro.cc index 8395055..5d1f54c 100644 --- a/swoole_postgresql_coro.cc +++ b/swoole_postgresql_coro.cc @@ -228,12 +228,36 @@ void swoole_postgresql_init(int module_number) le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); zend_declare_property_null(swoole_postgresql_coro_ce, ZEND_STRL("error"), ZEND_ACC_PUBLIC); + zend_declare_property_null(swoole_postgresql_coro_ce, ZEND_STRL("errorInfo"), ZEND_ACC_PUBLIC); SW_REGISTER_LONG_CONSTANT("SW_PGSQL_ASSOC", PGSQL_ASSOC); SW_REGISTER_LONG_CONSTANT("SW_PGSQL_NUM", PGSQL_NUM); SW_REGISTER_LONG_CONSTANT("SW_PGSQL_BOTH", PGSQL_BOTH); } +static void resetError(pg_object *object) +{ + zend_update_property_null(swoole_postgresql_coro_ce, object->object, ZEND_STRL("error")); + zend_update_property_null(swoole_postgresql_coro_ce, object->object, ZEND_STRL("errorInfo")); +} + +static void setErrorFromResult(pg_object *object, PGresult *pgsql_result) +{ + ExecStatusType status = PQresultStatus(pgsql_result); + char *err_msg = PQerrorMessage(object->conn); + char *err_code = PQresultErrorField(pgsql_result, PG_DIAG_SQLSTATE); + + zval errorInfo; + array_init_size(&errorInfo, 3); + + add_index_string(&errorInfo, 0, err_code); + add_index_long(&errorInfo, 1, status); + add_index_string(&errorInfo, 2, err_msg); + + zend_update_property_string(swoole_postgresql_coro_ce, object->object, "error", 5, err_msg); + zend_update_property(swoole_postgresql_coro_ce, object->object, "errorInfo", 9, &errorInfo); +} + static PHP_METHOD(swoole_postgresql_coro, __construct) { } static PHP_METHOD(swoole_postgresql_coro, connect) @@ -427,7 +451,7 @@ static void connect_callback(pg_object *object, swReactor *reactor, swEvent *eve if (object->connected == 1) { - zend_update_property_null(swoole_postgresql_coro_ce, object->object, ZEND_STRL("error")); + resetError(object); } int ret = PHPCoroutine::resume_m(context, &return_value, retval); @@ -537,7 +561,9 @@ static int meta_data_result_parse(pg_object *object) } php_coro_context *context = php_swoole_postgresql_coro_get_context(object->object); - zend_update_property_null(swoole_postgresql_coro_ce, object->object, "error", 5); + + setErrorFromResult(object, pg_result); + int ret = PHPCoroutine::resume_m(context, &return_value, retval); if (ret == SW_CORO_ERR_END && retval) { @@ -554,7 +580,6 @@ static int query_result_parse(pg_object *object) ExecStatusType status; int error = 0; - char *err_msg; int ret, res; zval *retval = NULL; zval return_value; @@ -569,11 +594,12 @@ static int query_result_parse(pg_object *object) case PGRES_BAD_RESPONSE: case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: - err_msg = PQerrorMessage(object->conn); PQclear(pgsql_result); ZVAL_FALSE(&return_value); swoole_event_del(object->fd); - zend_update_property_string(swoole_postgresql_coro_ce, object->object, "error", 5, err_msg); + + setErrorFromResult(object, pgsql_result); + ret = PHPCoroutine::resume_m(context, &return_value, retval); if (ret == SW_CORO_ERR_END && retval) { @@ -588,7 +614,9 @@ static int query_result_parse(pg_object *object) res = PQflush(object->conn); swoole_event_del(object->fd); ZVAL_RES(&return_value, zend_register_resource(object, le_result)); - zend_update_property_null(swoole_postgresql_coro_ce, object->object, "error", 5); + + resetError(object); + ret = PHPCoroutine::resume_m(context, &return_value, retval); if (ret == SW_CORO_ERR_END && retval) { @@ -615,10 +643,25 @@ static int prepare_result_parse(pg_object *object) zval return_value; php_coro_context *context = php_swoole_postgresql_coro_get_context(object->object); + PGresult *pgsql_result = PQgetResult(object->conn); + ExecStatusType status = PQresultStatus(pgsql_result); + + if (status != PGRES_COMMAND_OK) { + setErrorFromResult(object, pgsql_result); + + ZVAL_FALSE(&return_value); + } else { + resetError(object); + + ZVAL_TRUE(&return_value); + } + + PQclear(pgsql_result); + /* Wait to finish sending buffer */ //res = PQflush(object->conn); - ZVAL_TRUE(&return_value); swoole_event_del(object->fd); + ret = PHPCoroutine::resume_m(context, &return_value, retval); if (ret == SW_CORO_END && retval) @@ -1338,6 +1381,7 @@ static int swoole_pgsql_coro_onError(swReactor *reactor, swEvent *event) ZVAL_FALSE(result); php_coro_context *context = php_swoole_postgresql_coro_get_context(zobject); + zend_update_property_string(swoole_postgresql_coro_ce, zobject, "error", 5, "onerror"); int ret = PHPCoroutine::resume_m(context, result, retval); zval_ptr_dtor(result);