Passed
Push — master ( 78ff77...606203 )
by Aimeos
04:53
created

DBAL::createConnection()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
dl 0
loc 24
rs 8.8333
c 0
b 0
f 0
cc 7
nc 12
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016-2022
6
 * @package MW
7
 * @subpackage DB
8
 */
9
10
11
namespace Aimeos\Base\DB\Manager;
12
13
14
/**
15
 * Manager for database connections using the DBAL library
16
 *
17
 * @package MW
18
 * @subpackage DB
19
 */
20
class DBAL implements \Aimeos\Base\DB\Manager\Iface
21
{
22
	private $connections = [];
23
	private $count = [];
24
	private $config;
25
26
27
	/**
28
	 * Initializes the database manager object
29
	 *
30
	 * @param \Aimeos\Base\Config\Iface $config Object holding the configuration data
31
	 */
32
	public function __construct( \Aimeos\Base\Config\Iface $config )
33
	{
34
		$this->config = $config;
35
	}
36
37
38
	/**
39
	 * Cleans up the object
40
	 */
41
	public function __destruct()
42
	{
43
		foreach( $this->connections as $name => $list )
44
		{
45
			foreach( $list as $key => $conn ) {
46
				unset( $this->connections[$name][$key] );
47
			}
48
		}
49
	}
50
51
52
	/**
53
	 * Reset when cloning the object
54
	 */
55
	public function __clone()
56
	{
57
		$this->connections = [];
58
		$this->count = [];
59
	}
60
61
62
	/**
63
	 * Clean up the objects inside
64
	 */
65
	public function __sleep()
66
	{
67
		$this->__destruct();
68
69
		$this->connections = [];
70
		$this->count = [];
71
72
		return get_object_vars( $this );
73
	}
74
75
76
	/**
77
	 * Returns a database connection.
78
	 *
79
	 * @param string $name Name of the resource in configuration
80
	 * @return \Aimeos\Base\DB\Connection\Iface
81
	 */
82
	public function acquire( string $name = 'db' )
83
	{
84
		try
85
		{
86
			if( $this->config->get( 'resource/' . $name ) === null ) {
87
				$name = 'db';
88
			}
89
90
			$adapter = $this->config->get( 'resource/' . $name . '/adapter', 'mysql' );
91
92
			if( !isset( $this->connections[$name] ) || empty( $this->connections[$name] ) )
93
			{
94
				if( !isset( $this->count[$name] ) ) {
95
					$this->count[$name] = 0;
96
				}
97
98
				$limit = $this->config->get( 'resource/' . $name . '/limit', -1 );
99
100
				if( $limit >= 0 && $this->count[$name] >= $limit )
101
				{
102
					$msg = sprintf( 'Maximum number of connections (%1$d) for "%2$s" exceeded', $limit, $name );
103
					throw new \Aimeos\Base\DB\Exception( $msg );
104
				}
105
106
				$this->connections[$name] = array( $this->createConnection( $name, $adapter ) );
107
				$this->count[$name]++;
108
			}
109
110
			return array_pop( $this->connections[$name] );
111
		}
112
		catch( \Exception $e ) {
113
			throw new \Aimeos\Base\DB\Exception( $e->getMessage(), $e->getCode() );
114
		}
115
	}
116
117
118
	/**
119
	 * Releases the connection for reuse
120
	 *
121
	 * @param \Aimeos\Base\DB\Connection\Iface $connection Connection object
122
	 * @param string $name Name of resource
123
	 */
124
	public function release( \Aimeos\Base\DB\Connection\Iface $connection, string $name = 'db' )
125
	{
126
		if( ( $connection instanceof \Aimeos\Base\DB\Connection\DBAL ) === false ) {
127
			throw new \Aimeos\Base\DB\Exception( 'Connection object isn\'t of type DBAL' );
128
		}
129
130
		if( $this->config->get( 'resource/' . $name ) === null ) {
131
			$name = 'db';
132
		}
133
134
		$this->connections[$name][] = $connection;
135
	}
136
137
138
	/**
139
	 * Creates a new database connection.
140
	 *
141
	 * @param string $name Name to the database configuration in the resource file
142
	 * @param string $adapter Name of the database adapter, e.g. "mysql"
143
	 * @return \Aimeos\Base\DB\Connection\Iface Database connection
144
	 */
145
	protected function createConnection( string $name, string $adapter ) : \Aimeos\Base\DB\Connection\Iface
146
	{
147
		$params = $this->config->get( 'resource/' . $name, [] );
148
149
		$params['user'] = $this->config->get( 'resource/' . $name . '/username' );
150
		$params['dbname'] = $this->config->get( 'resource/' . $name . '/database' );
151
152
		if( ( $socket = $this->config->get( 'resource/' . $name . '/socket' ) ) != null ) {
153
			$params['unix_socket'] = $socket;
154
		}
155
156
		switch( $adapter )
157
		{
158
			case 'mysql': $params['driver'] = 'pdo_mysql'; break;
159
			case 'oracle': $params['driver'] = 'pdo_oci'; break;
160
			case 'pgsql': $params['driver'] = 'pdo_pgsql'; break;
161
			case 'sqlite': $params['driver'] = 'pdo_sqlite'; break;
162
			case 'sqlsrv': $params['driver'] = 'pdo_sqlsrv'; break;
163
			default: $params['driver'] = $adapter;
164
		}
165
166
		$stmts = $this->config->get( 'resource/' . $name . '/stmt', [] );
167
168
		return new \Aimeos\Base\DB\Connection\DBAL( $params, $stmts );
169
	}
170
}
171