Skip to content

Commit 8d30b8f

Browse files
committed
PCBC-660: Detect when to raise CasMismatchException
Change-Id: Ia1f6f812697aa4be7550ece327d69bcc02946bba Reviewed-on: http://review.couchbase.org/123053 Tested-by: Build Bot <[email protected]> Reviewed-by: Sergey Avseyev <[email protected]>
1 parent cc27c6d commit 8d30b8f

File tree

6 files changed

+36
-12
lines changed

6 files changed

+36
-12
lines changed

couchbase.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,13 @@ extern zend_class_entry *pcbc_binary_collection_ce;
130130
#define PCBC_RESOLVE_COLLECTION PCBC_RESOLVE_COLLECTION_EX(pcbc_collection_ce)
131131
#define PCBC_RESOLVE_BINARY_COLLECTION PCBC_RESOLVE_COLLECTION_EX(pcbc_binary_collection_ce)
132132

133+
#define PCBC_OPCODE_UNSPEC (-1)
134+
#define PCBC_OPCODE_REPLACE (1)
135+
#define PCBC_OPCODE_DELETE (2)
136+
#define PCBC_OPCODE_UNLOCK (3)
137+
133138
void pcbc_create_lcb_exception(zval *return_value, long code, zend_string *context, zend_string *ref, int http_code,
134-
const char *http_msg TSRMLS_DC);
139+
const char *http_msg, int opcode TSRMLS_DC);
135140

136141
void pcbc_exception_init(zval *return_value, long code, const char *message TSRMLS_DC);
137142
#define throw_pcbc_exception(__pcbc_message, __pcbc_code) \
@@ -142,7 +147,7 @@ void pcbc_exception_init(zval *return_value, long code, const char *message TSRM
142147
zend_throw_exception_object(&__pcbc_error TSRMLS_CC); \
143148
} while (0)
144149

145-
#define throw_lcb_exception(code, result_ce) \
150+
#define throw_lcb_exception_ex(code, opcode, result_ce) \
146151
do { \
147152
zend_string *ctx = NULL, *ref = NULL; \
148153
zval *zref, __rv1, *zctx, __rv2; \
@@ -158,15 +163,18 @@ void pcbc_exception_init(zval *return_value, long code, const char *message TSRM
158163
} \
159164
zval __pcbc_error; \
160165
ZVAL_UNDEF(&__pcbc_error); \
161-
pcbc_create_lcb_exception(&__pcbc_error, code, ctx, ref, 0, NULL TSRMLS_CC); \
166+
pcbc_create_lcb_exception(&__pcbc_error, code, ctx, ref, 0, NULL, opcode TSRMLS_CC); \
162167
zend_throw_exception_object(&__pcbc_error TSRMLS_CC); \
163168
} while (0)
164169

170+
#define throw_lcb_exception(code, result_ce) throw_lcb_exception_ex((code), PCBC_OPCODE_UNSPEC, (result_ce))
171+
165172
#define throw_http_exception(code, query_code, query_msg) \
166173
do { \
167174
zval __pcbc_error; \
168175
ZVAL_UNDEF(&__pcbc_error); \
169-
pcbc_create_lcb_exception(&__pcbc_error, code, NULL, NULL, query_code, query_msg TSRMLS_CC); \
176+
pcbc_create_lcb_exception(&__pcbc_error, code, NULL, NULL, query_code, query_msg, \
177+
PCBC_OPCODE_UNSPEC TSRMLS_CC); \
170178
zend_throw_exception_object(&__pcbc_error TSRMLS_CC); \
171179
} while (0)
172180

exception.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ PHP_MINIT_FUNCTION(CouchbaseException)
138138

139139
INIT_NS_CLASS_ENTRY(ce, "Couchbase", "KeyValueException", NULL);
140140
pcbc_key_value_exception_ce = zend_register_internal_class_ex(&ce, pcbc_base_exception_ce TSRMLS_CC);
141-
INIT_NS_CLASS_ENTRY(ce, "Couchbase", "KeyNotFoundException", NULL);
141+
INIT_NS_CLASS_ENTRY(ce, "Couchbase", "DocumentNotFoundException", NULL);
142142
pcbc_key_not_found_exception_ce = zend_register_internal_class_ex(&ce, pcbc_key_value_exception_ce TSRMLS_CC);
143+
zend_register_class_alias("Couchbase\\KeyNotFoundException", pcbc_key_not_found_exception_ce);
143144
INIT_NS_CLASS_ENTRY(ce, "Couchbase", "KeyExistsException", NULL);
144145
pcbc_key_exists_exception_ce = zend_register_internal_class_ex(&ce, pcbc_key_value_exception_ce TSRMLS_CC);
145146
INIT_NS_CLASS_ENTRY(ce, "Couchbase", "ValueTooBigException", NULL);
@@ -196,7 +197,7 @@ PHP_MINIT_FUNCTION(CouchbaseException)
196197
}
197198

