split source
[m6w6/ext-pq] / src / php_pqconn_event.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: pq |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2013, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <php.h>
18
19 #include <libpq-events.h>
20
21 #include "php_pq.h"
22 #include "php_pq_misc.h"
23 #include "php_pq_object.h"
24 #include "php_pqconn_event.h"
25 #include "php_pqres.h"
26
27 static int apply_event(void *p, void *a TSRMLS_DC)
28 {
29 php_pq_callback_t *cb = p;
30 zval *args = a;
31 zval *retval = NULL;
32
33 zend_fcall_info_args(&cb->fci, args TSRMLS_CC);
34 zend_fcall_info_call(&cb->fci, &cb->fcc, &retval, NULL TSRMLS_CC);
35 if (retval) {
36 zval_ptr_dtor(&retval);
37 }
38
39 return ZEND_HASH_APPLY_KEEP;
40 }
41
42 static void php_pqconn_event_connreset(PGEventConnReset *event)
43 {
44 php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
45
46 if (data) {
47 HashTable *evhs;
48 TSRMLS_DF(data);
49
50 if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("reset"), (void *) &evhs)) {
51 zval *args, *connection = NULL;
52
53 MAKE_STD_ZVAL(args);
54 array_init(args);
55 php_pq_object_to_zval(data->obj, &connection TSRMLS_CC);
56 add_next_index_zval(args, connection);
57 zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC);
58 zval_ptr_dtor(&args);
59 }
60 }
61 }
62
63 static void php_pqconn_event_resultcreate(PGEventResultCreate *event)
64 {
65 php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
66
67 if (data) {
68 php_pqres_object_t *obj;
69 HashTable *evhs;
70 TSRMLS_DF(data);
71
72 php_pqres_init_instance_data(event->result, &obj TSRMLS_CC);
73
74 /* event listener */
75 if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("result"), (void *) &evhs)) {
76 zval *args, *connection = NULL, *res = NULL;
77
78 MAKE_STD_ZVAL(args);
79 array_init(args);
80 php_pq_object_to_zval(data->obj, &connection TSRMLS_CC);
81 add_next_index_zval(args, connection);
82 php_pq_object_to_zval(obj, &res TSRMLS_CC);
83 add_next_index_zval(args, res);
84 zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC);
85 zval_ptr_dtor(&args);
86 }
87
88 /* async callback */
89 if (data->obj->intern->onevent.fci.size > 0) {
90 zval *res = NULL;
91
92 php_pq_object_to_zval(obj, &res TSRMLS_CC);
93 zend_fcall_info_argn(&data->obj->intern->onevent.fci TSRMLS_CC, 1, &res);
94 zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL TSRMLS_CC);
95 zval_ptr_dtor(&res);
96 }
97
98 }
99 }
100
101 static void php_pqconn_event_resultdestroy(PGEventResultDestroy *event)
102 {
103 php_pqres_object_t *obj = PQresultInstanceData(event->result, php_pqconn_event);
104
105 if (obj) {
106 obj->intern->res = NULL;
107 }
108 }
109
110 int php_pqconn_event(PGEventId id, void *e, void *data)
111 {
112 switch (id) {
113 case PGEVT_CONNRESET:
114 php_pqconn_event_connreset(e);
115 break;
116 case PGEVT_RESULTCREATE:
117 php_pqconn_event_resultcreate(e);
118 break;
119 case PGEVT_RESULTDESTROY:
120 php_pqconn_event_resultdestroy(e);
121 break;
122 default:
123 break;
124 }
125
126 return 1;
127 }
128
129 php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj TSRMLS_DC)
130 {
131 php_pqconn_event_data_t *data = emalloc(sizeof(*data));
132
133 data->obj = obj;
134 TSRMLS_CF(data);
135
136 return data;
137 }
138
139 void php_pqconn_notice_recv(void *p, const PGresult *res)
140 {
141 php_pqconn_event_data_t *data = p;
142
143 if (data) {
144 HashTable *evhs;
145 TSRMLS_DF(data);
146
147 if (SUCCESS == zend_hash_find(&data->obj->intern->eventhandlers, ZEND_STRS("notice"), (void *) &evhs)) {
148 zval *args, *connection = NULL;
149
150 MAKE_STD_ZVAL(args);
151 array_init(args);
152 php_pq_object_to_zval(data->obj, &connection TSRMLS_CC);
153 add_next_index_zval(args, connection);
154 add_next_index_string(args, PHP_PQresultErrorMessage(res), 1);
155 zend_hash_apply_with_argument(evhs, apply_event, args TSRMLS_CC);
156 zval_ptr_dtor(&args);
157 }
158 }
159 }
160
161 void php_pqconn_notice_ignore(void *p, const PGresult *res)
162 {
163 }
164
165 /*
166 * Local variables:
167 * tab-width: 4
168 * c-basic-offset: 4
169 * End:
170 * vim600: noet sw=4 ts=4 fdm=marker
171 * vim<600: noet sw=4 ts=4
172 */