flush
[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(zval *p, void *a)
28 {
29 php_pq_callback_t *cb = Z_PTR_P(p);
30 zval *args = a;
31 zval rv;
32
33 ZVAL_NULL(&rv);
34 zend_fcall_info_args(&cb->fci, args);
35 zend_fcall_info_call(&cb->fci, &cb->fcc, &rv, NULL);
36 zval_ptr_dtor(&rv);
37
38 return ZEND_HASH_APPLY_KEEP;
39 }
40
41 static void php_pqconn_event_connreset(PGEventConnReset *event)
42 {
43 php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
44
45 if (data) {
46 HashTable *evhs;
47
48 if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRS("reset")))) {
49 zval args, connection;
50
51 array_init(&args);
52 php_pq_object_to_zval(data->obj, &connection);
53 add_next_index_zval(&args, &connection);
54 zend_hash_apply_with_argument(evhs, apply_event, &args);
55 zval_ptr_dtor(&args);
56 }
57 }
58 }
59
60 static void php_pqconn_event_resultcreate(PGEventResultCreate *event)
61 {
62 php_pqconn_event_data_t *data = PQinstanceData(event->conn, php_pqconn_event);
63
64 if (data) {
65 php_pqres_object_t *obj;
66 HashTable *evhs;
67
68 php_pqres_init_instance_data(event->result, data->obj, &obj);
69
70 /* event listener */
71 if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRL("result")))) {
72 zval args, connection, res;
73
74 array_init(&args);
75 php_pq_object_to_zval(data->obj, &connection);
76 add_next_index_zval(&args, &connection);
77 php_pq_object_to_zval(obj, &res);
78 add_next_index_zval(&args, &res);
79 zend_hash_apply_with_argument(evhs, apply_event, &args);
80 zval_ptr_dtor(&args);
81 }
82
83 /* async callback */
84 if (data->obj->intern->onevent.fci.size > 0) {
85 zval res;
86
87 php_pq_object_to_zval(obj, &res);
88 zend_fcall_info_argn(&data->obj->intern->onevent.fci, 1, &res);
89 zend_fcall_info_call(&data->obj->intern->onevent.fci, &data->obj->intern->onevent.fcc, NULL, NULL);
90 zval_ptr_dtor(&res);
91 }
92
93 }
94 }
95
96 static void php_pqconn_event_resultdestroy(PGEventResultDestroy *event)
97 {
98 php_pqres_object_t *obj = PQresultInstanceData(event->result, php_pqconn_event);
99
100 if (obj) {
101 obj->intern->res = NULL;
102 }
103 }
104
105 int php_pqconn_event(PGEventId id, void *e, void *data)
106 {
107 switch (id) {
108 case PGEVT_CONNRESET:
109 php_pqconn_event_connreset(e);
110 break;
111 case PGEVT_RESULTCREATE:
112 php_pqconn_event_resultcreate(e);
113 break;
114 case PGEVT_RESULTDESTROY:
115 php_pqconn_event_resultdestroy(e);
116 break;
117 default:
118 break;
119 }
120
121 return 1;
122 }
123
124 php_pqconn_event_data_t *php_pqconn_event_data_init(php_pqconn_object_t *obj)
125 {
126 php_pqconn_event_data_t *data = emalloc(sizeof(*data));
127
128 data->obj = obj;
129
130 return data;
131 }
132
133 void php_pqconn_notice_recv(void *p, const PGresult *res)
134 {
135 php_pqconn_event_data_t *data = p;
136
137 if (data) {
138 HashTable *evhs;
139
140 if ((evhs = zend_hash_str_find_ptr(&data->obj->intern->eventhandlers, ZEND_STRL("notice")))) {
141 zval args, connection;
142
143 array_init(&args);
144 php_pq_object_to_zval(data->obj, &connection);
145 add_next_index_zval(&args, &connection);
146 add_next_index_string(&args, PHP_PQresultErrorMessage(res));
147 zend_hash_apply_with_argument(evhs, apply_event, &args);
148 zval_ptr_dtor(&args);
149 }
150 }
151 }
152
153 void php_pqconn_notice_ignore(void *p, const PGresult *res)
154 {
155 }
156
157 /*
158 * Local variables:
159 * tab-width: 4
160 * c-basic-offset: 4
161 * End:
162 * vim600: noet sw=4 ts=4 fdm=marker
163 * vim<600: noet sw=4 ts=4
164 */