Passed
Push — master ( c0e9f0...37b7eb )
by Adrian
02:12
created

QueryStructure::prepare()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * Author: Adrian Dumitru
5
 * Date: 4/22/2017 2:33 AM
6
 */
7
8
namespace Qpdb\QueryBuilder\Dependencies;
9
10
11
use Qpdb\QueryBuilder\Statements\QueryStatement;
12
13
class QueryStructure
14
{
15
16
	const TABLE = 'table';
17
	const EXPLAIN = 'explain';
18
	const STATEMENT = 'statement';
19
	const PRIORITY = 'priority';
20
	const FIELDS = 'fields';
21
	const SET_FIELDS = 'set_fields';
22
	const WHERE = 'where';
23
	const HAVING = 'having';
24
	const WHERE_INVERT = 'where_invert';
25
	const HAVING_INVERT = 'having_invert';
26
	const LIMIT = 'limit_rows';
27
	const ORDER_BY = 'order_by';
28
	const GROUP_BY = 'group_by';
29
	const COUNT = 'count';
30
	const COLUMN = 'column';
31
	const FIRST = 'first';
32
	const DISTINCT = 'distinct';
33
	const JOIN = 'join';
34
	const IGNORE = 'ignore';
35
	const MULTIPLE_ROWS = 'multiple_rows';
36
	const QUERY = 'query';
37
	const BIND_PARAMS = 'bind_params';
38
	const REPLACEMENT = 'replacement';
39
	const QUERY_TYPE = 'query_type';
40
	const QUERY_STRING = 'query_string';
41
	const QUERY_COMMENT = 'query_comment';
42
	const QUERY_IDENTIFIER = 'query_identifier';
43
	const WHERE_TRIGGER = 'where_trigger';
44
	const INSTANCE = 'instance';
45
46
	/**
47
	 *  Elements type
48
	 */
49
50
	const ELEMENT_TYPE_BOOLEAN = 'boolean';
51
	const ELEMENT_TYPE_INTEGER = 'integer';
52
	const ELEMENT_TYPE_DOUBLE = 'double';
53
	const ELEMENT_TYPE_STRING = 'string';
54
	const ELEMENT_TYPE_ARRAY = 'array';
55
	const ELEMENT_TYPE_OBJECT = 'object';
56
	const ELEMENT_TYPE_RESOURCE = 'resource';
57
	const ELEMENT_TYPE_NULL = 'NULL';
58
	const ELEMENT_TYPE_UNKNOWN = 'unknown type';
59
60
	/**
61
	 * @var array
62
	 */
63
	private static $usedInstanceIds = [];
64
65
	/**
66
	 * @var array
67
	 */
68
	private $syntaxEL = array();
69
70
	/**
71
	 * @var array
72
	 */
73
	private $typeEL = array();
74
75
	/**
76
	 * @var int
77
	 */
78
	private $counter = 0;
79
80
	/**
81
	 * @var array
82
	 */
83
	private $reserved = [
84
		'order',
85
		'select',
86
		'insert',
87
		'update',
88
		'alter',
89
		'delete'
90
	];
91
92
93
	/**
94
	 * QueryStructure constructor.
95
	 */
96
	public function __construct()
97
	{
98
		$this->syntaxEL = $this->init();
99
100
		foreach ( $this->syntaxEL as $name => $value )
101
			$this->typeEL[ $name ] = gettype( $value );
102
103
	}
104
105
	private function init()
106
	{
107
		return [
108
			self::TABLE => '',
109
			self::EXPLAIN => 0,
110
			self::STATEMENT => '',
111
			self::PRIORITY => '',
112
			self::FIELDS => '*',
113
			self::SET_FIELDS => array(),
114
			self::WHERE => array(),
115
			self::HAVING => array(),
116
			self::WHERE_INVERT => 0,
117
			self::HAVING_INVERT => 0,
118
			self::LIMIT => 0,
119
			self::ORDER_BY => array(),
120
			self::GROUP_BY => array(),
121
			self::COUNT => 0,
122
			self::COLUMN => '',
123
			self::FIRST => 0,
124
			self::DISTINCT => 0,
125
			self::JOIN => array(),
126
			self::IGNORE => 0,
127
			self::MULTIPLE_ROWS => 0,
128
			self::QUERY => '',
129
			self::BIND_PARAMS => array(),
130
			self::REPLACEMENT => 0,
131
			self::QUERY_TYPE => 0,
132
			self::QUERY_STRING => '',
133
			self::QUERY_COMMENT => '',
134
			self::QUERY_IDENTIFIER => 'DEFAULT',
135
			self::WHERE_TRIGGER => 1,
136
			self::INSTANCE => $this->makeStatementInstance()
137
		];
138
	}
139
140
141
	private function makeStatementInstance()
142
	{
143
		$instance = QueryHelper::random( 5 );
144
		while ( in_array( $instance, self::$usedInstanceIds ) ) {
145
			$instance = QueryHelper::random( 7 );
146
		}
147
		self::$usedInstanceIds[] = $instance;
148
149
		return $instance;
150
	}
151
152
153
	/**
154
	 * @return array
155
	 */
156
	public static function getUsedInstances()
157
	{
158
		return self::$usedInstanceIds;
159
	}
160
161
162
	/**
163
	 * @return array
164
	 */
165
	public function getAllElements()
166
	{
167
		return $this->syntaxEL;
168
	}
169
170
	/**
171
	 * @param $elements
172
	 */
173
	public function setAllElements( $elements )
174
	{
175
		$this->syntaxEL = $elements;
176
	}
177
178
179
	/**
180
	 * @param $name
181
	 * @param $value
182
	 * @return bool
183
	 * @throws QueryException
184
	 */
185
	public function setElement( $name, $value )
186
	{
187
		if ( !array_key_exists( $name, $this->syntaxEL ) )
188
			throw new QueryException( 'Invalid Query property', QueryException::QUERY_ERROR_ELEMENT_NOT_FOUND );
189
190
		if ( $name == self::TABLE && is_a( $value, QueryStatement::class ) )
191
			return true;
192
193
		if ( $this->typeEL[ $name ] === self::ELEMENT_TYPE_ARRAY )
194
			$this->syntaxEL[ $name ][] = $value;
195
		else
196
			$this->syntaxEL[ $name ] = $value;
197
198
		return true;
199
	}
200
201
202
	/**
203
	 * @param string $elementName
204
	 * @param $elementValue
205
	 * @throws QueryException
206
	 */
207
	public function replaceElement( $elementName, $elementValue )
208
	{
209
		if ( !array_key_exists( $elementName, $this->syntaxEL ) )
210
			throw new QueryException( 'Invalid Query property', QueryException::QUERY_ERROR_ELEMENT_NOT_FOUND );
211
212
		$this->syntaxEL[ $elementName ] = $elementValue;
213
	}
214
215
216
	/**
217
	 * @param string $name
218
	 * @return mixed
219
	 */
220
	public function getElement( $name )
221
	{
222
		return $this->syntaxEL[ $name ];
223
	}
224
225
226
	/**
227
	 * @param $name
228
	 * @param $value
229
	 */
230
	public function setParams( $name, $value )
231
	{
232
		$this->syntaxEL[ QueryStructure::BIND_PARAMS ][ $name ] = $value;
233
	}
234
235
	/**
236
	 * @param $expression
237
	 * @param array $params
238
	 * @param string $search
239
	 * @return string
240
	 */
241
	public function bindParamsExpression( $expression, array $params = [], $search = '?' )
242
	{
243
		if ( !count( $params ) )
244
			return $expression;
245
246
		if ( strpos( $expression, $search ) === false )
247
			return $expression;
248
249
		$params = array_slice( $params, 0, substr_count( $expression, $search ) );
250
251
		$i = 0;
252
		$arrayReturn = [];
253
		$expressionToArray = explode( $search, $expression );
254
255
		foreach ( $expressionToArray as $sub ) {
256
			$arrayReturn[] = $sub;
257
			$arrayReturn[] = array_key_exists( $i, $params ) ? $this->bindParam( 'exp', $params[ $i ] ) : '';
258
			$i++;
259
		}
260
261
		return implode( '', $arrayReturn );
262
	}
263
264
	/**
265
	 * @param $name
266
	 * @param $value
267
	 * @return string
268
	 */
269
	public function bindParam( $name, $value )
270
	{
271
		$pdoName = $this->index( $name );
272
		$this->syntaxEL[ QueryStructure::BIND_PARAMS ][ $pdoName ] = $value;
273
274
		return ':' . $pdoName;
275
	}
276
277
	public function prepare( $fieldName = '' )
278
	{
279
		$fieldName = trim( $fieldName );
280
		if ( in_array( $fieldName, $this->reserved ) )
281
			$fieldName = '`' . $fieldName . '`';
282
283
		return $fieldName;
284
	}
285
286
	/**
287
	 * @param string $fieldName
288
	 * @return string
289
	 */
290
	public function index( $fieldName = '' )
291
	{
292
		return QueryHelper::alphaNum( $fieldName ) . '_' . $this->syntaxEL[ self::INSTANCE ] . '_' . ++$this->counter . 'i';
293
	}
294
295
}