source: branches/1.2/workflow/inc/log/Log/sql.php @ 1349

Revision 1349, 8.6 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

  • Property svn:executable set to *
Line 
1<?php
2/**
3 * $Header: /repository/pear/Log/Log/sql.php,v 1.42 2008/01/19 22:12:16 jon Exp $
4 * $Horde: horde/lib/Log/sql.php,v 1.12 2000/08/16 20:27:34 chuck Exp $
5 *
6 * @version $Revision: 1.42 $
7 * @package Log
8 */
9
10/**
11 * We require the PEAR DB class.  This is generally defined in the DB.php file,
12 * but it's possible that the caller may have provided the DB class, or a
13 * compatible wrapper (such as the one shipped with MDB2), so we first check
14 * for an existing 'DB' class before including 'DB.php'.
15 */
16if (!class_exists('DB')) {
17    require_once 'DB.php';
18}
19
20/**
21 * The Log_sql class is a concrete implementation of the Log::
22 * abstract class which sends messages to an SQL server.  Each entry
23 * occupies a separate row in the database.
24 *
25 * This implementation uses PHP's PEAR database abstraction layer.
26 *
27 * CREATE TABLE log_table (
28 *  id          INT NOT NULL,
29 *  logtime     TIMESTAMP NOT NULL,
30 *  ident       CHAR(16) NOT NULL,
31 *  priority    INT NOT NULL,
32 *  message     VARCHAR(200),
33 *  PRIMARY KEY (id)
34 * );
35 *
36 * @author  Jon Parise <jon@php.net>
37 * @since   Horde 1.3
38 * @since   Log 1.0
39 * @package Log
40 *
41 * @example sql.php     Using the SQL handler.
42 */
43class Log_sql extends Log
44{
45    /**
46     * Variable containing the DSN information.
47     * @var mixed
48     * @access private
49     */
50    var $_dsn = '';
51
52    /**
53     * String containing the SQL insertion statement.
54     *
55     * @var string
56     * @access private
57     */
58    var $_sql = '';
59
60    /**
61     * Array containing our set of DB configuration options.
62     * @var array
63     * @access private
64     */
65    var $_options = array('persistent' => true);
66
67    /**
68     * Object holding the database handle.
69     * @var object
70     * @access private
71     */
72    var $_db = null;
73
74    /**
75     * Resource holding the prepared statement handle.
76     * @var resource
77     * @access private
78     */
79    var $_statement = null;
80
81    /**
82     * Flag indicating that we're using an existing database connection.
83     * @var boolean
84     * @access private
85     */
86    var $_existingConnection = false;
87
88    /**
89     * String holding the database table to use.
90     * @var string
91     * @access private
92     */
93    var $_table = 'log_table';
94
95    /**
96     * String holding the name of the ID sequence.
97     * @var string
98     * @access private
99     */
100    var $_sequence = 'log_id';
101
102    /**
103     * Maximum length of the $ident string.  This corresponds to the size of
104     * the 'ident' column in the SQL table.
105     * @var integer
106     * @access private
107     */
108    var $_identLimit = 16;
109
110
111    /**
112     * Constructs a new sql logging object.
113     *
114     * @param string $name         The target SQL table.
115     * @param string $ident        The identification field.
116     * @param array $conf          The connection configuration array.
117     * @param int $level           Log messages up to and including this level.
118     * @access public
119     */
120    function Log_sql($name, $ident = '', $conf = array(),
121                     $level = PEAR_LOG_DEBUG)
122    {
123        $this->_id = md5(microtime());
124        $this->_table = $name;
125        $this->_mask = Log::UPTO($level);
126
127        /* Now that we have a table name, assign our SQL statement. */
128        if (!empty($conf['sql'])) {
129            $this->_sql = $conf['sql'];
130        } else {
131            $this->_sql = 'INSERT INTO ' . $this->_table .
132                          ' (id, logtime, ident, priority, message)' .
133                          ' VALUES(?, CURRENT_TIMESTAMP, ?, ?, ?)';
134        }
135
136        /* If an options array was provided, use it. */
137        if (isset($conf['options']) && is_array($conf['options'])) {
138            $this->_options = $conf['options'];
139        }
140
141        /* If a specific sequence name was provided, use it. */
142        if (!empty($conf['sequence'])) {
143            $this->_sequence = $conf['sequence'];
144        }
145
146        /* If a specific sequence name was provided, use it. */
147        if (isset($conf['identLimit'])) {
148            $this->_identLimit = $conf['identLimit'];
149        }
150
151        /* Now that the ident limit is confirmed, set the ident string. */
152        $this->setIdent($ident);
153
154        /* If an existing database connection was provided, use it. */
155        if (isset($conf['db'])) {
156            $this->_db = &$conf['db'];
157            $this->_existingConnection = true;
158            $this->_opened = true;
159        } else {
160            $this->_dsn = $conf['dsn'];
161        }
162    }
163
164    /**
165     * Opens a connection to the database, if it has not already
166     * been opened. This is implicitly called by log(), if necessary.
167     *
168     * @return boolean   True on success, false on failure.
169     * @access public
170     */
171    function open()
172    {
173        if (!$this->_opened) {
174            /* Use the DSN and options to create a database connection. */
175            $this->_db = &DB::connect($this->_dsn, $this->_options);
176            if (DB::isError($this->_db)) {
177                return false;
178            }
179
180            /* Create a prepared statement for repeated use in log(). */
181            if (!$this->_prepareStatement()) {
182                return false;
183            }
184
185            /* We now consider out connection open. */
186            $this->_opened = true;
187        }
188
189        return $this->_opened;
190    }
191
192    /**
193     * Closes the connection to the database if it is still open and we were
194     * the ones that opened it.  It is the caller's responsible to close an
195     * existing connection that was passed to us via $conf['db'].
196     *
197     * @return boolean   True on success, false on failure.
198     * @access public
199     */
200    function close()
201    {
202        if ($this->_opened && !$this->_existingConnection) {
203            $this->_opened = false;
204            $this->_db->freePrepared($this->_statement);
205            return $this->_db->disconnect();
206        }
207
208        return ($this->_opened === false);
209    }
210
211    /**
212     * Sets this Log instance's identification string.  Note that this
213     * SQL-specific implementation will limit the length of the $ident string
214     * to sixteen (16) characters.
215     *
216     * @param string    $ident      The new identification string.
217     *
218     * @access  public
219     * @since   Log 1.8.5
220     */
221    function setIdent($ident)
222    {
223        $this->_ident = substr($ident, 0, $this->_identLimit);
224    }
225
226    /**
227     * Inserts $message to the currently open database.  Calls open(),
228     * if necessary.  Also passes the message along to any Log_observer
229     * instances that are observing this Log.
230     *
231     * @param mixed  $message  String or object containing the message to log.
232     * @param string $priority The priority of the message.  Valid
233     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
234     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
235     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
236     * @return boolean  True on success or false on failure.
237     * @access public
238     */
239    function log($message, $priority = null)
240    {
241        /* If a priority hasn't been specified, use the default value. */
242        if ($priority === null) {
243            $priority = $this->_priority;
244        }
245
246        /* Abort early if the priority is above the maximum logging level. */
247        if (!$this->_isMasked($priority)) {
248            return false;
249        }
250
251        /* If the connection isn't open and can't be opened, return failure. */
252        if (!$this->_opened && !$this->open()) {
253            return false;
254        }
255
256        /* If we don't already have our statement object yet, create it. */
257        if (!is_object($this->_statement) && !$this->_prepareStatement()) {
258            return false;
259        }
260
261        /* Extract the string representation of the message. */
262        $message = $this->_extractMessage($message);
263
264        /* Build our set of values for this log entry. */
265        $id = $this->_db->nextId($this->_sequence);
266        $values = array($id, $this->_ident, $priority, $message);
267
268        /* Execute the SQL query for this log entry insertion. */
269        $result =& $this->_db->execute($this->_statement, $values);
270        if (DB::isError($result)) {
271            return false;
272        }
273
274        $this->_announce(array('priority' => $priority, 'message' => $message));
275
276        return true;
277    }
278
279    /**
280     * Prepare the SQL insertion statement.
281     *
282     * @return boolean  True if the statement was successfully created.
283     *
284     * @access  private
285     * @since   Log 1.9.1
286     */
287    function _prepareStatement()
288    {
289        $this->_statement = $this->_db->prepare($this->_sql);
290
291        /* Return success if we didn't generate an error. */
292        return (DB::isError($this->_statement) === false);
293    }
294}
Note: See TracBrowser for help on using the repository browser.