Completed
Push — develop ( 559c76...bb3821 )
by Timothy
08:58 queued 06:44
created

ConnectionManager::__wakeup()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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