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/types.h"
20
21 #include "src/Type/Tuple.h"
22 #include "src/Type/UserType.h"
23
24 zend_class_entry *php_driver_type_ce = NULL;
25
26 #define XX_SCALAR_METHOD(name, value) PHP_METHOD(Type, name) \
27 { \
28 php5to7_zval ztype; \
29 if (zend_parse_parameters_none() == FAILURE) { \
30 return; \
31 } \
32 ztype = php_driver_type_scalar(value TSRMLS_CC); \
33 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 1, 1); \
34 }
35
36 PHP_DRIVER_SCALAR_TYPES_MAP(XX_SCALAR_METHOD)
37 #undef XX_SCALAR_METHOD
38
PHP_METHOD(Type,collection)39 PHP_METHOD(Type, collection)
40 {
41 php5to7_zval ztype;
42 zval *value_type;
43
44 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
45 &value_type, php_driver_type_ce) == FAILURE) {
46 return;
47 }
48
49 if (!php_driver_type_validate(value_type, "type" TSRMLS_CC)) {
50 return;
51 }
52
53 ztype = php_driver_type_collection(value_type TSRMLS_CC);
54 Z_ADDREF_P(value_type);
55 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 0, 1);
56 }
57
PHP_METHOD(Type,tuple)58 PHP_METHOD(Type, tuple)
59 {
60 php5to7_zval ztype;
61 php_driver_type *type;
62 php5to7_zval_args args = NULL;
63 int argc = 0, i;
64
65 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+",
66 &args, &argc) == FAILURE) {
67 return;
68 }
69
70 for (i = 0; i < argc; ++i) {
71 zval *sub_type = PHP5TO7_ZVAL_ARG(args[i]);
72 if (!php_driver_type_validate(sub_type, "type" TSRMLS_CC)) {
73 PHP5TO7_MAYBE_EFREE(args);
74 return;
75 }
76 }
77
78 ztype = php_driver_type_tuple(TSRMLS_C);
79 type = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(ztype));
80
81 for (i = 0; i < argc; ++i) {
82 zval *sub_type = PHP5TO7_ZVAL_ARG(args[i]);
83 if (php_driver_type_tuple_add(type, sub_type TSRMLS_CC)) {
84 Z_ADDREF_P(sub_type);
85 } else {
86 break;
87 }
88 }
89
90 PHP5TO7_MAYBE_EFREE(args);
91 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 0, 1);
92 }
93
PHP_METHOD(Type,userType)94 PHP_METHOD(Type, userType)
95 {
96 php5to7_zval ztype;
97 php_driver_type *type;
98 php5to7_zval_args args = NULL;
99 int argc = 0, i;
100
101 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+",
102 &args, &argc) == FAILURE) {
103 return;
104 }
105
106 if (argc % 2 == 1) {
107 zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
108 "Not enough name/type pairs, user types can only be created " \
109 "from an even number of name/type pairs, where each odd " \
110 "argument is a name and each even argument is a type, " \
111 "e.g userType(name, type, name, type, name, type)");
112 PHP5TO7_MAYBE_EFREE(args);
113 return;
114 }
115
116 for (i = 0; i < argc; i += 2) {
117 zval *name = PHP5TO7_ZVAL_ARG(args[i]);
118 zval *sub_type = PHP5TO7_ZVAL_ARG(args[i + 1]);
119 if (Z_TYPE_P(name) != IS_STRING) {
120 zend_throw_exception_ex(php_driver_invalid_argument_exception_ce, 0 TSRMLS_CC,
121 "Argument %d is not a string", i + 1);
122 PHP5TO7_MAYBE_EFREE(args);
123 return;
124 }
125 if (!php_driver_type_validate(sub_type, "type" TSRMLS_CC)) {
126 PHP5TO7_MAYBE_EFREE(args);
127 return;
128 }
129 }
130
131 ztype = php_driver_type_user_type(TSRMLS_C);
132 type = PHP_DRIVER_GET_TYPE(PHP5TO7_ZVAL_MAYBE_P(ztype));
133
134 for (i = 0; i < argc; i += 2) {
135 zval *name = PHP5TO7_ZVAL_ARG(args[i]);
136 zval *sub_type = PHP5TO7_ZVAL_ARG(args[i + 1]);
137 if (php_driver_type_user_type_add(type,
138 Z_STRVAL_P(name), Z_STRLEN_P(name),
139 sub_type TSRMLS_CC)) {
140 Z_ADDREF_P(sub_type);
141 } else {
142 break;
143 }
144 }
145
146
147 PHP5TO7_MAYBE_EFREE(args);
148 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 0, 1);
149 }
150
PHP_METHOD(Type,set)151 PHP_METHOD(Type, set)
152 {
153 php5to7_zval ztype;
154 zval *value_type;
155
156 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
157 &value_type, php_driver_type_ce) == FAILURE) {
158 return;
159 }
160
161 if (!php_driver_type_validate(value_type, "type" TSRMLS_CC)) {
162 return;
163 }
164
165 ztype = php_driver_type_set(value_type TSRMLS_CC);
166 Z_ADDREF_P(value_type);
167 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 0, 1);
168 }
169
PHP_METHOD(Type,map)170 PHP_METHOD(Type, map)
171 {
172 php5to7_zval ztype;
173 zval *key_type;
174 zval *value_type;
175
176 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO",
177 &key_type, php_driver_type_ce,
178 &value_type, php_driver_type_ce) == FAILURE) {
179 return;
180 }
181
182 if (!php_driver_type_validate(key_type, "keyType" TSRMLS_CC)) {
183 return;
184 }
185
186 if (!php_driver_type_validate(value_type, "valueType" TSRMLS_CC)) {
187 return;
188 }
189
190 ztype = php_driver_type_map(key_type, value_type TSRMLS_CC);
191 Z_ADDREF_P(key_type);
192 Z_ADDREF_P(value_type);
193 RETURN_ZVAL(PHP5TO7_ZVAL_MAYBE_P(ztype), 0, 1);
194 }
195
196 ZEND_BEGIN_ARG_INFO_EX(arginfo_none, 0, ZEND_RETURN_VALUE, 0)
197 ZEND_END_ARG_INFO()
198
199 ZEND_BEGIN_ARG_INFO_EX(arginfo_types, 0, ZEND_RETURN_VALUE, 0)
200 ZEND_ARG_INFO(0, types)
201 ZEND_END_ARG_INFO()
202
203 ZEND_BEGIN_ARG_INFO_EX(arginfo_type, 0, ZEND_RETURN_VALUE, 1)
204 PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, type, Type, 0)
205 ZEND_END_ARG_INFO()
206
207 ZEND_BEGIN_ARG_INFO_EX(arginfo_map, 0, ZEND_RETURN_VALUE, 2)
208 PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, keyType, Type, 0)
209 PHP_DRIVER_NAMESPACE_ZEND_ARG_OBJ_INFO(0, valueType, Type, 0)
210 ZEND_END_ARG_INFO()
211
212 static zend_function_entry php_driver_type_methods[] = {
213 PHP_ABSTRACT_ME(Type, name, arginfo_none)
214 PHP_ABSTRACT_ME(Type, __toString, arginfo_none)
215
216 #define XX_SCALAR_METHOD(name, _) PHP_ME(Type, name, arginfo_none, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
217 PHP_DRIVER_SCALAR_TYPES_MAP(XX_SCALAR_METHOD)
218 #undef XX_SCALAR_METHOD
219 PHP_ME(Type, collection, arginfo_type, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
220 PHP_ME(Type, set, arginfo_type, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
221 PHP_ME(Type, map, arginfo_map, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
222 PHP_ME(Type, tuple, arginfo_types, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
223 PHP_ME(Type, userType, arginfo_types, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
224 PHP_FE_END
225 };
226
php_driver_define_Type(TSRMLS_D)227 void php_driver_define_Type(TSRMLS_D)
228 {
229 zend_class_entry ce;
230
231 INIT_CLASS_ENTRY(ce, PHP_DRIVER_NAMESPACE "\\Type", php_driver_type_methods);
232 php_driver_type_ce = zend_register_internal_class(&ce TSRMLS_CC);
233 php_driver_type_ce->ce_flags |= ZEND_ACC_ABSTRACT;
234 }
235