Index: includes/view.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v retrieving revision 1.120 diff -u -r1.120 view.inc --- includes/view.inc 8 Aug 2008 21:55:01 -0000 1.120 +++ includes/view.inc 11 Aug 2008 13:40:06 -0000 @@ -490,7 +490,9 @@ $this->base_database = $views_data['table']['base']['database']; } views_include('query'); - $this->query = new views_query($this->base_table, $this->base_field); + $query_class = empty($views_data['table']['base']['query class']) ? + 'views_query' : $views_data['table']['base']['query class']; + $this->query = new $query_class($this->base_table, $this->base_field); // Call a module hook and see if it wants to present us with a // pre-built query or instruct us not to build the query for @@ -565,18 +567,21 @@ // Allow style handler to affect the query: $this->style_plugin->query(); - if (variable_get('views_sql_signature', FALSE)) { + if (variable_get('views_sql_signature', FALSE) && $query_class == 'views_query') { $this->query->add_field(NULL, "'" . $this->name . ':' . $this->current_display . "'", 'view_name'); } // Let modules modify the query just prior to finalizing it. - foreach (module_implements('views_query_alter') as $module) { - $function = $module . '_views_query_alter'; - $function($this, $this->query); + // Only do this, if the default query class is used. + if ($query_class == 'views_query') { + foreach (module_implements('views_query_alter') as $module) { + $function = $module . '_views_query_alter'; + $function($this, $this->query); + } } - $this->build_info['query'] = $this->query->query(); - $this->build_info['query_args'] = $this->query->get_where_args(); + $this->query->query(); + $this->query->get_where_args(); $this->built = TRUE; $this->build_time = microtime() - $start; return TRUE; @@ -617,79 +622,16 @@ return TRUE; } - $query = db_rewrite_sql($this->build_info['query'], $this->base_table, $this->base_field, array('view' => &$this)); - - $args = $this->build_info['query_args']; - - vpr($query); - - $items = array(); - if ($query) { - $replacements = module_invoke_all('views_query_substitutions', $this); - $query = str_replace(array_keys($replacements), $replacements, $query); - - if (is_array($args)) { - foreach ($args as $id => $arg) { - $args[$id] = str_replace(array_keys($replacements), $replacements, $arg); - } - } - - // Allow for a view to query an external database. - if (isset($this->base_database)) { - db_set_active($this->base_database); - $external = TRUE; - } - - // make count from subselect now - $count_query = "SELECT COUNT(*) FROM ($query) AS count_alias"; - - $start = microtime(); - if (!empty($this->pager['items_per_page'])) { - // We no longer use pager_query() here because pager_query() does not - // support an offset. This is fine as we don't actually need pager - // query; we've already been doing most of what it does, and we - // just need to do a little more playing with globals. - $this->total_rows = db_result(db_query($count_query, $args)); - - if (!empty($this->pager['use_pager'])) { - // dump information about what we already know into the globals - global $pager_page_array, $pager_total, $pager_total_items; - // total rows in query - $pager_total_items[$this->pager['element']] = $this->total_rows; - // total pages - $pager_total[$this->pager['element']] = ceil($pager_total_items[$this->pager['element']] / $this->pager['items_per_page']); + $response = $this->query->execute($this); - // What page was requested: - $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array(); - - // If the requested page was within range. $this->pager['current_page'] - // defaults to 0 so we don't need to set it in an out-of-range condition. - if (!empty($pager_page_array[$this->pager['element']])) { - $page = intval($pager_page_array[$this->pager['element']]); - if ($page > 0 && $page < $pager_total[$this->pager['element']]) { - $this->pager['current_page'] = $page; - } - } - $pager_page_array[$this->pager['element']] = $this->pager['current_page']; - } - - $offset = $this->pager['current_page'] * $this->pager['items_per_page'] + $this->pager['offset']; - $result = db_query_range($query, $args, $offset, $this->pager['items_per_page']); - - } - else { - $result = db_query($query, $args); - } - - $this->result = array(); - while ($item = db_fetch_object($result)) { - $this->result[] = $item; - } - if (!empty($external)) { - db_set_active(); + if (is_array($response)) { + $this->total_rows = $response['total_rows']; + if (isset($response['current_page'])) { + $this->pager['current_page'] = $response['current_page']; } + $this->result = $response['result']; + $this->execute_time = $response['execute_time']; } - $this->execute_time = microtime() - $start; $this->executed = TRUE; } @@ -1092,7 +1034,7 @@ $cache[$arg] = NULL; } else { - $view = new view(); + $view =& new view(); $view->load_row($data); $view->type = t('Normal'); // Load all of our subtables. Index: includes/query.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/query.inc,v retrieving revision 1.23 diff -u -r1.23 query.inc --- includes/query.inc 8 Aug 2008 21:55:01 -0000 1.23 +++ includes/query.inc 11 Aug 2008 13:40:04 -0000 @@ -66,6 +66,16 @@ var $distinct = FALSE; /** + * The query to use to get the results. + */ + var $_query; + + /** + * The WHERE and HAVING clauses of this query. + */ + var $_args; + + /** * Constructor; Create the basic query object and fill with default values. */ function views_query($base_table = 'node', $base_field = 'nid') { @@ -892,7 +902,7 @@ $replace = array('>' => '>', '<' => '<'); $query = strtr($query, $replace); - return $query; + $this->_query = $query; } /** @@ -906,7 +916,88 @@ foreach ($this->having as $group => $having) { $args = array_merge($args, $having['args']); } - return $args; + $this->_args = $args; } -} + + /** + * Executes the query and returns the result. + */ + function execute(&$view) { + $query = db_rewrite_sql($this->_query, $view->base_table, $view->base_field, array('view' => &$view)); + + $args = $this->_args; + + vpr($query); + + $items = array(); + $results = NULL; + if ($query) { + $replacements = module_invoke_all('views_query_substitutions', $view); + $query = str_replace(array_keys($replacements), $replacements, $query); + + if (is_array($args)) { + foreach ($args as $id => $arg) { + $args[$id] = str_replace(array_keys($replacements), $replacements, $arg); + } + } + // Allow for a view to query an external database. + if (isset($view->base_database)) { + db_set_active($view->base_database); + $external = TRUE; + } + + // make count from subselect now + $count_query = "SELECT COUNT(*) FROM ($query) AS count_alias"; + + $start = microtime(); + if (!empty($view->pager['items_per_page'])) { + // We no longer use pager_query() here because pager_query() does not + // support an offset. This is fine as we don't actually need pager + // query; we've already been doing most of what it does, and we + // just need to do a little more playing with globals. + $ret['total_rows'] = db_result(db_query($count_query, $args)); + + if (!empty($view->pager['use_pager'])) { + // dump information about what we already know into the globals + global $pager_page_array, $pager_total, $pager_total_items; + // total rows in query + $pager_total_items[$view->pager['element']] = $view->total_rows; + // total pages + $pager_total[$view->pager['element']] = ceil($pager_total_items[$view->pager['element']] / $view->pager['items_per_page']); + + // What page was requested: + $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array(); + + // If the requested page was within range. $view->pager['current_page'] + // defaults to 0 so we don't need to set it in an out-of-range condition. + if (!empty($pager_page_array[$view->pager['element']])) { + $page = intval($pager_page_array[$view->pager['element']]); + if ($page > 0 && $page < $pager_total[$view->pager['element']]) { + $ret['current_page'] = $page; + } + } + $pager_page_array[$view->pager['element']] = $view->pager['current_page']; + } + + $offset = $view->pager['current_page'] * $view->pager['items_per_page'] + $view->pager['offset']; + $result = db_query_range($query, $args, $offset, $view->pager['items_per_page']); + + } + else { + $result = db_query($query, $args); + } + + $ret['result'] = array(); + while ($item = db_fetch_object($result)) { + $ret['result'][] = $item; + } + if (!empty($external)) { + db_set_active(); + } + $ret['execute_time'] = microtime() - $start; + } + + return $ret; + } +}