XCL Web Application Platform 2.5.0
The XoopsCube Legacy Project
Loading...
Searching...
No Matches
EasyLex_SQLScanner.class.php
1<?php
2
10
11define('EASYLEX_SQL_UNKNOWN', 0);
12define('EASYLEX_SQL_DIGIT', 1);
13define('EASYLEX_SQL_LETTER', 2);
14define('EASYLEX_SQL_STRING_LITERAL', 3);
15define('EASYLEX_SQL_STRING_LITERAL_ESCAPE', 10);
16define('EASYLEX_SQL_OPEN_PARENTHESIS', 4);
17define('EASYLEX_SQL_CLOSE_PARENTHESIS', 5);
18define('EASYLEX_SQL_SEPARATER', 6);
19define('EASYLEX_SQL_SEMICOLON', 7);
20define('EASYLEX_SQL_MARK', 8);
21define('EASYLEX_SQL_COMMA', 9);
22
24{
25 public $mType = EASYLEX_SQL_UNKNOWN;
26 public $mValue = '';
27
28 public function __construct($type, $value)
29 {
30 $this->mType = $type;
31 $this->mValue = $value;
32 }
33
34 public function getOutputValue()
35 {
36 if (EASYLEX_SQL_SEPARATER == $this->mType) {
37 return '';
38 } else {
39 return $this->mValue;
40 }
41 }
42
43 public function getValue()
44 {
45 if (EASYLEX_SQL_SEPARATER == $this->mType) {
46 return '';
47 }
48
49 if (EASYLEX_SQL_STRING_LITERAL == $this->mType) {
50 return substr($this->mValue, 1, strlen($this->mValue) - 2);
51 }
52
53 return $this->mValue;
54 }
55}
56
63{
64 public $mTokens = [];
65 public $mStatus = EASYLEX_SQL_UNKNOWN;
66
70 public $mBuffer = [];
71
72 public $mIndex = 0;
73
74 public $mActiveToken = '';
75
76 public $mActiveQuoteMark = null;
77
78 public function setBuffer($buffer)
79 {
80 $this->mBuffer = [];
81 for ($i = 0; $i < strlen($buffer); $i++) {
82 $this->mBuffer[$i] = $buffer[$i];
83 }
84
85 $this->mIndex = 0;
86 }
87
88 public function parse()
89 {
90 while ($this->mIndex <= count($this->mBuffer)) {
91 if ($this->mIndex == count($this->mBuffer)) {
92 $ch = '';
93 $type = EASYLEX_SQL_UNKNOWN;
94 } else {
95 $ch = $this->mBuffer[$this->mIndex];
96 $type = $this->_getChrType($ch);
97 }
98
99 switch ($this->mStatus) {
100 case EASYLEX_SQL_UNKNOWN:
101 $this->_parseUnknown($ch, $type);
102 break;
103
104 case EASYLEX_SQL_DIGIT:
105 $this->_parseDigit($ch, $type);
106 break;
107
108 case EASYLEX_SQL_LETTER:
109 $this->_parseLetter($ch, $type);
110 break;
111
112 case EASYLEX_SQL_STRING_LITERAL:
113 $this->_parseStringLiteral($ch, $type);
114 break;
115
116 case EASYLEX_SQL_STRING_LITERAL_ESCAPE:
117 $this->_parseStringLiteralEscape($ch, $type);
118 break;
119
120 case EASYLEX_SQL_OPEN_PARENTHESIS:
121 $this->_parseOpenParenthesis($ch, $type);
122 break;
123
124 case EASYLEX_SQL_CLOSE_PARENTHESIS:
125 $this->_parseCloseParenthesis($ch, $type);
126 break;
127
128 case EASYLEX_SQL_SEPARATER:
129 $this->_parseSeparater($ch, $type);
130 break;
131
132 case EASYLEX_SQL_MARK:
133 $this->_parseMark($ch, $type);
134 break;
135
136 case EASYLEX_SQL_SEMICOLON:
137 $this->_parseSemicolon($ch, $type);
138 break;
139
140 case EASYLEX_SQL_COMMA:
141 $this->_parseComma($ch, $type);
142 break;
143 }
144 }
145 }
146
155 public function loadFile($path, $preprocess = true)
156 {
157 if (!file_exists($path)) {
158 return false;
159 }
160
161 $fp = fopen($path, 'rb');
162 if (!$fp) {
163 return false;
164 }
165
166 $t_buff = '';
167 while ($str = fgets($fp)) {
168 if ($preprocess) {
169 $str = preg_replace("/^\s*\#.*/", '', $str);
170 }
171 $t_buff .= $str;
172 }
173
174 $this->setBuffer($t_buff);
175
176 fclose($fp);
177 return true;
178 }
179
180 public function _getChrType($ch)
181 {
182 if (preg_match("/\s/", $ch)) {
183 return EASYLEX_SQL_SEPARATER;
184 }
185
186 if ('(' == $ch) {
187 return EASYLEX_SQL_OPEN_PARENTHESIS;
188 }
189
190 if (')' == $ch) {
191 return EASYLEX_SQL_CLOSE_PARENTHESIS;
192 }
193
194 if (';' == $ch) {
195 return EASYLEX_SQL_SEMICOLON;
196 }
197
198 if (',' == $ch) {
199 return EASYLEX_SQL_COMMA;
200 }
201
202 if (preg_match('/[0-9]/', $ch)) {
203 return EASYLEX_SQL_DIGIT;
204 }
205
206 if (preg_match("/[!=<>%\*]/", $ch)) {
207 return EASYLEX_SQL_MARK;
208 }
209
210 return EASYLEX_SQL_LETTER;
211 }
212
213 public function _parseUnknown($ch, $type)
214 {
215 $this->mStatus = $type;
216 $this->mActiveToken .= $ch;
217 $this->mIndex++;
218
219 if ("'" == $ch || '"' == $ch || '`' == $ch) {
220 $this->mStatus = EASYLEX_SQL_STRING_LITERAL;
221 $this->mActiveQuoteMark = $ch;
222 }
223 }
224
225 public function _parseDigit($ch, $type)
226 {
227 if (EASYLEX_SQL_DIGIT == $type) {
228 $this->mActiveToken .= $ch;
229 $this->mIndex++;
230 } elseif (EASYLEX_SQL_LETTER == $type) {
231 $this->mStatus = EASYLEX_SQL_LETTER;
232 $this->mActiveToken .= $ch;
233 $this->mIndex++;
234 } else {
235 $this->_createToken();
236 }
237 }
238
239 public function _parseLetter($ch, $type)
240 {
241 if (EASYLEX_SQL_LETTER == $type || EASYLEX_SQL_DIGIT == $type) {
242 $this->mActiveToken .= $ch;
243 $this->mIndex++;
244 } else {
245 $this->_createToken();
246 }
247 }
248
249 public function _parseStringLiteral($ch, $type)
250 {
251 $this->mActiveToken .= $ch;
252 $this->mIndex++;
253
254 if ("\\" == $ch) {
255 $this->mStatus = EASYLEX_SQL_STRING_LITERAL_ESCAPE;
256 } elseif ($ch == $this->mActiveQuoteMark) {
257 $this->_createToken();
258 }
259 }
260
261 public function _parseStringLiteralEscape($ch, $type)
262 {
263 $this->mStatus = EASYLEX_SQL_STRING_LITERAL;
264 }
265
266 public function _parseOpenParenthesis($ch, $type)
267 {
268 $this->_createToken();
269 }
270
271 public function _parseCloseParenthesis($ch, $type)
272 {
273 $this->_createToken();
274 }
275
276 public function _parseSeparater($ch, $type)
277 {
278 if (EASYLEX_SQL_SEPARATER == $type) {
279 $this->mActiveToken .= $ch;
280 $this->mIndex++;
281 } else {
282 // $this->_createToken();
283 $this->mStatus = EASYLEX_SQL_UNKNOWN;
284 $this->mActiveToken = '';
285 }
286 }
287
288 public function _parseSemicolon($ch, $type)
289 {
290 $this->_createToken();
291 }
292
293 public function _parseMark($ch, $type)
294 {
295 if (EASYLEX_SQL_MARK == $type) {
296 $this->mActiveToken .= $ch;
297 $this->mIndex++;
298 } else {
299 $this->_createToken();
300 }
301 }
302
303 public function _parseComma($ch, $type)
304 {
305 $this->_createToken();
306 }
307
308 public function _createToken($type = null, $value = null)
309 {
310 if (null === $type) {
311 $type = $this->mStatus;
312 }
313
314 if (null === $value) {
315 $value = $this->mActiveToken;
316 }
317
318 $token = new EasyLex_SQLToken($type, $value);
319 $this->mTokens[] = &$token;
320
321 $this->mStatus = EASYLEX_SQL_UNKNOWN;
322 $this->mActiveToken = '';
323
324 return $token;
325 }
326
332 public function &getOperations()
333 {
334 $ret = [];
335 $t_tokens = [];
336 $depth = 0;
337
338 foreach (array_keys($this->mTokens) as $key) {
339 if (EASYLEX_SQL_OPEN_PARENTHESIS == $this->mTokens[$key]->mType) {
340 $depth++;
341 } elseif (EASYLEX_SQL_CLOSE_PARENTHESIS == $this->mTokens[$key]->mType) {
342 $depth--;
343 }
344
345 $t_tokens[] = &$this->mTokens[$key];
346
347 if (EASYLEX_SQL_SEMICOLON == $this->mTokens[$key]->mType && 0 == $depth) {
348 $ret[] = &$t_tokens;
349 unset($t_tokens);
350 $t_tokens = [];
351 }
352 }
353
354 if (count($t_tokens) > 0) {
355 $ret[] = &$t_tokens;
356 unset($t_tokens);
357 }
358
359 return $ret;
360 }
361
362 public function getSQL()
363 {
364 $sqls = [];
365 $lines = &$this->getOperations();
366
367 foreach ($lines as $line) {
368 $t_arr = [];
369 foreach ($line as $token) {
370 $t_arr[] = $token->getOutputValue();
371 }
372 $sqls[] = implode(' ', $t_arr);
373 }
374
375 return $sqls;
376 }
377}
loadFile($path, $preprocess=true)