X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FMemcached_DataObject.php;h=288457c0f1a7933e8e33e968777be7d50538021f;hb=a9c4bcd71f0ce046bd57ea727c140c6e91fcd013;hp=11be6c7c27c8fd8a766f1ba505a433c224b9cb9c;hpb=ed31052d2641d0cc8f9f87facce88ab779d7a909;p=quix0rs-gnu-social.git diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index 11be6c7c27..288457c0f1 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -30,23 +30,23 @@ class Memcached_DataObject extends Safe_DataObject * @param mixed $v key field value, or leave out for primary key lookup * @return mixed Memcached_DataObject subtype or false */ - function &staticGet($cls, $k, $v=null) + static function getClassKV($cls, $k, $v=null) { + if (!is_a($cls, __CLASS__, true)) { + throw new Exception('Trying to fetch ' . __CLASS__ . ' into a non-related class'); + } if (is_null($v)) { $v = $k; - // XXX: HACK! - $i = new $cls; - $keys = $i->keys(); + $keys = self::pkeyCols($cls); + if (count($keys) > 1) { + // FIXME: maybe call pkeyGetClass() ourselves? + throw new Exception('Use pkeyGetClass() for compound primary keys'); + } $k = $keys[0]; - unset($i); } - $i = Memcached_DataObject::getcached($cls, $k, $v); + $i = self::getcached($cls, $k, $v); if ($i === false) { // false == cache miss - $i = DB_DataObject::factory($cls); - if (empty($i)) { - $i = false; - return $i; - } + $i = new $cls; $result = $i->get($k, $v); if ($result) { // Hit! @@ -63,48 +63,51 @@ class Memcached_DataObject extends Safe_DataObject } return $i; } - + /** * Get multiple items from the database by key - * + * * @param string $cls Class to fetch * @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 */ - function multiGet($cls, $keyCol, $keyVals, $skipNulls=true) - { - $result = self::pivotGet($cls, $keyCol, $keyVals); - - $values = array_values($result); - - if ($skipNulls) { - $tmp = array(); - foreach ($values as $value) { - if (!empty($value)) { - $tmp[] = $value; - } - } - $values = $tmp; - } - - return new ArrayWrapper($values); - } - + static function multiGetClass($cls, $keyCol, array $keyVals, $skipNulls=true) + { + $result = self::pivotGetClass($cls, $keyCol, $keyVals); + + $values = array_values($result); + + if ($skipNulls) { + $tmp = array(); + foreach ($values as $value) { + if (!empty($value)) { + $tmp[] = $value; + } + } + $values = $tmp; + } + + return new ArrayWrapper($values); + } + /** * Get multiple items from the database by key - * + * * @param string $cls Class to fetch * @param string $keyCol name of column for key * @param array $keyVals key values to fetch * @param boolean $otherCols Other columns to hold fixed - * + * * @return array Array mapping $keyVals to objects, or null if not found */ - static function pivotGet($cls, $keyCol, $keyVals, $otherCols = array()) + static function pivotGetClass($cls, $keyCol, array $keyVals, array $otherCols = array()) { + if (!is_a($cls, __CLASS__, true)) { + throw new Exception('Trying to fetch ' . __CLASS__ . ' into a non-related class'); + } if (is_array($keyCol)) { foreach ($keyVals as $keyVal) { $result[implode(',', $keyVal)] = null; @@ -112,10 +115,10 @@ class Memcached_DataObject extends Safe_DataObject } else { $result = array_fill_keys($keyVals, null); } - - $toFetch = array(); - - foreach ($keyVals as $keyVal) { + + $toFetch = array(); + + foreach ($keyVals as $keyVal) { if (is_array($keyCol)) { $kv = array_combine($keyCol, $keyVal); @@ -123,26 +126,23 @@ class Memcached_DataObject extends Safe_DataObject $kv = array($keyCol => $keyVal); } - $kv = array_merge($otherCols, $kv); - - $i = self::multicache($cls, $kv); - - if ($i !== false) { + $kv = array_merge($otherCols, $kv); + + $i = self::multicache($cls, $kv); + + if ($i !== false) { if (is_array($keyCol)) { $result[implode(',', $keyVal)] = $i; } else { $result[$keyVal] = $i; } - } else if (!empty($keyVal)) { - $toFetch[] = $keyVal; - } - } - - if (count($toFetch) > 0) { - $i = DB_DataObject::factory($cls); - if (empty($i)) { - throw new Exception(_('Cannot instantiate class ' . $cls)); + } else if (!empty($keyVal)) { + $toFetch[] = $keyVal; } + } + + if (count($toFetch) > 0) { + $i = new $cls; foreach ($otherCols as $otherKeyCol => $otherKeyVal) { $i->$otherKeyCol = $otherKeyVal; } @@ -151,10 +151,10 @@ class Memcached_DataObject extends Safe_DataObject } else { $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol)); } - if ($i->find()) { - while ($i->fetch()) { - $copy = clone($i); - $copy->encache(); + if ($i->find()) { + while ($i->fetch()) { + $copy = clone($i); + $copy->encache(); if (is_array($keyCol)) { $vals = array(); foreach ($keyCol as $k) { @@ -164,36 +164,36 @@ class Memcached_DataObject extends Safe_DataObject } else { $result[$i->$keyCol] = $copy; } - } - } - - // Save state of DB misses - - foreach ($toFetch as $keyVal) { + } + } + + // Save state of DB misses + + foreach ($toFetch as $keyVal) { $r = null; if (is_array($keyCol)) { $r = $result[implode(',', $keyVal)]; } else { $r = $result[$keyVal]; } - if (empty($r)) { + if (empty($r)) { if (is_array($keyCol)) { $kv = array_combine($keyCol, $keyVal); } else { $kv = array($keyCol => $keyVal); } $kv = array_merge($otherCols, $kv); - // save the fact that no such row exists - $c = self::memcache(); - if (!empty($c)) { - $ck = self::multicacheKey($cls, $kv); - $c->set($ck, null); - } - } - } - } + // save the fact that no such row exists + $c = self::memcache(); + if (!empty($c)) { + $ck = self::multicacheKey($cls, $kv); + $c->set($ck, null); + } + } + } + } - return $result; + return $result; } static function _inMultiKey($i, $cols, $values) @@ -246,10 +246,10 @@ class Memcached_DataObject extends Safe_DataObject static function pkeyCols($cls) { - $i = DB_DataObject::factory($cls); - if (empty($i)) { - throw new Exception(_('Cannot instantiate a ' . $cls)); + if (!is_a($cls, __CLASS__, true)) { + throw new Exception('Trying to fetch ' . __CLASS__ . ' into a non-related class'); } + $i = new $cls; $types = $i->keyTypes(); ksort($types); @@ -264,46 +264,51 @@ class Memcached_DataObject extends Safe_DataObject return $pkey; } - function listGet($cls, $keyCol, $keyVals) + static function listGetClass($cls, $keyCol, array $keyVals) { - $pkeyMap = array_fill_keys($keyVals, array()); - $results = array_fill_keys($keyVals, array()); + if (!is_a($cls, __CLASS__, true)) { + throw new Exception('Trying to fetch ' . __CLASS__ . ' into a non-related class'); + } + $pkeyMap = array_fill_keys($keyVals, array()); + $result = array_fill_keys($keyVals, array()); $pkeyCols = self::pkeyCols($cls); - - $toFetch = array(); + + $toFetch = array(); $allPkeys = array(); // We only cache keys -- not objects! - foreach ($keyVals as $keyVal) { - $l = self::cacheGet(sprintf("%s:list-ids:%s:%s", $cls, $keyCol, $keyVal)); - if ($l !== false) { - $pkeyMap[$keyVal] = $l; - $allPkeys = array_merge($allPkeys, $l); - } else { - $toFetch[] = $keyVal; - } - } - - $keyResults = self::pivotGet($cls, $pkeyCols, $allPkeys); - - foreach ($pkeyMap as $keyVal => $pkeyList) { - foreach ($pkeyList as $pkeyVal) { - $i = $keyResults[$pkeyVal]; - if (!empty($i)) { - $results[$keyVal][] = $i; + foreach ($keyVals as $keyVal) { + $l = self::cacheGet(sprintf("%s:list-ids:%s:%s", strtolower($cls), $keyCol, $keyVal)); + if ($l !== false) { + $pkeyMap[$keyVal] = $l; + foreach ($l as $pkey) { + $allPkeys[] = $pkey; + } + } else { + $toFetch[] = $keyVal; + } + } + + if (count($allPkeys) > 0) { + $keyResults = self::pivotGetClass($cls, $pkeyCols, $allPkeys); + + foreach ($pkeyMap as $keyVal => $pkeyList) { + foreach ($pkeyList as $pkeyVal) { + $i = $keyResults[implode(',',$pkeyVal)]; + if (!empty($i)) { + $result[$keyVal][] = $i; + } } } } if (count($toFetch) > 0) { - $i = DB_DataObject::factory($cls); - if (empty($i)) { - throw new Exception(_('Cannot instantiate class ' . $cls)); - } + $i = new $cls; $i->whereAddIn($keyCol, $toFetch, $i->columnType($keyCol)); if ($i->find()) { + sprintf(__CLASS__ . "() got {$i->N} results for class $cls key $keyCol"); while ($i->fetch()) { $copy = clone($i); $copy->encache(); @@ -314,53 +319,53 @@ class Memcached_DataObject extends Safe_DataObject } $pkeyMap[$i->$keyCol][] = $pkeyVal; } - } - foreach ($toFetch as $keyVal) { - self::cacheSet(sprintf("%s:list-ids:%s:%s", $cls, $keyCol, $keyVal), + } + foreach ($toFetch as $keyVal) { + self::cacheSet(sprintf("%s:list-ids:%s:%s", strtolower($cls), $keyCol, $keyVal), $pkeyMap[$keyVal]); - } - } - - return $result; - } - - function columnType($columnName) - { - $keys = $this->table(); - if (!array_key_exists($columnName, $keys)) { - throw new Exception('Unknown key column ' . $columnName . ' in ' . join(',', array_keys($keys))); - } - - $def = $keys[$columnName]; - - if ($def & DB_DATAOBJECT_INT) { - return 'integer'; - } else { - return 'string'; - } - } - + } + } + + return $result; + } + + function columnType($columnName) + { + $keys = $this->table(); + if (!array_key_exists($columnName, $keys)) { + throw new Exception('Unknown key column ' . $columnName . ' in ' . join(',', array_keys($keys))); + } + + $def = $keys[$columnName]; + + if ($def & DB_DATAOBJECT_INT) { + return 'integer'; + } else { + return 'string'; + } + } + /** - * @fixme Should this return false on lookup fail to match staticGet? + * @todo FIXME: Should this return false on lookup fail to match getKV? */ - function pkeyGet($cls, $kv) + static function pkeyGetClass($cls, array $kv) { + if (!is_a($cls, __CLASS__, true)) { + throw new Exception('Trying to fetch ' . __CLASS__ . ' into a non-related class'); + } $i = Memcached_DataObject::multicache($cls, $kv); if ($i !== false) { // false == cache miss return $i; } else { - $i = DB_DataObject::factory($cls); - if (empty($i) || PEAR::isError($i)) { - return false; - } + $i = new $cls; foreach ($kv as $k => $v) { - if (is_null($v)) { - // XXX: possible SQL injection...? Don't - // pass keys from the browser, eh. - $i->whereAdd("$k is null"); - } else { - $i->$k = $v; - } + if (is_null($v)) { + // XXX: possible SQL injection...? Don't + // pass keys from the browser, eh. + $i->whereAdd("$k is null"); + } else { + $i->$k = $v; + } } if ($i->find(true)) { $i->encache(); @@ -533,7 +538,7 @@ class Memcached_DataObject extends Safe_DataObject return $ckeys; } - function multicache($cls, $kv) + static function multicache($cls, $kv) { ksort($kv); $c = self::memcache(); @@ -671,8 +676,10 @@ class Memcached_DataObject extends Safe_DataObject 'delete', 'update', 'find'); - $ignoreStatic = array('staticGet', + $ignoreStatic = array('getKV', + 'getClassKV', 'pkeyGet', + 'pkeyGetClass', 'cachedQuery'); $here = get_class($this); // if we get confused $bt = debug_backtrace(); @@ -691,7 +698,7 @@ class Memcached_DataObject extends Safe_DataObject continue; } if (in_array($func, $ignoreStatic)) { - continue; // @fixme this shouldn't be needed? + continue; // @todo FIXME: This shouldn't be needed? } $here = get_class($frame['object']) . '->' . $func; break; @@ -834,7 +841,7 @@ class Memcached_DataObject extends Safe_DataObject if (!$dsn) { // TRANS: Exception thrown when database name or Data Source Name could not be found. - throw new Exception(_("No database name or DSN found anywhere.")); + throw new Exception(_('No database name or DSN found anywhere.')); } return $dsn;