|
- <?php
- /**
- * $Header: /home/ppcvs/paypal_php_sdk/Log/mdb2.php,v 1.1 2006/02/19 08:22:29 dennis Exp $
- *
- * @version $Revision: 1.1 $
- * @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)
- {
- $this->_id = md5(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');
- $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);
-
- /* Return success if we didn't generate an error. */
- return (PEAR::isError($this->_statement) === false);
- }
- }
|