diff options
author | Dries Buytaert <dries@buytaert.net> | 2005-01-29 22:02:37 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2005-01-29 22:02:37 +0000 |
commit | 993ea0c6c5a07cf9c2edadf2c0f6a378cde56acb (patch) | |
tree | 3a0999b14fee17844a3318ee2f564191a83e31f3 /includes | |
parent | e6d36892abca87d1c668d6294106a154c219cee4 (diff) | |
download | brdo-993ea0c6c5a07cf9c2edadf2c0f6a378cde56acb.tar.gz brdo-993ea0c6c5a07cf9c2edadf2c0f6a378cde56acb.tar.bz2 |
- Patch #16111 by chx: generalized node_rewrite_query to db_rewrite_query.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/database.inc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/includes/database.inc b/includes/database.inc index 0148f328d..e2d8057b6 100644 --- a/includes/database.inc +++ b/includes/database.inc @@ -169,6 +169,98 @@ function db_queryd($query) { } /** + * Helper function for db_rewrite_sql. + * + * Collects JOIN and WHERE statements via hook_sql. + * Decides whether to select primary_key or DISTINCT(primary_key) + * + * @param $query + * query to be rewritten + * @param $primary_table + * Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, taxonomy, vocabulary + * @param $primary_key + * name of the primary key field. + * @param $args + * array of additional args + * @return + * An array: join statements, where statements, field or DISTINCT(field) + */ +function _db_rewrite_sql($query = '', $primary_table = 'n', $primary_key = 'nid', $args = array()) { + $where = array(); + $join = array(); + $distinct = FALSE; + foreach (module_implements('db_rewrite_sql') as $module) { + $result = module_invoke($module, 'db_rewrite_sql', $query, $primary_table, $primary_key, $args); + if (is_array($result)) { + if (isset($result['where'])) { + $where[] .= $result['where']; + } + if (isset($result['join'])) { + $join[] .= $result['join']; + } + if (isset($result['distinct']) && $result['distinct']) { + $distinct = TRUE; + } + } + elseif (isset($result)) { + $where[] .= $result; + } + } + + $where = empty($where) ? '' : '('. implode(') AND (',$where).')'; + $join = empty($join) ? '' : implode(' ',$join); + $field = $primary_table .'.'. $primary_key; + + return array($join, $where, $distinct ? 'DISTINCT('. $field .')' : $field); +} + +/** + * Rewrites node queries. + * + * @param $query + * query to be rewritten + * @param $primary_table + * Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, taxonomy, vocabulary + * @param $primary_key + * name of the primary key field. + * @param $args + * an array of arguments, passed to the implementations of hook_db_rewrite_sql + * @return + * The original query with JOIN and WHERE statements inserted from hook_db_rewrite_sql implementations. nid is rewritten if needed. + */ +function db_rewrite_sql($query, $primary_table = 'n', $primary_key = 'nid', $args = array()) { + list($join, $where, $field_to_select) = _db_rewrite_sql($query, $primary_table, $primary_key, $args); + + // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT). + $query = preg_replace('/(SELECT.*)('. $primary_table .'\.)?(?<!DISTINCT\()(?<!DISTINCT\('. $primary_table .'\.)'. $primary_key .'(.*FROM)/AUsi', '\1'. $field_to_select .'\3', $query); + + $query = preg_replace('|FROM[^[:upper:]/,]+|','\0 '. $join .' ', $query); + if (strpos($query, 'WHERE')) { + $replace = 'WHERE'; + $add = 'AND'; + } + elseif (strpos($query, 'GROUP')) { + $replace = 'GROUP'; + $add = 'GROUP'; + } + elseif (strpos($query, 'ORDER')) { + $replace = 'ORDER'; + $add = 'ORDER'; + } + elseif (strpos($query, 'LIMIT')) { + $replace = 'LIMIT'; + $add = 'LIMIT'; + } + else { + $query .= ' WHERE '. $where; + } + if (isset($replace)) { + $query = str_replace($replace, 'WHERE '. $where .' '. $add .' ', $query); + } + return $query; +} + +/** * @} End of "defgroup database". */ |