diff --git a/.cvsignore b/.cvsignore
index 60a8bcf5..cc617d3d 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -43,3 +43,4 @@ Release_TS_inline
Debug_TS
memcached*.tgz
run-tests.php
+cscope.out
diff --git a/.gitignore b/.gitignore
index fdd0d2cf..0b25b31d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,4 @@ Release_TS_inline
Debug_TS
memcached*.tgz
run-tests.php
+cscope.out
diff --git a/ChangeLog b/ChangeLog
index ee21066a..5791c661 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
memcached extension changelog
+Version 0.1.3
+-------------
+ * Bludgeon bug #15896 (Memcached setMulti error) into submission.
+
+Version 0.1.2
+-------------
+ * Fix bug #15896 (Memcached setMulti error).
+ * Check for empty key in getServerByKey().
+ * Allow passing 'null' for callbacks.
+ * get() with cas token fetching wasn't erroring out properly.
+ * Rename certain parameters in the API to be more clear.
+ * Allow only strings as the append/prepend value.
+ * Remove expiration parameter from append/prepend.
+
Version 0.1.1
-------------
* Add OPT_LIBKETAMA_COMPATIBLE option.
diff --git a/README b/README.markdown
similarity index 69%
rename from README
rename to README.markdown
index 3f324136..2b3b4579 100644
--- a/README
+++ b/README.markdown
@@ -1,3 +1,5 @@
+Description
+-----------
This extension uses libmemcached library to provide API for communicating with
memcached servers.
@@ -7,8 +9,5 @@ by alleviating database load.
Resources
---------
- libmemcached:
- http://tangent.org/552/libmemcached.html
-
- memcached:
- http://www.danga.com/memcached/
+ * [libmemcached](http://tangent.org/552/libmemcached.html)
+ * [memcached](http://www.danga.com/memcached/)
diff --git a/memcached-api.php b/memcached-api.php
index 22be44e7..f1851e14 100644
--- a/memcached-api.php
+++ b/memcached-api.php
@@ -95,9 +95,9 @@ public function set( $key, $value, $expiration = 0 ) {}
public function setByKey( $server_key, $key, $value, $expiration = 0 ) {}
- public function setMulti( $array, $expiration = 0 ) {}
+ public function setMulti( array $items, $expiration = 0 ) {}
- public function setMultiByKey( $server_key, $array, $expiration = 0 ) {}
+ public function setMultiByKey( $server_key, array $items, $expiration = 0 ) {}
public function cas( $token, $key, $value, $expiration = 0 ) {}
@@ -119,9 +119,9 @@ public function replace( $key, $value, $expiration = 0 ) {}
public function replaceByKey( $serve_key, $key, $value, $expiration = 0 ) {}
- public function delete( $key, $expiration = 0 ) {}
+ public function delete( $key, $time = 0 ) {}
- public function deleteByKey( $key, $expiration = 0 ) {}
+ public function deleteByKey( $key, $time = 0 ) {}
public function increment( $key, $offset = 1) {}
@@ -139,7 +139,9 @@ public function getServerList( ) {}
public function getServerByKey( $server_key ) {}
- public function flush( ) {}
+ public function flush( $delay = 0 ) {}
+
+ public function getStats( ) {}
public function getResultCode( ) {}
diff --git a/package.xml b/package.xml
index 620a423c..bf8496d0 100644
--- a/package.xml
+++ b/package.xml
@@ -15,10 +15,10 @@ http://pear.php.net/dtd/package-2.0.xsd">
andrei@php.net
yes
- 2009-02-02
+ 2009-02-06
- 0.1.1
- 0.1.1
+ 0.1.3
+ 0.1.3
beta
@@ -26,14 +26,12 @@ http://pear.php.net/dtd/package-2.0.xsd">
PHP
-- Add OPT_LIBKETAMA_COMPATIBLE option.
-- Implement addServers() method.
-- Swap internal compressed and serialized flags to be compatible with other clients.
+- Bludgeon bug #15896 (Memcached setMulti error) into submission.
-
+
@@ -59,6 +57,30 @@ http://pear.php.net/dtd/package-2.0.xsd">
memcached
+
+ betabeta
+ 0.1.30.1.3
+ 2009-02-06
+
+- Bludgeon bug #15896 (Memcached setMulti error) into submission.
+
+
+
+
+ betabeta
+ 0.1.20.1.2
+ 2009-02-06
+
+- Fix bug #15896 (Memcached setMulti error).
+- Check for empty key in getServerByKey().
+- Allow passing 'null' for callbacks.
+- get() with cas token fetching wasn't erroring out properly.
+- Rename certain parameters in the API to be more clear.
+- Allow only strings as the append/prepend value.
+- Remove expiration parameter from append/prepend.
+
+
+
betabeta
0.1.10.1.1
@@ -69,6 +91,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
- Swap internal compressed and serialized flags to be compatible with other clients.
+
betabeta
0.1.00.1.0
diff --git a/php_memcached.c b/php_memcached.c
index d9fa0d73..60441542 100644
--- a/php_memcached.c
+++ b/php_memcached.c
@@ -17,6 +17,9 @@
/* $ Id: $ */
/* TODO
+ * - set LIBKETAMA_COMPATIBLE as the default?
+ * - add payload flag for IS_BOOL?
+ * - add getVersion()
*/
#ifdef HAVE_CONFIG_H
@@ -290,12 +293,12 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
MEMC_METHOD_INIT_VARS;
if (by_key) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|fz", &server_key,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|f!z", &server_key,
&server_key_len, &key, &key_len, &fci, &fcc, &cas_token) == FAILURE) {
return;
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|fz", &key, &key_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|f!z", &key, &key_len,
&fci, &fcc, &cas_token) == FAILURE) {
return;
}
@@ -332,12 +335,16 @@ static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
if (memcached_fetch_result(i_obj->memc, &result, &status) == NULL) {
+ /* This is for historical reasons */
+ if (status == MEMCACHED_END)
+ status = MEMCACHED_NOTFOUND;
+
/*
* If the result wasn't found, and we have the read-through callback, invoke
* it to get the value. The CAS token will be 0, because we cannot generate it
* ourselves.
*/
- if ((status == MEMCACHED_END || status == MEMCACHED_NOTFOUND) && fci.size != 0) {
+ if (status == MEMCACHED_NOTFOUND && fci.size != 0) {
status = php_memc_do_cache_callback(getThis(), &fci, &fcc, key, key_len,
return_value TSRMLS_DC);
ZVAL_DOUBLE(cas_token, 0);
@@ -609,12 +616,12 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_
MEMC_METHOD_INIT_VARS;
if (by_key) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|bf", &server_key,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|bf!", &server_key,
&server_key_len, &keys, &with_cas, &fci, &fcc) == FAILURE) {
return;
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|bf", &keys, &with_cas,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|bf!", &keys, &with_cas,
&fci, &fcc) == FAILURE) {
return;
}
@@ -837,16 +844,16 @@ PHP_METHOD(Memcached, setByKey)
}
/* }}} */
-/* {{{ Memcached::setMulti(array entries [, int expiration ])
- Sets the keys/values specified in the entries array */
+/* {{{ Memcached::setMulti(array items [, int expiration ])
+ Sets the keys/values specified in the items array */
PHP_METHOD(Memcached, setMulti)
{
php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
}
/* }}} */
-/* {{{ Memcached::setMultiByKey(string server_key, array entries [, int expiration ])
- Sets the keys/values specified in the entries array on the server identified by the given server key */
+/* {{{ Memcached::setMultiByKey(string server_key, array items [, int expiration ])
+ Sets the keys/values specified in the items array on the server identified by the given server key */
PHP_METHOD(Memcached, setMultiByKey)
{
php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
@@ -905,10 +912,10 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke
if (!by_key) {
server_key = str_key;
- server_key_len = str_key_len;
+ server_key_len = str_key_len-1;
}
status = memcached_set_by_key(i_obj->memc, server_key, server_key_len, str_key,
- str_key_len, payload, payload_len, expiration, flags);
+ str_key_len-1, payload, payload_len, expiration, flags);
efree(payload);
if (php_memc_handle_error(status TSRMLS_CC) < 0) {
@@ -991,6 +998,8 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool
int key_len = 0;
char *server_key = NULL;
int server_key_len = 0;
+ char *s_value = NULL;
+ int s_value_len = 0;
zval *value;
time_t expiration = 0;
char *payload;
@@ -1000,14 +1009,32 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool
MEMC_METHOD_INIT_VARS;
if (by_key) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|l", &server_key,
- &server_key_len, &key, &key_len, &value, &expiration) == FAILURE) {
- return;
+ if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &server_key,
+ &server_key_len, &key, &key_len, &s_value, &s_value_len, &expiration) == FAILURE) {
+ return;
+ }
+ MAKE_STD_ZVAL(value);
+ ZVAL_STRINGL(value, s_value, s_value_len, 1);
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssz|l", &server_key,
+ &server_key_len, &key, &key_len, &value, &expiration) == FAILURE) {
+ return;
+ }
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &key, &key_len,
- &value, &expiration) == FAILURE) {
- return;
+ if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &key, &key_len,
+ &s_value, &s_value_len) == FAILURE) {
+ return;
+ }
+ MAKE_STD_ZVAL(value);
+ ZVAL_STRINGL(value, s_value, s_value_len, 1);
+ } else {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &key, &key_len,
+ &value, &expiration) == FAILURE) {
+ return;
+ }
}
server_key = key;
server_key_len = key_len;
@@ -1035,6 +1062,9 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool
}
payload = php_memc_zval_to_payload(value, &payload_len, &flags TSRMLS_CC);
+ if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) {
+ zval_ptr_dtor(&value);
+ }
if (payload == NULL) {
MEMC_G(rescode) = MEMC_RES_PAYLOAD_FAILURE;
RETURN_FALSE;
@@ -1158,7 +1188,7 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key)
}
/* }}} */
-/* {{{ Memcached::delete(string key [, int expiration ])
+/* {{{ Memcached::delete(string key [, int time ])
Deletes the given key */
PHP_METHOD(Memcached, delete)
{
@@ -1166,7 +1196,7 @@ PHP_METHOD(Memcached, delete)
}
/* }}} */
-/* {{{ Memcached::deleteByKey(string server_key, string key [, int expiration ])
+/* {{{ Memcached::deleteByKey(string server_key, string key [, int time ])
Deletes the given key from the server identified by the server key */
PHP_METHOD(Memcached, deleteByKey)
{
@@ -1354,6 +1384,7 @@ PHP_METHOD(Memcached, addServers)
}
}
+ /* catch-all for all errors */
php_error_docref(NULL TSRMLS_CC, E_WARNING, "could not add entry #%d to the server list", i+1);
}
@@ -1414,6 +1445,11 @@ PHP_METHOD(Memcached, getServerByKey)
return;
}
+ if (server_key_len == 0) {
+ MEMC_G(rescode) = MEMCACHED_BAD_KEY_PROVIDED;
+ RETURN_FALSE;
+ }
+
MEMC_METHOD_FETCH_OBJECT;
MEMC_G(rescode) = MEMCACHED_SUCCESS;
@@ -1501,22 +1537,22 @@ PHP_METHOD(Memcached, getStats)
}
/* }}} */
-/* {{{ Memcached::flush([ int expiration ])
+/* {{{ Memcached::flush([ int delay ])
Flushes the data on all the servers */
static PHP_METHOD(Memcached, flush)
{
- time_t expiration = 0;
+ time_t delay = 0;
memcached_return status;
MEMC_METHOD_INIT_VARS;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &expiration) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &delay) == FAILURE) {
return;
}
MEMC_METHOD_FETCH_OBJECT;
MEMC_G(rescode) = MEMCACHED_SUCCESS;
- status = memcached_flush(i_obj->memc, expiration);
+ status = memcached_flush(i_obj->memc, delay);
if (php_memc_handle_error(status TSRMLS_CC) < 0) {
RETURN_FALSE;
}
@@ -2302,14 +2338,14 @@ ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_setMulti, 0, 0, 1)
- ZEND_ARG_ARRAY_INFO(0, entries, 0)
+ ZEND_ARG_ARRAY_INFO(0, items, 0)
ZEND_ARG_INFO(0, expiration)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_setMultiByKey, 0, 0, 2)
ZEND_ARG_INFO(0, server_key)
- ZEND_ARG_ARRAY_INFO(0, entries, 0)
+ ZEND_ARG_ARRAY_INFO(0, items, 0)
ZEND_ARG_INFO(0, expiration)
ZEND_END_ARG_INFO()
@@ -2393,14 +2429,14 @@ ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_delete, 0, 0, 1)
ZEND_ARG_INFO(0, key)
- ZEND_ARG_INFO(0, expiration)
+ ZEND_ARG_INFO(0, time)
ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteByKey, 0, 0, 2)
ZEND_ARG_INFO(0, server_key)
ZEND_ARG_INFO(0, key)
- ZEND_ARG_INFO(0, expiration)
+ ZEND_ARG_INFO(0, time)
ZEND_END_ARG_INFO()
static
@@ -2417,7 +2453,7 @@ ZEND_END_ARG_INFO()
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_flush, 0, 0, 0)
- ZEND_ARG_INFO(0, expiration)
+ ZEND_ARG_INFO(0, delay)
ZEND_END_ARG_INFO()
static
diff --git a/php_memcached.h b/php_memcached.h
index fdb79a8e..d8f2a06b 100644
--- a/php_memcached.h
+++ b/php_memcached.h
@@ -49,7 +49,7 @@ PHP_RINIT_FUNCTION(memcached);
PHP_RSHUTDOWN_FUNCTION(memcached);
PHP_MINFO_FUNCTION(memcached);
-#define PHP_MEMCACHED_VERSION "0.1.1"
+#define PHP_MEMCACHED_VERSION "0.1.3"
#ifdef ZTS
#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_memcache_globals *, v)