3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Log\Writer
;
13 use Zend\Db\Adapter\Adapter
;
14 use Zend\Log\Exception
;
15 use Zend\Log\Formatter
;
16 use Zend\Log\Formatter\Db
as DbFormatter
;
18 class Db
extends AbstractWriter
35 * Relates database columns names to log data field keys.
42 * Field separator for sub-elements
46 protected $separator = '_';
51 * We used the Adapter instead of Zend\Db for a performance reason.
53 * @param Adapter|array|Traversable $db
54 * @param string $tableName
55 * @param array $columnMap
56 * @param string $separator
57 * @throws Exception\InvalidArgumentException
59 public function __construct($db, $tableName = null, array $columnMap = null, $separator = null)
61 if ($db instanceof Traversable
) {
62 $db = iterator_to_array($db);
66 parent
::__construct($db);
67 $separator = isset($db['separator']) ?
$db['separator'] : null;
68 $columnMap = isset($db['column']) ?
$db['column'] : null;
69 $tableName = isset($db['table']) ?
$db['table'] : null;
70 $db = isset($db['db']) ?
$db['db'] : null;
73 if (!$db instanceof Adapter
) {
74 throw new Exception\
InvalidArgumentException('You must pass a valid Zend\Db\Adapter\Adapter');
77 $tableName = (string) $tableName;
78 if ('' === $tableName) {
79 throw new Exception\
InvalidArgumentException('You must specify a table name. Either directly in the constructor, or via options');
83 $this->tableName
= $tableName;
84 $this->columnMap
= $columnMap;
86 if (!empty($separator)) {
87 $this->separator
= $separator;
90 $this->setFormatter(new DbFormatter());
94 * Remove reference to database adapter
98 public function shutdown()
104 * Write a message to the log.
106 * @param array $event event data
108 * @throws Exception\RuntimeException
110 protected function doWrite(array $event)
112 if (null === $this->db
) {
113 throw new Exception\
RuntimeException('Database adapter is null');
116 $event = $this->formatter
->format($event);
118 // Transform the event array into fields
119 if (null === $this->columnMap
) {
120 $dataToInsert = $this->eventIntoColumn($event);
122 $dataToInsert = $this->mapEventIntoColumn($event, $this->columnMap
);
125 $statement = $this->db
->query($this->prepareInsert($this->db
, $this->tableName
, $dataToInsert));
126 $statement->execute($dataToInsert);
131 * Prepare the INSERT SQL statement
134 * @param string $tableName
135 * @param array $fields
138 protected function prepareInsert(Adapter
$db, $tableName, array $fields)
140 $keys = array_keys($fields);
141 $sql = 'INSERT INTO ' . $db->platform
->quoteIdentifier($tableName) . ' (' .
142 implode(",",array_map(array($db->platform
, 'quoteIdentifier'), $keys)) . ') VALUES (' .
143 implode(",",array_map(array($db->driver
, 'formatParameterName'), $keys)) . ')';
149 * Map event into column using the $columnMap array
151 * @param array $event
152 * @param array $columnMap
155 protected function mapEventIntoColumn(array $event, array $columnMap = null)
162 foreach ($event as $name => $value) {
163 if (is_array($value)) {
164 foreach ($value as $key => $subvalue) {
165 if (isset($columnMap[$name][$key])) {
166 $data[$columnMap[$name][$key]] = $subvalue;
169 } elseif (isset($columnMap[$name])) {
170 $data[$columnMap[$name]] = $value;
177 * Transform event into column for the db table
179 * @param array $event
182 protected function eventIntoColumn(array $event)
189 foreach ($event as $name => $value) {
190 if (is_array($value)) {
191 foreach ($value as $key => $subvalue) {
192 $data[$name . $this->separator
. $key] = $subvalue;
195 $data[$name] = $value;