1 /**
2 * Copyright 2015-2017 DataStax, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "php_driver.h"
18 #include "php_driver_types.h"
19 #include "util/consistency.h"
20 #include "util/math.h"
21
22 zend_class_entry *php_driver_execution_options_ce = NULL;
23
init_execution_options(php_driver_execution_options * self)24 static void init_execution_options(php_driver_execution_options *self)
25 {
26 self->consistency = -1;
27 self->serial_consistency = -1;
28 self->page_size = -1;
29 self->paging_state_token = NULL;
30 self->paging_state_token_size = 0;
31 self->timestamp = INT64_MIN;
32 PHP5TO7_ZVAL_UNDEF(self->arguments);
33 PHP5TO7_ZVAL_UNDEF(self->timeout);
34 PHP5TO7_ZVAL_UNDEF(self->retry_policy);
35 }
36
build_from_array(php_driver_execution_options * self,zval * options,int copy TSRMLS_DC)37 static int build_from_array(php_driver_execution_options *self, zval *options, int copy TSRMLS_DC)
38 {
39 php5to7_zval *consistency = NULL;
40 php5to7_zval *serial_consistency = NULL;
41 php5to7_zval *page_size = NULL;
42 php5to7_zval *paging_state_token = NULL;
43 php5to7_zval *timeout = NULL;
44 php5to7_zval *arguments = NULL;
45 php5to7_zval *retry_policy = NULL;
46 php5to7_zval *timestamp = NULL;
47
48 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "consistency", sizeof("consistency"), consistency)) {
49 if (php_driver_get_consistency(PHP5TO7_ZVAL_MAYBE_DEREF(consistency), &self->consistency TSRMLS_CC) == FAILURE) {
50 return FAILURE;
51 }
52 }
53
54 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "serial_consistency", sizeof("serial_consistency"), serial_consistency)) {
55 if (php_driver_get_serial_consistency(PHP5TO7_ZVAL_MAYBE_DEREF(serial_consistency), &self->serial_consistency TSRMLS_CC) == FAILURE) {
56 return FAILURE;
57 }
58 }
59
60 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "page_size", sizeof("page_size"), page_size)) {
61 if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(page_size)) != IS_LONG || Z_LVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(page_size)) <= 0) {
62 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(page_size), "page_size", "greater than zero" TSRMLS_CC);
63 return FAILURE;
64 }
65 self->page_size = Z_LVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(page_size));
66 }
67
68 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "paging_state_token", sizeof("paging_state_token"), paging_state_token)) {
69 if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token)) != IS_STRING) {
70 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token), "paging_state_token", "a string" TSRMLS_CC);
71 return FAILURE;
72 }
73 if (copy) {
74 self->paging_state_token = estrndup(Z_STRVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token)),
75 Z_STRLEN_P(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token)));
76 } else {
77 self->paging_state_token = Z_STRVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token));
78 }
79 self->paging_state_token_size = Z_STRLEN_P(PHP5TO7_ZVAL_MAYBE_DEREF(paging_state_token));
80 }
81
82 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "timeout", sizeof("timeout"), timeout)) {
83 if (!(Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(timeout)) == IS_LONG && Z_LVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(timeout)) > 0) &&
84 !(Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(timeout)) == IS_DOUBLE && Z_DVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(timeout)) > 0) &&
85 !(Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(timeout)) == IS_NULL)) {
86 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(timeout), "timeout", "a number of seconds greater than zero or null" TSRMLS_CC);
87 return FAILURE;
88 }
89
90 if (copy) {
91 PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(self->timeout), PHP5TO7_ZVAL_MAYBE_DEREF(timeout));
92 } else {
93 self->timeout = *timeout;
94 }
95 }
96
97 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "arguments", sizeof("arguments"), arguments)) {
98 if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(arguments)) != IS_ARRAY) {
99 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(arguments), "arguments", "an array" TSRMLS_CC);
100 return FAILURE;
101 }
102
103 if (copy) {
104 PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(self->arguments), PHP5TO7_ZVAL_MAYBE_DEREF(arguments));
105 } else {
106 self->arguments = *arguments;
107 }
108 }
109
110 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "retry_policy", sizeof("retry_policy"), retry_policy)) {
111 if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(retry_policy)) != IS_OBJECT &&
112 !instanceof_function(Z_OBJCE_P(PHP5TO7_ZVAL_MAYBE_DEREF(retry_policy)),
113 php_driver_retry_policy_ce TSRMLS_CC)) {
114 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(retry_policy),
115 "retry_policy",
116 "an instance of " PHP_DRIVER_NAMESPACE "\\RetryPolicy" TSRMLS_CC);
117 return FAILURE;
118 }
119
120 if (copy) {
121 PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(self->retry_policy), PHP5TO7_ZVAL_MAYBE_DEREF(retry_policy));
122 } else {
123 self->retry_policy = *retry_policy;
124 }
125 }
126
127 if (PHP5TO7_ZEND_HASH_FIND(Z_ARRVAL_P(options), "timestamp", sizeof("timestamp"), timestamp)) {
128 if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp)) == IS_LONG) {
129 self->timestamp = Z_LVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp));
130 } else if (Z_TYPE_P(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp)) == IS_STRING) {
131 if (!php_driver_parse_bigint(Z_STRVAL_P(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp)),
132 Z_STRLEN_P(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp)),
133 &self->timestamp TSRMLS_CC)) {
134 return FAILURE;
135 }
136 } else {
137 throw_invalid_argument(PHP5TO7_ZVAL_MAYBE_DEREF(timestamp), "timestamp", "an integer or integer string" TSRMLS_CC);
138 return FAILURE;
139 }
140 }
141 return SUCCESS;
142 }
143
php_driver_execution_options_build_local_from_array(php_driver_execution_options * self,zval * options TSRMLS_DC)144 int php_driver_execution_options_build_local_from_array(php_driver_execution_options *self, zval *options TSRMLS_DC)
145 {
146 init_execution_options(self);
147 return build_from_array(self, options, 0 TSRMLS_CC);
148 }
149
PHP_METHOD(ExecutionOptions,__construct)150 PHP_METHOD(ExecutionOptions, __construct)
151 {
152 zval *options = NULL;
153 php_driver_execution_options *self = NULL;
154
155 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &options) == FAILURE) {
156 return;
157 }
158
159 if (!options) return;
160
161 if (Z_TYPE_P(options) != IS_ARRAY) {
162 INVALID_ARGUMENT(options, "an array");
163 }
164
165 self = PHP_DRIVER_GET_EXECUTION_OPTIONS(getThis());
166
167 build_from_array(self, options, 1 TSRMLS_CC);
168 }
169
PHP_METHOD(ExecutionOptions,__get)170 PHP_METHOD(ExecutionOptions, __get)
171 {
172 char *name;
173 php5to7_size name_len;
174
175 php_driver_execution_options *self = NULL;
176
177 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
178 return;
179 }
180
181 self = PHP_DRIVER_GET_EXECUTION_OPTIONS(getThis());
182
183 if (name_len == 11 && strncmp("consistency", name, name_len) == 0) {
184 if (self->consistency == -1) {
185 RETURN_NULL();
186 }
187 RETURN_LONG(self->consistency);
188 } else if (name_len == 17 && strncmp("serialConsistency", name, name_len) == 0) {
189 if (self->serial_consistency == -1) {
190 RETURN_NULL();
191 }
192 RETURN_LONG(self->serial_consistency);
193 } else if (name_len == 8 && strncmp("pageSize", name, name_len) == 0) {
194 if (self->page_size == -1) {
195 RETURN_NULL();
196 }
197 RETURN_LONG(self->page_size);
198 } else if (name_len == 16 && strncmp("pagingStateToken", name, name_len) == 0) {
199 if (!self->paging_state_token) {
200 RETURN_NULL();
201 }
202 PHP5TO7_RETURN_STRINGL(self->paging_state_token,
203 self->paging_state_token_size);
204 } else if (name_len == 7 && strncmp("timeout", name, name_len) == 0) {
205 if (PHP5TO7_ZVAL_IS_UNDEF(self->timeout)) {
206 RETURN_NULL();
207 }
208 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(self->timeout), 1, 0);
209 } else if (name_len == 9 && strncmp("arguments", name, name_len) == 0) {
210 if (PHP5TO7_ZVAL_IS_UNDEF(self->arguments)) {
211 RETURN_NULL();
212 }
213 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(self->arguments), 1, 0);
214 } else if (name_len == 11 && strncmp("retryPolicy", name, name_len) == 0) {
215 if (PHP5TO7_ZVAL_IS_UNDEF(self->retry_policy)) {
216 RETURN_NULL();
217 }
218 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(self->retry_policy), 1, 0);
219 } else if (name_len == 9 && strncmp("timestamp", name, name_len) == 0) {
220 char *string;
221 if (self->timestamp == INT64_MIN) {
222 RETURN_NULL();
223 }
224 #ifdef WIN32
225 spprintf(&string, 0, "%I64d", (long long int) self->timestamp);
226 #else
227 spprintf(&string, 0, "%lld", (long long int) self->timestamp);
228 #endif
229 PHP5TO7_RETVAL_STRING(string);
230 efree(string);
231 }
232 }
233
234 ZEND_BEGIN_ARG_INFO_EX(arginfo__construct, 0, ZEND_RETURN_VALUE, 0)
235 ZEND_ARG_ARRAY_INFO(0, options, 1)
236 ZEND_END_ARG_INFO()
237
238 ZEND_BEGIN_ARG_INFO_EX(arginfo___get, 0, ZEND_RETURN_VALUE, 1)
239 ZEND_ARG_INFO(0, name)
240 ZEND_END_ARG_INFO()
241
242 static zend_function_entry php_driver_execution_options_methods[] = {
243 PHP_ME(ExecutionOptions, __construct, arginfo__construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR | ZEND_ACC_DEPRECATED)
244 PHP_ME(ExecutionOptions, __get, arginfo___get, ZEND_ACC_PUBLIC)
245 PHP_FE_END
246 };
247
248 static zend_object_handlers php_driver_execution_options_handlers;
249
250 static HashTable *
php_driver_execution_options_properties(zval * object TSRMLS_DC)251 php_driver_execution_options_properties(zval *object TSRMLS_DC)
252 {
253 HashTable *props = zend_std_get_properties(object TSRMLS_CC);
254
255 return props;
256 }
257
258 static int
php_driver_execution_options_compare(zval * obj1,zval * obj2 TSRMLS_DC)259 php_driver_execution_options_compare(zval *obj1, zval *obj2 TSRMLS_DC)
260 {
261 if (Z_OBJCE_P(obj1) != Z_OBJCE_P(obj2))
262 return 1; /* different classes */
263
264 return Z_OBJ_HANDLE_P(obj1) != Z_OBJ_HANDLE_P(obj1);
265 }
266
267 static void
php_driver_execution_options_free(php5to7_zend_object_free * object TSRMLS_DC)268 php_driver_execution_options_free(php5to7_zend_object_free *object TSRMLS_DC)
269 {
270 php_driver_execution_options *self =
271 PHP5TO7_ZEND_OBJECT_GET(execution_options, object);
272
273 if (self->paging_state_token) {
274 efree(self->paging_state_token);
275 }
276 PHP5TO7_ZVAL_MAYBE_DESTROY(self->arguments);
277 PHP5TO7_ZVAL_MAYBE_DESTROY(self->timeout);
278 PHP5TO7_ZVAL_MAYBE_DESTROY(self->retry_policy);
279
280 zend_object_std_dtor(&self->zval TSRMLS_CC);
281 PHP5TO7_MAYBE_EFREE(self);
282 }
283
284 static php5to7_zend_object
php_driver_execution_options_new(zend_class_entry * ce TSRMLS_DC)285 php_driver_execution_options_new(zend_class_entry *ce TSRMLS_DC)
286 {
287 php_driver_execution_options *self =
288 PHP5TO7_ZEND_OBJECT_ECALLOC(execution_options, ce);
289
290 init_execution_options(self);
291
292 PHP5TO7_ZEND_OBJECT_INIT(execution_options, self, ce);
293 }
294
php_driver_define_ExecutionOptions(TSRMLS_D)295 void php_driver_define_ExecutionOptions(TSRMLS_D)
296 {
297 zend_class_entry ce;
298
299 INIT_CLASS_ENTRY(ce, PHP_DRIVER_NAMESPACE "\\ExecutionOptions", php_driver_execution_options_methods);
300 php_driver_execution_options_ce = zend_register_internal_class(&ce TSRMLS_CC);
301 php_driver_execution_options_ce->ce_flags |= PHP5TO7_ZEND_ACC_FINAL;
302 php_driver_execution_options_ce->create_object = php_driver_execution_options_new;
303
304 memcpy(&php_driver_execution_options_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
305 php_driver_execution_options_handlers.get_properties = php_driver_execution_options_properties;
306 php_driver_execution_options_handlers.compare_objects = php_driver_execution_options_compare;
307 php_driver_execution_options_handlers.clone_obj = NULL;
308 }
309