+ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_construct, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
+ ZEND_ARG_INFO(0, async)
+ ZEND_ARG_INFO(0, isolation)
+ ZEND_ARG_INFO(0, readonly)
+ ZEND_ARG_INFO(0, deferrable)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqtxn, __construct) {
+ zend_error_handling zeh;
+ zval *zconn;
+ long isolation = PHP_PQTXN_READ_COMMITTED;
+ zend_bool async = 0, readonly = 0, deferrable = 0;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|blbb", &zconn, php_pqconn_class_entry, &async, &isolation, &readonly, &deferrable)) {
+ STATUS rv;
+ php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+ php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC);
+
+ if (conn_obj->intern) {
+ if (async) {
+ rv = php_pqconn_start_transaction_async(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC);
+ } else {
+ rv = php_pqconn_start_transaction(zconn, conn_obj, isolation, readonly, deferrable TSRMLS_CC);
+ }
+
+ if (SUCCESS == rv) {
+ obj->intern = ecalloc(1, sizeof(*obj->intern));
+
+ php_pq_object_addref(conn_obj TSRMLS_CC);
+ obj->intern->conn = conn_obj;
+ obj->intern->isolation = isolation;
+ obj->intern->readonly = readonly;
+ obj->intern->deferrable = deferrable;
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqtxn, commit) {
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters_none()) {
+ php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+
+ if (obj->intern->conn->intern) {
+ PGresult *res = PQexec(obj->intern->conn->intern->conn, "COMMIT");
+
+ if (res) {
+ php_pqres_success(res TSRMLS_CC);
+ PQclear(res);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not commit transaction: %s", PQerrorMessage(obj->intern->conn->intern->conn));
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not intialized");
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Transaction not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_commit_async, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqtxn, commitAsync) {
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters_none()) {
+ php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+ if (obj->intern->conn->intern) {
+ obj->intern->conn->intern->poller = PQconsumeInput;
+
+ if (!PQsendQuery(obj->intern->conn->intern->conn, "COMMIT")) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not commit transaction: %s", PQerrorMessage(obj->intern->conn->intern->conn));
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not intialized");
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Transaction not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqtxn, rollback) {
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters_none()) {
+ php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+ if (obj->intern->conn->intern) {
+ PGresult *res = PQexec(obj->intern->conn->intern->conn, "ROLLBACK");
+
+ if (res) {
+ php_pqres_success(res TSRMLS_CC);
+ PQclear(res);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not rollback transaction: %s", PQerrorMessage(obj->intern->conn->intern->conn));
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not intialized");
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Transaction not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqtxn_rollback_async, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqtxn, rollbackAsync) {
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters_none()) {
+ php_pqtxn_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+ if (obj->intern->conn->intern) {
+ obj->intern->conn->intern->poller = PQconsumeInput;
+ if (!PQsendQuery(obj->intern->conn->intern->conn, "REOLLBACK")) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not rollback transaction: %s", PQerrorMessage(obj->intern->conn->intern->conn));
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not intialized");
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Transaction not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+static zend_function_entry php_pqtxn_methods[] = {
+ PHP_ME(pqtxn, __construct, ai_pqtxn_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(pqtxn, commit, ai_pqtxn_commit, ZEND_ACC_PUBLIC)
+ PHP_ME(pqtxn, rollback, ai_pqtxn_rollback, ZEND_ACC_PUBLIC)
+ PHP_ME(pqtxn, commitAsync, ai_pqtxn_commit_async, ZEND_ACC_PUBLIC)
+ PHP_ME(pqtxn, rollbackAsync, ai_pqtxn_rollback_async, ZEND_ACC_PUBLIC)
+ {0}
+};
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_construct, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqcancel, __construct) {
+ zend_error_handling zeh;
+ zval *zconn;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zconn, php_pqconn_class_entry)) {
+ php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC);
+
+ if (conn_obj->intern) {
+ PGcancel *cancel = PQgetCancel(conn_obj->intern->conn);
+
+ if (cancel) {
+ php_pqcancel_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ obj->intern = ecalloc(1, sizeof(*obj->intern));
+ obj->intern->cancel = cancel;
+ php_pq_object_addref(conn_obj TSRMLS_CC);
+ obj->intern->conn = conn_obj;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not acquire cancel: %s", PQerrorMessage(conn_obj->intern->conn));
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqcancel_cancel, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqcancel, cancel) {
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters_none()) {
+ php_pqcancel_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+ char err[256];
+
+ if (!PQcancel(obj->intern->cancel, err, sizeof(err))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not request cancellation: %s", err);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Cancel not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+static zend_function_entry php_pqcancel_methods[] = {
+ PHP_ME(pqcancel, __construct, ai_pqcancel_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(pqcancel, cancel, ai_pqcancel_cancel, ZEND_ACC_PUBLIC)
+ {0}
+};
+
+static void php_pqconn_add_eventhandler(zval *zconn, php_pqconn_object_t *conn_obj, const char *type_str, size_t type_len, zval *zevent TSRMLS_DC)
+{
+ zval **evhs;
+
+ if (SUCCESS == zend_hash_find(&conn_obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evhs)) {
+ Z_ADDREF_P(zevent);
+ add_next_index_zval(*evhs, zevent);
+ } else {
+ zval *evh;
+
+ MAKE_STD_ZVAL(evh);
+ array_init(evh);
+ Z_ADDREF_P(zevent);
+ add_next_index_zval(evh, zevent);
+ zend_hash_add(&conn_obj->intern->eventhandlers, type_str, type_len + 1, (void *) &evh, sizeof(zval *), NULL);
+ }
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_construct, 0, 0, 3)
+ ZEND_ARG_OBJ_INFO(0, connection, pq\\Connection, 0)
+ ZEND_ARG_INFO(0, type)
+ ZEND_ARG_INFO(0, callable)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqevent, __construct) {
+ zend_error_handling zeh;
+ zval *zconn;
+ char *type_str;
+ int type_len;
+ php_pq_callback_t cb;
+
+ zend_replace_error_handling(EH_THROW, NULL, &zeh TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Osf", &zconn, php_pqconn_class_entry, &type_str, &type_len, &cb.fci, &cb.fcc)) {
+ php_pqconn_object_t *conn_obj = zend_object_store_get_object(zconn TSRMLS_CC);
+
+ if (conn_obj->intern) {
+ php_pqevent_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ obj->intern = ecalloc(1, sizeof(*obj->intern));
+ php_pq_callback_addref(&cb);
+ obj->intern->cb = cb;
+ php_pq_object_addref(conn_obj TSRMLS_CC);
+ obj->intern->conn = conn_obj;
+ obj->intern->type = estrdup(type_str);
+
+ php_pqconn_add_eventhandler(zconn, conn_obj, type_str, type_len, getThis() TSRMLS_CC);
+
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Connection not initialized");
+ }
+ }
+ zend_restore_error_handling(&zeh TSRMLS_CC);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_pqevent_trigger, 0, 0, 1)
+ ZEND_ARG_ARRAY_INFO(0, args, 1)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(pqevent, trigger) {
+ zval *args;
+
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a/", &args)) {
+ php_pqevent_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ if (obj->intern) {
+ zval *rv = NULL;
+
+ if (SUCCESS == zend_fcall_info_call(&obj->intern->cb.fci, &obj->intern->cb.fcc, &rv, args TSRMLS_CC)) {
+ if (rv) {
+ RETVAL_ZVAL(rv, 0, 1);
+ } else {
+ RETVAL_TRUE;
+ }
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "pq\\Event not initialized");
+ RETVAL_FALSE;
+ }
+ }
+}
+
+static zend_function_entry php_pqevent_methods[] = {
+ PHP_ME(pqevent, __construct, ai_pqevent_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
+ PHP_ME(pqevent, trigger, ai_pqevent_trigger, ZEND_ACC_PUBLIC)
+ {0}
+};
+