Completed
Push — master ( e46910...56fa23 )
by Alexander
02:53
created

StatementProfiler::getProfiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file is part of the SVN-Buddy library.
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 *
7
 * @copyright Alexander Obuhovich <[email protected]>
8
 * @link      https://github.com/console-helpers/svn-buddy
9
 */
10
11
namespace ConsoleHelpers\SVNBuddy\Database;
12
13
14
use Aura\Sql\ProfilerInterface;
15
use ConsoleHelpers\ConsoleKit\ConsoleIO;
16
17
class StatementProfiler implements ProfilerInterface
18
{
19
20
	/**
21
	 * Is the profiler active?
22
	 *
23
	 * @var boolean
24
	 */
25
	protected $active = false;
26
27
	/**
28
	 * Retained profiles.
29
	 *
30
	 * @var array
31
	 */
32
	protected $profiles = array();
33
34
	/**
35
	 * Ignore statements.
36
	 *
37
	 * @var array
38
	 */
39
	protected $ignoreStatements = array(
40
		'SELECT LastRevision FROM PluginData WHERE Name = :name',
41
		'SELECT Id FROM Projects WHERE Path = :path',
42
	);
43
44
	/**
45
	 * Console IO.
46
	 *
47
	 * @var ConsoleIO
48
	 */
49
	private $_io;
50
51
	/**
52
	 * Debug mode.
53
	 *
54
	 * @var boolean
55
	 */
56
	private $_debugMode = false;
57
58
	/**
59
	 * Creates statement profiler
60
	 *
61
	 * @param ConsoleIO $io Console IO.
62
	 */
63 14
	public function __construct(ConsoleIO $io = null)
64
	{
65 14
		$this->_io = $io;
66 14
		$this->_debugMode = isset($io) && $io->isVerbose();
67 14
	}
68
69
	/**
70
	 * Turns the profiler on and off.
71
	 *
72
	 * @param boolean $active True to turn on, false to turn off.
73
	 *
74
	 * @return void
75
	 */
76 11
	public function setActive($active)
77
	{
78 11
		$this->active = (bool)$active;
79 11
	}
80
81
	/**
82
	 * Is the profiler active?
83
	 *
84
	 * @return boolean
85
	 */
86 13
	public function isActive()
87
	{
88 13
		return (bool)$this->active;
89
	}
90
91
	/**
92
	 * Adds a profile entry.
93
	 *
94
	 * @param float  $duration    The query duration.
95
	 * @param string $function    The PDO method that made the entry.
96
	 * @param string $statement   The SQL query statement.
97
	 * @param array  $bind_values The values bound to the statement.
98
	 *
99
	 * @return void
100
	 * @throws \PDOException When duplicate statement is detected.
101
	 */
102 11
	public function addProfile(
103
		$duration,
104
		$function,
105
		$statement,
106
		array $bind_values = array()
107
	) {
108 11
		if ( !$this->isActive() || $function === 'prepare' || !$statement ) {
109 3
			return;
110
		}
111
112 8
		$normalized_statement = preg_replace('/\s+/', ' ', $statement);
113
114 8
		if ( in_array($normalized_statement, $this->ignoreStatements) ) {
115 2
			return;
116
		}
117
118 6
		$profile_key = md5('statement:' . $normalized_statement . ';bind_values:' . serialize($bind_values));
119
120 6
		if ( isset($this->profiles[$profile_key]) ) {
121 1
			$error_msg = 'Duplicate statement:' . PHP_EOL . $normalized_statement;
122 1
			$error_msg .= PHP_EOL . 'Bind Values:' . PHP_EOL . print_r($bind_values, true);
123
124 1
			throw new \PDOException($error_msg);
125
		}
126
127 6
		$this->profiles[$profile_key] = array(
128 6
			'duration' => $duration,
129 6
			'function' => $function,
130 6
			'statement' => $statement,
131 6
			'bind_values' => $bind_values,
132
		);
133
134 6
		if ( $this->_debugMode ) {
135 1
			$runtime = sprintf('%01.2f', $duration);
136 1
			$this->_io->writeln(array(
137 1
				'',
138 1
				'<debug>[db, ' . round($runtime, 2) . 's]: ' . $normalized_statement . '</debug>',
139 1
			));
140 1
		}
141 6
	}
142
143
	/**
144
	 * Returns all the profile entries.
145
	 *
146
	 * @return array
147
	 */
148 11
	public function getProfiles()
149
	{
150 11
		return $this->profiles;
151
	}
152
153
	/**
154
	 * Reset all the profiles
155
	 *
156
	 * @return void
157
	 */
158 1
	public function resetProfiles()
159
	{
160 1
		$this->profiles = array();
161 1
	}
162
163
}
164