| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  | <?php | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * StatusNet - the distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2010, StatusNet, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Wrapper for Memcached_DataObject which knows its own schema definition. | 
					
						
							|  |  |  |  * Builds its own damn settings from a schema definition. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-08-16 15:14:16 -07:00
										 |  |  |  * @author Brion Vibber <brion@status.net> | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-08-16 15:14:16 -07:00
										 |  |  | abstract class Managed_DataObject extends Memcached_DataObject | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * The One True Thingy that must be defined and declared. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-09-21 18:44:05 +02:00
										 |  |  |     public static function schemaDef() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         throw new MethodNotImplementedException(__METHOD__); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-12 19:12:13 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get an instance by key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $k Key to use to lookup (usually 'id' for this class) | 
					
						
							|  |  |  |      * @param mixed  $v Value to lookup | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return get_called_class() object if found, or null for no hits | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-08-18 13:04:58 +02:00
										 |  |  |     static function getKV($k,$v=NULL) | 
					
						
							| 
									
										
										
										
											2013-08-12 19:12:13 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-08-18 15:42:51 +02:00
										 |  |  |         return parent::getClassKV(get_called_class(), $k, $v); | 
					
						
							| 
									
										
										
										
											2013-08-12 19:12:13 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-18 15:42:51 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get an instance by compound key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This is a utility method to get a single instance with a given set of | 
					
						
							|  |  |  |      * key-value pairs. Usually used for the primary key for a compound key; thus | 
					
						
							|  |  |  |      * the name. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $kv array of key-value mappings | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return get_called_class() object if found, or null for no hits | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-08-29 10:27:39 +02:00
										 |  |  |     static function pkeyGet(array $kv) | 
					
						
							| 
									
										
										
										
											2013-08-18 15:42:51 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         return parent::pkeyGetClass(get_called_class(), $kv); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-08-12 19:12:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 10:38:11 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get multiple items from the database by key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string  $keyCol    name of column for key | 
					
						
							|  |  |  |      * @param array   $keyVals   key values to fetch | 
					
						
							|  |  |  |      * @param boolean $skipNulls return only non-null results? | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array Array of objects, in order | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 	static function multiGet($keyCol, array $keyVals, $skipNulls=true) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    return parent::multiGetClass(get_called_class(), $keyCol, $keyVals, $skipNulls); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-29 10:13:07 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get multiple items from the database by key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string  $keyCol    name of column for key | 
					
						
							|  |  |  |      * @param array   $keyVals   key values to fetch | 
					
						
							|  |  |  |      * @param array   $otherCols Other columns to hold fixed | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array Array mapping $keyVals to objects, or null if not found | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 	static function pivotGet($keyCol, array $keyVals, array $otherCols=array()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    return parent::pivotGetClass(get_called_class(), $keyCol, $keyVals, $otherCols); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Get a multi-instance object | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This is a utility method to get multiple instances with a given set of | 
					
						
							| 
									
										
										
										
											2013-09-21 16:55:18 +02:00
										 |  |  |      * values for a specific column. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param string $keyCol  key column name | 
					
						
							|  |  |  |      * @param array  $keyVals array of key values | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return get_called_class() object with multiple instances if found, | 
					
						
							|  |  |  |      *         Exception is thrown when no entries are found. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     static function listFind($keyCol, array $keyVals) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return parent::listFindClass(get_called_class(), $keyCol, $keyVals); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2013-10-01 11:37:59 +02:00
										 |  |  |      * Get a multi-instance object separated into an array | 
					
						
							| 
									
										
										
										
											2013-09-21 16:55:18 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      * This is a utility method to get multiple instances with a given set of | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |      * values for a specific key column. Usually used for the primary key when | 
					
						
							| 
									
										
										
										
											2013-09-21 16:55:18 +02:00
										 |  |  |      * multiple values are desired. Result is an array. | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2013-08-29 10:27:39 +02:00
										 |  |  |      * @param string $keyCol  key column name | 
					
						
							|  |  |  |      * @param array  $keyVals array of key values | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2013-09-21 16:55:18 +02:00
										 |  |  |      * @return array with an get_called_class() object for each $keyVals entry | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |      * | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-08-29 10:27:39 +02:00
										 |  |  |     static function listGet($keyCol, array $keyVals) | 
					
						
							| 
									
										
										
										
											2013-08-18 21:02:33 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         return parent::listGetClass(get_called_class(), $keyCol, $keyVals); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * get/set an associative array of table columns | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @access public | 
					
						
							|  |  |  |      * @return array (associative) | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2013-10-14 18:18:11 +02:00
										 |  |  |     public function table() | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-08-20 09:43:51 +02:00
										 |  |  |         $table = static::schemaDef(); | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         return array_map(array($this, 'columnBitmap'), $table['fields']); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * get/set an  array of table primary keys | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Key info is pulled from the table definition array. | 
					
						
							|  |  |  |      *  | 
					
						
							|  |  |  |      * @access private | 
					
						
							|  |  |  |      * @return array | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function keys() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return array_keys($this->keyTypes()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a sequence key | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * Returns the first serial column defined in the table, if any. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @access private | 
					
						
							|  |  |  |      * @return array (column,use_native,sequence_name) | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function sequenceKey() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-10-14 18:18:11 +02:00
										 |  |  |         $table = static::schemaDef(); | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         foreach ($table['fields'] as $name => $column) { | 
					
						
							|  |  |  |             if ($column['type'] == 'serial') { | 
					
						
							|  |  |  |                 // We have a serial/autoincrement column.
 | 
					
						
							|  |  |  |                 // Declare it to be a native sequence!
 | 
					
						
							|  |  |  |                 return array($name, true, false); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // No sequence key on this table.
 | 
					
						
							|  |  |  |         return array(false, false, false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Return key definitions for DB_DataObject and Memcache_DataObject. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * DB_DataObject needs to know about keys that the table has; this function
 | 
					
						
							|  |  |  |      * defines them. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array key definitions | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function keyTypes() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-10-14 18:18:11 +02:00
										 |  |  |         $table = static::schemaDef(); | 
					
						
							| 
									
										
										
										
											2011-03-21 15:04:32 -07:00
										 |  |  |         $keys = array(); | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($table['unique keys'])) { | 
					
						
							|  |  |  |             foreach ($table['unique keys'] as $idx => $fields) { | 
					
						
							|  |  |  |                 foreach ($fields as $name) { | 
					
						
							|  |  |  |                     $keys[$name] = 'U'; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($table['primary key'])) { | 
					
						
							|  |  |  |             foreach ($table['primary key'] as $name) { | 
					
						
							|  |  |  |                 $keys[$name] = 'K'; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $keys; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Build the appropriate DB_DataObject bitfield map for this field. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param array $column | 
					
						
							|  |  |  |      * @return int | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function columnBitmap($column) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-08-16 15:28:00 -07:00
										 |  |  |         $type = $column['type']; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // For quoting style...
 | 
					
						
							|  |  |  |         $intTypes = array('int', | 
					
						
							|  |  |  |                           'integer', | 
					
						
							|  |  |  |                           'float', | 
					
						
							|  |  |  |                           'serial', | 
					
						
							|  |  |  |                           'numeric'); | 
					
						
							|  |  |  |         if (in_array($type, $intTypes)) { | 
					
						
							|  |  |  |             $style = DB_DATAOBJECT_INT; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             $style = DB_DATAOBJECT_STR; | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 15:28:00 -07:00
										 |  |  |         // Data type formatting style...
 | 
					
						
							|  |  |  |         $formatStyles = array('blob' => DB_DATAOBJECT_BLOB, | 
					
						
							|  |  |  |                               'text' => DB_DATAOBJECT_TXT, | 
					
						
							|  |  |  |                               'date' => DB_DATAOBJECT_DATE, | 
					
						
							|  |  |  |                               'time' => DB_DATAOBJECT_TIME, | 
					
						
							|  |  |  |                               'datetime' => DB_DATAOBJECT_DATE | DB_DATAOBJECT_TIME, | 
					
						
							|  |  |  |                               'timestamp' => DB_DATAOBJECT_MYSQLTIMESTAMP); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isset($formatStyles[$type])) { | 
					
						
							|  |  |  |             $style |= $formatStyles[$type]; | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 15:28:00 -07:00
										 |  |  |         // Nullable?
 | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         if (!empty($column['not null'])) { | 
					
						
							| 
									
										
										
										
											2010-08-16 15:28:00 -07:00
										 |  |  |             $style |= DB_DATAOBJECT_NOTNULL; | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-16 15:28:00 -07:00
										 |  |  |         return $style; | 
					
						
							| 
									
										
										
										
											2010-08-16 14:02:31 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-08-26 11:37:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function links() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $links = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-14 18:18:11 +02:00
										 |  |  |         $table = static::schemaDef(); | 
					
						
							| 
									
										
										
										
											2011-08-26 11:37:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach ($table['foreign keys'] as $keyname => $keydef) { | 
					
						
							|  |  |  |             if (count($keydef) == 2 && is_string($keydef[0]) && is_array($keydef[1]) && count($keydef[1]) == 1) { | 
					
						
							| 
									
										
										
										
											2011-09-07 21:45:49 -07:00
										 |  |  |                 if (isset($keydef[1][0])) { | 
					
						
							|  |  |  |                     $links[$keydef[1][0]] = $keydef[0].':'.$keydef[1][1]; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2011-08-26 11:37:45 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return $links; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Return a list of all primary/unique keys / vals that will be used for | 
					
						
							|  |  |  |      * caching. This will understand compound unique keys, which | 
					
						
							|  |  |  |      * Memcached_DataObject doesn't have enough info to handle properly. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @return array of strings | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     function _allCacheKeys() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-10-14 18:18:11 +02:00
										 |  |  |         $table = static::schemaDef(); | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |         $ckeys = array(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($table['unique keys'])) { | 
					
						
							| 
									
										
											  
											
												Further fixes to Managed_DataObject::_allCacheKeys(): now uses self::multicacheKey() to generate the (possibly compound) keys, which makes it match the order of the keys used when calling pkeyGet().
This should resolve the issues darkip was reporting with user_im_prefs entries returning null immediately after insertion (seen with memcached off, so it was happening even with the built-in in-process cache in the Cache base class).
What was happening was that the initial pkeyGet() would end up saving a negative cache entry under the form with the fields sorted in the key, as via multicacheKey():
    'statusnet:blaguette:user_im_prefs:screenname,transport:brionv,sms' => 'N;'
then we'd do an insert() on the new entry, saving cache entries for the non-sorted key names returned by _allCacheKeys():
    'statusnet:blaguette:user_im_prefs:transport,screenname:sms,brionv' => 'O...'
    'statusnet:blaguette:user_im_prefs:user_id,transport:1234,sms' => 'O...'
but the next query via pkeyGet() still saw the negative lookup cache from before, and came back with null.
Now, _allCacheKeys() sorts the fields in the keys by using the same key-builder function, and queries pick up the same thing you just inserted. :)
											
										 
											2011-09-29 15:21:52 -07:00
										 |  |  |             $keyNames = $table['unique keys']; | 
					
						
							|  |  |  |             foreach ($keyNames as $idx => $fields) { | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |                 $val = array(); | 
					
						
							|  |  |  |                 foreach ($fields as $name) { | 
					
						
							| 
									
										
											  
											
												Further fixes to Managed_DataObject::_allCacheKeys(): now uses self::multicacheKey() to generate the (possibly compound) keys, which makes it match the order of the keys used when calling pkeyGet().
This should resolve the issues darkip was reporting with user_im_prefs entries returning null immediately after insertion (seen with memcached off, so it was happening even with the built-in in-process cache in the Cache base class).
What was happening was that the initial pkeyGet() would end up saving a negative cache entry under the form with the fields sorted in the key, as via multicacheKey():
    'statusnet:blaguette:user_im_prefs:screenname,transport:brionv,sms' => 'N;'
then we'd do an insert() on the new entry, saving cache entries for the non-sorted key names returned by _allCacheKeys():
    'statusnet:blaguette:user_im_prefs:transport,screenname:sms,brionv' => 'O...'
    'statusnet:blaguette:user_im_prefs:user_id,transport:1234,sms' => 'O...'
but the next query via pkeyGet() still saw the negative lookup cache from before, and came back with null.
Now, _allCacheKeys() sorts the fields in the keys by using the same key-builder function, and queries pick up the same thing you just inserted. :)
											
										 
											2011-09-29 15:21:52 -07:00
										 |  |  |                     $val[$name] = self::valueString($this->$name); | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |                 } | 
					
						
							| 
									
										
											  
											
												Further fixes to Managed_DataObject::_allCacheKeys(): now uses self::multicacheKey() to generate the (possibly compound) keys, which makes it match the order of the keys used when calling pkeyGet().
This should resolve the issues darkip was reporting with user_im_prefs entries returning null immediately after insertion (seen with memcached off, so it was happening even with the built-in in-process cache in the Cache base class).
What was happening was that the initial pkeyGet() would end up saving a negative cache entry under the form with the fields sorted in the key, as via multicacheKey():
    'statusnet:blaguette:user_im_prefs:screenname,transport:brionv,sms' => 'N;'
then we'd do an insert() on the new entry, saving cache entries for the non-sorted key names returned by _allCacheKeys():
    'statusnet:blaguette:user_im_prefs:transport,screenname:sms,brionv' => 'O...'
    'statusnet:blaguette:user_im_prefs:user_id,transport:1234,sms' => 'O...'
but the next query via pkeyGet() still saw the negative lookup cache from before, and came back with null.
Now, _allCacheKeys() sorts the fields in the keys by using the same key-builder function, and queries pick up the same thing you just inserted. :)
											
										 
											2011-09-29 15:21:52 -07:00
										 |  |  |                 $ckeys[] = self::multicacheKey($this->tableName(), $val); | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($table['primary key'])) { | 
					
						
							|  |  |  |             $fields = $table['primary key']; | 
					
						
							|  |  |  |             $val = array(); | 
					
						
							|  |  |  |             foreach ($fields as $name) { | 
					
						
							| 
									
										
											  
											
												Further fixes to Managed_DataObject::_allCacheKeys(): now uses self::multicacheKey() to generate the (possibly compound) keys, which makes it match the order of the keys used when calling pkeyGet().
This should resolve the issues darkip was reporting with user_im_prefs entries returning null immediately after insertion (seen with memcached off, so it was happening even with the built-in in-process cache in the Cache base class).
What was happening was that the initial pkeyGet() would end up saving a negative cache entry under the form with the fields sorted in the key, as via multicacheKey():
    'statusnet:blaguette:user_im_prefs:screenname,transport:brionv,sms' => 'N;'
then we'd do an insert() on the new entry, saving cache entries for the non-sorted key names returned by _allCacheKeys():
    'statusnet:blaguette:user_im_prefs:transport,screenname:sms,brionv' => 'O...'
    'statusnet:blaguette:user_im_prefs:user_id,transport:1234,sms' => 'O...'
but the next query via pkeyGet() still saw the negative lookup cache from before, and came back with null.
Now, _allCacheKeys() sorts the fields in the keys by using the same key-builder function, and queries pick up the same thing you just inserted. :)
											
										 
											2011-09-29 15:21:52 -07:00
										 |  |  |                 $val[$name] = self::valueString($this->$name); | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
											  
											
												Further fixes to Managed_DataObject::_allCacheKeys(): now uses self::multicacheKey() to generate the (possibly compound) keys, which makes it match the order of the keys used when calling pkeyGet().
This should resolve the issues darkip was reporting with user_im_prefs entries returning null immediately after insertion (seen with memcached off, so it was happening even with the built-in in-process cache in the Cache base class).
What was happening was that the initial pkeyGet() would end up saving a negative cache entry under the form with the fields sorted in the key, as via multicacheKey():
    'statusnet:blaguette:user_im_prefs:screenname,transport:brionv,sms' => 'N;'
then we'd do an insert() on the new entry, saving cache entries for the non-sorted key names returned by _allCacheKeys():
    'statusnet:blaguette:user_im_prefs:transport,screenname:sms,brionv' => 'O...'
    'statusnet:blaguette:user_im_prefs:user_id,transport:1234,sms' => 'O...'
but the next query via pkeyGet() still saw the negative lookup cache from before, and came back with null.
Now, _allCacheKeys() sorts the fields in the keys by using the same key-builder function, and queries pick up the same thing you just inserted. :)
											
										 
											2011-09-29 15:21:52 -07:00
										 |  |  |             $ckeys[] = self::multicacheKey($this->tableName(), $val); | 
					
						
							| 
									
										
										
										
											2011-09-28 18:32:43 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         return $ckeys; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-08-12 19:12:13 +02:00
										 |  |  | } |