mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Added async query functions
This commit is contained in:
parent
b11d1eb440
commit
db8bb9f23c
2 changed files with 294 additions and 3 deletions
|
@ -94,6 +94,12 @@ function_entry pgsql_functions[] = {
|
|||
PHP_FALIAS(pg_clientencoding, pg_client_encoding, NULL)
|
||||
PHP_FALIAS(pg_setclientencoding, pg_set_client_encoding, NULL)
|
||||
#endif
|
||||
PHP_FE(pg_reset, NULL)
|
||||
PHP_FE(pg_status, NULL)
|
||||
PHP_FE(pg_send_query, NULL)
|
||||
PHP_FE(pg_request_cancel, NULL)
|
||||
PHP_FE(pg_get_result, NULL)
|
||||
PHP_FE(pg_is_busy, NULL)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
@ -147,7 +153,17 @@ static void php_pgsql_set_default_link(int id)
|
|||
static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
PGconn *link = (PGconn *)rsrc->ptr;
|
||||
PGresult *res;
|
||||
|
||||
PQsetnonblocking(link,1);
|
||||
if (PQisBusy(link)) {
|
||||
if (!PQrequestCancel(link)) {
|
||||
php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", PQerrorMessage(link));
|
||||
}
|
||||
}
|
||||
while ((res = PQgetResult(link))) {
|
||||
PQclear(res);
|
||||
}
|
||||
PQfinish(link);
|
||||
PGG(num_links)--;
|
||||
}
|
||||
|
@ -158,7 +174,17 @@ static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
|||
static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
PGconn *link = (PGconn *)rsrc->ptr;
|
||||
PGresult *res;
|
||||
|
||||
PQsetnonblocking(link,1);
|
||||
if (PQisBusy(link)) {
|
||||
if (!PQrequestCancel(link)) {
|
||||
php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", PQerrorMessage(link));
|
||||
}
|
||||
}
|
||||
while ((res = PQgetResult(link))) {
|
||||
PQclear(res);
|
||||
}
|
||||
PQfinish(link);
|
||||
PGG(num_persistent)--;
|
||||
PGG(num_links)--;
|
||||
|
@ -187,12 +213,22 @@ static void _notice_handler(void *arg, const char *message)
|
|||
static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC)
|
||||
{
|
||||
PGconn *link;
|
||||
PGresult *res;
|
||||
|
||||
if (Z_TYPE_P(rsrc) != le_plink)
|
||||
return 0;
|
||||
|
||||
link = (PGconn *) rsrc->ptr;
|
||||
|
||||
PQsetnonblocking(link,1);
|
||||
if (PQisBusy(link)) {
|
||||
if (!PQrequestCancel(link)) {
|
||||
php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", PQerrorMessage(link));
|
||||
}
|
||||
}
|
||||
while ((res = PQgetResult(link))) {
|
||||
PQclear(res);
|
||||
}
|
||||
PGG(ignore_notices) = 1;
|
||||
PQexec(link,"BEGIN;ROLLBACK;");
|
||||
PGG(ignore_notices) = 0;
|
||||
|
@ -262,6 +298,9 @@ PHP_MINIT_FUNCTION(pgsql)
|
|||
REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -717,11 +756,12 @@ PHP_FUNCTION(pg_exec)
|
|||
{
|
||||
zval **query, **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
int leftover = 0;
|
||||
PGconn *pgsql;
|
||||
PGresult *pgsql_result;
|
||||
ExecStatusType status;
|
||||
pgsql_result_handle *pg_result;
|
||||
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &query)==FAILURE) {
|
||||
|
@ -743,6 +783,17 @@ PHP_FUNCTION(pg_exec)
|
|||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
|
||||
convert_to_string_ex(query);
|
||||
if (PQisBusy(pgsql)) {
|
||||
php_error(E_NOTICE,"PostgreSQL: Cannot execute query while executing async query.");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
while ((pgsql_result = PQgetResult(pgsql))) {
|
||||
PQclear(pgsql_result);
|
||||
leftover = 1;
|
||||
}
|
||||
if (leftover) {
|
||||
php_error(E_WARNING,"PostgreSQL: There are results on this connection. Use pg_get_result() to get results");
|
||||
}
|
||||
pgsql_result = PQexec(pgsql, Z_STRVAL_PP(query));
|
||||
|
||||
if (pgsql_result) {
|
||||
|
@ -751,7 +802,6 @@ PHP_FUNCTION(pg_exec)
|
|||
status = (ExecStatusType) PQstatus(pgsql);
|
||||
}
|
||||
|
||||
|
||||
switch (status) {
|
||||
case PGRES_EMPTY_QUERY:
|
||||
case PGRES_BAD_RESPONSE:
|
||||
|
@ -816,6 +866,8 @@ PHP_FUNCTION(pg_end_copy)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
#define COPYBUFSIZ 8192
|
||||
|
||||
/* {{{ proto int pg_put_line([int connection,] string query)
|
||||
Send null-terminated string to backend server*/
|
||||
PHP_FUNCTION(pg_put_line)
|
||||
|
@ -1962,7 +2014,240 @@ PHP_FUNCTION(pg_client_encoding)
|
|||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
|
||||
/* {{{ proto long pg_status(resource conn)
|
||||
Get connection status */
|
||||
PHP_FUNCTION(pg_status)
|
||||
{
|
||||
zval **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
PGconn *pgsql;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 0:
|
||||
id = PGG(default_link);
|
||||
CHECK_DEFAULT_LINK(id);
|
||||
break;
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
Z_LVAL_P(return_value) = PQstatus(pgsql);
|
||||
Z_TYPE_P(return_value) = IS_LONG;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool pg_reset(resource conn)
|
||||
Reset connection */
|
||||
PHP_FUNCTION(pg_reset)
|
||||
{
|
||||
zval **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
PGconn *pgsql;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 0:
|
||||
id = PGG(default_link);
|
||||
CHECK_DEFAULT_LINK(id);
|
||||
break;
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
}
|
||||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
PQreset(pgsql);
|
||||
if (PQstatus(pgsql) == CONNECTION_BAD) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Following functions are for asyncronous query
|
||||
* Report bugs to yasuo_ohgaki@yahoo.com
|
||||
*/
|
||||
#define PHP_PG_ASYNC_IS_BUSY 1
|
||||
#define PHP_PG_ASYNC_REQUEST_CANCEL 2
|
||||
|
||||
/* {{{ php_pgsql_do_async
|
||||
*/
|
||||
void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
|
||||
{
|
||||
zval **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
PGconn *pgsql;
|
||||
PGresult *pgsql_result;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 0:
|
||||
id = PGG(default_link);
|
||||
CHECK_DEFAULT_LINK(id);
|
||||
break;
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
|
||||
switch(entry_type) {
|
||||
case PHP_PG_ASYNC_IS_BUSY:
|
||||
PQconsumeInput(pgsql);
|
||||
Z_LVAL_P(return_value) = PQisBusy(pgsql);
|
||||
Z_TYPE_P(return_value) = IS_LONG;
|
||||
break;
|
||||
case PHP_PG_ASYNC_REQUEST_CANCEL:
|
||||
Z_LVAL_P(return_value) = PQrequestCancel(pgsql);
|
||||
Z_TYPE_P(return_value) = IS_LONG;
|
||||
while ((pgsql_result = PQgetResult(pgsql))) {
|
||||
PQclear(pgsql_result);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
php_error(E_ERROR,"Pgsql module error. Report this error");
|
||||
break;
|
||||
}
|
||||
convert_to_boolean_ex(&return_value);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool pg_async_request_cancel([resource connection])
|
||||
Cancel request */
|
||||
PHP_FUNCTION(pg_request_cancel)
|
||||
{
|
||||
php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_ASYNC_REQUEST_CANCEL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto query bool pg_isbusy([resource connection])
|
||||
Get connection is busy or not */
|
||||
PHP_FUNCTION(pg_is_busy)
|
||||
{
|
||||
php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_PG_ASYNC_IS_BUSY);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto bool pg_async_exec([resource connection], string qeury)
|
||||
Send asynchronous query */
|
||||
PHP_FUNCTION(pg_send_query)
|
||||
{
|
||||
zval **query, **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
PGconn *pgsql;
|
||||
PGresult *res;
|
||||
int leftover = 0;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &query)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
id = PGG(default_link);
|
||||
CHECK_DEFAULT_LINK(id);
|
||||
break;
|
||||
case 2:
|
||||
if (zend_get_parameters_ex(2, &pgsql_link, &query)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
|
||||
convert_to_string_ex(query);
|
||||
if (PQsetnonblocking(pgsql, 1)) {
|
||||
php_error(E_NOTICE,"PostgreSQL: Cannot set connection to nonblocking mode in pg_send_query()");
|
||||
}
|
||||
if (PQisBusy(pgsql)) {
|
||||
php_error(E_WARNING,"PostgreSQL: Cannot send multiple query using pg_send_query()");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
while ((res = PQgetResult(pgsql))) {
|
||||
PQclear(res);
|
||||
leftover = 1;
|
||||
}
|
||||
if (leftover) {
|
||||
php_error(E_NOTICE,"PostgreSQL: There are results on this connection. Call pg_get_result() until it returns false");
|
||||
}
|
||||
if (!PQsendQuery(pgsql, Z_STRVAL_PP(query))) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (PQsetnonblocking(pgsql, 0)) {
|
||||
php_error(E_NOTICE,"PostgreSQL: Cannot set connection to blocking mode in pg_send_query()");
|
||||
}
|
||||
RETURN_TRUE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
/* {{{ proto query resouce pg_arync_result([resource connection])
|
||||
Get asynchronous query result */
|
||||
PHP_FUNCTION(pg_get_result)
|
||||
{
|
||||
zval **pgsql_link = NULL;
|
||||
int id = -1;
|
||||
PGconn *pgsql;
|
||||
PGresult *pgsql_result;
|
||||
pgsql_result_handle *pg_result;
|
||||
|
||||
switch(ZEND_NUM_ARGS()) {
|
||||
case 0:
|
||||
id = PGG(default_link);
|
||||
CHECK_DEFAULT_LINK(id);
|
||||
break;
|
||||
case 1:
|
||||
if (zend_get_parameters_ex(1, &pgsql_link)==FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WRONG_PARAM_COUNT;
|
||||
break;
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL link", le_link, le_plink);
|
||||
if (PQsetnonblocking(pgsql, 1)) {
|
||||
php_error(E_NOTICE,"PostgreSQL: Cannot set connection to nonblocking mode in pg_get_result()");
|
||||
}
|
||||
pgsql_result = PQgetResult(pgsql);
|
||||
if (!pgsql_result) {
|
||||
/* no result */
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (PQsetnonblocking(pgsql, 0)) {
|
||||
php_error(E_NOTICE,"PostgreSQL: Cannot set connection to blocking mode in pg_get_result()");
|
||||
}
|
||||
pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
|
||||
pg_result->conn = pgsql;
|
||||
pg_result->result = pgsql_result;
|
||||
pg_result->row = -1;
|
||||
ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -94,6 +94,12 @@ PHP_FUNCTION(pg_end_copy);
|
|||
PHP_FUNCTION(pg_client_encoding);
|
||||
PHP_FUNCTION(pg_set_client_encoding);
|
||||
#endif
|
||||
PHP_FUNCTION(pg_reset);
|
||||
PHP_FUNCTION(pg_status);
|
||||
PHP_FUNCTION(pg_send_query);
|
||||
PHP_FUNCTION(pg_request_cancel);
|
||||
PHP_FUNCTION(pg_get_result);
|
||||
PHP_FUNCTION(pg_is_busy);
|
||||
|
||||
void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);
|
||||
int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS);
|
||||
|
@ -102,7 +108,7 @@ void php_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
|
|||
char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list);
|
||||
void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
|
||||
void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
|
||||
|
||||
void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS,int entry_type);
|
||||
|
||||
typedef struct pgLofp {
|
||||
PGconn *conn;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue