Prepared::getDbalType()   B
last analyzed

Complexity

Conditions 8
Paths 13

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 25
rs 8.4444
cc 8
nc 13
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016-2025
6
 * @package Base
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 Base
18
 * @subpackage DB
19
 */
20
class Prepared extends \Aimeos\Base\DB\Statement\Base implements \Aimeos\Base\DB\Statement\Iface
21
{
22
	private array $binds = [];
23
	private string $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( \PDOException $e ) {
77
			throw new \Aimeos\Base\DB\Exception( $e->getMessage() . ': ' . $this->sql . json_encode( array_column( $this->binds, 0 ) ), $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
		try
92
		{
93
			$stmt = $this->getConnection()->getRawObject()->getNativeConnection()->prepare( $this->sql );
94
95
			foreach( $this->binds as $position => $list ) {
96
				$stmt->bindValue( $position, $list[0], $this->getDbalType( $list[1], $list[0] ) );
97
			}
98
99
			$result = $stmt->execute();
100
101
			if( $result instanceof \Doctrine\DBAL\Driver\Result ) {
102
				return $result;
103
			}
104
105
			return $stmt;
106
		}
107
		catch( \PDOException $e )
108
		{
109
			throw new \Aimeos\Base\DB\Exception( $e->getMessage(), $e->getCode() );
110
		}
111
	}
112
113
114
	/**
115
	 * Returns the PDO type mapped to the Aimeos type
116
	 *
117
	 * @param integer $type Type of given value defined in \Aimeos\Base\DB\Statement\Base as constant
118
	 * @param mixed $value Value which should be bound to the placeholder
119
	 * @return integer PDO parameter type constant
120
	 * @throws \Aimeos\Base\DB\Exception If the type is unknown
121
	 */
122
	protected function getDbalType( int $type, $value ) : int
123
	{
124
		switch( $type )
125
		{
126
			case \Aimeos\Base\DB\Statement\Base::PARAM_NULL:
127
				$dbaltype = \PDO::PARAM_NULL; break;
128
			case \Aimeos\Base\DB\Statement\Base::PARAM_BOOL:
129
				$dbaltype = \PDO::PARAM_BOOL; break;
130
			case \Aimeos\Base\DB\Statement\Base::PARAM_INT:
131
				$dbaltype = \PDO::PARAM_INT; break;
132
			case \Aimeos\Base\DB\Statement\Base::PARAM_FLOAT:
133
				$dbaltype = \PDO::PARAM_STR; break;
134
			case \Aimeos\Base\DB\Statement\Base::PARAM_STR:
135
				$dbaltype = \PDO::PARAM_STR; break;
136
			case \Aimeos\Base\DB\Statement\Base::PARAM_LOB:
137
				$dbaltype = \PDO::PARAM_LOB; break;
138
			default:
139
				throw new \Aimeos\Base\DB\Exception( sprintf( 'Invalid parameter type "%1$s"', $type ) );
140
		}
141
142
		if( is_null( $value ) ) {
143
			$dbaltype = \PDO::PARAM_NULL;
144
		}
145
146
		return $dbaltype;
147
	}
148
}
149