1 /**
2 * Copyright 2016-2017 Couchbase, 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 /**
18 * A FTS query that queries fields explicitly indexed as boolean.
19 */
20 #include "couchbase.h"
21
22 typedef struct {
23 PCBC_ZEND_OBJECT_PRE
24 double boost;
25 char *field;
26 zend_bool value;
27 PCBC_ZEND_OBJECT_POST
28 } pcbc_boolean_field_search_query_t;
29
30 #if PHP_VERSION_ID >= 70000
pcbc_boolean_field_search_query_fetch_object(zend_object * obj)31 static inline pcbc_boolean_field_search_query_t *pcbc_boolean_field_search_query_fetch_object(zend_object *obj)
32 {
33 return (pcbc_boolean_field_search_query_t *)((char *)obj - XtOffsetOf(pcbc_boolean_field_search_query_t, std));
34 }
35 #define Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ(zo) (pcbc_boolean_field_search_query_fetch_object(zo))
36 #define Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(zv) (pcbc_boolean_field_search_query_fetch_object(Z_OBJ_P(zv)))
37 #else
38 #define Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ(zo) ((pcbc_boolean_field_search_query_t *)zo)
39 #define Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(zv) \
40 ((pcbc_boolean_field_search_query_t *)zend_object_store_get_object(zv TSRMLS_CC))
41 #endif
42
43 #define LOGARGS(lvl) LCB_LOG_##lvl, NULL, "pcbc/boolean_field_search_query", __FILE__, __LINE__
44
45 zend_class_entry *pcbc_boolean_field_search_query_ce;
46
47 /* {{{ proto void BooleanFieldSearchQuery::__construct() */
PHP_METHOD(BooleanFieldSearchQuery,__construct)48 PHP_METHOD(BooleanFieldSearchQuery, __construct)
49 {
50 throw_pcbc_exception("Accessing private constructor.", LCB_EINVAL);
51 }
52 /* }}} */
53
54 /* {{{ proto \Couchbase\BooleanFieldSearchQuery BooleanFieldSearchQuery::field(string $field)
55 */
PHP_METHOD(BooleanFieldSearchQuery,field)56 PHP_METHOD(BooleanFieldSearchQuery, field)
57 {
58 pcbc_boolean_field_search_query_t *obj;
59 char *field = NULL;
60 int rv;
61 pcbc_str_arg_size field_len;
62
63 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &field, &field_len);
64 if (rv == FAILURE) {
65 RETURN_NULL();
66 }
67
68 obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(getThis());
69 if (obj->field) {
70 efree(obj->field);
71 }
72 obj->field = estrndup(field, field_len);
73
74 RETURN_ZVAL(getThis(), 1, 0);
75 } /* }}} */
76
77 /* {{{ proto \Couchbase\BooleanFieldSearchQuery BooleanFieldSearchQuery::boost(double $boost)
78 */
PHP_METHOD(BooleanFieldSearchQuery,boost)79 PHP_METHOD(BooleanFieldSearchQuery, boost)
80 {
81 pcbc_boolean_field_search_query_t *obj;
82 double boost = 0;
83 int rv;
84
85 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &boost);
86 if (rv == FAILURE) {
87 RETURN_NULL();
88 }
89
90 obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(getThis());
91 obj->boost = boost;
92
93 RETURN_ZVAL(getThis(), 1, 0);
94 } /* }}} */
95
96 /* {{{ proto array BooleanFieldSearchQuery::jsonSerialize()
97 */
PHP_METHOD(BooleanFieldSearchQuery,jsonSerialize)98 PHP_METHOD(BooleanFieldSearchQuery, jsonSerialize)
99 {
100 pcbc_boolean_field_search_query_t *obj;
101 int rv;
102
103 rv = zend_parse_parameters_none();
104 if (rv == FAILURE) {
105 RETURN_NULL();
106 }
107
108 obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(getThis());
109 array_init(return_value);
110 ADD_ASSOC_BOOL_EX(return_value, "bool", obj->value);
111 if (obj->field) {
112 ADD_ASSOC_STRING(return_value, "field", obj->field);
113 }
114 if (obj->boost >= 0) {
115 ADD_ASSOC_DOUBLE_EX(return_value, "boost", obj->boost);
116 }
117 } /* }}} */
118
119 ZEND_BEGIN_ARG_INFO_EX(ai_BooleanFieldSearchQuery_none, 0, 0, 0)
120 ZEND_END_ARG_INFO()
121
122 ZEND_BEGIN_ARG_INFO_EX(ai_BooleanFieldSearchQuery_field, 0, 0, 1)
123 ZEND_ARG_INFO(0, field)
124 ZEND_END_ARG_INFO()
125
126 ZEND_BEGIN_ARG_INFO_EX(ai_BooleanFieldSearchQuery_boost, 0, 0, 1)
127 ZEND_ARG_INFO(0, boost)
128 ZEND_END_ARG_INFO()
129
130 // clang-format off
131 zend_function_entry boolean_field_search_query_methods[] = {
132 PHP_ME(BooleanFieldSearchQuery, __construct, ai_BooleanFieldSearchQuery_none, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL | ZEND_ACC_CTOR)
133 PHP_ME(BooleanFieldSearchQuery, jsonSerialize, ai_BooleanFieldSearchQuery_none, ZEND_ACC_PUBLIC)
134 PHP_ME(BooleanFieldSearchQuery, boost, ai_BooleanFieldSearchQuery_boost, ZEND_ACC_PUBLIC)
135 PHP_ME(BooleanFieldSearchQuery, field, ai_BooleanFieldSearchQuery_field, ZEND_ACC_PUBLIC)
136 PHP_FE_END
137 };
138 // clang-format on
139
pcbc_boolean_field_search_query_init(zval * return_value,zend_bool value TSRMLS_DC)140 void pcbc_boolean_field_search_query_init(zval *return_value, zend_bool value TSRMLS_DC)
141 {
142 pcbc_boolean_field_search_query_t *obj;
143
144 object_init_ex(return_value, pcbc_boolean_field_search_query_ce);
145 obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(return_value);
146 obj->boost = -1;
147 obj->value = value;
148 obj->field = NULL;
149 }
150
151 zend_object_handlers boolean_field_search_query_handlers;
152
boolean_field_search_query_free_object(pcbc_free_object_arg * object TSRMLS_DC)153 static void boolean_field_search_query_free_object(pcbc_free_object_arg *object TSRMLS_DC) /* {{{ */
154 {
155 pcbc_boolean_field_search_query_t *obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ(object);
156
157 if (obj->field != NULL) {
158 efree(obj->field);
159 }
160
161 zend_object_std_dtor(&obj->std TSRMLS_CC);
162 #if PHP_VERSION_ID < 70000
163 efree(obj);
164 #endif
165 } /* }}} */
166
boolean_field_search_query_create_object(zend_class_entry * class_type TSRMLS_DC)167 static pcbc_create_object_retval boolean_field_search_query_create_object(zend_class_entry *class_type TSRMLS_DC)
168 {
169 pcbc_boolean_field_search_query_t *obj = NULL;
170
171 obj = PCBC_ALLOC_OBJECT_T(pcbc_boolean_field_search_query_t, class_type);
172
173 zend_object_std_init(&obj->std, class_type TSRMLS_CC);
174 object_properties_init(&obj->std, class_type);
175
176 #if PHP_VERSION_ID >= 70000
177 obj->std.handlers = &boolean_field_search_query_handlers;
178 return &obj->std;
179 #else
180 {
181 zend_object_value ret;
182 ret.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object,
183 boolean_field_search_query_free_object, NULL TSRMLS_CC);
184 ret.handlers = &boolean_field_search_query_handlers;
185 return ret;
186 }
187 #endif
188 }
189
pcbc_boolean_field_search_query_get_debug_info(zval * object,int * is_temp TSRMLS_DC)190 static HashTable *pcbc_boolean_field_search_query_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
191 {
192 pcbc_boolean_field_search_query_t *obj = NULL;
193 #if PHP_VERSION_ID >= 70000
194 zval retval;
195 #else
196 zval retval = zval_used_for_init;
197 #endif
198
199 *is_temp = 1;
200 obj = Z_BOOLEAN_FIELD_SEARCH_QUERY_OBJ_P(object);
201
202 array_init(&retval);
203 ADD_ASSOC_BOOL_EX(&retval, "bool", obj->value);
204 if (obj->field) {
205 ADD_ASSOC_STRING(&retval, "field", obj->field);
206 }
207 if (obj->boost >= 0) {
208 ADD_ASSOC_DOUBLE_EX(&retval, "boost", obj->boost);
209 }
210 return Z_ARRVAL(retval);
211 } /* }}} */
212
PHP_MINIT_FUNCTION(BooleanFieldSearchQuery)213 PHP_MINIT_FUNCTION(BooleanFieldSearchQuery)
214 {
215 zend_class_entry ce;
216
217 INIT_NS_CLASS_ENTRY(ce, "Couchbase", "BooleanFieldSearchQuery", boolean_field_search_query_methods);
218 pcbc_boolean_field_search_query_ce = zend_register_internal_class(&ce TSRMLS_CC);
219 pcbc_boolean_field_search_query_ce->create_object = boolean_field_search_query_create_object;
220 PCBC_CE_DISABLE_SERIALIZATION(pcbc_boolean_field_search_query_ce);
221
222 zend_class_implements(pcbc_boolean_field_search_query_ce TSRMLS_CC, 1, pcbc_json_serializable_ce);
223 zend_class_implements(pcbc_boolean_field_search_query_ce TSRMLS_CC, 1, pcbc_search_query_part_ce);
224
225 memcpy(&boolean_field_search_query_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
226 boolean_field_search_query_handlers.get_debug_info = pcbc_boolean_field_search_query_get_debug_info;
227 #if PHP_VERSION_ID >= 70000
228 boolean_field_search_query_handlers.free_obj = boolean_field_search_query_free_object;
229 boolean_field_search_query_handlers.offset = XtOffsetOf(pcbc_boolean_field_search_query_t, std);
230 #endif
231
232 zend_register_class_alias("\\CouchbaseBooleanFieldSearchQuery", pcbc_boolean_field_search_query_ce);
233 return SUCCESS;
234 }
235