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

DBAL::getRawObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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