[PHP-dev 125] Re: [patch] pgsql async query
Yasuo Ohgaki
php-dev@php.gr.jp
Sun, 25 Nov 2001 19:03:06 +0900
This is a multi-part message in MIME format.
------=_NextPart_000_00AD_01C175E3.D0EC2F10
Content-Type: text/plain;
charset="iso-2022-jp"
Content-Transfer-Encoding: 7bit
A few changes,
- pg_reset() returns boolean value now
- added more cleanup for leftover
Comments are welcome.
PS: If you have problem with attachment, please let me know.
--
Yasuo Ohgaki
------=_NextPart_000_00AD_01C175E3.D0EC2F10
Content-Type: application/octet-stream;
name="pgsql_async.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="pgsql_async.diff"
Index: pgsql.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /repository/php4/ext/pgsql/pgsql.c,v=0A=
retrieving revision 1.130=0A=
diff -u -r1.130 pgsql.c=0A=
--- pgsql.c 11 Oct 2001 23:33:40 -0000 1.130=0A=
+++ pgsql.c 25 Nov 2001 09:35:22 -0000=0A=
@@ -94,6 +94,12 @@=0A=
PHP_FALIAS(pg_clientencoding, pg_client_encoding, NULL)=0A=
PHP_FALIAS(pg_setclientencoding, pg_set_client_encoding, NULL)=0A=
#endif=0A=
+ PHP_FE(pg_reset, NULL)=0A=
+ PHP_FE(pg_status, NULL)=0A=
+ PHP_FE(pg_send_query, NULL)=0A=
+ PHP_FE(pg_request_cancel, NULL)=0A=
+ PHP_FE(pg_get_result, NULL)=0A=
+ PHP_FE(pg_is_busy, NULL)=0A=
{NULL, NULL, NULL}=0A=
};=0A=
/* }}} */=0A=
@@ -147,7 +153,17 @@=0A=
static void _close_pgsql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)=0A=
{=0A=
PGconn *link =3D (PGconn *)rsrc->ptr;=0A=
+ PGresult *res;=0A=
=0A=
+ PQsetnonblocking(link,1);=0A=
+ if (PQisBusy(link)) {=0A=
+ if (!PQrequestCancel(link)) {=0A=
+ php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", =
PQerrorMessage(link));=0A=
+ }=0A=
+ }=0A=
+ while ((res =3D PQgetResult(link))) {=0A=
+ PQclear(res);=0A=
+ }=0A=
PQfinish(link);=0A=
PGG(num_links)--;=0A=
}=0A=
@@ -158,7 +174,17 @@=0A=
static void _close_pgsql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)=0A=
{=0A=
PGconn *link =3D (PGconn *)rsrc->ptr;=0A=
+ PGresult *res;=0A=
=0A=
+ PQsetnonblocking(link,1);=0A=
+ if (PQisBusy(link)) {=0A=
+ if (!PQrequestCancel(link)) {=0A=
+ php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", =
PQerrorMessage(link));=0A=
+ }=0A=
+ }=0A=
+ while ((res =3D PQgetResult(link))) {=0A=
+ PQclear(res);=0A=
+ }=0A=
PQfinish(link);=0A=
PGG(num_persistent)--;=0A=
PGG(num_links)--;=0A=
@@ -187,12 +213,22 @@=0A=
static int _rollback_transactions(zend_rsrc_list_entry *rsrc TSRMLS_DC)=0A=
{=0A=
PGconn *link;=0A=
+ PGresult *res;=0A=
=0A=
if (Z_TYPE_P(rsrc) !=3D le_plink) =0A=
return 0;=0A=
=0A=
link =3D (PGconn *) rsrc->ptr;=0A=
=0A=
+ PQsetnonblocking(link,1);=0A=
+ if (PQisBusy(link)) {=0A=
+ if (!PQrequestCancel(link)) {=0A=
+ php_error(E_WARNING,"PostgreSQL: failed to cancel qeury. %s", =
PQerrorMessage(link));=0A=
+ }=0A=
+ }=0A=
+ while ((res =3D PQgetResult(link))) {=0A=
+ PQclear(res);=0A=
+ }=0A=
PGG(ignore_notices) =3D 1;=0A=
PQexec(link,"BEGIN;ROLLBACK;");=0A=
PGG(ignore_notices) =3D 0;=0A=
@@ -262,6 +298,9 @@=0A=
REGISTER_LONG_CONSTANT("PGSQL_NUM", PGSQL_NUM, CONST_CS | =
CONST_PERSISTENT);=0A=
REGISTER_LONG_CONSTANT("PGSQL_BOTH", PGSQL_BOTH, CONST_CS | =
CONST_PERSISTENT);=0A=
=0A=
+ REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_BAD", CONNECTION_BAD, =
CONST_CS | CONST_PERSISTENT);=0A=
+ REGISTER_LONG_CONSTANT("PGSQL_CONNECTION_OK", CONNECTION_OK, CONST_CS =
| CONST_PERSISTENT);=0A=
+=0A=
return SUCCESS;=0A=
}=0A=
/* }}} */=0A=
@@ -717,11 +756,12 @@=0A=
{=0A=
zval **query, **pgsql_link =3D NULL;=0A=
int id =3D -1;=0A=
+ int leftover =3D 0;=0A=
PGconn *pgsql;=0A=
PGresult *pgsql_result;=0A=
ExecStatusType status;=0A=
pgsql_result_handle *pg_result;=0A=
-=0A=
+ =0A=
switch(ZEND_NUM_ARGS()) {=0A=
case 1:=0A=
if (zend_get_parameters_ex(1, &query)=3D=3DFAILURE) {=0A=
@@ -743,6 +783,17 @@=0A=
ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
=0A=
convert_to_string_ex(query);=0A=
+ if (PQisBusy(pgsql)) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: Cannot execute query while executing =
async query.");=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ while ((pgsql_result =3D PQgetResult(pgsql))) {=0A=
+ PQclear(pgsql_result);=0A=
+ leftover =3D 1;=0A=
+ }=0A=
+ if (leftover) {=0A=
+ php_error(E_WARNING,"PostgreSQL: There are results on this =
connection. Use pg_get_result() to get results");=0A=
+ }=0A=
pgsql_result =3D PQexec(pgsql, Z_STRVAL_PP(query));=0A=
=0A=
if (pgsql_result) {=0A=
@@ -751,7 +802,6 @@=0A=
status =3D (ExecStatusType) PQstatus(pgsql);=0A=
}=0A=
=0A=
- =0A=
switch (status) {=0A=
case PGRES_EMPTY_QUERY:=0A=
case PGRES_BAD_RESPONSE:=0A=
@@ -1962,7 +2012,240 @@=0A=
}=0A=
/* }}} */=0A=
#endif=0A=
+=0A=
+=0A=
+/* {{{ proto long pg_status(resource conn)=0A=
+ Get connection status */=0A=
+PHP_FUNCTION(pg_status)=0A=
+{=0A=
+ zval **pgsql_link =3D NULL;=0A=
+ int id =3D -1;=0A=
+ PGconn *pgsql;=0A=
+=0A=
+ switch(ZEND_NUM_ARGS()) {=0A=
+ case 0:=0A=
+ id =3D PGG(default_link);=0A=
+ CHECK_DEFAULT_LINK(id);=0A=
+ break;=0A=
+ case 1:=0A=
+ if (zend_get_parameters_ex(1, &pgsql_link)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ WRONG_PARAM_COUNT;=0A=
+ break;=0A=
+ }=0A=
+=0A=
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
+ Z_LVAL_P(return_value) =3D PQstatus(pgsql);=0A=
+ Z_TYPE_P(return_value) =3D IS_LONG;=0A=
+}=0A=
+=0A=
+/* }}} */=0A=
+=0A=
+/* {{{ proto bool pg_reset(resource conn)=0A=
+ Reset connection */=0A=
+PHP_FUNCTION(pg_reset)=0A=
+{=0A=
+ zval **pgsql_link =3D NULL;=0A=
+ int id =3D -1;=0A=
+ PGconn *pgsql;=0A=
+=0A=
+ switch(ZEND_NUM_ARGS()) {=0A=
+ case 0:=0A=
+ id =3D PGG(default_link);=0A=
+ CHECK_DEFAULT_LINK(id);=0A=
+ break;=0A=
+ case 1:=0A=
+ if (zend_get_parameters_ex(1, &pgsql_link)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ WRONG_PARAM_COUNT;=0A=
+ break;=0A=
+ }=0A=
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
+ PQreset(pgsql);=0A=
+ if (PQstatus(pgsql) =3D=3D CONNECTION_BAD) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ RETURN_TRUE;=0A=
+}=0A=
+=0A=
+/* }}} */=0A=
+=0A=
+/* Following functions are for asyncronous query=0A=
+ * Report bugs to yasuo_ohgaki@yahoo.com=0A=
+ */ =0A=
+#define PHP_PG_ASYNC_IS_BUSY 1=0A=
+#define PHP_PG_ASYNC_REQUEST_CANCEL 2=0A=
+=0A=
+/* {{{ php_pgsql_do_async=0A=
+ */=0A=
+void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) =0A=
+{=0A=
+ zval **pgsql_link =3D NULL;=0A=
+ int id =3D -1;=0A=
+ PGconn *pgsql;=0A=
+ PGresult *pgsql_result;=0A=
+=0A=
+ switch(ZEND_NUM_ARGS()) {=0A=
+ case 0:=0A=
+ id =3D PGG(default_link);=0A=
+ CHECK_DEFAULT_LINK(id);=0A=
+ break;=0A=
+ case 1:=0A=
+ if (zend_get_parameters_ex(1, &pgsql_link)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ WRONG_PARAM_COUNT;=0A=
+ break;=0A=
+ }=0A=
+=0A=
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
+=0A=
+ switch(entry_type) {=0A=
+ case PHP_PG_ASYNC_IS_BUSY:=0A=
+ PQconsumeInput(pgsql);=0A=
+ Z_LVAL_P(return_value) =3D PQisBusy(pgsql);=0A=
+ Z_TYPE_P(return_value) =3D IS_LONG;=0A=
+ break;=0A=
+ case PHP_PG_ASYNC_REQUEST_CANCEL:=0A=
+ Z_LVAL_P(return_value) =3D PQrequestCancel(pgsql);=0A=
+ Z_TYPE_P(return_value) =3D IS_LONG;=0A=
+ while ((pgsql_result =3D PQgetResult(pgsql))) {=0A=
+ PQclear(pgsql_result);=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ php_error(E_ERROR,"Pgsql module error. Report this error");=0A=
+ break;=0A=
+ }=0A=
+ convert_to_boolean_ex(&return_value);=0A=
+}=0A=
+/* }}} */=0A=
+=0A=
+/* {{{ proto bool pg_async_request_cancel([resource connection])=0A=
+ Cancel request */=0A=
+PHP_FUNCTION(pg_request_cancel)=0A=
+{=0A=
+ php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, =
PHP_PG_ASYNC_REQUEST_CANCEL);=0A=
+}=0A=
+/* }}} */=0A=
+=0A=
+/* {{{ proto query bool pg_isbusy([resource connection])=0A=
+ Get connection is busy or not */=0A=
+PHP_FUNCTION(pg_is_busy)=0A=
+{=0A=
+ php_pgsql_do_async(INTERNAL_FUNCTION_PARAM_PASSTHRU, =
PHP_PG_ASYNC_IS_BUSY);=0A=
+}=0A=
+/* }}} */=0A=
+=0A=
+/* {{{ proto bool pg_async_exec([resource connection], string qeury)=0A=
+ Send asynchronous query */=0A=
+PHP_FUNCTION(pg_send_query)=0A=
+{=0A=
+ zval **query, **pgsql_link =3D NULL;=0A=
+ int id =3D -1;=0A=
+ PGconn *pgsql;=0A=
+ PGresult *res;=0A=
+ int leftover =3D 0;=0A=
+=0A=
+ switch(ZEND_NUM_ARGS()) {=0A=
+ case 1:=0A=
+ if (zend_get_parameters_ex(1, &query)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ id =3D PGG(default_link);=0A=
+ CHECK_DEFAULT_LINK(id);=0A=
+ break;=0A=
+ case 2:=0A=
+ if (zend_get_parameters_ex(2, &pgsql_link, &query)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ WRONG_PARAM_COUNT;=0A=
+ break;=0A=
+ }=0A=
=0A=
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
+=0A=
+ convert_to_string_ex(query);=0A=
+ if (PQsetnonblocking(pgsql, 1)) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: Cannot set connection to nonblocking =
mode in pg_send_query()");=0A=
+ }=0A=
+ if (PQisBusy(pgsql)) {=0A=
+ php_error(E_WARNING,"PostgreSQL: Cannot send multiple query using =
pg_send_query()");=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ while ((res =3D PQgetResult(pgsql))) {=0A=
+ PQclear(res);=0A=
+ leftover =3D 1;=0A=
+ }=0A=
+ if (leftover) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: There are results on this connection. =
Call pg_get_result() until it returns false");=0A=
+ }=0A=
+ if (!PQsendQuery(pgsql, Z_STRVAL_PP(query))) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ if (PQsetnonblocking(pgsql, 0)) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: Cannot set connection to blocking =
mode in pg_send_query()");=0A=
+ }=0A=
+ RETURN_TRUE;=0A=
+}=0A=
+/* }}} */=0A=
+=0A=
+=0A=
+/* {{{ proto query resouce pg_arync_result([resource connection])=0A=
+ Get asynchronous query result */=0A=
+PHP_FUNCTION(pg_get_result)=0A=
+{=0A=
+ zval **pgsql_link =3D NULL;=0A=
+ int id =3D -1;=0A=
+ PGconn *pgsql;=0A=
+ PGresult *pgsql_result;=0A=
+ pgsql_result_handle *pg_result;=0A=
+=0A=
+ switch(ZEND_NUM_ARGS()) {=0A=
+ case 0:=0A=
+ id =3D PGG(default_link);=0A=
+ CHECK_DEFAULT_LINK(id);=0A=
+ break;=0A=
+ case 1:=0A=
+ if (zend_get_parameters_ex(1, &pgsql_link)=3D=3DFAILURE) {=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ break;=0A=
+ default:=0A=
+ WRONG_PARAM_COUNT;=0A=
+ break;=0A=
+ }=0A=
+=0A=
+ ZEND_FETCH_RESOURCE2(pgsql, PGconn *, pgsql_link, id, "PostgreSQL =
link", le_link, le_plink);=0A=
+ if (PQsetnonblocking(pgsql, 1)) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: Cannot set connection to nonblocking =
mode in pg_get_result()");=0A=
+ }=0A=
+ pgsql_result =3D PQgetResult(pgsql);=0A=
+ if (!pgsql_result) {=0A=
+ /* no result */=0A=
+ RETURN_FALSE;=0A=
+ }=0A=
+ if (PQsetnonblocking(pgsql, 0)) {=0A=
+ php_error(E_NOTICE,"PostgreSQL: Cannot set connection to blocking =
mode in pg_get_result()");=0A=
+ }=0A=
+ pg_result =3D (pgsql_result_handle *) =
emalloc(sizeof(pgsql_result_handle));=0A=
+ pg_result->conn =3D pgsql;=0A=
+ pg_result->result =3D pgsql_result;=0A=
+ pg_result->row =3D -1;=0A=
+ ZEND_REGISTER_RESOURCE(return_value, pg_result, le_result);=0A=
+}=0A=
+/* }}} */=0A=
+=0A=
#endif=0A=
=0A=
/*=0A=
Index: php_pgsql.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /repository/php4/ext/pgsql/php_pgsql.h,v=0A=
retrieving revision 1.33=0A=
diff -u -r1.33 php_pgsql.h=0A=
--- php_pgsql.h 26 Sep 2001 21:44:48 -0000 1.33=0A=
+++ php_pgsql.h 25 Nov 2001 09:35:23 -0000=0A=
@@ -94,6 +94,12 @@=0A=
PHP_FUNCTION(pg_client_encoding);=0A=
PHP_FUNCTION(pg_set_client_encoding);=0A=
#endif=0A=
+PHP_FUNCTION(pg_reset);=0A=
+PHP_FUNCTION(pg_status);=0A=
+PHP_FUNCTION(pg_send_query);=0A=
+PHP_FUNCTION(pg_request_cancel);=0A=
+PHP_FUNCTION(pg_get_result);=0A=
+PHP_FUNCTION(pg_is_busy);=0A=
=0A=
void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);=0A=
int php_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS);=0A=
@@ -102,7 +108,7 @@=0A=
char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list);=0A=
void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int =
entry_type);=0A=
void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);=0A=
-=0A=
+void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS,int entry_type);=0A=
=0A=
typedef struct pgLofp {=0A=
PGconn *conn;=0A=
------=_NextPart_000_00AD_01C175E3.D0EC2F10--