198199
void pcbc_create_lcb_exception(zval *return_value, long code, zend_string *context, zend_string *ref, int http_code,
199-
const char *http_msg TSRMLS_DC)
200+
const char *http_msg, int opcode TSRMLS_DC)
200201
{
201202
zend_class_entry *exc_ce = NULL;
202203

@@ -210,7 +211,22 @@ void pcbc_create_lcb_exception(zval *return_value, long code, zend_string *conte
210211
break;
211212

212213
case LCB_ERR_DOCUMENT_EXISTS:
213-
exc_ce = pcbc_key_exists_exception_ce;
214+
switch (opcode) {
215+
case PCBC_OPCODE_DELETE:
216+
case PCBC_OPCODE_REPLACE:
217+
exc_ce = pcbc_cas_mismatch_exception_ce;
218+
break;
219+
default:
220+
exc_ce = pcbc_key_exists_exception_ce;
221+
}
222+
break;
223+
224+
case LCB_ERR_DOCUMENT_LOCKED:
225+
if (opcode == PCBC_OPCODE_UNLOCK) {
226+
exc_ce = pcbc_cas_mismatch_exception_ce;
227+
} else {
228+
exc_ce = pcbc_key_exists_exception_ce;
229+
}
214230
break;
215231

216232
case LCB_ERR_DOCUMENT_NOT_FOUND:

src/couchbase/bucket/remove.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ PHP_METHOD(Collection, remove)
159159
lcb_cmdremove_create(&cmd);
160160
lcb_cmdremove_collection(cmd, scope_str, scope_len, collection_str, collection_len);
161161
lcb_cmdremove_key(cmd, ZSTR_VAL(id), ZSTR_LEN(id));
162+
uint64_t cas = 0;
162163
if (options) {
163164
zval *prop, ret;
164165
prop = zend_read_property(pcbc_remove_options_ce, options, ZEND_STRL("timeout"), 0, &ret);
@@ -173,7 +174,6 @@ PHP_METHOD(Collection, remove)
173174
if (Z_TYPE_P(prop) == IS_STRING) {
174175
zend_string *decoded = php_base64_decode_str(Z_STR_P(prop));
175176
if (decoded) {
176-
uint64_t cas = 0;
177177
memcpy(&cas, ZSTR_VAL(decoded), ZSTR_LEN(decoded));
178178
lcb_cmdremove_cas(cmd, cas);
179179
zend_string_free(decoded);
@@ -202,7 +202,7 @@ PHP_METHOD(Collection, remove)
202202
}
203203

204204
if (err != LCB_SUCCESS) {
205-
throw_lcb_exception(err, pcbc_mutation_result_impl_ce);
205+
throw_lcb_exception_ex(err, cas == 0 ? PCBC_OPCODE_UNSPEC : PCBC_OPCODE_DELETE, pcbc_mutation_result_impl_ce);
206206
}
207207
}
208208

src/couchbase/bucket/store.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ PHP_METHOD(Collection, replace)
578578
lcbtrace_span_finish(parent_span, LCBTRACE_NOW);
579579
}
580580
if (err != LCB_SUCCESS) {
581-
throw_lcb_exception(err, pcbc_store_result_impl_ce);
581+
throw_lcb_exception_ex(err, PCBC_OPCODE_REPLACE, pcbc_store_result_impl_ce);
582582
}
583583
}
584584

src/couchbase/bucket/unlock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ PHP_METHOD(Collection, unlock)
132132
}
133133

134134
if (err != LCB_SUCCESS) {
135-
throw_lcb_exception(err, pcbc_result_impl_ce);
135+
throw_lcb_exception_ex(err, PCBC_OPCODE_UNLOCK, pcbc_result_impl_ce);
136136
}
137137
}
138138

tests/BucketTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ function testCas($c) {
171171
$this->wrapException(function() use($c, $key, $old_cas) {
172172
$options = (new \Couchbase\ReplaceOptions())->cas($old_cas);
173173
$c->replace($key, 'ferret', $options);
174-
}, '\Couchbase\KeyExistsException', COUCHBASE_KEYALREADYEXISTS);
174+
}, '\Couchbase\CasMismatchException', COUCHBASE_KEYALREADYEXISTS);
175175
}
176176

177177
/**

0 commit comments

Comments
 (0)