From 5dff3b8e153f246a49907478092e2a5cf5a02241 Mon Sep 17 00:00:00 2001 From: Angie Byron Date: Sat, 11 Oct 2008 21:53:36 +0000 Subject: [PATCH] #242873 follow-up by pwolanin: Move new check_plain() check constants to bootstrap.inc so they're there in early bootstrap. --- includes/bootstrap.inc | 20 +++++ includes/common.inc | 21 ----- includes/database/log.inc | 159 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+), 21 deletions(-) create mode 100644 includes/database/log.inc diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 58d395dea9b..56a4b9b715c 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -185,6 +185,26 @@ define('LANGUAGE_NEGOTIATION_DOMAIN', 3); */ define('REQUEST_TIME', $_SERVER['REQUEST_TIME']); +/** + * @name Title text filtering flags + * @{ + * Flags for use in drupal_set_title(). + */ + +/** + * Flag for drupal_set_title(); text is not sanitized, so run check_plain(). + */ +define('CHECK_PLAIN', 0); + +/** + * Flag for drupal_set_title(); text has already been sanitized. + */ +define('PASS_THROUGH', -1); + +/** + * @} End of "Title text filtering flags". + */ + /** * Start the timer with the specified name. If you start and stop * the same timer multiple times, the measured intervals will be diff --git a/includes/common.inc b/includes/common.inc index f6b3c1553fa..4c03bce7b9e 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -24,27 +24,6 @@ define('SAVED_UPDATED', 2); */ define('SAVED_DELETED', 3); -/** - * @name Title text filtering flags - * @{ - * Flags for use in drupal_set_title(). - */ - -/** - * Flag for drupal_set_title(); text is not sanitized, so run check_plain(). - */ -define('CHECK_PLAIN', 0); - -/** - * Flag for drupal_set_title(); text has already been sanitized. - */ -define('PASS_THROUGH', -1); - -/** - * @} End of "Title text filtering flags". - */ - - /** * Set content for a specified region. * diff --git a/includes/database/log.inc b/includes/database/log.inc new file mode 100644 index 00000000000..da3f2bb88ff --- /dev/null +++ b/includes/database/log.inc @@ -0,0 +1,159 @@ + '', args => array(), caller => '', target => '', time => 0), + * array(query => '', args => array(), caller => '', target => '', time => 0), + * ), + * ); + * + * @var array + */ + protected $queryLog = array(); + + /** + * The connection key for which this object is logging. + * + * @var string + */ + protected $connectionKey = 'default'; + + /** + * Constructor. + * + * @param $key + * The database connection key for which to enable logging. + */ + public function __construct($key = 'default') { + $this->connectionKey = $key; + } + + /** + * Begin logging queries to the specified connection and logging key. + * + * If the specified logging key is already running this method does nothing. + * + * @param $logging_key + * The identification key for this log request. By specifying different + * logging keys we are able to start and stop multiple logging runs + * simultaneously without them colliding. + */ + public function start($logging_key) { + if (empty($this->queryLog[$logging_key])) { + $this->clear($logging_key); + } + } + + /** + * Retrieve the query log for the specified logging key so far. + * + * @param $logging_key + * The logging key to fetch. + * @return + * An indexed array of all query records for this logging key. + */ + public function get($logging_key) { + return $this->queryLog[$logging_key]; + } + + /** + * Empty the query log for the specified logging key. + * + * This method does not stop logging, it simply clears the log. To stop + * logging, use the end() method. + * + * @param $logging_key + * The logging key to empty. + */ + public function clear($logging_key) { + $this->queryLog[$logging_key] = array(); + } + + /** + * Stop logging for the specified logging key. + * + * @param $logging_key + * The logging key to stop. + */ + public function end($logging_key) { + unset($this->queryLog[$logging_key]); + } + + /** + * Log a query to all active logging keys. + * + * @param $statement + * The prepared statement object to log. + * @param $args + * The arguments passed to the statement object. + * @param $time + * The time in milliseconds the query took to execute. + */ + public function log(DatabaseStatement $statement, $args, $time) { + foreach (array_keys($this->queryLog) as $key) { + $this->queryLog[$key][] = array( + 'query' => $statement->queryString, + 'args' => $args, + 'target' => $statement->dbh->getTarget(), + 'caller' => $this->findCaller(), + 'time' => $time, + ); + } + } + + /** + * Determine the routine that called this query. + * + * We define "the routine that called this query" as the first entry in + * the call stack that is not inside includes/database. That makes the + * climbing logic very simple, and handles the variable stack depth caused + * by the query builders. + * + * @link http://www.php.net/debug_backtrace + * @return + * This method returns a stack trace entry similar to that generated by + * debug_backtrace(). However, it flattens the trace entry and the trace + * entry before it so that we get the function and args of the function that + * called into the database system, not the function and args of the + * database call itself. + */ + public function findCaller() { + $stack = debug_backtrace(); + $stack_count = count($stack); + for ($i = 0; $i < $stack_count; ++$i) { + if (strpos($stack[$i]['file'], 'includes/database') === FALSE) { + return array( + 'file' => $stack[$i]['file'], + 'line' => $stack[$i]['line'], + 'function' => $stack[$i + 1]['function'], + 'args' => $stack[$i + 1]['args'], + ); + return $stack[$i]; + } + } + } +}