Index: modules/statistics/statistics.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.admin.inc,v
retrieving revision 1.20
diff -u -p -r1.20 statistics.admin.inc
--- modules/statistics/statistics.admin.inc	1 Apr 2009 20:00:47 -0000	1.20
+++ modules/statistics/statistics.admin.inc	9 Apr 2009 20:25:50 -0000
@@ -17,11 +17,17 @@ function statistics_recent_hits() {
     array('data' => t('Operations'))
   );
 
-  $sql = 'SELECT a.aid, a.path, a.title, a.uid, u.name, a.timestamp FROM {accesslog} a LEFT JOIN {users} u ON u.uid = a.uid' . tablesort_sql($header);
+  $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
+  $query->join('users', 'u', 'a.uid = u.uid');
+  $query
+    ->fields('a', array('aid', 'timestamp', 'path', 'title', 'uid'))
+    ->fields('u', array('name'))
+    ->limit(30)
+    ->setHeader($header);
 
-  $result = pager_query($sql, 30);
+  $result = $query->execute();
   $rows = array();
-  while ($log = db_fetch_object($result)) {
+  foreach($result as $log) {
     $rows[] = array(
       array('data' => format_date($log->timestamp, 'small'), 'class' => 'nowrap'),
       _statistics_format_item($log->title, $log->path),
@@ -42,21 +48,33 @@ function statistics_recent_hits() {
  * Menu callback; presents the "top pages" page.
  */
 function statistics_top_pages() {
-  // MAX(title) avoids having empty node titles which otherwise causes duplicates in the top pages list
-  $sql = "SELECT COUNT(path) AS hits, path, MAX(title) AS title, AVG(timer) AS average_time, SUM(timer) AS total_time FROM {accesslog} GROUP BY path";
-  $sql_cnt = "SELECT COUNT(DISTINCT(path)) FROM {accesslog}";
-
   $header = array(
     array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'),
     array('data' => t('Page'), 'field' => 'path'),
     array('data' => t('Average page generation time'), 'field' => 'average_time'),
     array('data' => t('Total page generation time'), 'field' => 'total_time')
   );
-  $sql .= tablesort_sql($header);
-  $result = pager_query($sql, 30, 0, $sql_cnt);
 
+  $query = db_select('accesslog')->extend('PagerDefault')->extend('TableSort');
+  $query->addExpression('COUNT(path)', 'hits');
+  // MAX(title) avoids having empty node titles which otherwise causes duplicates in the top pages list
+  $query->addExpression('MAX(title)', 'title');
+  $query->addExpression('AVG(timer)', 'average_time');
+  $query->addExpression('SUM(timer)', 'total_time');
+  
+  $query
+    ->fields('accesslog', array('path'))
+    ->groupBy('path')
+    ->limit(30)
+    ->setHeader($header);
+
+  $count_query = db_select('accesslog');
+  $count_query->addExpression('COUNT(DISTINCT path)');
+  $query->setCountQuery($count_query);
+
+  $result = $query->execute();
   $rows = array();
-  while ($page = db_fetch_object($result)) {
+  foreach ($result as $page) {
     $rows[] = array($page->hits, _statistics_format_item($page->title, $page->path), t('%time ms', array('%time' => round($page->average_time))), format_interval(round($page->total_time / 1000)));
   }
 
@@ -81,13 +99,30 @@ function statistics_top_visitors() {
     array('data' => t('Total page generation time'), 'field' => 'total'),
     array('data' => user_access('block IP addresses') ? t('Operations') : '', 'colspan' => 2),
   );
-
-  $sql = "SELECT COUNT(a.uid) AS hits, a.uid, u.name, a.hostname, SUM(a.timer) AS total, bl.iid FROM {accesslog} a LEFT JOIN {blocked_ips} bl ON a.hostname = bl.ip LEFT JOIN {users} u ON a.uid = u.uid GROUP BY a.hostname, a.uid, u.name, bl.iid" . tablesort_sql($header);
-  $sql_cnt = "SELECT COUNT(DISTINCT(CONCAT(CAST(uid AS char), hostname))) FROM {accesslog}";
-  $result = pager_query($sql, 30, 0, $sql_cnt);
-
+  $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
+  $query->leftJoin('blocked_ips', 'bl', 'a.hostname = bl.ip');
+  $query->leftJoin('users', 'u', 'a.uid = u.uid');
+
+  $query->addExpression('COUNT(a.uid)', 'hits');
+  $query->addExpression('SUM(a.timer)', 'total');
+  $query
+    ->fields('a', array('uid', 'hostname'))
+    ->fields('u', array('name'))
+    ->fields('bl', array('iid'))
+    ->groupBy('a.hostname')
+    ->groupBy('a.uid')
+    ->groupBy('u.name')
+    ->groupBy('bl.iid')
+    ->limit(30)
+    ->setHeader($header);
+
+  $count_query = db_select('accesslog');
+  $count_query->addExpression('COUNT(DISTINCT CONCAT(CAST(uid AS char), hostname))');
+  $query->setCountQuery($count_query);
+  
+  $result = $query->execute();
   $rows = array();
-  while ($account = db_fetch_object($result)) {
+  foreach ($result as $account) {
     $qs = drupal_get_destination();
     $ban_link =  $account->iid ? l(t('unblock IP address'), "admin/settings/ip-blocking/delete/$account->iid", array('query' => $qs)) : l(t('block IP address'), "admin/settings/ip-blocking/$account->hostname", array('query' => $qs));
     $rows[] = array($account->hits, ($account->uid ? theme('username', $account) : $account->hostname), format_interval(round($account->total / 1000)), (user_access('block IP addresses') && !$account->uid) ? $ban_link : '');
@@ -107,8 +142,6 @@ function statistics_top_visitors() {
  * Menu callback; presents the "referrer" page.
  */
 function statistics_top_referrers() {
-  $query = "SELECT url, COUNT(url) AS hits, MAX(timestamp) AS last FROM {accesslog} WHERE LOWER(url) NOT LIKE :host AND url <> '' GROUP BY url";
-  $query_cnt = "SELECT COUNT(DISTINCT(url)) FROM {accesslog} WHERE url <> '' AND LOWER(url) NOT LIKE :host";
   drupal_set_title(t('Top referrers in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200)))), PASS_THROUGH);
 
   $header = array(
@@ -116,12 +149,28 @@ function statistics_top_referrers() {
     array('data' => t('Url'), 'field' => 'url'),
     array('data' => t('Last visit'), 'field' => 'last'),
   );
+  $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
 
-  $query .= tablesort_sql($header);
-  $result = pager_query($query, 30, 0, $query_cnt, array(':host' => '%'. $_SERVER['HTTP_HOST'] .'%'));
+  $query->addExpression('COUNT(url)', 'hits');
+  $query->addExpression('MAX(timestamp)', 'last');
+  $query
+    ->fields('a', array('url'))
+    ->where('LOWER(url) NOT LIKE :host', array(':host' => '%'. $_SERVER['HTTP_HOST'] .'%'))
+    ->condition('url', '', '<>')
+    ->groupBy('url')
+    ->limit(30)
+    ->setHeader($header);
+
+  $count_query = db_select('accesslog');
+  $count_query->addExpression('COUNT(DISTINCT url)');
+  $count_query
+    ->where('LOWER(url) NOT LIKE :host', array(':host' => '%'. $_SERVER['HTTP_HOST'] .'%'))
+    ->condition('url', '', '<>');
+  $query->setCountQuery($count_query);
 
+  $result = $query->execute();
   $rows = array();
-  while ($referrer = db_fetch_object($result)) {
+  foreach ($result as $referrer) {
     $rows[] = array($referrer->hits, _statistics_link($referrer->url), t('@time ago', array('@time' => format_interval(REQUEST_TIME - $referrer->last))));
   }
 
@@ -138,8 +187,8 @@ function statistics_top_referrers() {
  * Menu callback; Displays recent page accesses.
  */
 function statistics_access_log($aid) {
-  $result = db_query('SELECT a.*, u.name FROM {accesslog} a LEFT JOIN {users} u ON a.uid = u.uid WHERE aid = %d', $aid);
-  if ($access = db_fetch_object($result)) {
+  $access = db_query('SELECT a.*, u.name FROM {accesslog} a LEFT JOIN {users} u ON a.uid = u.uid WHERE aid = :aid', array(':aid' => $aid))->fetch();
+  if ($access) {
     $rows[] = array(
       array('data' => t('URL'), 'header' => TRUE),
       l(url($access->path, array('absolute' => TRUE)), $access->path)
Index: modules/statistics/statistics.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v
retrieving revision 1.299
diff -u -p -r1.299 statistics.module
--- modules/statistics/statistics.module	8 Mar 2009 04:25:06 -0000	1.299
+++ modules/statistics/statistics.module	9 Apr 2009 20:25:50 -0000
@@ -74,7 +74,7 @@ function statistics_exit() {
       'sid' => session_id(),
       'timer' => (int) timer_read('page'),
       'timestamp' => REQUEST_TIME,
-    ))->execute();
+    ))->delay()->execute();
   }
 }
 
@@ -206,12 +206,16 @@ function statistics_cron() {
 
   if ((REQUEST_TIME - $statistics_timestamp) >= 86400) {
     // Reset day counts.
-    db_query('UPDATE {node_counter} SET daycount = 0');
+    db_update('node_counter')
+      ->fields(array('daycount' => 0))
+      ->execute();
     variable_set('statistics_day_timestamp', REQUEST_TIME);
   }
 
   // Clean up expired access logs.
-  db_query('DELETE FROM {accesslog} WHERE timestamp < %d', REQUEST_TIME - variable_get('statistics_flush_accesslog_timer', 259200));
+  db_delete('accesslog')
+    ->condition('timestamp', REQUEST_TIME - variable_get('statistics_flush_accesslog_timer', 259200), '<')
+    ->execute();
 }
 
 /**
@@ -232,7 +236,20 @@ function statistics_cron() {
  */
 function statistics_title_list($dbfield, $dbrows) {
   if (in_array($dbfield, array('totalcount', 'daycount', 'timestamp'))) {
-    return db_query_range(db_rewrite_sql("SELECT n.nid, n.title, u.uid, u.name FROM {node} n INNER JOIN {node_counter} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE s." . $dbfield . " != 0 AND n.status = 1 ORDER BY s." . $dbfield . " DESC"), 0, $dbrows);
+    $query = db_select('node', 'n')->extend('PagerDefault');
+    $query->addTag('node_access');
+    $query
+      ->join('node_counter', 's', 'n.nid = s.nid')
+      ->join('user', 'u', 'n.nid = u.nid');
+
+    return $query
+      ->fields('n', array('nid', 'title'))
+      ->fields('u', array('uid', 'name'))
+      ->condition($dbfield, 0, '<>')
+      ->condition('status', 1)
+      ->orderBy($dbfield, 'DESC')
+      ->limit($dbrows)
+      ->execute();
   }
   return FALSE;
 }
@@ -255,8 +272,7 @@ function statistics_get($nid) {
 
   if ($nid > 0) {
     // Retrieve an array with both totalcount and daycount.
-    $statistics = db_fetch_array(db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = %d', $nid));
-    return $statistics;
+    return db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = :nid', array(':nid' => $nid))->fetchAssoc();
   }
 }
 
@@ -345,7 +361,7 @@ function _statistics_format_item($title,
  */
 function statistics_node_delete($node) {
   // clean up statistics table when node is deleted
-  db_query('DELETE FROM {node_counter} WHERE nid = %d', $node->nid);
+  db_delete('node_counter')->condition('nid', $node->nid)->execute();
 }
 
 /**
Index: modules/statistics/statistics.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.pages.inc,v
retrieving revision 1.9
diff -u -p -r1.9 statistics.pages.inc
--- modules/statistics/statistics.pages.inc	14 Mar 2009 23:01:37 -0000	1.9
+++ modules/statistics/statistics.pages.inc	9 Apr 2009 20:25:50 -0000
@@ -15,9 +15,19 @@ function statistics_node_tracker() {
         array('data' => t('User'), 'field' => 'u.name'),
         array('data' => t('Operations')));
 
-    $result = pager_query('SELECT a.aid, a.timestamp, a.url, a.uid, u.name FROM {accesslog} a LEFT JOIN {users} u ON a.uid = u.uid WHERE a.path LIKE \'node/%d%%\'' . tablesort_sql($header), 30, 0, NULL, $node->nid);
+    $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
+    $query->join('users', 'u', 'a.uid = u.uid');
+
+    $query
+      ->fields('a', array('aid', 'timestamp', 'url', 'uid'))
+      ->fields('u', array('name'))
+      ->condition('path', 'node/' . $node->nid . '%', 'LIKE')
+      ->limit(30)
+      ->setHeader($header);
+
+    $result = $query->execute();
     $rows = array();
-    while ($log = db_fetch_object($result)) {
+    foreach($result as $log) {
       $rows[] = array(
         array('data' => format_date($log->timestamp, 'small'), 'class' => 'nowrap'),
         _statistics_link($log->url),
@@ -46,10 +56,16 @@ function statistics_user_tracker() {
         array('data' => t('Timestamp'), 'field' => 'timestamp', 'sort' => 'desc'),
         array('data' => t('Page'), 'field' => 'path'),
         array('data' => t('Operations')));
+    $query = db_select('accesslog', 'a')->extend('PagerDefault')->extend('TableSort');
+    $query
+      ->fields('a', array('aid', 'timestamp', 'path', 'title'))
+      ->condition('uid', $account->uid)
+      ->limit(30)
+      ->setHeader($header);
 
-    $result = pager_query('SELECT aid, timestamp, path, title FROM {accesslog} WHERE uid = %d' . tablesort_sql($header), 30, 0, NULL, $account->uid);
+    $result = $query->execute();
     $rows = array();
-    while ($log = db_fetch_object($result)) {
+    foreach($result as $log) {
       $rows[] = array(
         array('data' => format_date($log->timestamp, 'small'), 'class' => 'nowrap'),
         _statistics_format_item($log->title, $log->path),
Index: modules/statistics/statistics.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.test,v
retrieving revision 1.7
diff -u -p -r1.7 statistics.test
--- modules/statistics/statistics.test	31 Mar 2009 01:49:54 -0000	1.7
+++ modules/statistics/statistics.test	9 Apr 2009 20:25:50 -0000
@@ -17,7 +17,18 @@ class StatisticsBlockVisitorsTestCase ex
     $this->blocking_user = $this->drupalCreateUser(array('block IP addresses', 'access statistics'));
 
     // Insert dummy access by anonymous user into access log.
-    db_query("INSERT INTO {accesslog} (title, path, url, hostname, uid, sid, timer, timestamp) values('%s', '%s', '%s', '%s', %d, '%s', %d, %d)", 'test', 'node/1', 'http://example.com', '192.168.1.1', '0', '10', '10', REQUEST_TIME);
+    db_insert('accesslog')
+      ->fields(array(
+        'title' => 'test',
+        'path' => 'node/1',
+        'url' => 'http://example.com',
+        'hostname' => '192.168.1.1',
+        'uid' => 0,
+        'sid' => 10,
+        'timer' => 10,
+        'timestamp' => REQUEST_TIME,
+      ))
+      ->execute();
   }
 
   /**
@@ -43,8 +54,8 @@ class StatisticsBlockVisitorsTestCase ex
     $edit = array();
     $edit['ip'] = $test_ip_address;
     $this->drupalPost('admin/settings/ip-blocking', $edit, t('Save'));
-    $ip = db_result(db_query("SELECT iid from {blocked_ips} WHERE ip = '%s'", $edit['ip']));
-    $this->assertNotNull($ip, t('IP address found in database'));
+    $ip = db_query("SELECT iid from {blocked_ips} WHERE ip = :ip", array(':ip' => $edit['ip']))->fetchField();
+    $this->assertNotEqual($ip, FALSE, t('IP address found in database'));
     $this->assertRaw(t('The IP address %ip has been blocked.', array('%ip' => $edit['ip'])), t('IP address was blocked.'));
 
     // Verify that the block/unblock link on the top visitors page has been altered.
