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

Prepared   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 16
eloc 38
dl 0
loc 120
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A bind() 0 4 1
B getDbalType() 0 25 8
A exec() 0 15 3
A __toString() 0 3 1
A __construct() 0 4 1
A execute() 0 9 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\Statement\DBAL;
12
13
14
/**
15
 * Database statement class for prepared DBAL statements
16
 *
17
 * @package MW
18
 * @subpackage DB
19
 */
20
class Prepared extends \Aimeos\Base\DB\Statement\Base implements \Aimeos\Base\DB\Statement\Iface
21
{
22
	private $binds = [];
23
	private $sql;
24
25
26
	/**
27
	 * Initializes the statement object
28
	 *
29
	 * @param \Aimeos\Base\DB\Connection\DBAL $conn Database connection object
30
	 * @param string $sql SQL statement
31
	 */
32
	public function __construct( \Aimeos\Base\DB\Connection\DBAL $conn, string $sql )
33
	{
34
		parent::__construct( $conn );
35
		$this->sql = $sql;
36
	}
37
38
39
	/**
40
	 * Returns the SQL string as sent to the database (magic PHP method)
41
	 *
42
	 * @return string SQL statement
43
	 */
44
	public function __toString()
45
	{
46
		return $this->sql . ":\n" . print_r( array_column( $this->binds, 0 ), true );
0 ignored issues
show
Bug introduced by
Are you sure print_r(array_column($this->binds, 0), true) of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
		return $this->sql . ":\n" . /** @scrutinizer ignore-type */ print_r( array_column( $this->binds, 0 ), true );
Loading history...
47
	}
48
49
50
	/**
51
	 * Binds a value to a parameter in the statement
52
	 *
53
	 * @param int $position Position index of the placeholder
54
	 * @param mixed $value Value which should be bound to the placeholder
55
	 * @param int $type Type of given value defined in \Aimeos\Base\DB\Statement\Base as constant
56
	 * @return \Aimeos\Base\DB\Statement\Iface Statement instance for method chaining
57
	 * @throws \Aimeos\Base\DB\Exception If an error occured in the unterlying driver
58
	 */
59
	public function bind( int $position, $value, int $type = \Aimeos\Base\DB\Statement\Base::PARAM_STR ) : \Aimeos\Base\DB\Statement\Iface
60
	{
61
		$this->binds[$position] = [$value, $type];
62
		return $this;
63
	}
64
65
66
	/**
67
	 * Executes the statement
68
	 *
69
	 * @return \Aimeos\Base\DB\Result\Iface Result object
70
	 * @throws \Aimeos\Base\DB\Exception If an error occured in the unterlying driver
71
	 */
72
	public function execute() : \Aimeos\Base\DB\Result\Iface
73
	{
74
		try {
75
			$result = $this->exec();
76
		} catch( \Doctrine\DBAL\Driver\Exception $e ) {
77
			throw new \Aimeos\Base\DB\Exception( $e->getMessage() . ': ' . $this->sql . map( $this->binds )->col( 0 )->toJson(), $e->getCode() );
78
		}
79
80
		return new \Aimeos\Base\DB\Result\DBAL( $result );
81
	}
82
83
84
	/**
85
	 * Binds the parameters and executes the SQL statment
86
	 *
87
	 * @return \Doctrine\DBAL\Driver\Statement|\Doctrine\DBAL\Driver\Result DBAL statement or result object
88
	 */
89
	protected function exec()
90
	{
91
		$stmt = $this->getConnection()->getRawObject()->getWrappedConnection()->prepare( $this->sql );
92
93
		foreach( $this->binds as $position => $list ) {
94
			$stmt->bindValue( $position, $list[0], $this->getDbalType( $list[1], $list[0] ) );
95
		}
96
97
		$result = $stmt->execute();
98
99
		if( $result instanceof \Doctrine\DBAL\Driver\Result ) {
100
			return $result;
101
		}
102
103
		return $stmt;
104
	}
105
106
107
	/**
108
	 * Returns the PDO type mapped to the Aimeos type
109
	 *
110
	 * @param integer $type Type of given value defined in \Aimeos\Base\DB\Statement\Base as constant
111
	 * @param mixed $value Value which should be bound to the placeholder
112
	 * @return integer PDO parameter type constant
113
	 * @throws \Aimeos\Base\DB\Exception If the type is unknown
114
	 */
115
	protected function getDbalType( int $type, $value ) : int
116
	{
117
		switch( $type )
118
		{
119
			case \Aimeos\Base\DB\Statement\Base::PARAM_NULL:
120
				$dbaltype = \Doctrine\DBAL\ParameterType::NULL; break;
121
			case \Aimeos\Base\DB\Statement\Base::PARAM_BOOL:
122
				$dbaltype = \Doctrine\DBAL\ParameterType::BOOLEAN; break;
123
			case \Aimeos\Base\DB\Statement\Base::PARAM_INT:
124
				$dbaltype = \Doctrine\DBAL\ParameterType::INTEGER; break;
125
			case \Aimeos\Base\DB\Statement\Base::PARAM_FLOAT:
126
				$dbaltype = \Doctrine\DBAL\ParameterType::STRING; break;
127
			case \Aimeos\Base\DB\Statement\Base::PARAM_STR:
128
				$dbaltype = \Doctrine\DBAL\ParameterType::STRING; break;
129
			case \Aimeos\Base\DB\Statement\Base::PARAM_LOB:
130
				$dbaltype = \Doctrine\DBAL\ParameterType::LARGE_OBJECT; break;
131
			default:
132
				throw new \Aimeos\Base\DB\Exception( sprintf( 'Invalid parameter type "%1$s"', $type ) );
133
		}
134
135
		if( is_null( $value ) ) {
136
			$dbaltype = \Doctrine\DBAL\ParameterType::NULL;
137
		}
138
139
		return $dbaltype;
140
	}
141
}
142