From 628aa953ec150a1ed34680ef1d4f9c81dfc99bb1 Mon Sep 17 00:00:00 2001 From: Brett Profitt Date: Sat, 16 Apr 2011 17:43:18 -0400 Subject: Denormalizing annotation names for calculation functions. --- .gitignore | 1 + engine/classes/ElggFile.php | 1 + engine/lib/annotations.php | 22 ++++----- engine/lib/metadata.php | 5 ++ engine/lib/metastrings.php | 69 ++++++++++++++++++++-------- engine/tests/api/entity_getter_functions.php | 2 +- engine/tests/suite.php | 6 +-- 7 files changed, 70 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 1540c7db6..8bae532ad 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ engine/settings.php /.buildpath /.settings /.project +/nbproject/private/ \ No newline at end of file diff --git a/engine/classes/ElggFile.php b/engine/classes/ElggFile.php index fe25491a8..df42ab97f 100644 --- a/engine/classes/ElggFile.php +++ b/engine/classes/ElggFile.php @@ -322,6 +322,7 @@ class ElggFile extends ElggObject { $options = array( 'guid' => $this->guid, 'where' => array("n.string LIKE 'filestore::%'"), + 'join' => "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id" ); $mds = elgg_get_metadata($options); diff --git a/engine/lib/annotations.php b/engine/lib/annotations.php index 7a4e62921..cd733c629 100644 --- a/engine/lib/annotations.php +++ b/engine/lib/annotations.php @@ -392,14 +392,14 @@ function elgg_list_entities_from_annotations($options = array()) { * as entity_row_to_elggstar * * @param array $options An options array: - * 'annotation_calculation' => The calculation to use. Must be a valid MySQL function. - * Defaults to sum. Result selected as 'annotation_calculation'. - * 'order_by' => The order for the sorting. Defaults to 'calculation desc'. - * 'annotation_names' => The names of annotations on the entity. - * 'annotation_values' => The values of annotations on the entity. + * 'calculation' => The calculation to use. Must be a valid MySQL function. + * Defaults to sum. Result selected as 'annotation_calculation'. + * 'order_by' => The order for the sorting. Defaults to 'calculation desc'. + * 'annotation_names' => The names of annotations on the entity. + * 'annotation_values' => The values of annotations on the entity. * - * 'metadata_names' => The name of metadata on the entity. - * 'metadata_values' => The value of metadata on the entitiy. + * 'metadata_names' => The name of metadata on the entity. + * 'metadata_values' => The value of metadata on the entitiy. * * @return mixed */ @@ -410,22 +410,18 @@ function elgg_get_entities_from_annotation_calculation($options) { ); $options = array_merge($defaults, $options); - $function = sanitize_string(elgg_extract('calculation', $options, 'sum', false)); + $db_prefix = elgg_get_config('dbprefix'); // you must cast this as an int or it sorts wrong. $options['selects'][] = 'e.*'; $options['selects'][] = "$function(cast(v.string as signed)) as calculation"; - // need our own join to get the values. -// $options['joins'][] = "JOIN {$db_prefix}metastrings msv ON a.value_id = msv.id"; -// $options['joins'][] = "JOIN {$db_prefix}entities ae ON a.entity_guid = ae.guid"; - $options['wheres'][] = get_access_sql_suffix('n_table'); -// $options['wheres'][] = "e.guid = a.entity_guid"; $options['group_by'] = 'n_table.entity_guid'; $options['callback'] = 'entity_row_to_elggstar'; + $options['denormalize'] = 'name'; return elgg_get_annotations($options); } diff --git a/engine/lib/metadata.php b/engine/lib/metadata.php index a6b1bb43a..26741af90 100644 --- a/engine/lib/metadata.php +++ b/engine/lib/metadata.php @@ -290,6 +290,11 @@ $access_id = ACCESS_PRIVATE, $allow_multiple = false) { */ function elgg_get_metadata(array $options = array()) { $options['metastring_type'] = 'metadata'; + if (isset($options['joins'])) { + if (!is_array($options['joins'])) { + $options['joins'] = array($options['joins']); + } + } return elgg_get_metastring_based_objects($options); } diff --git a/engine/lib/metastrings.php b/engine/lib/metastrings.php index 604c7f765..6cdf9ee47 100644 --- a/engine/lib/metastrings.php +++ b/engine/lib/metastrings.php @@ -229,6 +229,8 @@ function delete_orphaned_metastrings() { * * metastring_type => STR metadata or annotation(s) * + * denormalize => Mixed Denormalize nothing (false, default), all, name, or value. + * * @return mixed * @access private */ @@ -293,7 +295,8 @@ function elgg_get_metastring_based_objects($options) { 'wheres' => array(), 'joins' => array(), - 'callback' => $callback + 'callback' => $callback, + 'denormalize' => false ); // @todo Ignore site_guid right now because of #2910 @@ -378,7 +381,6 @@ function elgg_get_metastring_based_objects($options) { $joins[] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id"; $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id"; - // remove identical join clauses $joins = array_unique($joins); @@ -393,7 +395,7 @@ function elgg_get_metastring_based_objects($options) { // metastrings $metastring_clauses = elgg_get_metastring_sql('n_table', $options['metastring_names'], $options['metastring_values'], null, $options['metastring_ids'], - $options['metastring_case_sensitive']); + $options['metastring_case_sensitive'], $options['denormalize']); if ($metastring_clauses) { $wheres = array_merge($wheres, $metastring_clauses['wheres']); @@ -405,7 +407,12 @@ function elgg_get_metastring_based_objects($options) { $options['metastring_calculation'] = 'count'; } - if ($options['metastring_calculation'] === ELGG_ENTITIES_NO_VALUE) { + if ($options['metastring_calculation']) { +// $joins[] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id"; + + $function = sanitise_string($options['metastring_calculation']); + $query = "SELECT {$function}(v.string) as calculation FROM {$db_prefix}$type n_table"; + } else { // evalutate selects if ($options['selects']) { $selects = ''; @@ -418,8 +425,8 @@ function elgg_get_metastring_based_objects($options) { $query = "SELECT DISTINCT n_table.*, n.string as name, v.string as value{$selects} FROM {$db_prefix}$type n_table"; - } else { - $query = "SELECT {$options['metastring_calculation']}(v.string) as calculation FROM {$db_prefix}$type n_table"; + +// $query = "SELECT DISTINCT n_table.*{$selects} FROM {$db_prefix}$type n_table"; } // add joins @@ -459,7 +466,7 @@ function elgg_get_metastring_based_objects($options) { $offset = sanitise_int($options['offset']); $query .= " LIMIT $offset, $limit"; } - +global $test; if ($test) { var_dump($options, $query); } $dt = get_data($query, $options['callback']); return $dt; } else { @@ -479,11 +486,13 @@ function elgg_get_metastring_based_objects($options) { * @param array $pairs Name / value pairs. Not currently used. * @param array $ids Metastring IDs * @param bool $case_sensitive Should name and values be case sensitive? + * @param mixed $denormalize Denormalize none (false, default), all, name, value. If operators + * are anything but = or IN you cannot denormalize value. * * @return array */ function elgg_get_metastring_sql($table, $names = null, $values = null, - $pairs = null, $ids = null, $case_sensitive = false) { + $pairs = null, $ids = null, $case_sensitive = false, $denormalize = false) { if ((!$names && $names !== 0) && (!$values && $values !== 0) @@ -506,7 +515,7 @@ function elgg_get_metastring_sql($table, $names = null, $values = null, $access = get_access_sql_suffix($table); $return = array ( - 'joins' => array (), + 'joins' => array(), 'wheres' => array() ); @@ -515,28 +524,50 @@ function elgg_get_metastring_sql($table, $names = null, $values = null, // get names wheres and joins $names_where = ''; if ($names !== NULL) { + // @todo only really needed for metadata (vs annotations) +// $return['joins'][] = "JOIN {$db_prefix}metastrings n on n_table.name_id = n.id"; + if (!is_array($names)) { $names = array($names); } + + if ($denormalize == 'all' || $denormalize == 'name') { + $name_ids = array(); + foreach ($names as $name) { + if (!$name) { + $name = '0'; + } + + $name_ids[] = get_metastring_id($name, $case_sensitive); + } - $sanitised_names = array(); - foreach ($names as $name) { - // normalise to 0. - if (!$name) { - $name = '0'; + $names_str = implode(',', $name_ids); + if ($names_str) { + $names_where = "(n_table.name_id IN ($names_str))"; + } + } else { + $sanitised_names = array(); + foreach ($names as $name) { + // normalise to 0. + if (!$name) { + $name = '0'; + } + $sanitised_names[] = '\'' . sanitise_string($name) . '\''; } - $sanitised_names[] = '\'' . sanitise_string($name) . '\''; - } - if ($names_str = implode(',', $sanitised_names)) { - $return['joins'][] = "JOIN {$db_prefix}metastrings msn on $table.name_id = msn.id"; - $names_where = "(msn.string IN ($names_str))"; + $names_str = implode(',', $sanitised_names); + if ($names_str) { + $return['joins'][] = "JOIN {$db_prefix}metastrings msn on $table.name_id = msn.id"; + $names_where = "(msn.string IN ($names_str))"; + } } } // get values wheres and joins $values_where = ''; if ($values !== NULL) { +// $return['joins'][] = "JOIN {$db_prefix}metastrings v on n_table.value_id = v.id"; + if (!is_array($values)) { $values = array($values); } diff --git a/engine/tests/api/entity_getter_functions.php b/engine/tests/api/entity_getter_functions.php index aef7a991e..a1f180687 100644 --- a/engine/tests/api/entity_getter_functions.php +++ b/engine/tests/api/entity_getter_functions.php @@ -980,7 +980,7 @@ class ElggCoreEntityGetterFunctionsTest extends ElggCoreUnitTest { $this->assertIsa($entities, 'array'); $this->assertEqual(count($entities), 1); - +var_dump($entities); foreach ($entities as $entity) { $this->assertEqual($entity->getGUID(), $e->getGUID()); $this->assertEqual($entity->$md_name, $md_value); diff --git a/engine/tests/suite.php b/engine/tests/suite.php index 8f2eb41a3..1f7886d38 100644 --- a/engine/tests/suite.php +++ b/engine/tests/suite.php @@ -34,9 +34,9 @@ foreach ($test_files as $file) { } // Only run tests in debug mode. -if (!isset($CONFIG->debug)) { - exit ('The site must be in debug mode to run unit tests.'); -} +//if (!isset($CONFIG->debug)) { +// exit ('The site must be in debug mode to run unit tests.'); +//} if (TextReporter::inCli()) { // In CLI error codes are returned: 0 is success -- cgit v1.2.3