LoggerAppenderPDO.php
Current file: /home/ihabunek/apache/log4php/src/main/php/appenders/LoggerAppenderPDO.php
Legend: executed not executed dead code

  Coverage
  Classes Functions / Methods Lines
Total
0.00% 0 / 1
66.67% 8 / 12 CRAP
86.76% 59 / 68
LoggerAppenderPDO
0.00% 0 / 1
66.67% 8 / 12 25.34
86.76% 59 / 68
 activateOptions()
0.00% 0 / 1 8.10
88.24% 30 / 34
 append(LoggerLoggingEvent $event)
0.00% 0 / 1 4.02
90.00% 9 / 10
 close()
100.00% 1 / 1 3
100.00% 7 / 7
 setUser($user)
0.00% 0 / 1 2
0.00% 0 / 2
 setPassword($password)
0.00% 0 / 1 2
0.00% 0 / 2
 setCreateTable($flag)
100.00% 1 / 1 1
100.00% 2 / 2
 setSql($sql)
100.00% 1 / 1 1
100.00% 2 / 2
 setInsertSql($sql)
100.00% 1 / 1 1
100.00% 2 / 2
 setInsertPattern($pattern)
100.00% 1 / 1 1
100.00% 2 / 2
 setTable($table)
100.00% 1 / 1 1
100.00% 2 / 2
 setDSN($dsn)
100.00% 1 / 1 1
100.00% 2 / 2
 getDatabaseHandle()
