Completed
Push — master ( 687f7d...ab57ba )
by Aimeos
10:53
created

Base::getSqlParts()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 5
nop 1
dl 0
loc 29
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2017
7
 * @package MW
8
 * @subpackage DB
9
 */
10
11
12
namespace Aimeos\MW\DB\Statement;
13
14
15
/**
16
 * Base class for all statement implementations providing the parameter constants
17
 *
18
 * @package MW
19
 * @subpackage DB
20
 */
21
abstract class Base
22
{
23
	/**
24
	 * NULL values
25
	 */
26
	const PARAM_NULL = 0;
27
28
	/**
29
	 * Boolean (true/false) values
30
	 */
31
	const PARAM_BOOL = 1;
32
33
	/**
34
	 * 32bit integer values
35
	 */
36
	const PARAM_INT = 2;
37
38
	/**
39
	 * 32bit floating point values
40
	 */
41
	const PARAM_FLOAT = 3;
42
43
	/**
44
	 * String values
45
	 */
46
	const PARAM_STR = 4;
47
48
	/**
49
	 * Large objects
50
	 */
51
	const PARAM_LOB = 5;
52
53
54
	private $conn;
55
56
57
	/**
58
	 * Initializes the base object
59
	 *
60
	 * @param \Aimeos\MW\DB\Connection\Iface $conn Database connection object
61
	 */
62
	public function __construct( \Aimeos\MW\DB\Connection\Iface $conn )
63
	{
64
		$this->conn = $conn;
65
	}
66
67
68
	/**
69
	 * Creates the SQL string with bound parameters.
70
	 *
71
	 * @param array $parts List of SQL statement parts
72
	 * @param array $binds List of values for the markers
73
	 * @return string SQL statement
74
	 */
75
	protected function buildSQL( array $parts, array $binds )
76
	{
77
		$i = 1; $stmt = '';
78
79
		foreach( $parts as $part )
80
		{
81
			$stmt .= $part;
82
			if( isset( $binds[$i] ) ) {
83
				$stmt .= $binds[$i];
84
			}
85
			$i++;
86
		}
87
88
		return $stmt;
89
	}
90
91
92
	/**
93
	 * Returns the connection object
94
	 *
95
	 * @return \Aimeos\MW\DB\Connection\Iface Connection object
96
	 */
97
	protected function getConnection()
98
	{
99
		return $this->conn;
100
	}
101
102
103
	/**
104
	 * Returns the PDO type mapped to the Aimeos type
105
	 *
106
	 * @param integer $type Type of given value defined in \Aimeos\MW\DB\Statement\Base as constant
107
	 * @param mixed $value Value which should be bound to the placeholder
108
	 * @return integer PDO parameter type constant
109
	 * @throws \Aimeos\MW\DB\Exception If the type is unknown
110
	 */
111
	protected function getPdoType( $type, $value )
112
	{
113
		switch( $type )
114
		{
115
			case \Aimeos\MW\DB\Statement\Base::PARAM_NULL:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
116
				$pdotype = \PDO::PARAM_NULL; break;
117
			case \Aimeos\MW\DB\Statement\Base::PARAM_BOOL:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
118
				$pdotype = \PDO::PARAM_BOOL; break;
119
			case \Aimeos\MW\DB\Statement\Base::PARAM_INT:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
120
				$pdotype = \PDO::PARAM_INT; break;
121
			case \Aimeos\MW\DB\Statement\Base::PARAM_FLOAT:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
122
				$pdotype = \PDO::PARAM_STR; break;
123
			case \Aimeos\MW\DB\Statement\Base::PARAM_STR:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
124
				$pdotype = \PDO::PARAM_STR; break;
125
			case \Aimeos\MW\DB\Statement\Base::PARAM_LOB:
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
126
				$pdotype = \PDO::PARAM_LOB; break;
127
			default:
128
				throw new \Aimeos\MW\DB\Exception( sprintf( 'Invalid parameter type "%1$s"', $type ) );
129
		}
130
131
		if( is_null( $value ) ) {
132
			$pdotype = \PDO::PARAM_NULL;
133
		}
134
135
		return $pdotype;
136
	}
137
138
139
	/**
140
	 * Returns the SQL parts split at the markers
141
	 *
142
	 * @param string $sql SQL statement, mayby with markers
143
	 * @return array List of SQL parts split at the markers
144
	 * @throws \Aimeos\MW\DB\Exception If the SQL statement is invalid
145
	 */
146
	protected function getSqlParts( $sql )
147
	{
148
		$result = [];
149
		$parts = explode( '?', $sql );
150
151
		if( count( $parts ) === 1 ) {
152
			return $parts;
153
		}
154
155
		if( ( $part = reset( $parts ) ) !== false )
156
		{
157
			do
158
			{
159
				$count = 0; $temp = $part;
160
				while( ( $pr = str_replace( ['\\\'', '\'\''], '', $part ) ) !== false
161
					&& ( $count += substr_count( $pr, '\'' ) ) % 2 !== 0 )
162
				{
163
					if( ( $part = next( $parts ) ) === false ) {
164
						throw new \Aimeos\MW\DB\Exception( 'Number of apostrophes don\'t match: ' . $sql );
165
					}
166
					$temp .= '?' . $part;
167
				}
168
				$result[] = $temp;
169
			}
170
			while( ( $part = next( $parts ) ) !== false );
171
		}
172
173
		return $result;
174
	}
175
176
177
	/**
178
	 * Reconnects to the database server if not in a transaction
179
	 *
180
	 * @param \Exception $e Exception to throw if a transaction is running
181
	 * @return \Aimeos\MW\DB\Statement\Iface Object for method chaining
182
	 * @throws \Exception If a transaction is running
183
	 */
184
	protected function reconnect( \Exception $e )
185
	{
186
		if( $this->conn->inTransaction() ) {
187
			throw $e;
188
		}
189
190
		$this->conn->connect();
191
		return $this;
192
	}
193
}
194