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 matches 0 document (usually for debugging purposes).
19  */
20 #include "couchbase.h"
21 
22 typedef struct {
23     PCBC_ZEND_OBJECT_PRE
24     double boost;
25     PCBC_ZEND_OBJECT_POST
26 } pcbc_match_none_search_query_t;
27 
28 #if PHP_VERSION_ID >= 70000
pcbc_match_none_search_query_fetch_object(zend_object * obj)29 static inline pcbc_match_none_search_query_t *pcbc_match_none_search_query_fetch_object(zend_object *obj)
30 {
31     return (pcbc_match_none_search_query_t *)((char *)obj - XtOffsetOf(pcbc_match_none_search_query_t, std));
32 }
33 #define Z_MATCH_NONE_SEARCH_QUERY_OBJ(zo) (pcbc_match_none_search_query_fetch_object(zo))
34 #define Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(zv) (pcbc_match_none_search_query_fetch_object(Z_OBJ_P(zv)))
35 #else
36 #define Z_MATCH_NONE_SEARCH_QUERY_OBJ(zo) ((pcbc_match_none_search_query_t *)zo)
37 #define Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(zv)                                                                            \
38     ((pcbc_match_none_search_query_t *)zend_object_store_get_object(zv TSRMLS_CC))
39 #endif
40 
41 #define LOGARGS(lvl) LCB_LOG_##lvl, NULL, "pcbc/match_none_search_query", __FILE__, __LINE__
42 
43 zend_class_entry *pcbc_match_none_search_query_ce;
44 
45 /* {{{ proto void MatchNoneSearchQuery::__construct() */
PHP_METHOD(MatchNoneSearchQuery,__construct)46 PHP_METHOD(MatchNoneSearchQuery, __construct)
47 {
48     throw_pcbc_exception("Accessing private constructor.", LCB_EINVAL);
49 }
50 /* }}} */
51 
52 /* {{{ proto \Couchbase\MatchNoneSearchQuery MatchNoneSearchQuery::boost(double $boost)
53  */
PHP_METHOD(MatchNoneSearchQuery,boost)54 PHP_METHOD(MatchNoneSearchQuery, boost)
55 {
56     pcbc_match_none_search_query_t *obj;
57     double boost = 0;
58     int rv;
59 
60     rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &boost);
61     if (rv == FAILURE) {
62         RETURN_NULL();
63     }
64 
65     obj = Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(getThis());
66     obj->boost = boost;
67 
68     RETURN_ZVAL(getThis(), 1, 0);
69 } /* }}} */
70 
71 /* {{{ proto array MatchNoneSearchQuery::jsonSerialize()
72  */
PHP_METHOD(MatchNoneSearchQuery,jsonSerialize)73 PHP_METHOD(MatchNoneSearchQuery, jsonSerialize)
74 {
75     pcbc_match_none_search_query_t *obj;
76     int rv;
77 
78     rv = zend_parse_parameters_none();
79     if (rv == FAILURE) {
80         RETURN_NULL();
81     }
82 
83     obj = Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(getThis());
84     array_init(return_value);
85     ADD_ASSOC_NULL_EX(return_value, "match_none");
86     if (obj->boost >= 0) {
87         ADD_ASSOC_DOUBLE_EX(return_value, "boost", obj->boost);
88     }
89 } /* }}} */
90 
91 ZEND_BEGIN_ARG_INFO_EX(ai_MatchNoneSearchQuery_none, 0, 0, 0)
92 ZEND_END_ARG_INFO()
93 
94 ZEND_BEGIN_ARG_INFO_EX(ai_MatchNoneSearchQuery_boost, 0, 0, 1)
95 ZEND_ARG_INFO(0, boost)
96 ZEND_END_ARG_INFO()
97 
98 // clang-format off
99 zend_function_entry match_none_search_query_methods[] = {
100     PHP_ME(MatchNoneSearchQuery, __construct, ai_MatchNoneSearchQuery_none, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL | ZEND_ACC_CTOR)
101     PHP_ME(MatchNoneSearchQuery, jsonSerialize, ai_MatchNoneSearchQuery_none, ZEND_ACC_PUBLIC)
102     PHP_ME(MatchNoneSearchQuery, boost, ai_MatchNoneSearchQuery_boost, ZEND_ACC_PUBLIC)
103     PHP_FE_END
104 };
105 // clang-format on
106 
pcbc_match_none_search_query_init(zval * return_value TSRMLS_DC)107 void pcbc_match_none_search_query_init(zval *return_value TSRMLS_DC)
108 {
109     pcbc_match_none_search_query_t *obj;
110 
111     object_init_ex(return_value, pcbc_match_none_search_query_ce);
112     obj = Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(return_value);
113     obj->boost = -1;
114 }
115 
116 zend_object_handlers match_none_search_query_handlers;
117 
match_none_search_query_free_object(pcbc_free_object_arg * object TSRMLS_DC)118 static void match_none_search_query_free_object(pcbc_free_object_arg *object TSRMLS_DC) /* {{{ */
119 {
120     pcbc_match_none_search_query_t *obj = Z_MATCH_NONE_SEARCH_QUERY_OBJ(object);
121 
122     zend_object_std_dtor(&obj->std TSRMLS_CC);
123 #if PHP_VERSION_ID < 70000
124     efree(obj);
125 #endif
126 } /* }}} */
127 
match_none_search_query_create_object(zend_class_entry * class_type TSRMLS_DC)128 static pcbc_create_object_retval match_none_search_query_create_object(zend_class_entry *class_type TSRMLS_DC)
129 {
130     pcbc_match_none_search_query_t *obj = NULL;
131 
132     obj = PCBC_ALLOC_OBJECT_T(pcbc_match_none_search_query_t, class_type);
133 
134     zend_object_std_init(&obj->std, class_type TSRMLS_CC);
135     object_properties_init(&obj->std, class_type);
136 
137 #if PHP_VERSION_ID >= 70000
138     obj->std.handlers = &match_none_search_query_handlers;
139     return &obj->std;
140 #else
141     {
142         zend_object_value ret;
143         ret.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object,
144                                             match_none_search_query_free_object, NULL TSRMLS_CC);
145         ret.handlers = &match_none_search_query_handlers;
146         return ret;
147     }
148 #endif
149 }
150 
pcbc_match_none_search_query_get_debug_info(zval * object,int * is_temp TSRMLS_DC)151 static HashTable *pcbc_match_none_search_query_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
152 {
153     pcbc_match_none_search_query_t *obj = NULL;
154 #if PHP_VERSION_ID >= 70000
155     zval retval;
156 #else
157     zval retval = zval_used_for_init;
158 #endif
159 
160     *is_temp = 1;
161     obj = Z_MATCH_NONE_SEARCH_QUERY_OBJ_P(object);
162 
163     array_init(&retval);
164     ADD_ASSOC_NULL_EX(&retval, "match_none");
165     if (obj->boost >= 0) {
166         ADD_ASSOC_DOUBLE_EX(&retval, "boost", obj->boost);
167     }
168     return Z_ARRVAL(retval);
169 } /* }}} */
170 
PHP_MINIT_FUNCTION(MatchNoneSearchQuery)171 PHP_MINIT_FUNCTION(MatchNoneSearchQuery)
172 {
173     zend_class_entry ce;
174 
175     INIT_NS_CLASS_ENTRY(ce, "Couchbase", "MatchNoneSearchQuery", match_none_search_query_methods);
176     pcbc_match_none_search_query_ce = zend_register_internal_class(&ce TSRMLS_CC);
177     pcbc_match_none_search_query_ce->create_object = match_none_search_query_create_object;
178     PCBC_CE_DISABLE_SERIALIZATION(pcbc_match_none_search_query_ce);
179 
180     zend_class_implements(pcbc_match_none_search_query_ce TSRMLS_CC, 1, pcbc_json_serializable_ce);
181     zend_class_implements(pcbc_match_none_search_query_ce TSRMLS_CC, 1, pcbc_search_query_part_ce);
182 
183     memcpy(&match_none_search_query_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
184     match_none_search_query_handlers.get_debug_info = pcbc_match_none_search_query_get_debug_info;
185 #if PHP_VERSION_ID >= 70000
186     match_none_search_query_handlers.free_obj = match_none_search_query_free_object;
187     match_none_search_query_handlers.offset = XtOffsetOf(pcbc_match_none_search_query_t, std);
188 #endif
189 
190     zend_register_class_alias("\\CouchbaseMatchNoneSearchQuery", pcbc_match_none_search_query_ce);
191     return SUCCESS;
192 }
193