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 #include "couchbase.h"
18 #include <Zend/zend_alloc.h>
19
20 #define LOGARGS(lvl) LCB_LOG_##lvl, NULL, "pcbc/mutation_token", __FILE__, __LINE__
21
22 zend_class_entry *pcbc_mutation_token_ce;
23
24 /* {{{ proto void MutationToken::__construct() Should not be called directly */
PHP_METHOD(MutationToken,__construct)25 PHP_METHOD(MutationToken, __construct)
26 {
27 throw_pcbc_exception("Accessing private constructor.", LCB_EINVAL);
28 }
29 /* }}} */
30
31 /* {{{ proto \Couchbase\MutationToken MutationToken::from(string $bucketName, int $vbucketID, string $vbucketUUID,
32 string $sequeceNumber) */
PHP_METHOD(MutationToken,from)33 PHP_METHOD(MutationToken, from)
34 {
35 long vbid = 0;
36 char *bucket = NULL, *vbuuid = NULL, *seqno = NULL;
37 pcbc_str_arg_size bucket_len = 0, vbuuid_len = 0, seqno_len = 0;
38 int rv;
39
40 rv = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "slss", &bucket, &bucket_len, &vbid, &vbuuid, &vbuuid_len,
41 &seqno, &seqno_len);
42 if (rv == FAILURE) {
43 RETURN_NULL();
44 }
45
46 pcbc_mutation_token_init_php(return_value, bucket, bucket_len, vbid, vbuuid, vbuuid_len, seqno,
47 seqno_len TSRMLS_CC);
48 } /* }}} */
49
50 /* {{{ proto string MutationToken::bucketName() */
PHP_METHOD(MutationToken,bucketName)51 PHP_METHOD(MutationToken, bucketName)
52 {
53 pcbc_mutation_token_t *obj;
54 int rv;
55
56 rv = zend_parse_parameters_none();
57 if (rv == FAILURE) {
58 RETURN_NULL();
59 }
60 obj = Z_MUTATION_TOKEN_OBJ_P(getThis());
61
62 #if PHP_VERSION_ID >= 70000
63 ZVAL_STRING(return_value, obj->bucket);
64 #else
65 ZVAL_STRING(return_value, obj->bucket, 1);
66 #endif
67 } /* }}} */
68
69 /* {{{ proto int MutationToken::vbucketId() */
PHP_METHOD(MutationToken,vbucketId)70 PHP_METHOD(MutationToken, vbucketId)
71 {
72 pcbc_mutation_token_t *obj;
73 int rv;
74
75 rv = zend_parse_parameters_none();
76 if (rv == FAILURE) {
77 RETURN_NULL();
78 }
79 obj = Z_MUTATION_TOKEN_OBJ_P(getThis());
80
81 RETURN_LONG(PCBC_MUTATION_TOKEN_VB(obj));
82 } /* }}} */
83
84 /* {{{ proto int MutationToken::vbucketUuid() */
PHP_METHOD(MutationToken,vbucketUuid)85 PHP_METHOD(MutationToken, vbucketUuid)
86 {
87 pcbc_mutation_token_t *obj;
88 int rv;
89 char *str;
90
91 rv = zend_parse_parameters_none();
92 if (rv == FAILURE) {
93 RETURN_NULL();
94 }
95 obj = Z_MUTATION_TOKEN_OBJ_P(getThis());
96
97 str = pcbc_base36_encode_str(PCBC_MUTATION_TOKEN_ID(obj));
98 #if PHP_VERSION_ID >= 70000
99 ZVAL_STRING(return_value, str);
100 efree(str);
101 #else
102 ZVAL_STRING(return_value, str, 0);
103 #endif
104 } /* }}} */
105
106 /* {{{ proto int MutationToken::sequenceNumber() */
PHP_METHOD(MutationToken,sequenceNumber)107 PHP_METHOD(MutationToken, sequenceNumber)
108 {
109 pcbc_mutation_token_t *obj;
110 int rv;
111 char *str;
112
113 rv = zend_parse_parameters_none();
114 if (rv == FAILURE) {
115 RETURN_NULL();
116 }
117 obj = Z_MUTATION_TOKEN_OBJ_P(getThis());
118
119 str = pcbc_base36_encode_str(PCBC_MUTATION_TOKEN_SEQ(obj));
120 #if PHP_VERSION_ID >= 70000
121 ZVAL_STRING(return_value, str);
122 efree(str);
123 #else
124 ZVAL_STRING(return_value, str, 0);
125 #endif
126 } /* }}} */
127
128 ZEND_BEGIN_ARG_INFO_EX(ai_MutationToken_none, 0, 0, 0)
129 ZEND_END_ARG_INFO()
130
131 ZEND_BEGIN_ARG_INFO_EX(ai_MutationToken_from, 0, 0, 4)
132 ZEND_ARG_INFO(0, bucketName)
133 ZEND_ARG_INFO(0, vbucketId)
134 ZEND_ARG_INFO(0, vbucketUuid)
135 ZEND_ARG_INFO(0, sequenceNumber)
136 ZEND_END_ARG_INFO()
137
138 // clang-format off
139 zend_function_entry mutation_token_methods[] = {
140 PHP_ME(MutationToken, __construct, ai_MutationToken_none, ZEND_ACC_PRIVATE | ZEND_ACC_FINAL | ZEND_ACC_CTOR)
141 PHP_ME(MutationToken, from, ai_MutationToken_from, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
142 PHP_ME(MutationToken, bucketName, ai_MutationToken_none, ZEND_ACC_PUBLIC)
143 PHP_ME(MutationToken, vbucketId, ai_MutationToken_none, ZEND_ACC_PUBLIC)
144 PHP_ME(MutationToken, vbucketUuid, ai_MutationToken_none, ZEND_ACC_PUBLIC)
145 PHP_ME(MutationToken, sequenceNumber, ai_MutationToken_none, ZEND_ACC_PUBLIC)
146 PHP_FE_END
147 };
148 // clang-format on
149
150 zend_object_handlers pcbc_mutation_token_handlers;
151
pcbc_mutation_token_init(zval * return_value,const char * bucket,const lcb_MUTATION_TOKEN * mt TSRMLS_DC)152 void pcbc_mutation_token_init(zval *return_value, const char *bucket, const lcb_MUTATION_TOKEN *mt TSRMLS_DC)
153 {
154 pcbc_mutation_token_t *token;
155
156 object_init_ex(return_value, pcbc_mutation_token_ce);
157 token = Z_MUTATION_TOKEN_OBJ_P(return_value);
158 token->bucket = estrdup(bucket);
159 token->mt = *mt;
160 }
161
pcbc_mutation_token_init_php(zval * return_value,char * bucket,int bucket_len,long vbid,char * vbuuid,int vbuuid_len,char * seqno,int seqno_len TSRMLS_DC)162 void pcbc_mutation_token_init_php(zval *return_value, char *bucket, int bucket_len, long vbid, char *vbuuid,
163 int vbuuid_len, char *seqno, int seqno_len TSRMLS_DC)
164 {
165 lcb_MUTATION_TOKEN mt;
166 LCB_MUTATION_TOKEN_VB(&mt) = (lcb_U16)vbid;
167 LCB_MUTATION_TOKEN_ID(&mt) = pcbc_base36_decode_str(vbuuid, vbuuid_len);
168 LCB_MUTATION_TOKEN_SEQ(&mt) = pcbc_base36_decode_str(seqno, seqno_len);
169 pcbc_mutation_token_init(return_value, bucket, &mt TSRMLS_CC);
170 }
171
mutation_token_free_object(pcbc_free_object_arg * object TSRMLS_DC)172 static void mutation_token_free_object(pcbc_free_object_arg *object TSRMLS_DC) /* {{{ */
173 {
174 pcbc_mutation_token_t *obj = Z_MUTATION_TOKEN_OBJ(object);
175
176 efree(obj->bucket);
177
178 zend_object_std_dtor(&obj->std TSRMLS_CC);
179 #if PHP_VERSION_ID < 70000
180 efree(obj);
181 #endif
182 } /* }}} */
183
mutation_token_create_object(zend_class_entry * class_type TSRMLS_DC)184 static pcbc_create_object_retval mutation_token_create_object(zend_class_entry *class_type TSRMLS_DC)
185 {
186 pcbc_mutation_token_t *obj = NULL;
187
188 obj = PCBC_ALLOC_OBJECT_T(pcbc_mutation_token_t, class_type);
189
190 zend_object_std_init(&obj->std, class_type TSRMLS_CC);
191 object_properties_init(&obj->std, class_type);
192
193 #if PHP_VERSION_ID >= 70000
194 obj->std.handlers = &pcbc_mutation_token_handlers;
195 return &obj->std;
196 #else
197 {
198 zend_object_value ret;
199 ret.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t)zend_objects_destroy_object,
200 mutation_token_free_object, NULL TSRMLS_CC);
201 ret.handlers = &pcbc_mutation_token_handlers;
202 return ret;
203 }
204 #endif
205 }
206
mutation_token_get_debug_info(zval * object,int * is_temp TSRMLS_DC)207 static HashTable *mutation_token_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
208 {
209 pcbc_mutation_token_t *obj = NULL;
210 #if PHP_VERSION_ID >= 70000
211 zval retval;
212 #else
213 zval retval = zval_used_for_init;
214 #endif
215 char *num36;
216
217 *is_temp = 1;
218 obj = Z_MUTATION_TOKEN_OBJ_P(object);
219
220 array_init(&retval);
221 ADD_ASSOC_STRING(&retval, "bucket", obj->bucket);
222 ADD_ASSOC_LONG_EX(&retval, "vbucketId", PCBC_MUTATION_TOKEN_VB(obj));
223 num36 = pcbc_base36_encode_str(PCBC_MUTATION_TOKEN_ID(obj));
224 ADD_ASSOC_STRING(&retval, "vbucketUuid", num36);
225 efree(num36);
226 num36 = pcbc_base36_encode_str(PCBC_MUTATION_TOKEN_SEQ(obj));
227 ADD_ASSOC_STRING(&retval, "sequenceNumber", num36);
228 efree(num36);
229
230 return Z_ARRVAL(retval);
231 } /* }}} */
232
PHP_MINIT_FUNCTION(MutationToken)233 PHP_MINIT_FUNCTION(MutationToken)
234 {
235 zend_class_entry ce;
236
237 INIT_NS_CLASS_ENTRY(ce, "Couchbase", "MutationToken", mutation_token_methods);
238 pcbc_mutation_token_ce = zend_register_internal_class(&ce TSRMLS_CC);
239 pcbc_mutation_token_ce->create_object = mutation_token_create_object;
240 PCBC_CE_DISABLE_SERIALIZATION(pcbc_mutation_token_ce);
241
242 memcpy(&pcbc_mutation_token_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
243 pcbc_mutation_token_handlers.get_debug_info = mutation_token_get_debug_info;
244 #if PHP_VERSION_ID >= 70000
245 pcbc_mutation_token_handlers.free_obj = mutation_token_free_object;
246 pcbc_mutation_token_handlers.offset = XtOffsetOf(pcbc_mutation_token_t, std);
247 #endif
248
249 zend_register_class_alias("\\CouchbaseMutationToken", pcbc_mutation_token_ce);
250 return SUCCESS;
251 }
252