ConnectionManager::create_dsn()   B
last analyzed

Complexity

Conditions 6
Paths 12

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 35
rs 8.439
cc 6
eloc 19
nc 12
nop 2
1
<?php
2
/**
3
 * Query
4
 *
5
 * Free Query Builder / Database Abstraction Layer
6
 *
7
 * @package		Query
8
 * @author		Timothy J. Warren
9
 * @copyright	Copyright (c) 2012 - 2015
10
 * @link 		https://github.com/aviat4ion/Query
11
 * @license		http://philsturgeon.co.uk/code/dbad-license
12
 */
13
14
// --------------------------------------------------------------------------
15
16
namespace Query;
17
18
/**
19
 * Connection manager class to manage connections for the
20
 * Query method
21
 *
22
 * @package Query
23
 * @subpackage Core
24
 */
25
final class ConnectionManager {
26
27
	/**
28
	 * Map of named database connections
29
	 * @var array
30
	 */
31
	private $connections = array();
32
33
	/**
34
	 * Class instance variable
35
	 * @var Connection_Manager
36
	 */
37
	private static $instance = null;
38
39
	// --------------------------------------------------------------------------
40
41
	/**
42
	 * Private constructor to prevent multiple instances
43
	 * @codeCoverageIgnore
44
	 */
45
	private function __construct() {}
46
47
	// --------------------------------------------------------------------------
48
49
	/**
50
	 * Private clone method to prevent cloning
51
	 * @throws \DomainException
52
	 */
53
	public function __clone()
54
	{
55
		throw new \DomainException("Can't clone singleton");
56
	}
57
58
	// --------------------------------------------------------------------------
59
60
	/**
61
	 * Prevent serialization of this object
62
	 * @throws \DomainException
63
	 */
64
	public function __sleep()
65
	{
66
		throw new \DomainException("No serializing of singleton");
67
	}
68
69
	// --------------------------------------------------------------------------
70
71
	/**
72
	 * Make sure serialize/deserialize doesn't work
73
	 * @throws \DomainException
74
	 */
75
	public function __wakeup()
76
	{
77
		throw new \DomainException("Can't unserialize singleton");
78
	}
79
80
	// --------------------------------------------------------------------------
81
82
	/**
83
	 * Return  a connection manager instance
84
	 *
85
	 * @staticvar null $instance
86
	 * @return ConnectionManager
87
	 */
88
	public static function get_instance()
89
	{
90
		if (self::$instance === null)
91
		{
92
			self::$instance = new self();
93
		}
94
95
		return self::$instance;
0 ignored issues
show
Bug Compatibility introduced by
The expression self::$instance; of type Query\ConnectionManager|Query\Connection_Manager adds the type Query\Connection_Manager to the return on line 95 which is incompatible with the return type documented by Query\ConnectionManager::get_instance of type Query\ConnectionManager.
Loading history...
96
	}
97
98
	// --------------------------------------------------------------------------
99
100
	/**
101
	 * Returns the connection specified by the name given
102
	 *
103
	 * @param string|array|object $name
104
	 * @return QueryBuilder
105
	 * @throws \InvalidArgumentException
106
	 */
107
	public function get_connection($name = '')
108
	{
109
		// If the parameter is a string, use it as an array index
110
		if (is_scalar($name) && isset($this->connections[$name]))
111
		{
112
			return $this->connections[$name];
113
		}
114
		elseif (empty($name) && ! empty($this->connections)) // Otherwise, return the last one
115
		{
116
			return end($this->connections);
117
		}
118
119
		// You should actually connect before trying to get a connection...
120
		throw new \InvalidArgumentException("The specified connection does not exist");
121
	}
122
123
	// --------------------------------------------------------------------------
124
125
	/**
126
	 * Parse the passed parameters and return a connection
127
	 *
128
	 * @param \stdClass $params
129
	 * @return QueryBuilder
130
	 */
131
	public function connect(\stdClass $params)
132
	{
133
		list($dsn, $dbtype, $params, $options) = $this->parse_params($params);
134
135
		$dbtype = ucfirst($dbtype);
136
		$driver = "\\Query\\Drivers\\{$dbtype}\\Driver";
137
138
		// Create the database connection
139
		$db = ( ! empty($params->user))
140
			? new $driver($dsn, $params->user, $params->pass, $options)
141
			: new $driver($dsn, '', '', $options);
142
143
		// Set the table prefix, if it exists
144
		if (isset($params->prefix))
145
		{
146
			$db->set_table_prefix($params->prefix);
147
		}
148
149
		// Create Query Builder object
150
		$conn = new QueryBuilder($db, new QueryParser($db));
151
152
153
		// Save it for later
154
		if (isset($params->alias))
155
		{
156
			$this->connections[$params->alias] = $conn;
157
		}
158
		else
159
		{
160
			$this->connections[] = $conn;
161
		}
162
163
		return $conn;
164
	}
165
166
	// --------------------------------------------------------------------------
167
168
	/**
169
	 * Parses params into a dsn and option array
170
	 *
171
	 * @param \stdClass $params
172
	 * @return array
173
	 * @throws BadDBDriverException
174
	 */
175
	public function parse_params(\stdClass $params)
176
	{
177
		$params->type = strtolower($params->type);
178
		$dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql';
179
		$dbtype = ucfirst($dbtype);
180
181
		// Make sure the class exists
182
		if ( ! class_exists("\\Query\\Drivers\\{$dbtype}\\Driver"))
183
		{
184
			throw new BadDBDriverException('Database driver does not exist, or is not supported');
185
		}
186
187
		// Set additional PDO options
188
		$options = array();
189
190
		if (isset($params->options))
191
		{
192
			$options = (array) $params->options;
193
		}
194
195
		// Create the dsn for the database to connect to
196
		if (strtolower($dbtype) === 'firebird')
197
		{
198
			$dsn = "{$params->host}:{$params->file}";
199
		}
200
		else if(strtolower($dbtype) === 'sqlite')
201
		{
202
			$dsn = $params->file;
203
		}
204
		else
205
		{
206
			$dsn = $this->create_dsn($dbtype, $params);
207
		}
208
209
210
		return array($dsn, $dbtype, $params, $options);
211
	}
212
213
	// --------------------------------------------------------------------------
214
215
	/**
216
	 * Create the dsn from the db type and params
217
	 *
218
	 * @param string $dbtype
219
	 * @param \stdClass $params
220
	 * @return string
221
	 */
222
	private function create_dsn($dbtype, \stdClass $params)
223
	{
224
		if (strtolower($dbtype) === 'pdo_firebird')
225
		{
226
			$dbtype = 'firebird';
227
		}
228
229
		$pairs = array();
230
231
		if ( ! empty($params->database))
232
		{
233
			$pairs[] = implode('=', array('dbname', $params->database));
234
		}
235
236
		$skip = array(
237
			'name' => 'name',
238
			'pass' => 'pass',
239
			'user' => 'user',
240
			'type' => 'type',
241
			'prefix' => 'prefix',
242
			'options' => 'options',
243
			'database' => 'database',
244
			'alias' => 'alias'
245
		);
246
247
		foreach($params as $key => $val)
248
		{
249
			if (( ! array_key_exists($key, $skip)) && ( ! empty($val)))
250
			{
251
				$pairs[] = implode('=', array($key, $val));
252
			}
253
		}
254
255
		return strtolower($dbtype) . ':' . implode(';', $pairs);
256
	}
257
}
258
// End of connection_manager.php