Пример #1
0
PHP_COUCHBASE_LOCAL
void pcbc_ht_storeb(zval *assoc, const char *key, int nkey, zend_bool value)
{
	pcbc_ht_key hk;
	pcbc_ht_key_create(key, nkey, &hk);
	pcbc_ht_hkstoreb(assoc, &hk, value);
	pcbc_ht_key_cleanup(&hk);
}
Пример #2
0
PHP_COUCHBASE_LOCAL
void pcbc_ht_key_free(pcbc_ht_key *info)
{
	if (!info) {
		return;
	}
	pcbc_ht_key_cleanup(info);
	efree(info);
}
Пример #3
0
PHP_COUCHBASE_LOCAL
zval *pcbc_ht_find(zval *assoc, const char *key, int key_len)
{
	zval *ret;
	pcbc_ht_key hk = { NULL };
	pcbc_ht_key_create(key, key_len, &hk);
	ret = pcbc_ht_hkfind(assoc, &hk);
	pcbc_ht_key_cleanup(&hk);
	return ret;
}
Пример #4
0
PHP_COUCHBASE_LOCAL
void pcbc_ht_del(zval *assoc, const char *key, unsigned int key_len)
{
	pcbc_ht_key hk = { NULL };
	ISARRAY_SANITY(assoc);
	pcbc_ht_key_create(key, key_len, &hk);

	zend_hash_del(Z_ARRVAL_P(assoc), hk.key, hk.key_len + 1);

	pcbc_ht_key_cleanup(&hk);
}
Пример #5
0
/**
 * Populate the snapshot results from the observe operations
 * @param res the couchbase object
 * @param ocoll the observe collection
 * @param abools an array (or single) boolean
 * @param adetails an array of details to be indexed by key
 * @param multi boolean param - this determines whether abools is a scalar or
 *  an array
 */
static void oks_populate_results(php_couchbase_res *res,
								 struct observe_collection *ocoll,
								 zval *abools,
								 zval *adetails,
								 int multi)
{
	int ii;

	if (multi && IS_ARRAY != Z_TYPE_P(abools)) {
		array_init(abools);
	}

	for (ii = 0; ii < ocoll->nks; ii++) {
		/* get the key */
		pcbc_ht_key reski;
		zval *tmpary;

		struct observe_keystate *oks = ocoll->ks + ii;

		pcbc_ht_key_create(
			oks->ocmd.v.v0.key,
			oks->ocmd.v.v0.nkey,
			&reski);

		if (multi) {
			pcbc_ht_hkstoreb(abools,
							 &reski, oks_get_boolval(oks));

		} else {

			if (oks_get_boolval(oks)) {
				ZVAL_TRUE(abools);

			} else {
				ZVAL_FALSE(abools);
			}
		}

		if (adetails != NULL) {
			ALLOC_INIT_ZVAL(tmpary);
			array_init(tmpary);
			oks_to_zvarray(oks, tmpary);
			pcbc_ht_hkstorez(adetails, &reski, tmpary);
		}

		pcbc_ht_key_cleanup(&reski);
	}
}
Пример #6
0
PHP_COUCHBASE_LOCAL
int pcbc_ht_exists(zval *assoc, const char *key, int key_len)
{
	pcbc_ht_key hk = { NULL };
	const char *zh_key;
	int zh_nkey;
	int ret;

	ISARRAY_SANITY(assoc);


	pcbc_ht_key_create(key, key_len, &hk);

	HK_STRING(&hk, zh_key, zh_nkey);
	ret = zend_hash_exists(Z_ARRVAL_P(assoc), zh_key, zh_nkey);

	pcbc_ht_key_cleanup(&hk);

	return ret;
}
Пример #7
0
PHP_COUCHBASE_LOCAL
void php_couchbase_observe_impl(INTERNAL_FUNCTION_PARAMETERS,
								int multi, int oo, int poll)
{

	zval *adurability = NULL,
		  *adetails = NULL; /* zval passed by ref, will be stuffed with details if given */

	php_couchbase_res *couchbase_res;
	struct observe_collection ocoll = { 0 };
	struct observe_expectation expect = { 0 };
	struct observe_pollprefs pollprefs;
	int argflags = oo ? PHP_COUCHBASE_ARG_F_OO : PHP_COUCHBASE_ARG_F_FUNCTIONAL;

	/* param handling, return value setup */
	if (multi) {
		zval *akey_to_cas;
		if (poll) {
			PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags, "aa",
									 &akey_to_cas, &adurability);
		} else {
			PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags,
									 "a|z", &akey_to_cas, &adetails);
		}

		array_init(return_value);

		if (poll) {
			if (-1 == oks_extract_durability(couchbase_res,
											 &expect, &pollprefs, adurability)) {
				RETURN_FALSE;
			}
		}

		if (-1 == oks_build_context(couchbase_res,
									&ocoll, &expect, akey_to_cas, 1)) {
			RETURN_FALSE;
		}

	} else { /* single */

		char *key = NULL;
		long nkey = 0;
		zval *cas;
		zval *akc_dummy = NULL;

		pcbc_ht_key dummy_hk;
		lcb_cas_t tmpcas = 0;
		ZVAL_FALSE(return_value);

		if (poll) {
			PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags,
									 "sza", &key, &nkey, &cas, &adurability);
		} else {
			PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags,
									 "sz|z", &key, &nkey, &cas, &adetails);
		}

		if (adetails && IS_ARRAY != Z_TYPE_P(adetails)) {
			array_init(adetails);
		}

		if (key == NULL || nkey == 0) {
			/* empty key */
			RETURN_FALSE;
		}

		make_prefixed_hk(couchbase_res, key, nkey, &dummy_hk);
		tmpcas = cas_from_zval(cas);

		if (tmpcas == -1) {
			pcbc_ht_key_cleanup(&dummy_hk);
			RETURN_FALSE;
		}

		ALLOC_INIT_ZVAL(akc_dummy);
		array_init(akc_dummy);

		if (tmpcas) {
			pcbc_ht_hkstores(akc_dummy, &dummy_hk,
							 Z_STRVAL_P(cas), Z_STRLEN_P(cas));
		} else {
			pcbc_ht_hkstoreb(akc_dummy, &dummy_hk, 0);
		}

		/* Weird block right here to sanely free the structures allocated */
		{
			int have_failure = 0;
			do {

				if (poll) {
					if (-1 == oks_extract_durability(couchbase_res,
													 &expect,
													 &pollprefs,
													 adurability)) {
						have_failure = 1;
						break;
					}
				}

				if (-1 == oks_build_context(
							couchbase_res, &ocoll, &expect, akc_dummy, 0)) {

					have_failure = 1;
					break;
				}
			} while (0);

			/** >> CLEANUP HERE */
			zval_ptr_dtor(&akc_dummy);
			pcbc_ht_key_cleanup(&dummy_hk);

			if (have_failure) {
				RETURN_FALSE;
			}
		}
	}

	if (adetails && Z_TYPE_P(adetails) != IS_ARRAY) {
		array_init(adetails);
	}

	if (poll) {
		observe_poll(couchbase_res, &ocoll, &pollprefs);

	} else {
		observe_iterate(couchbase_res, &ocoll);
	}

	oks_populate_results(couchbase_res,
						 &ocoll, return_value, adetails, multi);

	oks_cleanup_context(&ocoll);
}
Пример #8
0
/**
 * Populate an observe collection with the appropriate key contexts
 * @param res the couchbase object
 * @param ocoll an already allocated collection object
 * @param akc a zend array mapping keys to their expected CAS values
 * @param expectation an array of durability requirements
 * @param append_prefix - whether the keys should be appended with the
 * 	couchbase-level prefix
 */
