Permalink
Browse files

feature(metastrings): add function to get map of strings to metastrin…

…g IDs

We use this in messages_get_unread() to eliminate 3 queries per page.
  • Loading branch information...
mrclay committed Oct 25, 2015
1 parent ed21578 commit 8d28a8dd4eacfc427d925166885fa68081f42b4b
Showing with 60 additions and 9 deletions.
  1. +43 −2 engine/classes/Elgg/Database/MetastringsTable.php
  2. +15 −0 engine/lib/metastrings.php
  3. +2 −7 mod/messages/start.php
@@ -50,6 +50,8 @@ public function __construct(Pool $cache, Database $db) {
* If not, there may be more than one result
*
* @return int|array metastring id or array of ids
*
* @see elgg_get_metastring_id
*/
function getId($string, $case_sensitive = true) {
if ($case_sensitive) {
@@ -58,6 +60,45 @@ function getId($string, $case_sensitive = true) {
return $this->getIdCaseInsensitive($string);
}
}
/**
* Get a map of strings to their metastring identifiers (case sensitive matches)
*
* @param string[] $string_keys Strings to look up
*
* @return int[] map of [string] => [id]
*
* @see elgg_get_metastring_map
*/
function getMap(array $string_keys) {
if (!$string_keys) {
return [];
}
if (count($string_keys) === 1) {
$key = reset($string_keys);
return [$key => $this->getIdCaseSensitive($key)];
}
$missing = array_fill_keys($string_keys, true);
$set_element = array_map(function ($string) {
return "BINARY '" . $this->db->sanitizeString($string) . "'";
}, $string_keys);
$set = implode(',', $set_element);
$query = "SELECT * FROM {$this->getTableName()} WHERE string IN ($set)";
$ret = [];
foreach ($this->db->getData($query) as $row) {
$ret[$row->string] = (int)$row->id;
unset($missing[$row->string]);
}
foreach (array_keys($missing) as $string) {
$ret[$string] = $this->getIdCaseSensitive($string);
}
return $ret;
}
/**
* Gets the id associated with this string, case-sensitively.
@@ -71,7 +112,7 @@ private function getIdCaseSensitive($string) {
$string = (string)$string;
return $this->cache->get($string, function() use ($string) {
$escaped_string = $this->db->sanitizeString($string);
$query = "SELECT * FROM {$this->getTableName()} WHERE string = BINARY '$escaped_string' LIMIT 1";
$query = "SELECT id FROM {$this->getTableName()} WHERE string = BINARY '$escaped_string' LIMIT 1";
$results = $this->db->getData($query);
if (isset($results[0])) {
return $results[0]->id;
@@ -93,7 +134,7 @@ private function getIdCaseInsensitive($string) {
$string = (string)$string;
// caching doesn't work for case insensitive requests
$escaped_string = $this->db->sanitizeString($string);
$query = "SELECT * FROM {$this->getTableName()} WHERE string = '$escaped_string'";
$query = "SELECT id FROM {$this->getTableName()} WHERE string = '$escaped_string'";
$results = $this->db->getData($query);
$ids = array();
foreach ($results as $result) {
View
@@ -26,6 +26,21 @@ function elgg_get_metastring_id($string, $case_sensitive = true) {
return _elgg_services()->metastringsTable->getId($string, $case_sensitive);
}
/**
* Get a map of strings to their metastring identifiers (case sensitive matches)
*
* If you need several metastring IDs at once, use this to get a an array of them
* instead of calling elgg_get_metastring_id() several times.
*
* @param string[] $strings Strings to look up
*
* @return int[] map of [string] => [id]
* @since 2.1
*/
function elgg_get_metastring_map(array $strings) {
return _elgg_services()->metastringsTable->getMap($strings);
}
/**
* Returns an array of either \ElggAnnotation or \ElggMetadata objects.
* Accepts all elgg_get_entities() options for entity restraints.
View
@@ -374,12 +374,7 @@ function messages_get_unread($user_guid = 0, $limit = null, $offset = 0, $count
// denormalize the md to speed things up.
// seriously, 10 joins if you don't.
$strings = array('toId', $user_guid, 'readYet', 0);
$map = array();
foreach ($strings as $string) {
$id = elgg_get_metastring_id($string);
$map[$string] = $id;
}
$map = elgg_get_metastring_map(['toId', $user_guid, 'readYet', 0]);
if ($limit === null) {
$limit = elgg_get_config('default_limit');
@@ -407,7 +402,7 @@ function messages_get_unread($user_guid = 0, $limit = null, $offset = 0, $count
'distinct' => false,
);
return elgg_get_entities_from_metadata($options);
return elgg_get_entities($options);
}
/**

0 comments on commit 8d28a8d

Please sign in to comment.