thirdparty/google_appengine/google/appengine/api/memcache/__init__.py
changeset 297 35211afcd563
parent 149 f2e327a7c5de
child 2273 e4cb9c53db3e
equal deleted inserted replaced
296:b02dd2a5f329 297:35211afcd563
   339     """
   339     """
   340     request = MemcacheStatsRequest()
   340     request = MemcacheStatsRequest()
   341     response = MemcacheStatsResponse()
   341     response = MemcacheStatsResponse()
   342     try:
   342     try:
   343       self._make_sync_call('memcache', 'Stats', request, response)
   343       self._make_sync_call('memcache', 'Stats', request, response)
   344     except apiproxy_errors.ApplicationError, e:
   344     except apiproxy_errors.Error:
   345       return None
   345       return None
   346 
   346 
   347     if not response.has_stats():
   347     if not response.has_stats():
   348       return None
   348       return None
   349 
   349 
   365     """
   365     """
   366     request = MemcacheFlushRequest()
   366     request = MemcacheFlushRequest()
   367     response = MemcacheFlushResponse()
   367     response = MemcacheFlushResponse()
   368     try:
   368     try:
   369       self._make_sync_call('memcache', 'FlushAll', request, response)
   369       self._make_sync_call('memcache', 'FlushAll', request, response)
   370     except apiproxy_errors.ApplicationError:
   370     except apiproxy_errors.Error:
   371       return False
   371       return False
   372     return True
   372     return True
   373 
   373 
   374   def get(self, key):
   374   def get(self, key):
   375     """Looks up a single key in memcache.
   375     """Looks up a single key in memcache.
   389     request = MemcacheGetRequest()
   389     request = MemcacheGetRequest()
   390     request.add_key(_key_string(key))
   390     request.add_key(_key_string(key))
   391     response = MemcacheGetResponse()
   391     response = MemcacheGetResponse()
   392     try:
   392     try:
   393       self._make_sync_call('memcache', 'Get', request, response)
   393       self._make_sync_call('memcache', 'Get', request, response)
   394     except apiproxy_errors.ApplicationError:
   394     except apiproxy_errors.Error:
   395       return None
   395       return None
   396 
   396 
   397     if not response.item_size():
   397     if not response.item_size():
   398       return None
   398       return None
   399 
   399 
   425     user_key = {}
   425     user_key = {}
   426     for key in keys:
   426     for key in keys:
   427       request.add_key(_key_string(key, key_prefix, user_key))
   427       request.add_key(_key_string(key, key_prefix, user_key))
   428     try:
   428     try:
   429       self._make_sync_call('memcache', 'Get', request, response)
   429       self._make_sync_call('memcache', 'Get', request, response)
   430     except apiproxy_errors.ApplicationError:
   430     except apiproxy_errors.Error:
   431       return {}
   431       return {}
   432 
   432 
   433     return_value = {}
   433     return_value = {}
   434     for returned_item in response.item_list():
   434     for returned_item in response.item_list():
   435       value = _decode_value(returned_item.value(), returned_item.flags(),
   435       value = _decode_value(returned_item.value(), returned_item.flags(),
   468     delete_item = request.add_item()
   468     delete_item = request.add_item()
   469     delete_item.set_key(_key_string(key))
   469     delete_item.set_key(_key_string(key))
   470     delete_item.set_delete_time(int(math.ceil(seconds)))
   470     delete_item.set_delete_time(int(math.ceil(seconds)))
   471     try:
   471     try:
   472       self._make_sync_call('memcache', 'Delete', request, response)
   472       self._make_sync_call('memcache', 'Delete', request, response)
   473     except apiproxy_errors.ApplicationError:
   473     except apiproxy_errors.Error:
   474       return DELETE_NETWORK_FAILURE
   474       return DELETE_NETWORK_FAILURE
   475     assert response.delete_status_size() == 1, 'Unexpected status size.'
   475     assert response.delete_status_size() == 1, 'Unexpected status size.'
   476 
   476 
   477     if response.delete_status(0) == MemcacheDeleteResponse.DELETED:
   477     if response.delete_status(0) == MemcacheDeleteResponse.DELETED:
   478       return DELETE_SUCCESSFUL
   478       return DELETE_SUCCESSFUL
   510       delete_item = request.add_item()
   510       delete_item = request.add_item()
   511       delete_item.set_key(_key_string(key, key_prefix=key_prefix))
   511       delete_item.set_key(_key_string(key, key_prefix=key_prefix))
   512       delete_item.set_delete_time(int(math.ceil(seconds)))
   512       delete_item.set_delete_time(int(math.ceil(seconds)))
   513     try:
   513     try:
   514       self._make_sync_call('memcache', 'Delete', request, response)
   514       self._make_sync_call('memcache', 'Delete', request, response)
   515     except apiproxy_errors.ApplicationError:
   515     except apiproxy_errors.Error:
   516       return False
   516       return False
   517     return True
   517     return True
   518 
   518 
   519   def set(self, key, value, time=0, min_compress_len=0):
   519   def set(self, key, value, time=0, min_compress_len=0):
   520     """Sets a key's value, regardless of previous contents in cache.
   520     """Sets a key's value, regardless of previous contents in cache.
   605     item.set_set_policy(policy)
   605     item.set_set_policy(policy)
   606     item.set_expiration_time(int(math.ceil(time)))
   606     item.set_expiration_time(int(math.ceil(time)))
   607     response = MemcacheSetResponse()
   607     response = MemcacheSetResponse()
   608     try:
   608     try:
   609       self._make_sync_call('memcache', 'Set', request, response)
   609       self._make_sync_call('memcache', 'Set', request, response)
   610     except apiproxy_errors.ApplicationError:
   610     except apiproxy_errors.Error:
   611       return False
   611       return False
   612     if response.set_status_size() != 1:
   612     if response.set_status_size() != 1:
   613       return False
   613       return False
   614     return response.set_status(0) == MemcacheSetResponse.STORED
   614     return response.set_status(0) == MemcacheSetResponse.STORED
   615 
   615 
       
   616   def _set_multi_with_policy(self, policy, mapping, time=0, key_prefix=''):
       
   617     """Set multiple keys with a specified policy.
       
   618 
       
   619     Helper function for set_multi(), add_multi(), and replace_multi(). This
       
   620     reduces the network latency of doing many requests in serial.
       
   621 
       
   622     Args:
       
   623       policy:  One of MemcacheSetRequest.SET, ADD, or REPLACE.
       
   624       mapping: Dictionary of keys to values.
       
   625       time: Optional expiration time, either relative number of seconds
       
   626         from current time (up to 1 month), or an absolute Unix epoch time.
       
   627         By default, items never expire, though items may be evicted due to
       
   628         memory pressure.  Float values will be rounded up to the nearest
       
   629         whole second.
       
   630       key_prefix: Prefix for to prepend to all keys.
       
   631 
       
   632     Returns:
       
   633       A list of keys whose values were NOT set.  On total success,
       
   634       this list should be empty.  On network/RPC/server errors,
       
   635       a list of all input keys is returned; in this case the keys
       
   636       may or may not have been updated.
       
   637     """
       
   638     if not isinstance(time, (int, long, float)):
       
   639       raise TypeError('Expiration must be a number.')
       
   640     if time < 0.0:
       
   641       raise ValueError('Expiration must not be negative.')
       
   642 
       
   643     request = MemcacheSetRequest()
       
   644     user_key = {}
       
   645     server_keys = []
       
   646     for key, value in mapping.iteritems():
       
   647       server_key = _key_string(key, key_prefix, user_key)
       
   648       stored_value, flags = _validate_encode_value(value, self._do_pickle)
       
   649       server_keys.append(server_key)
       
   650 
       
   651       item = request.add_item()
       
   652       item.set_key(server_key)
       
   653       item.set_value(stored_value)
       
   654       item.set_flags(flags)
       
   655       item.set_set_policy(policy)
       
   656       item.set_expiration_time(int(math.ceil(time)))
       
   657 
       
   658     response = MemcacheSetResponse()
       
   659     try:
       
   660       self._make_sync_call('memcache', 'Set', request, response)
       
   661     except apiproxy_errors.Error:
       
   662       return user_key.values()
       
   663 
       
   664     assert response.set_status_size() == len(server_keys)
       
   665 
       
   666     unset_list = []
       
   667     for server_key, set_status in zip(server_keys, response.set_status_list()):
       
   668       if set_status != MemcacheSetResponse.STORED:
       
   669         unset_list.append(user_key[server_key])
       
   670 
       
   671     return unset_list
       
   672 
   616   def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
   673   def set_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
   617     """Set multiple keys' values at once.
   674     """Set multiple keys' values at once, regardless of previous contents.
   618 
       
   619     This reduces the network latency of doing many requests in serial.
       
   620 
   675 
   621     Args:
   676     Args:
   622       mapping: Dictionary of keys to values.
   677       mapping: Dictionary of keys to values.
   623       time: Optional expiration time, either relative number of seconds
   678       time: Optional expiration time, either relative number of seconds
   624         from current time (up to 1 month), or an absolute Unix epoch time.
   679         from current time (up to 1 month), or an absolute Unix epoch time.
   630 
   685 
   631     Returns:
   686     Returns:
   632       A list of keys whose values were NOT set.  On total success,
   687       A list of keys whose values were NOT set.  On total success,
   633       this list should be empty.
   688       this list should be empty.
   634     """
   689     """
   635     if not isinstance(time, (int, long, float)):
   690     return self._set_multi_with_policy(MemcacheSetRequest.SET, mapping,
   636       raise TypeError('Expiration must be a number.')
   691                                        time=time, key_prefix=key_prefix)
   637     if time < 0.0:
   692 
   638       raise ValueError('Expiration must not be negative.')
   693   def add_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
   639 
   694     """Set multiple keys' values iff items are not already in memcache.
   640     request = MemcacheSetRequest()
   695 
   641     user_key = {}
   696     Args:
   642     server_keys = []
   697       mapping: Dictionary of keys to values.
   643     for key, value in mapping.iteritems():
   698       time: Optional expiration time, either relative number of seconds
   644       server_key = _key_string(key, key_prefix, user_key)
   699         from current time (up to 1 month), or an absolute Unix epoch time.
   645       stored_value, flags = _validate_encode_value(value, self._do_pickle)
   700         By default, items never expire, though items may be evicted due to
   646       server_keys.append(server_key)
   701         memory pressure.  Float values will be rounded up to the nearest
   647 
   702         whole second.
   648       item = request.add_item()
   703       key_prefix: Prefix for to prepend to all keys.
   649       item.set_key(server_key)
   704       min_compress_len: Unimplemented compatibility option.
   650       item.set_value(stored_value)
   705 
   651       item.set_flags(flags)
   706     Returns:
   652       item.set_set_policy(MemcacheSetRequest.SET)
   707       A list of keys whose values were NOT set because they did not already
   653       item.set_expiration_time(int(math.ceil(time)))
   708       exist in memcache.  On total success, this list should be empty.
   654 
   709     """
   655     response = MemcacheSetResponse()
   710     return self._set_multi_with_policy(MemcacheSetRequest.ADD, mapping,
   656     try:
   711                                        time=time, key_prefix=key_prefix)
   657       self._make_sync_call('memcache', 'Set', request, response)
   712 
   658     except apiproxy_errors.ApplicationError:
   713   def replace_multi(self, mapping, time=0, key_prefix='', min_compress_len=0):
   659       return False
   714     """Replace multiple keys' values, failing if the items aren't in memcache.
   660 
   715 
   661     assert response.set_status_size() == len(server_keys)
   716     Args:
   662 
   717       mapping: Dictionary of keys to values.
   663     unset_list = []
   718       time: Optional expiration time, either relative number of seconds
   664     for server_key, set_status in zip(server_keys, response.set_status_list()):
   719         from current time (up to 1 month), or an absolute Unix epoch time.
   665       if set_status != MemcacheSetResponse.STORED:
   720         By default, items never expire, though items may be evicted due to
   666         unset_list.append(user_key[server_key])
   721         memory pressure.  Float values will be rounded up to the nearest
   667 
   722         whole second.
   668     return unset_list
   723       key_prefix: Prefix for to prepend to all keys.
       
   724       min_compress_len: Unimplemented compatibility option.
       
   725 
       
   726     Returns:
       
   727       A list of keys whose values were NOT set because they already existed
       
   728       in memcache.  On total success, this list should be empty.
       
   729     """
       
   730     return self._set_multi_with_policy(MemcacheSetRequest.REPLACE, mapping,
       
   731                                        time=time, key_prefix=key_prefix)
   669 
   732 
   670   def incr(self, key, delta=1):
   733   def incr(self, key, delta=1):
   671     """Atomically increments a key's value.
   734     """Atomically increments a key's value.
   672 
   735 
   673     Internally, the value is a unsigned 64-bit integer.  Memcache
   736     Internally, the value is a unsigned 64-bit integer.  Memcache
   683       key: Key to increment.  See Client's docstring for details.
   746       key: Key to increment.  See Client's docstring for details.
   684       delta: Non-negative integer value (int or long) to increment key by,
   747       delta: Non-negative integer value (int or long) to increment key by,
   685         defaulting to 1.
   748         defaulting to 1.
   686 
   749 
   687     Returns:
   750     Returns:
   688       New long integer value, or None if key was not in the cache or could not
   751       New long integer value, or None if key was not in the cache, could not
   689       be incremented for any other reason.
   752       be incremented for any other reason, or a network/RPC/server error
       
   753       occurred.
   690 
   754 
   691     Raises:
   755     Raises:
   692       ValueError: If number is negative.
   756       ValueError: If number is negative.
   693       TypeError: If delta isn't an int or long.
   757       TypeError: If delta isn't an int or long.
   694     """
   758     """
   708       delta: Non-negative integer value (int or long) to decrement key by,
   772       delta: Non-negative integer value (int or long) to decrement key by,
   709         defaulting to 1.
   773         defaulting to 1.
   710 
   774 
   711     Returns:
   775     Returns:
   712       New long integer value, or None if key wasn't in cache and couldn't
   776       New long integer value, or None if key wasn't in cache and couldn't
   713       be decremented.
   777       be decremented, or a network/RPC/server error occurred.
   714 
   778 
   715     Raises:
   779     Raises:
   716       ValueError: If number is negative.
   780       ValueError: If number is negative.
   717       TypeError: If delta isn't an int or long.
   781       TypeError: If delta isn't an int or long.
   718     """
   782     """
   726       is_negative: Boolean, if this is a decrement.
   790       is_negative: Boolean, if this is a decrement.
   727       delta: Non-negative integer amount (int or long) to increment
   791       delta: Non-negative integer amount (int or long) to increment
   728         or decrement by.
   792         or decrement by.
   729 
   793 
   730     Returns:
   794     Returns:
   731       New long integer value, or None on cache miss.
   795       New long integer value, or None on cache miss or network/RPC/server
       
   796       error.
   732 
   797 
   733     Raises:
   798     Raises:
   734       ValueError: If delta is negative.
   799       ValueError: If delta is negative.
   735       TypeError: If delta isn't an int or long.
   800       TypeError: If delta isn't an int or long.
   736     """
   801     """
   748     else:
   813     else:
   749       request.set_direction(MemcacheIncrementRequest.INCREMENT)
   814       request.set_direction(MemcacheIncrementRequest.INCREMENT)
   750 
   815 
   751     try:
   816     try:
   752       self._make_sync_call('memcache', 'Increment', request, response)
   817       self._make_sync_call('memcache', 'Increment', request, response)
   753     except apiproxy_errors.ApplicationError:
   818     except apiproxy_errors.Error:
   754       return None
   819       return None
   755 
   820 
   756     if response.has_new_value():
   821     if response.has_new_value():
   757       return response.new_value()
   822       return response.new_value()
   758     return None
   823     return None
   781   var_dict['get'] = _CLIENT.get
   846   var_dict['get'] = _CLIENT.get
   782   var_dict['get_multi'] = _CLIENT.get_multi
   847   var_dict['get_multi'] = _CLIENT.get_multi
   783   var_dict['set'] = _CLIENT.set
   848   var_dict['set'] = _CLIENT.set
   784   var_dict['set_multi'] = _CLIENT.set_multi
   849   var_dict['set_multi'] = _CLIENT.set_multi
   785   var_dict['add'] = _CLIENT.add
   850   var_dict['add'] = _CLIENT.add
       
   851   var_dict['add_multi'] = _CLIENT.add_multi
   786   var_dict['replace'] = _CLIENT.replace
   852   var_dict['replace'] = _CLIENT.replace
       
   853   var_dict['replace_multi'] = _CLIENT.replace_multi
   787   var_dict['delete'] = _CLIENT.delete
   854   var_dict['delete'] = _CLIENT.delete
   788   var_dict['delete_multi'] = _CLIENT.delete_multi
   855   var_dict['delete_multi'] = _CLIENT.delete_multi
   789   var_dict['incr'] = _CLIENT.incr
   856   var_dict['incr'] = _CLIENT.incr
   790   var_dict['decr'] = _CLIENT.decr
   857   var_dict['decr'] = _CLIENT.decr
   791   var_dict['flush_all'] = _CLIENT.flush_all
   858   var_dict['flush_all'] = _CLIENT.flush_all