static int oks_build_context(php_couchbase_res *res,
							 struct observe_collection *ocoll,
							 struct observe_expectation *expectation,
							 zval *akc,
							 int append_prefix)
{
	int nks, ix;
	struct observe_keystate *ks;

	nks = pcbc_ht_len(akc);
	ks = ecalloc(sizeof(*ks), nks);

	for (ix = 0, pcbc_ht_iter_init(akc);
			pcbc_ht_iter_remaining(akc);
			pcbc_ht_iter_next(akc), ix++) {

		pcbc_ht_entry *kv = pcbc_ht_iter_entry(akc);
		struct observe_keystate *oks = ks + ix;

		if (kv->key_info->key_len == 0) {
			ix--;
			continue;
		}

		oks->parent = ocoll;
		if (expectation) {
			oks->expected = *expectation;
		}

		if ((oks->expected.cas = cas_from_zval(kv->data)) == -1) {
			pcbc_ht_entry_free(kv);
			goto GT_CLEANUP;
		}

		if (append_prefix && res->prefix_key_len &&
				ocoll->prefix_appended == 0) {

			pcbc_ht_key prefixed_ki;
			make_prefixed_hk(res, kv->key_info->key, kv->key_info->key_len,
							 &prefixed_ki);

			oks->ocmd.v.v0.nkey = prefixed_ki.key_len;
			oks->ocmd.v.v0.key = emalloc(prefixed_ki.key_len);

			memcpy((char *)oks->ocmd.v.v0.key,
				   prefixed_ki.key,
				   prefixed_ki.key_len);

			pcbc_ht_key_cleanup(&prefixed_ki);

		} else {
			oks->ocmd.v.v0.key = emalloc(kv->key_info->key_len);
			oks->ocmd.v.v0.nkey = kv->key_info->key_len;

			memcpy((char *)oks->ocmd.v.v0.key,
				   kv->key_info->key,
				   oks->ocmd.v.v0.nkey);
		}

		pcbc_ht_entry_free(kv);

		if (append_prefix && res->prefix_key_len) {
			ocoll->prefix_appended = 1;
		}
	}

	ocoll->ks = ks;
	ocoll->nks = ix;
	ocoll->remaining = ocoll->nks;
	ocoll->res = res;
	return 0;

GT_CLEANUP:
	for (ix = 0; ix < nks; ix++) {
		struct observe_keystate *oks = ks + ix;
		if (oks->ocmd.v.v0.key) {
			efree((void *) oks->ocmd.v.v0.key);
		}
	}
	efree(ks);
	return -1;
}