Passed
Push — master ( 1a5f01...95cf58 )
by Aimeos
09:39
created

DBAL::close()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 8
rs 10
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016-2022
6
 * @package Base
7
 * @subpackage DB
8
 */
9
10
11
namespace Aimeos\Base\DB\Connection;
12
13
14
/**
15
 * Database connection class for DBAL connections
16
 *
17
 * @package Base
18
 * @subpackage DB
19
 */
20
class DBAL extends \Aimeos\Base\DB\Connection\Base implements \Aimeos\Base\DB\Connection\Iface
21
{
22
	private $connection;
23
	private $txnumber = 0;
24
	private $stmts = [];
25
26
27
	/**
28
	 * Initializes the DBAL connection object
29
	 *
30
	 * @param array $params Associative list of connection parameters
31
	 * @param string[] $stmts List of SQL statements to execute after connecting
32
	 */
33
	public function __construct( array $params, array $stmts )
34
	{
35
		parent::__construct( $params );
36
37
		$this->stmts = $stmts;
38
		$this->connect();
39
	}
40
41
42
	/**
43
	 * Closes the connection to the database server
44
	 *
45
	 * @return \Aimeos\MW\DB\Connection\Iface Connection instance for method chaining
0 ignored issues
show
Bug introduced by
The type Aimeos\MW\DB\Connection\Iface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
46
	 */
47
	public function close() : Iface
48
	{
49
		if( $this->inTransaction() ) {
50
			$this->rollback();
51
		}
52
53
		$this->connection->close();
54
		return $this;
55
	}
56
57
58
	/**
59
	 * Connects (or reconnects) to the database server
60
	 *
61
	 * @return \Aimeos\Base\DB\Connection\Iface Connection instance for method chaining
62
	 */
63
	public function connect() : \Aimeos\Base\DB\Connection\Iface
64
	{
65
		if( $this->connection && $this->connection->ping() ) {
66
			return $this;
67
		}
68
69
		$param = $this->getParameters();
70
		$param['driverOptions'][\PDO::ATTR_CASE] = \PDO::CASE_NATURAL;
71
		$param['driverOptions'][\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_EXCEPTION;
72
		$param['driverOptions'][\PDO::ATTR_ORACLE_NULLS] = \PDO::NULL_NATURAL;
73
		$param['driverOptions'][\PDO::ATTR_STRINGIFY_FETCHES] = false;
74
75
		$conn = $this->connection;
76
77
		$this->connection = \Doctrine\DBAL\DriverManager::getConnection( $param );
78
		$this->txnumber = 0;
79
80
		unset( $conn );
81
82
		foreach( $this->stmts as $stmt ) {
83
			$this->create( $stmt )->execute()->finish();
84
		}
85
86
		return $this;
87
	}
88
89
90
	/**
91
	 * Creates a DBAL database statement
92
	 *
93
	 * @param string $sql SQL statement, maybe with place holders
94
	 * @return \Aimeos\Base\DB\Statement\Iface DBAL statement object
95
	 * @throws \Aimeos\Base\DB\Exception if type is invalid or the DBAL object throws an exception
96
	 */
97
	public function create( string $sql ) : \Aimeos\Base\DB\Statement\Iface
98
	{
99
		try
100
		{
101
			if( strpos( $sql, '?' ) === false ) {
102
				return new \Aimeos\Base\DB\Statement\DBAL\Simple( $this, $sql );
103
			}
104
105
			return new \Aimeos\Base\DB\Statement\DBAL\Prepared( $this, $sql );
106
		}
107
		catch( \Exception $e )
108
		{
109
			throw new \Aimeos\Base\DB\Exception( $e->getMessage(), $e->getCode() );
110
		}
111
	}
112
113
114
	/**
115
	 * Returns the underlying connection object
116
	 *
117
	 * @return \Doctrine\DBAL\Connection Underlying connection object
118
	 */
119
	public function getRawObject()
120
	{
121
		return $this->connection;
122
	}
123
124
125
	/**
126
	 * Checks if a transaction is currently running
127
	 *
128
	 * @return bool True if transaction is currently running, false if not
129
	 */
130
	public function inTransaction() : bool
131
	{
132
		$conn = $this->connection->getWrappedConnection();
133
134
		if( $conn instanceof \PDO ) {
135
			return $conn->inTransaction();
136
		}
137
138
		return $conn->getNativeConnection()->inTransaction();
139
	}
140
141
142
	/**
143
	 * Starts a transaction for this connection.
144
	 *
145
	 * Transactions can't be nested and a new transaction can only be started
146
	 * if the previous transaction was committed or rolled back before.
147
	 *
148
	 * @return \Aimeos\Base\DB\Connection\Iface Connection instance for method chaining
149
	 */
150
	public function begin() : Iface
151
	{
152
		if( $this->txnumber === 0 )
153
		{
154
			if( $this->connection->getWrappedConnection()->beginTransaction() === false ) {
155
				throw new \Aimeos\Base\DB\Exception( 'Unable to start new transaction' );
156
			}
157
		}
158
159
		$this->txnumber++;
160
		return $this;
161
	}
162
163
164
	/**
165
	 * Commits the changes done inside of the transaction to the storage.
166
	 *
167
	 * @return \Aimeos\Base\DB\Connection\Iface Connection instance for method chaining
168
	 */
169
	public function commit() : Iface
170
	{
171
		if( $this->txnumber === 1 )
172
		{
173
			if( $this->connection->getWrappedConnection()->commit() === false ) {
174
				throw new \Aimeos\Base\DB\Exception( 'Failed to commit transaction' );
175
			}
176
		}
177
178
		$this->txnumber--;
179
		return $this;
180
	}
181
182
183
	/**
184
	 * Discards the changes done inside of the transaction.
185
	 *
186
	 * @return \Aimeos\Base\DB\Connection\Iface Connection instance for method chaining
187
	 */
188
	public function rollback() : Iface
189
	{
190
		if( $this->txnumber === 1 )
191
		{
192
			if( $this->connection->getWrappedConnection()->rollBack() === false ) {
193
				throw new \Aimeos\Base\DB\Exception( 'Failed to roll back transaction' );
194
			}
195
		}
196
197
		$this->txnumber--;
198
		return $this;
199
	}
200
}
201