This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | //------------------------------------------------------------------------------ |
||
4 | // |
||
5 | // eTraxis - Records tracking web-based system |
||
6 | // Copyright (C) 2004-2011 Artem Rodygin |
||
7 | // |
||
8 | // This program is free software: you can redistribute it and/or modify |
||
9 | // it under the terms of the GNU General Public License as published by |
||
10 | // the Free Software Foundation, either version 3 of the License, or |
||
11 | // (at your option) any later version. |
||
12 | // |
||
13 | // This program is distributed in the hope that it will be useful, |
||
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
16 | // GNU General Public License for more details. |
||
17 | // |
||
18 | // You should have received a copy of the GNU General Public License |
||
19 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
20 | // |
||
21 | //------------------------------------------------------------------------------ |
||
22 | |||
23 | /** |
||
24 | * Database Abstraction Layer |
||
25 | * |
||
26 | * This module implements eTraxis connectivity. |
||
27 | * |
||
28 | * @package Engine |
||
29 | * @subpackage DAL |
||
30 | */ |
||
31 | |||
32 | /**#@+ |
||
33 | * Dependency. |
||
34 | */ |
||
35 | require_once('../engine/debug.php'); |
||
36 | require_once('../engine/utility.php'); |
||
37 | require_once('../engine/locale.php'); |
||
38 | /**#@-*/ |
||
39 | |||
40 | /**#@+ |
||
41 | * Supported database driver. |
||
42 | */ |
||
43 | define('DRIVER_MYSQL50', 1); // MySQL 5.0 or later |
||
44 | define('DRIVER_MSSQL2K', 2); // Microsoft SQL Server 2000 or later |
||
45 | define('DRIVER_ORACLE9', 3); // Oracle 9i or later |
||
46 | define('DRIVER_PGSQL80', 4); // PostgreSQL 8.0 or later |
||
47 | /**#@-*/ |
||
48 | |||
49 | $res_driver = array |
||
50 | ( |
||
51 | DRIVER_MYSQL50 => RES_MYSQL_ID, |
||
52 | DRIVER_MSSQL2K => RES_MSSQL_ID, |
||
53 | DRIVER_ORACLE9 => RES_ORACLE_ID, |
||
54 | DRIVER_PGSQL80 => RES_POSTGRESQL_ID, |
||
55 | ); |
||
56 | |||
57 | //------------------------------------------------------------------------------ |
||
58 | // DAL database connection. |
||
59 | //------------------------------------------------------------------------------ |
||
60 | |||
61 | /** |
||
62 | * Database connection, implemented via Singleton pattern. |
||
63 | * |
||
64 | * @package Engine |
||
65 | * @subpackage DAL |
||
66 | */ |
||
67 | class CDatabase |
||
68 | { |
||
69 | /** |
||
70 | * Static object of itself. |
||
71 | * @var CDatabase |
||
72 | */ |
||
73 | private static $object = NULL; |
||
74 | |||
75 | /** |
||
76 | * Link of opened connection. |
||
77 | * @var resource|mysqli |
||
78 | */ |
||
79 | private $link = FALSE; |
||
80 | |||
81 | /** |
||
82 | * TRUE if a transaction is currently under progress, FALSE otherwise. |
||
83 | * @var bool |
||
84 | */ |
||
85 | private $is_transaction = FALSE; |
||
86 | |||
87 | /** |
||
88 | * Establishes connection to eTraxis database. |
||
89 | */ |
||
90 | private function __construct () |
||
91 | { |
||
92 | debug_write_log(DEBUG_TRACE, '[CDatabase::__construct]'); |
||
93 | |||
94 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
95 | { |
||
96 | if (extension_loaded('mysqli')) |
||
97 | { |
||
98 | $this->link = mysqli_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_DBNAME); |
||
99 | |||
100 | if ($this->link) |
||
101 | { |
||
102 | mysqli_query($this->link, 'set names utf8'); |
||
103 | } |
||
104 | } |
||
105 | else |
||
106 | { |
||
107 | $this->link = mysql_connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD); |
||
108 | |||
109 | if ($this->link) |
||
110 | { |
||
111 | if (mysql_select_db(DATABASE_DBNAME, $this->link)) |
||
112 | { |
||
113 | mysql_query('set names utf8', $this->link); |
||
114 | } |
||
115 | else |
||
116 | { |
||
117 | debug_write_log(DEBUG_WARNING, '[CDatabase::__construct] Error on selecting MySQL database.'); |
||
118 | mysql_close($this->link); |
||
119 | $this->link = FALSE; |
||
120 | } |
||
121 | } |
||
122 | } |
||
123 | } |
||
124 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
125 | { |
||
126 | $conn_info = array |
||
127 | ( |
||
128 | 'APP' => 'eTraxis', |
||
129 | 'CharacterSet' => 'UTF-8', |
||
130 | 'Database' => DATABASE_DBNAME, |
||
131 | ); |
||
132 | |||
133 | View Code Duplication | if (ustrlen(trim(DATABASE_USERNAME)) != 0) |
|
0 ignored issues
–
show
|
|||
134 | { |
||
135 | $conn_info['UID'] = DATABASE_USERNAME; |
||
136 | $conn_info['PWD'] = DATABASE_PASSWORD; |
||
137 | } |
||
138 | |||
139 | $this->link = sqlsrv_connect(DATABASE_HOST, $conn_info); |
||
140 | } |
||
141 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
142 | { |
||
143 | $this->link = dbx_connect(DBX_OCI8, DATABASE_HOST, DATABASE_DBNAME, DATABASE_USERNAME, DATABASE_PASSWORD); |
||
144 | } |
||
145 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
146 | { |
||
147 | if (strlen(trim(DATABASE_HOST)) == 0) |
||
148 | { |
||
149 | $this->link = pg_connect(sprintf('dbname=%s user=%s password=%s', DATABASE_DBNAME, DATABASE_USERNAME, DATABASE_PASSWORD)); |
||
150 | } |
||
151 | View Code Duplication | else |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
152 | { |
||
153 | $this->link = pg_connect(sprintf('host=%s dbname=%s user=%s password=%s', DATABASE_HOST, DATABASE_DBNAME, DATABASE_USERNAME, DATABASE_PASSWORD)); |
||
154 | } |
||
155 | } |
||
156 | else |
||
157 | { |
||
158 | debug_write_log(DEBUG_WARNING, '[CDatabase::__construct] Unknown database driver.'); |
||
159 | $this->link = FALSE; |
||
160 | } |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Closes connection to eTraxis database. |
||
165 | */ |
||
166 | View Code Duplication | public function __destruct() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
167 | { |
||
168 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
169 | { |
||
170 | if (extension_loaded('mysqli')) |
||
171 | { |
||
172 | mysqli_close($this->link); |
||
173 | } |
||
174 | else |
||
175 | { |
||
176 | mysql_close($this->link); |
||
177 | } |
||
178 | } |
||
179 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
180 | { |
||
181 | sqlsrv_close($this->link); |
||
182 | } |
||
183 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
184 | { |
||
185 | dbx_close($this->link); |
||
186 | } |
||
187 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
188 | { |
||
189 | pg_close($this->link); |
||
190 | } |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * @ignore |
||
195 | */ |
||
196 | public function __get ($name) |
||
197 | { |
||
198 | switch ($name) |
||
199 | { |
||
200 | case 'link': return $this->link; |
||
201 | default: return NULL; |
||
202 | } |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * Connects to database. |
||
207 | * |
||
208 | * @return CDatabase Database singleton object. |
||
209 | */ |
||
210 | public static function connect () |
||
211 | { |
||
212 | if (is_null(self::$object)) |
||
213 | { |
||
214 | self::$object = new CDatabase(); |
||
215 | } |
||
216 | |||
217 | return self::$object; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * Starts transaction. |
||
222 | * |
||
223 | * @return bool TRUE if transaction is started successfully, FALSE otherwise. |
||
224 | */ |
||
225 | View Code Duplication | public function transaction () |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
226 | { |
||
227 | if ($this->is_transaction) |
||
228 | { |
||
229 | debug_write_log(DEBUG_WARNING, '[CDatabase::transaction] Transaction is under progress.'); |
||
230 | return FALSE; |
||
231 | } |
||
232 | |||
233 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
234 | { |
||
235 | if (extension_loaded('mysqli')) |
||
236 | { |
||
237 | mysqli_query($this->link, 'start transaction'); |
||
238 | } |
||
239 | else |
||
240 | { |
||
241 | mysql_query('start transaction', $this->link); |
||
242 | } |
||
243 | } |
||
244 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
245 | { |
||
246 | sqlsrv_begin_transaction($this->link); |
||
247 | } |
||
248 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
249 | { |
||
250 | dbx_query($this->link, 'set transaction'); |
||
251 | } |
||
252 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
253 | { |
||
254 | pg_query($this->link, 'start transaction'); |
||
255 | } |
||
256 | else |
||
257 | { |
||
258 | debug_write_log(DEBUG_WARNING, '[CDatabase::transaction] Unknown database driver.'); |
||
259 | return FALSE; |
||
260 | } |
||
261 | |||
262 | $this->is_transaction = TRUE; |
||
263 | return TRUE; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * Commits current transaction. |
||
268 | * |
||
269 | * @return bool TRUE if transaction is committed successfully, FALSE otherwise. |
||
270 | */ |
||
271 | View Code Duplication | public function commit () |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
272 | { |
||
273 | if (!$this->is_transaction) |
||
274 | { |
||
275 | debug_write_log(DEBUG_WARNING, '[CDatabase::commit] No active transactions.'); |
||
276 | return FALSE; |
||
277 | } |
||
278 | |||
279 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
280 | { |
||
281 | if (extension_loaded('mysqli')) |
||
282 | { |
||
283 | mysqli_query($this->link, 'commit'); |
||
284 | } |
||
285 | else |
||
286 | { |
||
287 | mysql_query('commit', $this->link); |
||
288 | } |
||
289 | } |
||
290 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
291 | { |
||
292 | sqlsrv_commit($this->link); |
||
293 | } |
||
294 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
295 | { |
||
296 | dbx_query($this->link, 'commit'); |
||
297 | } |
||
298 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
299 | { |
||
300 | pg_query($this->link, 'commit'); |
||
301 | } |
||
302 | else |
||
303 | { |
||
304 | debug_write_log(DEBUG_WARNING, '[CDatabase::commit] Unknown database driver.'); |
||
305 | return FALSE; |
||
306 | } |
||
307 | |||
308 | $this->is_transaction = FALSE; |
||
309 | return TRUE; |
||
310 | } |
||
311 | |||
312 | /** |
||
313 | * Rolls back current transaction. |
||
314 | * |
||
315 | * @return bool TRUE if transaction is rolled back successfully, FALSE otherwise. |
||
316 | */ |
||
317 | View Code Duplication | public function rollback () |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
318 | { |
||
319 | if (!$this->is_transaction) |
||
320 | { |
||
321 | debug_write_log(DEBUG_WARNING, '[CDatabase::rollback] No active transactions.'); |
||
322 | return FALSE; |
||
323 | } |
||
324 | |||
325 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
326 | { |
||
327 | if (extension_loaded('mysqli')) |
||
328 | { |
||
329 | mysqli_query($this->link, 'rollback'); |
||
330 | } |
||
331 | else |
||
332 | { |
||
333 | mysql_query('rollback', $this->link); |
||
334 | } |
||
335 | } |
||
336 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
337 | { |
||
338 | sqlsrv_rollback($this->link); |
||
339 | } |
||
340 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
341 | { |
||
342 | dbx_query($this->link, 'rollback'); |
||
343 | } |
||
344 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
345 | { |
||
346 | pg_query($this->link, 'rollback'); |
||
347 | } |
||
348 | else |
||
349 | { |
||
350 | debug_write_log(DEBUG_WARNING, '[CDatabase::rollback] Unknown database driver.'); |
||
351 | return FALSE; |
||
352 | } |
||
353 | |||
354 | $this->is_transaction = FALSE; |
||
355 | return TRUE; |
||
356 | } |
||
357 | } |
||
358 | |||
359 | //------------------------------------------------------------------------------ |
||
360 | // DAL recordset. |
||
361 | //------------------------------------------------------------------------------ |
||
362 | |||
363 | /** |
||
364 | * DAL recordset. |
||
365 | * |
||
366 | * The class implements DAL recordset and several functions to work with. |
||
367 | * The implementation is universal and doesn't depend on type of database. |
||
368 | * |
||
369 | * @package Engine |
||
370 | * @subpackage DAL |
||
371 | */ |
||
372 | class CRecordset |
||
373 | { |
||
374 | /**#@+ |
||
375 | * @ignore For internal use only. |
||
376 | */ |
||
377 | private $handle; // [resource] connection |
||
378 | private $result; // [resource] query result |
||
379 | private $resptr; // [int] recordset cursor (number of current record from 0) |
||
380 | /**#@-*/ |
||
381 | |||
382 | /** |
||
383 | * Number of rows in resulted recordset (read-only). |
||
384 | * @var int |
||
385 | */ |
||
386 | protected $rows; |
||
387 | |||
388 | /** |
||
389 | * Number of columns in resulted recordset (read-only). |
||
390 | * @var int |
||
391 | */ |
||
392 | protected $cols; |
||
393 | |||
394 | /** |
||
395 | * Executes specified query and constructs itself as resulted recordset. |
||
396 | * |
||
397 | * @param string $sql SQL-query being executed. |
||
398 | */ |
||
399 | public function __construct ($sql) |
||
400 | { |
||
401 | $this->handle = CDatabase::connect()->link; |
||
402 | $this->result = FALSE; |
||
403 | $this->resptr = 0; |
||
404 | $this->rows = 0; |
||
405 | $this->cols = 0; |
||
406 | |||
407 | list($msec, $sec) = explode(' ', microtime()); |
||
408 | $start = (float)$msec + (float)$sec; |
||
409 | |||
410 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
411 | { |
||
412 | if (extension_loaded('mysqli')) |
||
413 | { |
||
414 | $this->result = mysqli_query($this->handle, $sql); |
||
415 | |||
416 | if (is_object($this->result)) |
||
417 | { |
||
418 | $this->rows = $this->result->num_rows; |
||
419 | $this->cols = $this->result->field_count; |
||
420 | } |
||
421 | } |
||
422 | else |
||
423 | { |
||
424 | $this->result = mysql_query($sql, $this->handle); |
||
425 | |||
426 | if (is_resource($this->result)) |
||
427 | { |
||
428 | $this->rows = mysql_num_rows($this->result); |
||
429 | $this->cols = mysql_num_fields($this->result); |
||
430 | } |
||
431 | } |
||
432 | } |
||
433 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
434 | { |
||
435 | $this->result = sqlsrv_query($this->handle, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC)); |
||
436 | |||
437 | if (is_resource($this->result)) |
||
438 | { |
||
439 | $this->rows = sqlsrv_num_rows($this->result); |
||
440 | $this->cols = sqlsrv_num_fields($this->result); |
||
441 | } |
||
442 | |||
443 | $this->resptr = -1; |
||
444 | } |
||
445 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
446 | { |
||
447 | $this->result = dbx_query($this->handle, $sql, DBX_COLNAMES_LOWERCASE); |
||
448 | |||
449 | if (is_object($this->result)) |
||
450 | { |
||
451 | $this->rows = $this->result->rows; |
||
452 | $this->cols = $this->result->cols; |
||
453 | } |
||
454 | } |
||
455 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
456 | { |
||
457 | $this->result = pg_query($this->handle, $sql); |
||
458 | |||
459 | if (is_resource($this->result)) |
||
460 | { |
||
461 | $this->rows = pg_num_rows($this->result); |
||
462 | $this->cols = pg_num_fields($this->result); |
||
463 | } |
||
464 | } |
||
465 | else |
||
466 | { |
||
467 | debug_write_log(DEBUG_WARNING, '[CRecordset::__construct] Unknown database driver.'); |
||
468 | } |
||
469 | |||
470 | list($msec, $sec) = explode(' ', microtime()); |
||
471 | $stop = (float)$msec + (float)$sec; |
||
472 | |||
473 | debug_write_log(DEBUG_DUMP, 'SQL text = ' . $sql); |
||
474 | debug_write_log(DEBUG_PERFORMANCE, 'SQL time = ' . ($stop - $start)); |
||
475 | |||
476 | if (!$this->result) |
||
477 | { |
||
478 | debug_write_log(DEBUG_WARNING, '[CRecordset::__construct] ' . $this->error()); |
||
479 | } |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * Frees all resources associated with the recordset. |
||
484 | */ |
||
485 | View Code Duplication | public function __destruct() |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
486 | { |
||
487 | if (is_resource($this->result)) |
||
488 | { |
||
489 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
490 | { |
||
491 | if (extension_loaded('mysqli')) |
||
492 | { |
||
493 | mysqli_free_result($this->result); |
||
494 | } |
||
495 | else |
||
496 | { |
||
497 | mysql_free_result($this->result); |
||
498 | } |
||
499 | } |
||
500 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
501 | { |
||
502 | sqlsrv_free_stmt($this->result); |
||
503 | } |
||
504 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
505 | { |
||
506 | // nothing to do in case of DBX |
||
507 | } |
||
508 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
509 | { |
||
510 | pg_free_result($this->result); |
||
511 | } |
||
512 | else |
||
513 | { |
||
514 | debug_write_log(DEBUG_WARNING, '[CRecordset::__destruct] Unknown database driver.'); |
||
515 | } |
||
516 | } |
||
517 | } |
||
518 | |||
519 | /** |
||
520 | * @ignore |
||
521 | */ |
||
522 | public function __get ($name) |
||
523 | { |
||
524 | switch ($name) |
||
525 | { |
||
526 | case 'rows': return $this->rows; |
||
527 | case 'cols': return $this->cols; |
||
528 | default: return NULL; |
||
529 | } |
||
530 | } |
||
531 | |||
532 | /** |
||
533 | * Returns error message of last operation. |
||
534 | * |
||
535 | * @return string Error message of last operation, or NULL on failure. |
||
536 | */ |
||
537 | public function error () |
||
538 | { |
||
539 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
540 | { |
||
541 | if (extension_loaded('mysqli')) |
||
542 | { |
||
543 | $errno = mysqli_errno($this->handle); |
||
544 | $error = mysqli_error($this->handle); |
||
545 | } |
||
546 | else |
||
547 | { |
||
548 | $errno = mysql_errno($this->handle); |
||
549 | $error = mysql_error($this->handle); |
||
550 | } |
||
551 | $retval = "MySQL error {$errno}: {$error}"; |
||
552 | } |
||
553 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
554 | { |
||
555 | $error = sqlsrv_errors(SQLSRV_ERR_ALL); |
||
556 | $retval = (is_null($error) |
||
557 | ? NULL |
||
558 | : "MSSQL error {$error[0]['code']}: {$error[0]['message']}"); |
||
559 | } |
||
560 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
561 | { |
||
562 | $error = ocierror($this->handle->handle); |
||
563 | $retval = "Oracle error {$error['code']}: {$error['message']}"; |
||
564 | } |
||
565 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
566 | { |
||
567 | $error = pg_last_error($this->handle); |
||
568 | $retval = "PostgreSQL error: {$error}"; |
||
569 | } |
||
570 | else |
||
571 | { |
||
572 | debug_write_log(DEBUG_WARNING, '[CRecordset::error] Unknown database driver.'); |
||
573 | return NULL; |
||
574 | } |
||
575 | |||
576 | return $retval; |
||
577 | } |
||
578 | |||
579 | /** |
||
580 | * Moves cursor to specified record. |
||
581 | * |
||
582 | * @param int $row_number Number of record, zero-based. |
||
583 | * @return bool TRUE on success, FALSE otherwise. |
||
584 | */ |
||
585 | public function seek ($row_number = 0) |
||
586 | { |
||
587 | if (!$this->result) |
||
588 | { |
||
589 | debug_write_log(DEBUG_WARNING, '[CRecordset::seek] No stored recordset.'); |
||
590 | return FALSE; |
||
591 | } |
||
592 | |||
593 | if ($row_number < 0 || $row_number >= $this->rows) |
||
594 | { |
||
595 | debug_write_log(DEBUG_WARNING, '[CRecordset::seek] Row number is out of stored recordset.'); |
||
596 | return FALSE; |
||
597 | } |
||
598 | |||
599 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
600 | { |
||
601 | if (extension_loaded('mysqli')) |
||
602 | { |
||
603 | $retval = mysqli_data_seek($this->result, $row_number); |
||
604 | } |
||
605 | else |
||
606 | { |
||
607 | $retval = mysql_data_seek($this->result, $row_number); |
||
608 | } |
||
609 | } |
||
610 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
611 | { |
||
612 | $this->resptr = $row_number; |
||
613 | $retval = TRUE; |
||
614 | } |
||
615 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
616 | { |
||
617 | $this->resptr = $row_number; |
||
618 | $retval = TRUE; |
||
619 | } |
||
620 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
621 | { |
||
622 | $retval = pg_result_seek($this->result, $row_number); |
||
623 | } |
||
624 | else |
||
625 | { |
||
626 | debug_write_log(DEBUG_WARNING, '[CRecordset::seek] Unknown database driver.'); |
||
627 | return FALSE; |
||
628 | } |
||
629 | |||
630 | if (!$retval) |
||
631 | { |
||
632 | debug_write_log(DEBUG_WARNING, '[CRecordset::seek] ' . $this->error()); |
||
633 | } |
||
634 | |||
635 | return $retval; |
||
636 | } |
||
637 | |||
638 | /** |
||
639 | * Returns next record from recordset. |
||
640 | * |
||
641 | * Returns the record for current cursor and then moves cursor forward to the next one. |
||
642 | * The record is returned as array with two sets of keys - one set is zero-based indexes, another is names of record fields. |
||
643 | * |
||
644 | * @param int|string $field Optional field name or zero-based index. |
||
645 | * @return mixed|array If <i>field</i> is not specified, returns whole record as an array, or FALSE if there is no more record to return. |
||
646 | * If <i>field</i> is specified, then returns value of specified field (it could be both zero-based index, or field name). |
||
647 | * |
||
648 | * Example #1: |
||
649 | * <code> |
||
650 | * $rs = new CRecordset("select my_id, my_field from my_table"); |
||
651 | * |
||
652 | * while ($row = $rs->fetch()) |
||
653 | * { |
||
654 | * printf("%u\t%s\n", $row["my_id"], $row["my_field"]); |
||
655 | * } |
||
656 | * </code> |
||
657 | * |
||
658 | * Example #2: |
||
659 | * <code> |
||
660 | * $rs = new CRecordset("select count(*) from my_table"); |
||
661 | * echo($rs->fetch(0)); |
||
662 | * </code> |
||
663 | */ |
||
664 | public function fetch ($field = NULL) |
||
665 | { |
||
666 | if (!$this->result) |
||
667 | { |
||
668 | debug_write_log(DEBUG_WARNING, '[CRecordset::fetch] No stored recordset.'); |
||
669 | return FALSE; |
||
670 | } |
||
671 | |||
672 | if (DATABASE_DRIVER == DRIVER_MYSQL50) |
||
673 | { |
||
674 | if (extension_loaded('mysqli')) |
||
675 | { |
||
676 | $retval = mysqli_fetch_array($this->result, MYSQLI_BOTH); |
||
677 | } |
||
678 | else |
||
679 | { |
||
680 | $retval = mysql_fetch_array($this->result, MYSQL_BOTH); |
||
681 | } |
||
682 | } |
||
683 | elseif (DATABASE_DRIVER == DRIVER_MSSQL2K) |
||
684 | { |
||
685 | if ($this->resptr == -1) |
||
686 | { |
||
687 | $retval = sqlsrv_fetch_array($this->result, SQLSRV_FETCH_BOTH, SQLSRV_SCROLL_NEXT); |
||
688 | } |
||
689 | else |
||
690 | { |
||
691 | $retval = sqlsrv_fetch_array($this->result, SQLSRV_FETCH_BOTH, SQLSRV_SCROLL_ABSOLUTE, $this->resptr); |
||
692 | $this->resptr = -1; |
||
693 | } |
||
694 | } |
||
695 | elseif (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
696 | { |
||
697 | if ($this->resptr == $this->result->rows) |
||
698 | { |
||
699 | debug_write_log(DEBUG_WARNING, '[CRecordset::fetch] No more rows to return.'); |
||
700 | return FALSE; |
||
701 | } |
||
702 | |||
703 | $retval = $this->result->data[$this->resptr++]; |
||
704 | } |
||
705 | elseif (DATABASE_DRIVER == DRIVER_PGSQL80) |
||
706 | { |
||
707 | $retval = pg_fetch_array($this->result); |
||
708 | } |
||
709 | else |
||
710 | { |
||
711 | debug_write_log(DEBUG_WARNING, '[CRecordset::fetch] Unknown database driver.'); |
||
712 | return FALSE; |
||
713 | } |
||
714 | |||
715 | if (!is_array($retval)) |
||
716 | { |
||
717 | return NULL; |
||
718 | } |
||
719 | |||
720 | return (is_null($field) ? $retval : $retval[$field]); |
||
721 | } |
||
722 | } |
||
723 | |||
724 | //------------------------------------------------------------------------------ |
||
725 | // Functions. |
||
726 | //------------------------------------------------------------------------------ |
||
727 | |||
728 | /** |
||
729 | * Executes specified SQL-file from "sql" eTraxis directory. |
||
730 | * |
||
731 | * The function accepts variable number of arguments. It opens specified SQL-file and replaces each "%i" |
||
732 | * (where <i>i</i> is a natural number) substring with related additional argument. |
||
733 | * |
||
734 | * @param string $query Path to file with SQL-query (path is related to "sql" directory). |
||
735 | * @param mixed Value, which each "%1" substring will be replaced with. |
||
736 | * @param mixed Value, which each "%2" substring will be replaced with. |
||
737 | * @param mixed ... (and so on) |
||
738 | * @return CRecordset Resulted {@link CRecordset DAL recordset}. |
||
739 | * |
||
740 | * Example of usage: |
||
741 | * <code> |
||
742 | * $rs = dal_query("accounts/list.sql", "username"); |
||
743 | * |
||
744 | * while ($row = $rs->fetch()) |
||
745 | * { |
||
746 | * foreach ($row as $item) |
||
747 | * { |
||
748 | * echo("$item\t"); |
||
749 | * } |
||
750 | * |
||
751 | * echo("\n"); |
||
752 | * } |
||
753 | * </code> |
||
754 | */ |
||
755 | function dal_query ($query) |
||
756 | { |
||
757 | debug_write_log(DEBUG_TRACE, '[dal_query] ' . $query); |
||
758 | |||
759 | $sql = file_get_contents(LOCALROOT . '/sql/' . $query); |
||
760 | $sql = str_replace("\n", ' ', $sql); |
||
761 | $sql = preg_replace('([ ]+)', ' ', $sql); |
||
762 | |||
763 | if (DATABASE_DRIVER == DRIVER_ORACLE9) |
||
764 | { |
||
765 | $pos = ustrrpos($sql, 'order by'); |
||
766 | |||
767 | if ($pos !== FALSE) |
||
768 | { |
||
769 | $sql = usubstr($sql, 0, $pos) . preg_replace('(\s[a-z]+\.)', ' ', usubstr($sql, $pos)); |
||
770 | } |
||
771 | } |
||
772 | |||
773 | $count = func_num_args() - 1; |
||
774 | |||
775 | for ($i = $count; $i >= 1; $i--) |
||
776 | { |
||
777 | $search = '%' . $i; |
||
778 | $replace = func_get_arg($i); |
||
779 | |||
780 | if (strpos($sql, "'{$search}'") === FALSE) |
||
781 | { |
||
782 | if (is_null($replace)) |
||
783 | { |
||
784 | $replace = 'NULL'; |
||
785 | } |
||
786 | } |
||
787 | else |
||
788 | { |
||
789 | if (is_null($replace)) |
||
790 | { |
||
791 | $search = "'{$search}'"; |
||
792 | $replace = 'NULL'; |
||
793 | } |
||
794 | else |
||
795 | { |
||
796 | $replace = ustr2sql($replace); |
||
797 | } |
||
798 | } |
||
799 | |||
800 | $sql = ustr_replace($search, $replace, $sql); |
||
801 | } |
||
802 | |||
803 | return new CRecordset($sql); |
||
804 | } |
||
805 | |||
806 | /** |
||
807 | * Starts transaction. |
||
808 | * |
||
809 | * @return bool TRUE if transaction is started successfully, FALSE otherwise. |
||
810 | */ |
||
811 | function dal_transaction_start () |
||
812 | { |
||
813 | debug_write_log(DEBUG_TRACE, '[dal_transaction_start]'); |
||
814 | |||
815 | return CDatabase::connect()->transaction(); |
||
816 | } |
||
817 | |||
818 | /** |
||
819 | * Commits or rolls back current transaction. |
||
820 | * |
||
821 | * @param bool $commit TRUE if transaction must be committed, FALSE - rolled back. |
||
822 | * @return bool TRUE if transaction is stopped successfully, FALSE otherwise. |
||
823 | */ |
||
824 | function dal_transaction_stop ($commit) |
||
825 | { |
||
826 | debug_write_log(DEBUG_TRACE, '[dal_transaction_stop] ' . $commit); |
||
827 | |||
828 | return ($commit ? CDatabase::connect()->commit() |
||
829 | : CDatabase::connect()->rollback()); |
||
830 | } |
||
831 | |||
832 | ?> |
||
833 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.