Spaces:
Sleeping
Sleeping
| /** | |
| * $Header: /repository/pear/Log/Log/mdb2.php,v 1.5 2006/01/08 03:35:44 jon Exp $ | |
| * | |
| * @version $Revision: 1.5 $ | |
| * @package Log | |
| */ | |
| /** PEAR's MDB2 package */ | |
| require_once 'MDB2.php'; | |
| MDB2::loadFile('Date'); | |
| /** | |
| * The Log_mdb2 class is a concrete implementation of the Log:: abstract class | |
| * which sends messages to an SQL server. Each entry occupies a separate row | |
| * in the database. | |
| * | |
| * This implementation uses PEAR's MDB2 database abstraction layer. | |
| * | |
| * CREATE TABLE log_table ( | |
| * id INT NOT NULL, | |
| * logtime TIMESTAMP NOT NULL, | |
| * ident CHAR(16) NOT NULL, | |
| * priority INT NOT NULL, | |
| * message VARCHAR(200), | |
| * PRIMARY KEY (id) | |
| * ); | |
| * | |
| * @author Lukas Smith <smith@backendmedia.com> | |
| * @author Jon Parise <jon@php.net> | |
| * @since Log 1.9.0 | |
| * @package Log | |
| */ | |
| class Log_mdb2 extends Log | |
| { | |
| /** | |
| * Variable containing the DSN information. | |
| * @var mixed | |
| * @access private | |
| */ | |
| var $_dsn = ''; | |
| /** | |
| * Array containing our set of DB configuration options. | |
| * @var array | |
| * @access private | |
| */ | |
| var $_options = array('persistent' => true); | |
| /** | |
| * Object holding the database handle. | |
| * @var object | |
| * @access private | |
| */ | |
| var $_db = null; | |
| /** | |
| * Resource holding the prepared statement handle. | |
| * @var resource | |
| * @access private | |
| */ | |
| var $_statement = null; | |
| /** | |
| * Flag indicating that we're using an existing database connection. | |
| * @var boolean | |
| * @access private | |
| */ | |
| var $_existingConnection = false; | |
| /** | |
| * String holding the database table to use. | |
| * @var string | |
| * @access private | |
| */ | |
| var $_table = 'log_table'; | |
| /** | |
| * String holding the name of the ID sequence. | |
| * @var string | |
| * @access private | |
| */ | |
| var $_sequence = 'log_id'; | |
| /** | |
| * Maximum length of the $ident string. This corresponds to the size of | |
| * the 'ident' column in the SQL table. | |
| * @var integer | |
| * @access private | |
| */ | |
| var $_identLimit = 16; | |
| /** | |
| * Set of field types used in the database table. | |
| * @var array | |
| * @access private | |
| */ | |
| var $_types = array( | |
| 'id' => 'integer', | |
| 'logtime' => 'timestamp', | |
| 'ident' => 'text', | |
| 'priority' => 'text', | |
| 'message' => 'clob' | |
| ); | |
| /** | |
| * Constructs a new sql logging object. | |
| * | |
| * @param string $name The target SQL table. | |
| * @param string $ident The identification field. | |
| * @param array $conf The connection configuration array. | |
| * @param int $level Log messages up to and including this level. | |
| * @access public | |
| */ | |
| function Log_mdb2($name, $ident = '', $conf = array(), | |
| $level = PEAR_LOG_DEBUG) | |
| { | |
| if(!class_exists('G')){ | |
| $realdocuroot = str_replace( '\\', '/', $_SERVER['DOCUMENT_ROOT'] ); | |
| $docuroot = explode( '/', $realdocuroot ); | |
| array_pop( $docuroot ); | |
| $pathhome = implode( '/', $docuroot ) . '/'; | |
| array_pop( $docuroot ); | |
| $pathTrunk = implode( '/', $docuroot ) . '/'; | |
| require_once($pathTrunk.'gulliver/system/class.g.php'); | |
| } | |
| $this->_id = G::encryptOld(microtime()); | |
| $this->_table = $name; | |
| $this->_mask = Log::UPTO($level); | |
| /* If an options array was provided, use it. */ | |
| if (isset($conf['options']) && is_array($conf['options'])) { | |
| $this->_options = $conf['options']; | |
| } | |
| /* If a specific sequence name was provided, use it. */ | |
| if (!empty($conf['sequence'])) { | |
| $this->_sequence = $conf['sequence']; | |
| } | |
| /* If a specific sequence name was provided, use it. */ | |
| if (isset($conf['identLimit'])) { | |
| $this->_identLimit = $conf['identLimit']; | |
| } | |
| /* Now that the ident limit is confirmed, set the ident string. */ | |
| $this->setIdent($ident); | |
| /* If an existing database connection was provided, use it. */ | |
| if (isset($conf['db'])) { | |
| $this->_db = &$conf['db']; | |
| $this->_existingConnection = true; | |
| $this->_opened = true; | |
| } elseif (isset($conf['singleton'])) { | |
| $this->_db = &MDB2::singleton($conf['singleton'], $this->_options); | |
| $this->_existingConnection = true; | |
| $this->_opened = true; | |
| } else { | |
| $this->_dsn = $conf['dsn']; | |
| } | |
| } | |
| /** | |
| * Opens a connection to the database, if it has not already | |
| * been opened. This is implicitly called by log(), if necessary. | |
| * | |
| * @return boolean True on success, false on failure. | |
| * @access public | |
| */ | |
| function open() | |
| { | |
| if (!$this->_opened) { | |
| /* Use the DSN and options to create a database connection. */ | |
| $this->_db = &MDB2::connect($this->_dsn, $this->_options); | |
| if (PEAR::isError($this->_db)) { | |
| return false; | |
| } | |
| /* Create a prepared statement for repeated use in log(). */ | |
| if (!$this->_prepareStatement()) { | |
| return false; | |
| } | |
| /* We now consider out connection open. */ | |
| $this->_opened = true; | |
| } | |
| return $this->_opened; | |
| } | |
| /** | |
| * Closes the connection to the database if it is still open and we were | |
| * the ones that opened it. It is the caller's responsible to close an | |
| * existing connection that was passed to us via $conf['db']. | |
| * | |
| * @return boolean True on success, false on failure. | |
| * @access public | |
| */ | |
| function close() | |
| { | |
| /* If we have a statement object, free it. */ | |
| if (is_object($this->_statement)) { | |
| $this->_statement->free(); | |
| $this->_statement = null; | |
| } | |
| /* If we opened the database connection, disconnect it. */ | |
| if ($this->_opened && !$this->_existingConnection) { | |
| $this->_opened = false; | |
| return $this->_db->disconnect(); | |
| } | |
| return ($this->_opened === false); | |
| } | |
| /** | |
| * Sets this Log instance's identification string. Note that this | |
| * SQL-specific implementation will limit the length of the $ident string | |
| * to sixteen (16) characters. | |
| * | |
| * @param string $ident The new identification string. | |
| * | |
| * @access public | |
| * @since Log 1.8.5 | |
| */ | |
| function setIdent($ident) | |
| { | |
| $this->_ident = substr($ident, 0, $this->_identLimit); | |
| } | |
| /** | |
| * Inserts $message to the currently open database. Calls open(), | |
| * if necessary. Also passes the message along to any Log_observer | |
| * instances that are observing this Log. | |
| * | |
| * @param mixed $message String or object containing the message to log. | |
| * @param string $priority The priority of the message. Valid | |
| * values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT, | |
| * PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING, | |
| * PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG. | |
| * @return boolean True on success or false on failure. | |
| * @access public | |
| */ | |
| function log($message, $priority = null) | |
| { | |
| /* If a priority hasn't been specified, use the default value. */ | |
| if ($priority === null) { | |
| $priority = $this->_priority; | |
| } | |
| /* Abort early if the priority is above the maximum logging level. */ | |
| if (!$this->_isMasked($priority)) { | |
| return false; | |
| } | |
| /* If the connection isn't open and can't be opened, return failure. */ | |
| if (!$this->_opened && !$this->open()) { | |
| return false; | |
| } | |
| /* If we don't already have a statement object, create one. */ | |
| if (!is_object($this->_statement) && !$this->_prepareStatement()) { | |
| return false; | |
| } | |
| /* Extract the string representation of the message. */ | |
| $message = $this->_extractMessage($message); | |
| /* Build our set of values for this log entry. */ | |
| $values = array( | |
| 'id' => $this->_db->nextId($this->_sequence), | |
| 'logtime' => MDB2_Date::mdbNow(), | |
| 'ident' => $this->_ident, | |
| 'priority' => $priority, | |
| 'message' => $message | |
| ); | |
| /* Execute the SQL query for this log entry insertion. */ | |
| $this->_db->expectError(MDB2_ERROR_NOSUCHTABLE); | |
| $result = &$this->_statement->execute($values); | |
| $this->_db->popExpect(); | |
| /* Attempt to handle any errors. */ | |
| if (PEAR::isError($result)) { | |
| /* We can only handle MDB2_ERROR_NOSUCHTABLE errors. */ | |
| if ($result->getCode() != MDB2_ERROR_NOSUCHTABLE) { | |
| return false; | |
| } | |
| /* Attempt to create the target table. */ | |
| if (!$this->_createTable()) { | |
| return false; | |
| } | |
| /* Recreate our prepared statement resource. */ | |
| $this->_statement->free(); | |
| if (!$this->_prepareStatement()) { | |
| return false; | |
| } | |
| /* Attempt to re-execute the insertion query. */ | |
| $result = $this->_statement->execute($values); | |
| if (PEAR::isError($result)) { | |
| return false; | |
| } | |
| } | |
| $this->_announce(array('priority' => $priority, 'message' => $message)); | |
| return true; | |
| } | |
| /** | |
| * Create the log table in the database. | |
| * | |
| * @return boolean True on success or false on failure. | |
| * @access private | |
| */ | |
| function _createTable() | |
| { | |
| $this->_db->loadModule('Manager', null, true); | |
| $result = $this->_db->manager->createTable( | |
| $this->_table, | |
| array( | |
| 'id' => array('type' => $this->_types['id']), | |
| 'logtime' => array('type' => $this->_types['logtime']), | |
| 'ident' => array('type' => $this->_types['ident']), | |
| 'priority' => array('type' => $this->_types['priority']), | |
| 'message' => array('type' => $this->_types['message']) | |
| ) | |
| ); | |
| if (PEAR::isError($result)) { | |
| return false; | |
| } | |
| $result = $this->_db->manager->createIndex( | |
| $this->_table, | |
| 'unique_id', | |
| array('fields' => array('id' => true), 'unique' => true) | |
| ); | |
| if (PEAR::isError($result)) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| /** | |
| * Prepare the SQL insertion statement. | |
| * | |
| * @return boolean True if the statement was successfully created. | |
| * | |
| * @access private | |
| * @since Log 1.9.0 | |
| */ | |
| function _prepareStatement() | |
| { | |
| $this->_statement = &$this->_db->prepare( | |
| 'INSERT INTO ' . $this->_table . | |
| ' (id, logtime, ident, priority, message)' . | |
| ' VALUES(:id, :logtime, :ident, :priority, :message)', | |
| $this->_types, MDB2_PREPARE_MANIP); | |
| /* Return success if we didn't generate an error. */ | |
| return (PEAR::isError($this->_statement) === false); | |
| } | |
| } | |