requiresLayout = false; } public function __destruct() { $this->close(); } /** * Setup db connection. * Based on defined options, this method connects to db defined in {@link $dsn} * and creates a {@link $table} table if {@link $createTable} is true. * @return boolean true if all ok. * @throws a PDOException if the attempt to connect to the requested database fails. */ public function activateOptions() { try { if($this->user === null) { $this->db = new PDO($this->dsn); } else if($this->password === null) { $this->db = new PDO($this->dsn, $this->user); } else { $this->db = new PDO($this->dsn,$this->user,$this->password); } $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // test if log table exists try { $result = $this->db->query('select * from ' . $this->table . ' where 1 = 0'); } catch (PDOException $e) { // It could be something else but a "no such table" is the most likely $result = false; } // create table if necessary if ($result == false and $this->createTable) { // TODO mysql syntax? $query = "CREATE TABLE {$this->table} ( timestamp varchar(32)," . "logger varchar(32)," . "level varchar(32)," . "message varchar(64)," . "thread varchar(32)," . "file varchar(64)," . "line varchar(4) );"; $result = $this->db->query($query); } } catch (PDOException $e) { $this->canAppend = false; throw new LoggerException($e); } if($this->sql == '' || $this->sql == null) { $this->sql = "INSERT INTO $this->table ( timestamp, " . "logger, " . "level, " . "message, " . "thread, " . "file, " . "line" . ") VALUES ('%d','%c','%p','%m','%t','%F','%L')"; } $this->layout = LoggerReflectionUtils::createObject('LoggerLayoutPattern'); $this->layout->setConversionPattern($this->sql); $this->canAppend = true; return true; } /** * Appends a new event to the database using the sql format. */ // TODO:should work with prepared statement public function append(LoggerLoggingEvent $event) { if ($this->canAppend) { $query = $this->layout->format($event); try { $this->db->exec($query); } catch (Exception $e) { throw new LoggerException($e); } } } /** * Closes the connection to the logging database */ public function close() { if($this->closed != true) { if ($this->db !== null) { $db = null; } $this->closed = true; } } /** * Sets the username for this connection. * Defaults to '' */ public function setUser($user) { $this->user = $user; } /** * Sets the password for this connection. * Defaults to '' */ public function setPassword($password) { $this->password = $password; } /** * Indicator if the logging table should be created on startup, * if its not existing. */ public function setCreateTable($flag) { $this->createTable = LoggerOptionConverter::toBoolean($flag, true); } /** * Sets the SQL string into which the event should be transformed. * Defaults to: * * INSERT INTO $this->table * ( timestamp, logger, level, message, thread, file, line) * VALUES * ('%d','%c','%p','%m','%t','%F','%L') * * It's not necessary to change this except you have customized logging' */ public function setSql($sql) { $this->sql = $sql; } /** * Sets the tablename to which this appender should log. * Defaults to log4php_log */ public function setTable($table) { $this->table = $table; } /** * Sets the DSN string for this connection. In case of * SQLite it could look like this: 'sqlite:appenders/pdotest.sqlite' */ public function setDSN($dsn) { $this->dsn = $dsn; } /** * Sometimes databases allow only one connection to themselves in one thread. * SQLite has this behaviour. In that case this handle is needed if the database * must be checked for events. * * @return PDO */ public function getDatabaseHandle() { return $this->db; } }