100.00% 1 / 1 1
100.00% 1 / 1


       1                 : <?php                                                                                                                             
       2                 : /**                                                                                                                               
       3                 :  * Licensed to the Apache Software Foundation (ASF) under one or more                                                             
       4                 :  * contributor license agreements.  See the NOTICE file distributed with                                                          
       5                 :  * this work for additional information regarding copyright ownership.                                                            
       6                 :  * The ASF licenses this file to You under the Apache License, Version 2.0                                                        
       7                 :  * (the "License"); you may not use this file except in compliance with                                                           
       8                 :  * the License.  You may obtain a copy of the License at                                                                          
       9                 :  *                                                                                                                                
      10                 :  *     http://www.apache.org/licenses/LICENSE-2.0                                                                                 
      11                 :  *                                                                                                                                
      12                 :  * Unless required by applicable law or agreed to in writing, software                                                            
      13                 :  * distributed under the License is distributed on an "AS IS" BASIS,                                                              
      14                 :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.                                                       
      15                 :  * See the License for the specific language governing permissions and                                                            
      16                 :  * limitations under the License.                                                                                                 
      17                 :  *                                                                                                                                
      18                 :  * @package log4php                                                                                                               
      19                 :  */                                                                                                                               
      20                 :                                                                                                                                   
      21                 : /**                                                                                                                               
      22                 :  * Appends log events to a db table using PDO.                                                                                    
      23                 :  *                                                                                                                                
      24                 :  * Configurable parameters of this appender are:                                                                                  
      25                 :  *                                                                                                                                
      26                 :  * - user            - Sets the user of this database connection                                                                  
      27                 :  * - password        - Sets the password of this database connection                                                              
      28                 :  * - createTable     - true, if the table should be created if necessary. false otherwise                                         
      29                 :  * - table           - Sets the table name (default: log4php_log)                                                                 
      30                 :  * - sql             - Sets the insert statement for a logging event. Defaults                                                    
      31                 :  *                     to the correct one - change only if you are sure what you are doing.                                       
      32                 :  * - dsn             - Sets the DSN string for this connection                                                                    
      33                 :  *                                                                                                                                
      34                 :  * If $sql is set then $table and $sql are used, else $table, $insertSql and $insertPattern.                                      
      35                 :  *                                                                                                                                
      36                 :  * An example:                                                                                                                    
      37                 :  *                                                                                                                                
      38                 :  * {@example ../../examples/php/appender_pdo.php 19}                                                                              
      39                 :  *                                                                                                                                
      40                 :  * {@example ../../examples/resources/appender_pdo.properties 18}                                                                 
      41                 :  *                                                                                                                                
      42                 :  * @version $Revision: 806678 $                                                                                                   
      43                 :  * @package log4php                                                                                                               
      44                 :  * @subpackage appenders                                                                                                          
      45                 :  * @since 2.0                                                                                                                     
      46                 :  */                                                                                                                               
      47                 : class LoggerAppenderPDO extends LoggerAppender {                                                                                  
      48                 :                                                                                                                                   
      49                 :     /**                                                                                                                           
      50                 :      * Create the log table if it does not exists (optional).                                                                     
      51                 :      * @var string                                                                                                                
      52                 :      */                                                                                                                           
      53                 :     protected $createTable = true;                                                                                                
      54                 :                                                                                                                                   
      55                 :     /**                                                                                                                           
      56                 :      * Database user name.                                                                                                        
      57                 :      * @var string                                                                                                                
      58                 :      */                                                                                                                           
      59                 :     protected $user;                                                                                                              
      60                 :                                                                                                                                   
      61                 :     /**                                                                                                                           
      62                 :      * Database password                                                                                                          
      63                 :      * @var string                                                                                                                
      64                 :      */                                                                                                                           
      65                 :     protected $password;                                                                                                          
      66                 :                                                                                                                                   
      67                 :     /**                                                                                                                           
      68                 :      * DSN string for enabling a connection.                                                                                      
      69                 :      * @var string                                                                                                                
      70                 :      */                                                                                                                           
      71                 :     protected $dsn;                                                                                                               
      72                 :                                                                                                                                   
      73                 :     /**                                                                                                                           
      74                 :      * A {@link LoggerPatternLayout} string used to format a valid insert query.                                                  
      75                 :      * @deprecated Use {@link $insertSql} and {@link $insertPattern} which properly handle quotes in the messages!                
      76                 :      * @var string                                                                                                                
      77                 :      */                                                                                                                           
      78                 :     protected $sql;                                                                                                               
      79                 :                                                                                                                                   
      80                 :     /**                                                                                                                           
      81                 :      * Can be set to a complete insert statement with ? that are replaced using {@link insertPattern}.                            
      82                 :      * @var string                                                                                                                
      83                 :      */                                                                                                                           
      84                 :     protected $insertSql = "INSERT INTO __TABLE__ (timestamp, logger, level, message, thread, file, line) VALUES (?,?,?,?,?,?,?)";
      85                 :                                                                                                                                   
      86                 :     /**                                                                                                                           
      87                 :      * A comma separated list of {@link LoggerPatternLayout} format strings that replace the "?" in {@link $sql}.                 
      88                 :      * @var string                                                                                                                
      89                 :      */                                                                                                                           
      90                 :     protected $insertPattern = "%d,%c,%p,%m,%t,%F,%L";                                                                            
      91                 :                                                                                                                                   
      92                 :     /**                                                                                                                           
      93                 :      * Table name to write events. Used only for CREATE TABLE if {@link $createTable} is true.                                    
      94                 :      * @var string                                                                                                                
      95                 :      */                                                                                                                           
      96                 :     protected $table = 'log4php_log';                                                                                             
      97                 :                                                                                                                                   
      98                 :     /**                                                                                                                           
      99                 :      * The PDO instance.                                                                                                          
     100                 :      * @var PDO                                                                                                                   
     101                 :      */                                                                                                                           
     102                 :     protected $db = null;                                                                                                         
     103                 :                                                                                                                                   
     104                 :     /**                                                                                                                           
     105                 :      * Prepared statement for the INSERT INTO query.                                                                              
     106                 :      * @var PDOStatement                                                                                                          
     107                 :      */                                                                                                                           
     108                 :     protected $preparedInsert;                                                                                                    
     109                 :                                                                                                                                   
     110                 :     /**                                                                                                                           
     111                 :      * Set in activateOptions() and later used in append() to check if all conditions to append are true.                         
     112                 :      * @var boolean                                                                                                               
     113                 :      */                                                                                                                           
     114                 :     protected $canAppend = true;                                                                                                  
     115                 :                                                                                                                                   
     116                 :     /**                                                                                                                           
     117                 :      * This appender does not require a layout.                                                                                   
     118                 :      */                                                                                                                           
     119                 :     protected $requiresLayout = false;                                                                                            
     120                 :                                                                                                                                   
     121                 :     /**                                                                                                                           
     122                 :      * Setup db connection.                                                                                                       
     123                 :      * Based on defined options, this method connects to db defined in {@link $dsn}                                               
     124                 :      * and creates a {@link $table} table if {@link $createTable} is true.                                                        
     125                 :      * @return boolean true if all ok.                                                                                            
     126                 :      * @throws a PDOException if the attempt to connect to the requested database fails.                                          
     127                 :      */                                                                                                                           
     128                 :     public function activateOptions() {                                                                                           
     129                 :         try {                                                                                                                     
     130               5 :             if($this->user === null) {                                                                                            
     131               5 :                 $this->db = new PDO($this->dsn);                                                                                  
     132               4 :             } else if($this->password === null) {                                                                                 
     133               0 :                 $this->db = new PDO($this->dsn, $this->user);                                                                     
     134               0 :             } else {                                                                                                              
     135               0 :                 $this->db = new PDO($this->dsn,$this->user,$this->password);                                                      
     136                 :             }                                                                                                                     
     137               4 :             $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);                                                   
     138                 :                                                                                                                                   
     139                 :             // test if log table exists                                                                                           
     140                 :             try {                                                                                                                 
     141               4 :                 $result = $this->db->query('SELECT * FROM ' . $this->table . ' WHERE 1 = 0');                                     
     142               0 :                 $result->closeCursor();                                                                                           
     143               4 :             } catch (PDOException $e) {                                                                                           
     144                 :                 // It could be something else but a "no such table" is the most likely                                            
     145               4 :                 $result = false;                                                                                                  
     146                 :             }                                                                                                                     
     147                 :                                                                                                                                   
     148                 :             // create table if necessary                                                                                          
     149               4 :             if ($result == false and $this->createTable) {                                                                        
     150                 :                 // The syntax should at least be compatible with MySQL, PostgreSQL, SQLite and Oracle.                            
     151               3 :                 $query = "CREATE TABLE {$this->table} (".                                                                         
     152               3 :                             "timestamp varchar(32)," .                                                                            
     153               3 :                             "logger varchar(64)," .                                                                               
     154               3 :                             "level varchar(32)," .                                                                                
     155               3 :                             "message varchar(9999)," .                                                                            
     156               3 :                             "thread varchar(32)," .                                                                               
     157               3 :                             "file varchar(255)," .                                                                                
     158               3 :                             "line varchar(6))";                                                                                   
     159               3 :                 $result = $this->db->query($query);                                                                               
     160               3 :             }                                                                                                                     
     161               5 :         } catch (PDOException $e) {                                                                                               
     162               1 :             $this->canAppend = false;                                                                                             
     163               1 :             throw new LoggerException($e);                                                                                        
     164                 :         }                                                                                                                         
     165                 :                                                                                                                                   
     166               4 :         $this->layout = new LoggerLayoutPattern();                                                                                
     167                 :                                                                                                                                   
     168                 :         //                                                                                                                        
     169                 :         // Keep compatibility to legacy option $sql which already included the format patterns!                                   
     170                 :         //                                                                                                                        
     171               4 :         if (empty($this->sql)) {                                                                                                  
     172                 :             // new style with prepared Statment and $insertSql and $insertPattern                                                 
     173                 :             // Maybe the tablename has to be substituted.                                                                         
     174               3 :             $this->insertSql = preg_replace('/__TABLE__/', $this->table, $this->insertSql);                                       
     175               3 :             $this->preparedInsert = $this->db->prepare($this->insertSql);                                                         
     176               3 :             $this->layout->setConversionPattern($this->insertPattern);                                                            
     177               3 :         } else {                                                                                                                  
     178                 :             // Old style with format strings in the $sql query should be used.                                                    
     179               1 :         $this->layout->setConversionPattern($this->sql);                                                                          
     180                 :         }                                                                                                                         
     181                 :                                                                                                                                   
     182               4 :         $this->canAppend = true;                                                                                                  
     183               4 :         return true;                                                                                                              
     184                 :     }                                                                                                                             
     185                 :                                                                                                                                   
     186                 :     /**                                                                                                                           
     187                 :      * Appends a new event to the database.                                                                                       
     188                 :      *                                                                                                                            
     189                 :      * @throws LoggerException If the pattern conversion or the INSERT statement fails.                                           
     190                 :      */                                                                                                                           
     191                 :     public function append(LoggerLoggingEvent $event) {                                                                           
     192                 :         // TODO: Can't activateOptions() simply throw an Exception if it encounters problems?                                     
     193               4 :         if ( ! $this->canAppend) return;                                                                                          
     194                 :                                                                                                                                   
     195                 :             try {                                                                                                                 
     196               4 :             if (empty($this->sql)) {                                                                                              
     197                 :                 // new style with prepared statement                                                                              
     198               3 :                 $params = $this->layout->formatToArray($event);                                                                   
     199               3 :                 $this->preparedInsert->execute($params);                                                                          
     200               3 :             } else {                                                                                                              
     201                 :                 // old style                                                                                                      
     202               1 :                 $query = $this->layout->format($event);                                                                           
     203               1 :                 $this->db->exec($query);                                                                                          
     204                 :             }                                                                                                                     
     205               4 :             } catch (Exception $e) {                                                                                              
     206               0 :                 throw new LoggerException($e);                                                                                    
     207                 :             }                                                                                                                     
     208               4 :         }                                                                                                                         
     209                 :                                                                                                                                   
     210                 :     /**                                                                                                                           
     211                 :      * Closes the connection to the logging database                                                                              
     212                 :      */                                                                                                                           
     213                 :     public function close() {                                                                                                     
     214               2 :         if($this->closed != true) {                                                                                               
     215               2 :             if ($this->db !== null) {                                                                                             
     216               2 :                 $this->db = null;                                                                                                 
     217               2 :             }                                                                                                                     
     218               2 :             $this->closed = true;                                                                                                 
     219               2 :         }                                                                                                                         
     220               2 :     }                                                                                                                             
     221                 :                                                                                                                                   
     222                 :     /**                                                                                                                           
     223                 :      * Sets the username for this connection.                                                                                     
     224                 :      * Defaults to ''                                                                                                             
     225                 :      */                                                                                                                           
     226                 :     public function setUser($user) {                                                                                              
     227               0 :         $this->setString('user', $user);                                                                                          
     228               0 :     }                                                                                                                             
     229                 :                                                                                                                                   
     230                 :     /**                                                                                                                           
     231                 :      * Sets the password for this connection.                                                                                     
     232                 :      * Defaults to ''                                                                                                             
     233                 :      */                                                                                                                           
     234                 :     public function setPassword($password) {                                                                                      
     235               0 :         $this->setString('password', $password);                                                                                  
     236               0 :     }                                                                                                                             
     237                 :                                                                                                                                   
     238                 :     /**                                                                                                                           
     239                 :      * Indicator if the logging table should be created on startup,                                                               
     240                 :      * if its not existing.                                                                                                       
     241                 :      */                                                                                                                           
     242                 :     public function setCreateTable($flag) {                                                                                       
     243               2 :         $this->setBoolean('createTable', $flag);                                                                                  
     244               2 :     }                                                                                                                             
     245                 :                                                                                                                                   
     246                 :        /**                                                                                                                        
     247                 :      * Sets the SQL string into which the event should be transformed.                                                            
     248                 :      * Defaults to:                                                                                                               
     249                 :      *                                                                                                                            
     250                 :      * INSERT INTO $this->table                                                                                                   
     251                 :      * ( timestamp, logger, level, message, thread, file, line)                                                                   
     252                 :      * VALUES                                                                                                                     
     253                 :      * ('%d','%c','%p','%m','%t','%F','%L')                                                                                       
     254                 :      *                                                                                                                            
     255                 :      * It's not necessary to change this except you have customized logging'                                                      
     256                 :      *                                                                                                                            
     257                 :      * @deprecated See {@link setInsertSql} and {@link setInsertPattern}.                                                         
     258                 :      */                                                                                                                           
     259                 :     public function setSql($sql) {                                                                                                
     260               1 :         $this->setString('sql', $sql);                                                                                            
     261               1 :     }                                                                                                                             
     262                 :                                                                                                                                   
     263                 :     /**                                                                                                                           
     264                 :      * Sets the SQL INSERT string to use with {@link $insertPattern}.                                                             
     265                 :      *                                                                                                                            
     266                 :      * @param $sql          A complete INSERT INTO query with "?" that gets replaced.                                             
     267                 :      */                                                                                                                           
     268                 :     public function setInsertSql($sql) {                                                                                          
     269               1 :         $this->setString('insertSql', $sql);                                                                                      
     270               1 :     }                                                                                                                             
     271                 :                                                                                                                                   
     272                 :     /**                                                                                                                           
     273                 :      * Sets the {@link LoggerLayoutPattern} format strings for {@link $insertSql}.                                                
     274                 :      *                                                                                                                            
     275                 :      * It's not necessary to change this except you have customized logging.                                                      
     276                 :      *                                                                                                                            
     277                 :      * @param $pattern          Comma separated format strings like "%p,%m,%C"                                                    
     278                 :      */                                                                                                                           
     279                 :     public function setInsertPattern($pattern) {                                                                                  
     280               1 :         $this->setString('insertPattern', $pattern);                                                                              
     281               1 :     }                                                                                                                             
     282                 :                                                                                                                                   
     283                 :     /**                                                                                                                           
     284                 :      * Sets the tablename to which this appender should log.                                                                      
     285                 :      * Defaults to log4php_log                                                                                                    
     286                 :      */                                                                                                                           
     287                 :     public function setTable($table) {                                                                                            
     288               1 :         $this->setString('table', $table);                                                                                        
     289               1 :     }                                                                                                                             
     290                 :                                                                                                                                   
     291                 :     /**                                                                                                                           
     292                 :      * Sets the DSN string for this connection. In case of                                                                        
     293                 :      * SQLite it could look like this: 'sqlite:appenders/pdotest.sqlite'                                                          
     294                 :      */                                                                                                                           
     295                 :     public function setDSN($dsn) {                                                                                                
     296               5 :         $this->setString('dsn', $dsn);                                                                                            
     297               5 :     }                                                                                                                             
     298                 :                                                                                                                                   
     299                 :     /**                                                                                                                           
     300                 :      * Sometimes databases allow only one connection to themselves in one thread.                                                 
     301                 :      * SQLite has this behaviour. In that case this handle is needed if the database                                              
     302                 :      * must be checked for events.                                                                                                
     303                 :      *                                                                                                                            
     304                 :      * @return PDO                                                                                                                
     305                 :      */                                                                                                                           
     306                 :     public function getDatabaseHandle() {                                                                                         
     307               1 :         return $this->db;                                                                                                         
     308                 :     }                                                                                                                             
     309                 : }                                                                                                                                 
     310                 :                                                                                                                                   

Generated by PHP_CodeCoverage 1.1.1 using PHP 5.3.3-7+squeeze3 and PHPUnit 3.6.3 at Sat Feb 18 22:32:39 GMT 2012.