First pass through turning instance into ++
[m6w6/libmemcached] / libmemcached / fetch.cc
index 8977753489a33835f73d640289869893ab16442c..70e5bf75ef30989c5845a276357bf84553e799bf 100644 (file)
@@ -44,77 +44,166 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
 {
   memcached_result_st *result_buffer= &ptr->result;
   memcached_return_t unused;
-  if (not error)
+  if (error == NULL)
+  {
     error= &unused;
+  }
 
-
-  unlikely (ptr->flags.use_udp)
+  if (memcached_is_udp(ptr))
   {
+    if (value_length)
+    {
+      *value_length= 0;
+    }
+
+    if (key_length)
+    {
+      *key_length= 0;
+    }
+
+    if (flags)
+    {
+      *flags= 0;
+    }
+
+    if (key)
+    {
+      *key= 0;
+    }
+
     *error= MEMCACHED_NOT_SUPPORTED;
     return NULL;
   }
 
   result_buffer= memcached_fetch_result(ptr, result_buffer, error);
-
-  if (result_buffer == NULL or *error != MEMCACHED_SUCCESS)
+  if (result_buffer == NULL or memcached_failed(*error))
   {
     WATCHPOINT_ASSERT(result_buffer == NULL);
-    *value_length= 0;
+    if (value_length)
+    {
+      *value_length= 0;
+    }
+
+    if (key_length)
+    {
+      *key_length= 0;
+    }
+
+    if (flags)
+    {
+      *flags= 0;
+    }
+
+    if (key)
+    {
+      *key= 0;
+    }
+
     return NULL;
   }
 
-  *value_length= memcached_string_length(&result_buffer->value);
+  if (value_length)
+  {
+    *value_length= memcached_string_length(&result_buffer->value);
+  }
 
   if (key)
   {
     if (result_buffer->key_length > MEMCACHED_MAX_KEY)
     {
       *error= MEMCACHED_KEY_TOO_BIG;
-      *value_length= 0;
+      if (value_length)
+      {
+        *value_length= 0;
+      }
+
+      if (key_length)
+      {
+        *key_length= 0;
+      }
+
+      if (flags)
+      {
+        *flags= 0;
+      }
+
+      if (key)
+      {
+        *key= 0;
+      }
 
       return NULL;
     }
+
     strncpy(key, result_buffer->item_key, result_buffer->key_length); // For the binary protocol we will cut off the key :(
-    *key_length= result_buffer->key_length;
+    if (key_length)
+    {
+      *key_length= result_buffer->key_length;
+    }
   }
 
   if (flags)
+  {
     *flags= result_buffer->item_flags;
+  }
 
-  return memcached_string_c_copy(&result_buffer->value);
+  return memcached_string_take_value(&result_buffer->value);
 }
 
 memcached_result_st *memcached_fetch_result(memcached_st *ptr,
                                             memcached_result_st *result,
                                             memcached_return_t *error)
 {
-  memcached_server_st *server;
-
   memcached_return_t unused;
-  if (not error)
+  if (error == NULL)
+  {
     error= &unused;
+  }
+
+  if (ptr == NULL)
+  {
+    *error= MEMCACHED_INVALID_ARGUMENTS;
+    return NULL;
+  }
 
-  if (ptr->flags.use_udp)
+  if (memcached_is_udp(ptr))
   {
     *error= MEMCACHED_NOT_SUPPORTED;
     return NULL;
   }
 
-  if (not result)
+  if (result == NULL)
   {
-    if (not (result= memcached_result_create(ptr, NULL)))
+    // If we have already initialized (ie it is in use) our internal, we
+    // create one.
+    if (memcached_is_initialized(&ptr->result))
     {
-      return NULL;
+      if ((result= memcached_result_create(ptr, NULL)) == NULL)
+      {
+        *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+        return NULL;
+      }
+    }
+    else
+    {
+      result= memcached_result_create(ptr, &ptr->result);
     }
   }
 
+  *error= MEMCACHED_MAXIMUM_RETURN; // We use this to see if we ever go into the loop
+  org::libmemcached::Instance *server;
   while ((server= memcached_io_get_readable_server(ptr)))
   {
     char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
     *error= memcached_response(server, buffer, sizeof(buffer), result);
 
-    if (*error == MEMCACHED_SUCCESS)
+    if (*error == MEMCACHED_IN_PROGRESS)
+    {
+      continue;
+    }
+    else if (*error == MEMCACHED_SUCCESS)
     {
+      result->count++;
       return result;
     }
     else if (*error == MEMCACHED_END)
@@ -127,6 +216,27 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
     }
   }
 
+  if (*error == MEMCACHED_NOTFOUND and result->count)
+  {
+    *error= MEMCACHED_END;
+  }
+  else if (*error == MEMCACHED_MAXIMUM_RETURN and result->count)
+  {
+    *error= MEMCACHED_END;
+  }
+  else if (*error == MEMCACHED_MAXIMUM_RETURN) // while() loop was never entered
+  {
+    *error= MEMCACHED_NOTFOUND;
+  }
+  else if (*error == MEMCACHED_SUCCESS)
+  {
+    *error= MEMCACHED_END;
+  }
+  else if (result->count == 0)
+  {
+    *error= MEMCACHED_NOTFOUND;
+  }
+
   /* We have completed reading data */
   if (memcached_is_allocated(result))
   {
@@ -134,6 +244,7 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
   }
   else
   {
+    result->count= 0;
     memcached_string_reset(&result->value);
   }
 
@@ -146,19 +257,45 @@ memcached_return_t memcached_fetch_execute(memcached_st *ptr,
                                            uint32_t number_of_callbacks)
 {
   memcached_result_st *result= &ptr->result;
-  memcached_return_t rc= MEMCACHED_FAILURE;
+  memcached_return_t rc;
+  bool some_errors= false;
 
-  while ((result= memcached_fetch_result(ptr, result, &rc)) != NULL) 
+  while ((result= memcached_fetch_result(ptr, result, &rc)))
   {
-    if (rc == MEMCACHED_SUCCESS)
+    if (memcached_failed(rc) and rc == MEMCACHED_NOTFOUND)
+    {
+      continue;
+    }
+    else if (memcached_failed(rc))
     {
-      for (uint32_t x= 0; x < number_of_callbacks; x++)
+      memcached_set_error(*ptr, rc, MEMCACHED_AT);
+      some_errors= true;
+      continue;
+    }
+
+    for (uint32_t x= 0; x < number_of_callbacks; x++)
+    {
+      memcached_return_t ret= (*callback[x])(ptr, result, context);
+      if (memcached_failed(ret))
       {
-        rc= (*callback[x])(ptr, result, context);
-        if (rc != MEMCACHED_SUCCESS)
-          break;
+        some_errors= true;
+        memcached_set_error(*ptr, ret, MEMCACHED_AT);
+        break;
       }
     }
   }
+
+  if (some_errors)
+  {
+    return MEMCACHED_SOME_ERRORS;
+  }
+
+  // If we were able to run all keys without issue we return
+  // MEMCACHED_SUCCESS
+  if (memcached_success(rc))
+  {
+    return MEMCACHED_SUCCESS;
+  }
+
   return rc;
 }