noalyss Version-9
database_core.class.php
Go to the documentation of this file.
1<?php
2
3/*
4 * This file is part of NOALYSS.
5 *
6 * NOALYSS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * NOALYSS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with NOALYSS; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21// Copyright Author Dany De Bontridder danydb@aevalys.eu
22
23/**
24 * \file
25 * \brief contains the class for connecting to a postgresql database
26 */
27require_once NOALYSS_INCLUDE . '/constant.php';
28require_once NOALYSS_INCLUDE . '/lib/ac_common.php';
29
30/**
31 * \brief
32 * This class allow you to connect to the postgresql database, execute sql, retrieve data
33 *
34 */
36{
37
38 private $db;
39 /**< database connection */
40 private $ret;
41 /**< return value */
42 private $is_open; /*!< true is connected */
43 public $sql; //!< last SQL stmt executed
44 public $array;
45 /*** Connect to a database return an connx to db or false if it fails
46 *
47 * @param string $p_user Username
48 * @param type $p_password User's password
49 * @param $p_dbname name of the database to connect
50 * @param type $p_host Host of DB
51 * @param type $p_port Port of DB
52 */
53
54 function __construct($p_user, $p_password, $p_dbname, $p_host, $p_port)
55 {
56 $this->db = @pg_connect("dbname=$p_dbname host='$p_host' user='$p_user'
57 password='$p_password' port=$p_port");
58 if ($this->db == false) {
59 if ( DEBUGNOALYSS > 0 ) {
60
61 echo '<h2 class="error">'._('Impossible de se connecter à postgreSql').'</h2>';
62 echo '<p>';
63 echo _("Vos paramètres sont incorrectes").": <br>";
64 echo "<br>";
65 printf (_("base de donnée = %s"), $p_dbname)."<br>";
66 printf (_("Port %s"),$p_port )."<br>";
67 printf ( _("Utilisateur : %s"),$p_user )."<br>";
68 echo '</p>';
69
70 die();
71 } else {
72 echo '<h2 class="error">' . _('Erreur de connexion !') . '</h2>';
73 $this->is_open = false;
74 throw new Exception(_('Erreur Connexion'));
75 }
76 }
77
78 $this->is_open = TRUE;
79 $this->sql="";
80
81 }
82
83 /**
84 * return the name of the current database
85 * @return false|string
86 */
87 public function get_name () {
88 return pg_dbname($this->ret);
89 }
90
91 public function verify()
92 {
93 // Verify that the elt we want to add is correct
94 }
95
96 function set_encoding($p_charset)
97 {
98 pg_set_client_encoding($this->db, $p_charset);
99 }
100
101 function get_encoding()
102 {
103 return pg_client_encoding($this->db);
104 }
105
106
107 /**
108 * @return mixed
109 */
110 public function get_db()
111 {
112 return $this->db;
113 }
114
115 /**
116 * @param mixed $db
117 */
118 public function set_db($db)
119 {
120 $this->db = $db;
121 }
122
123 /**
124 * @return mixed
125 */
126 public function get_ret()
127 {
128 return $this->ret;
129 }
130
131 /**
132 * @param mixed $ret
133 */
134 public function set_ret($ret)
135 {
136 $this->ret = $ret;
137 }
138
139 /**
140 * @return mixed
141 */
142 public function get_is_open()
143 {
144 return $this->is_open;
145 }
146
147 /**
148 * @param mixed $is_open
149 */
150 public function set_is_open($is_open)
151 {
152 $this->is_open = $is_open;
153 }
154 /**
155 * last SQL stmt executed
156 * @param string $sql
157 */
158 public function get_sql()
159 {
160 return $this->sql;
161 }
162 /**
163 * last SQL stmt executed
164 * @param string $sql
165 */
166 public function set_sql($sql)
167 {
168 $this->sql=$sql;
169 return $this;
170 }
171
172 /**
173 * \brief send a sql string to the database
174 * \param $p_string sql string
175 * \param $p_array array for the SQL string (see pg_query_params)
176 * \return the result of the query, a resource or false if an
177 * error occured
178 */
179
180 function exec_sql($p_string, $p_array = null)
181 {
182 try {
183 if (!$this->is_open) throw new Exception(' Database is closed');
184 $this->sql = $p_string;
185 $this->array = $p_array;
186
187 if ($p_array == null) {
188 if ( DEBUGNOALYSS == 0 )
189 $this->ret = pg_query($this->db, $p_string);
190 else
191 $this->ret = @pg_query($this->db, $p_string);
192 } else {
193 $a = is_array($p_array);
194 if (!is_array($p_array)) {
195 throw new Exception(_("Erreur : exec_sql attend un array"));
196 }
197 if ( DEBUGNOALYSS == 0 )
198 $this->ret =@pg_query_params($this->db, $p_string, $p_array);
199 else
200 $this->ret = pg_query_params($this->db, $p_string, $p_array);
201 }
202 if ($this->ret == false) {
203 $str_error = pg_last_error($this->db) ;
204 throw new Exception(" SQL ERROR $p_string " . $str_error, 1);
205 }
206 } catch (Exception $a) {
207 if ( DEBUGNOALYSS > 0 ) {
208 print_r($p_string);
209 print_r($p_array);
210 echo $a->getMessage();
211 echo $a->getTraceAsString();
212 echo pg_last_error($this->db);
213 }
214 record_log($a);
215 record_log($p_string);
217 $this->rollback();
218
219 throw ($a);
220 }
221
222 return $this->ret;
223 }
224
225 /**
226 * \brief Count the number of row returned by a sql statement
227 *
228 * \param $p_sql sql string
229 * \param $p_array if not null we use the safer pg_query_params
230 */
231
232 function count_sql($p_sql, $p_array = null)
233 {
234 $r_sql = $this->exec_sql($p_sql, $p_array);
235 return pg_num_rows($r_sql);
236 }
237
238 /**
239 * \brief get the current sequence value
240 */
241
242 function get_current_seq($p_seq)
243 {
244 $Res = $this->get_value("select currval('$p_seq') as seq");
245 return $Res;
246 }
247
248 /**
249 * \brief get the next sequence value
250 */
251
252 function get_next_seq($p_seq)
253 {
254 $Res = $this->exec_sql("select nextval('$p_seq') as seq");
255 $seq = pg_fetch_array($Res, 0);
256 return $seq['seq'];
257 }
258
259 /**
260 * @brief : start a transaction
261 *
262 */
263 function start()
264 {
265 $Res = $this->exec_sql("start transaction");
266 }
267
268 /**
269 * Commit the transaction
270 *
271 */
272 function commit()
273 {
274 if (!$this->is_open) return;
275 $Res = $this->exec_sql("commit");
276 }
277
278 /**
279 * rollback the current transaction
280 */
281 function rollback()
282 {
283 if (!$this->is_open) return;
284 $Res = $this->exec_sql("rollback");
285 }
286
287 /**
288 * @brief alter the sequence value
289 * @param $p_name name of the sequence
290 * @param $min the start value of the sequence
291 */
292 function alter_seq($p_name, $min)
293 {
294 if ($min < 1)
295 $min = 1;
296 $Res = $this->exec_sql("alter sequence $p_name restart $min");
297 }
298
299 /**
300 * \brief Execute a sql script
301 * \param $script script name
302 */
303
305 {
306
307 if ( DEBUGNOALYSS == 0 ) {
308 ob_start();
309 } else {
310 $debug = fopen("/tmp/debug_execute_script".uniqid().".log", "w+");
311 }
312 $hf = fopen($script, 'r');
313 if ($hf == false) {
314 throw new Exception ('Ne peut ouvrir ' . $script);
315 }
316 printf (" open %s <br>", $script);
317 $sql = "";
318 $flag_function = false;
319 while (!feof($hf)) {
320 $buffer = fgets($hf);
321 $buffer = str_replace('$BODY$', '$_$', $buffer);
322 print $buffer . "<br>";
323 // comment are not execute
324 if (substr($buffer, 0, 2) == "--") {
325 //echo "comment $buffer";
326 continue;
327 }
328 // Blank Lines Are Skipped
329 If (Strlen($buffer) == 0) {
330 //echo "Blank $buffer";
331 Continue;
332 }
333 if (strpos(strtolower($buffer), "create function") === 0) {
334 echo "found a function";
335 $flag_function = true;
336 $sql = $buffer;
337 continue;
338 }
339 if (strpos(strtolower($buffer), "create or replace function") === 0) {
340 echo "found a function";
341 $flag_function = true;
342 $sql = $buffer;
343 continue;
344 }
345 // No semi colon -> multiline command
346 if ($flag_function == false && strpos($buffer, ';') == false) {
347 $sql .= $buffer;
348 continue;
349 }
350 if ($flag_function) {
351 if (strpos(strtolower($buffer), "$$;") === false &&
352 strpos(strtolower($buffer), '$_$;') === false &&
353 strpos(strtolower($buffer), '$function$;') === false &&
354 strpos(strtolower($buffer), 'language plpgsql;') === false &&
355 strpos(strtolower($buffer), 'language plpgsql ;') === false
356 ) {
357 $sql .= $buffer;
358 continue;
359 }
360 } else {
361 // cut the semi colon
362 $buffer = str_replace(';', '', $buffer);
363 }
364 $sql .= $buffer;
365 if ( DEBUGNOALYSS > 0 ) fwrite($debug, $sql);
366 if ($this->exec_sql($sql) == false) {
367
368 $this->rollback();
369 if ( DEBUGNOALYSS == 0 )
370 ob_end_clean();
371 print "ERROR : $sql";
372 throw new Exception("ERROR : $sql");
373 }
374 $sql = "";
375 $flag_function = false;
376 print "<hr>";
377 } // while (feof)
378 fclose($hf);
379 if ( DEBUGNOALYSS == 0 )
380 ob_end_clean();
381 }
382
383
384 /**
385 * @brief fetch the $p_indice array from the last query
386 * @param $p_indice index
387 *
388 */
389 function fetch($p_indice)
390 {
391 if ($this->ret == false)
392 throw new Exception('this->ret is empty');
393 return pg_fetch_array($this->ret, $p_indice,PGSQL_ASSOC);
394 }
395
396 /**
397 *
398 * @brief return the number of rows found by the last query, or the number
399 * of rows from $p_ret
400 * @param $p_ret is the result of a query, the default value is null, in that case
401 * it is related to the last query
402 * @note synomym for count()
403 */
404
405 function size($p_ret = null)
406 {
407 if ($p_ret == null)
408 return pg_num_rows($this->ret);
409 else
410 return pg_num_rows($p_ret);
411 }
412
413 /**
414 * @brief synomym for size()
415 */
416
417 function count($p_ret = null)
418 {
419 return $this->size($p_ret);
420 }
421
422
423 /**
424 *
425 * \brief return the value of the sql, the sql will return only one value
426 * with the value
427 * \param $p_sql the sql stmt example :select s_value from
428 * document_state where s_id=2
429 * \param $p_array if array is not null we use the ExecSqlParm (safer)
430 * \see exec_sql
431 * \note print a warning if several value are found, if only the first value is needed
432 * consider using a LIMIT clause
433 * \return only the first value or an empty string if nothing is found
434 */
435
436 function get_value($p_sql, $p_array = null)
437 {
438 try {
439 $this->ret = $this->exec_sql($p_sql, $p_array);
440 $r = pg_num_rows($this->ret);
441 if ($r == 0)
442 return "";
443 if ($r > 1) {
444 $array = pg_fetch_all($this->ret);
445 throw new Exception("Attention $p_sql retourne " . pg_num_rows($this->ret) . " valeurs " .
446 var_export($p_array, true) . " values=" . var_export($array, true));
447 }
448 $r = pg_fetch_row($this->ret, 0);
449 return $r[0];
450
451 } catch (Exception $ex) {
452 throw($ex);
453 }
454 }
455
456 /**
457 * @brief return the number of rows affected by the previous query
458 */
459 function get_affected()
460 {
461 return Database::num_row($this->ret);
462 }
463
464 /**
465 * \brief purpose return the result of a sql statment
466 * in a array
467 * \param $p_sql sql query
468 * \param $p_array if not null we use ExecSqlParam
469 * \return false if nothing is found
470 */
471
472 function get_array($p_sql, $p_array = null)
473 {
474 $r = $this->exec_sql($p_sql, $p_array);
475
476 if (pg_num_rows($r) == 0)
477 return array();
478 $array = pg_fetch_all($r);
479 return $array;
480 }
481
482 /**
483 * @brief Returns only one row from a query
484 * @param string $p_sql
485 * @param array $p_array
486 * @return array , idx = column of the table or null if nothing is found
487 * @throws Exception if too many rows are found code 100
488 */
489 function get_row($p_sql, $p_array = NULL)
490 {
491 $array = $this->get_array($p_sql, $p_array);
492 if (empty($array)) return null;
493 if (count($array) == 1) return $array[0];
494 throw new Exception(_("Database:get_row retourne trop de lignes"), 100);
495 }
496
497 /**
498 * @brief Create a sequence
499 * @param string $p_name Sequence Name
500 * @param int $min starting value
501 */
502 function create_sequence($p_name, $min = 1)
503 {
504 if ($min < 1)
505 $min = 1;
506 $sql = "create sequence " . $p_name . " minvalue $min";
507 $this->exec_sql($sql);
508 }
509
510 /**
511 * \brief test if a sequence exist */
512 /* \return true if the seq. exist otherwise false
513 */
514
515 function exist_sequence($p_name)
516 {
517 $r = $this->count_sql("select relname from pg_class where relname=lower($1)", array($p_name));
518 if ($r == 0)
519 return false;
520 return true;
521 }
522
523 /**
524 * \brief test if a table exist
525 * \param $p_name table name
526 * \param $schema name of the schema default public
527 * \return true if a table exist otherwise false
528 */
529
530 function exist_table($p_name, $p_schema = 'public')
531 {
532 $r = $this->count_sql("select table_name from information_schema.tables where table_schema=$1 and table_name=lower($2)", array($p_schema, $p_name));
533 if ($r == 0)
534 return false;
535 return true;
536 }
537
538 /**
539 * Check if a column exists in a table
540 * @param $col : column name
541 * @param $table :table name
542 * @param $schema :schema name, default public
543 * @return true or false
544 */
545 function exist_column($col, $table, $schema)
546 {
547 $r = $this->get_value('select count(*) from information_schema.columns where table_name=lower($1) and column_name=lower($2) and table_schema=lower($3)', array($col, $table, $schema));
548 if ($r > 0)
549 return true;
550 return false;
551 }
552
553
554 /**
555 * Count the database name in a system view
556 * @param $p_name string database name
557 * @return number of database found (normally 0 or 1)
558 */
559 function exist_database($p_name)
560 {
561 $database_exist = $this->get_value('select count(*)
562 from pg_catalog.pg_database where datname = lower($1)', array($p_name));
563 return $database_exist;
564 }
565
566 /**
567 * @brief check if the large object exists
568 * @param $p_oid of the large object
569 * @return return true if the large obj exist or false if not
570 */
571 function exist_blob($p_oid)
572 {
573 $r = $this->get_value('select count(*) from pg_largeobject_metadata where oid=$1'
574 , array($p_oid));
575 if ($r > 0)
576 return true;
577 else
578 return false;
579 }
580
581 /*
582 *!\brief test if a view exist
583 * \return true if the view. exist otherwise false
584 */
585
586 function exist_view($p_name)
587 {
588 $r = $this->count_sql("select viewname from pg_views where viewname=lower($1)", array($p_name));
589 if ($r == 0)
590 return false;
591 return true;
592 }
593
594 /***
595 * @brief test if a schema exists
596 * @return true if the schemas exists otherwise false
597 */
598
599 function exist_schema($p_name)
600 {
601 $r = $this->count_sql("select nspname from pg_namespace where nspname=lower($1)", array($p_name));
602 if ($r == 0)
603 return false;
604 return true;
605 }
606
607 /**
608 * \brief create a string containing the value separated by comma
609 * for use in a SQL in statement
610 * \return the string or empty if nothing is found
611 * \see fid_card.php
612 */
613
614 function make_list($sql, $p_array = null)
615 {
616 if ($p_array == null) {
617 $aArray = $this->get_array($sql);
618 } else {
619 $aArray = $this->get_array($sql, $p_array);
620 }
621 if (empty($aArray))
622 return "";
623 $aIdx = array_keys($aArray[0]);
624 $idx = $aIdx[0];
625 $ret = "";
626 $f = "";
627 for ($i = 0; $i < count($aArray); $i++) {
628 $row = $aArray[$i];
629 $ret .= $f . $aArray[$i][$idx];
630 $f = ',';
631 }
632 $ret = trim($ret, ',');
633 return $ret;
634 }
635
636 /**
637 * \brief make a array with the sql.
638 *
639 * \param $p_sql sql statement, only the first two column will be returned in
640 * an array. The first col. is the label and the second the value
641 * \param $p_null if the array start with a null value Yes = 1 , No=0
642 * \param $p_array is the array with the bind value
643 * \note this function is used with ISelect when it is needed to have a list of
644 * options.
645 * \return: a double array like
646 * \verbatim
647 * Array
648 * (
649 * [0] => Array
650 * (
651 * [value] => 1
652 * [label] => Marchandise A
653 * )
654 *
655 * [1] => Array
656 * (
657 * [value] => 2
658 * [label] => Marchandise B
659 * )
660 *
661 * [2] => Array
662 * (
663 * [value] => 3
664 * [label] => Marchandise C
665 * )
666 * )
667 * \endverbatim
668 * \see ISelect
669 */
670
671 function make_array($p_sql, $p_null = 0, $p_array = null)
672 {
673 $a = $this->exec_sql($p_sql, $p_array);
674 $max = pg_num_rows($a);
675 if ($max == 0 && $p_null == 0)
676 return null;
677 for ($i = 0; $i < $max; $i++) {
678 $row = pg_fetch_row($a);
679 $r[$i]['value'] = $row[0];
680 $r[$i]['label'] = h($row[1]);
681 }
682 // add a blank item ?
683 if ($p_null == 1) {
684 for ($i = $max; $i != 0; $i--) {
685 $r[$i]['value'] = $r[$i - 1]['value'];
686 $r[$i]['label'] = $r[$i - 1]['label'];
687 }
688 $r[0]['value'] = -1;
689 $r[0]['label'] = " ";
690 } // if ( $p_null == 1 )
691
692 return $r;
693 }
694
695 /***
696 * \brief Save a document into the database , it just puts the file in the database
697 * and returns the corresponding OID , the mimetype , size ... of the document
698 * must be set in the calling function.
699 *
700 * \param name of the variable in $_FILES
701 * \return $oid of the lob file if success
702 * false if a error occurs or if there is no file to upload
703 *
704 */
705
706 function upload($p_name)
707 {
708 /* there is no file to upload */
709 if ($_FILES[$p_name]["error"] == UPLOAD_ERR_NO_FILE) {
710 return false;
711 }
712
713 $new_name = tempnam($_ENV['TMP'], $p_name);
714 if ($_FILES[$p_name]["error"] > 0) {
715 print_r($_FILES);
716 echo_error(__FILE__ . ":" . __LINE__ . "Error: " . $_FILES[$p_name]["error"]);
717 return false;
718 }
719 if (strlen($_FILES[$p_name]['tmp_name']) != 0) {
720 if (move_uploaded_file($_FILES[$p_name]['tmp_name'], $new_name)) {
721 // echo "Image saved";
722 $oid = pg_lo_import($this->db, $new_name);
723 if ($oid == false) {
724 echo_error(__FILE__, __LINE__, "cannot upload document");
725 $this->rollback();
726 return false;
727 }
728 return $oid;
729 } else {
730 echo "<H1>Error</H1>";
731 $this->rollback();
732 return false;
733 }
734 }
735 return false;
736 }
737
738 /**
739 * \brief wrapper for the function pg_num_rows
740 * \param $ret is the result of a exec_sql
741 * \return number of line affected
742 */
743
744 static function num_row($ret)
745 {
746 return pg_num_rows($ret);
747 }
748
749 /**
750 * \brief wrapper for the function pg_fetch_array
751 * \param $ret is the result of a pg_exec
752 * \param $p_indice is the index
753 * \param $p_indice is the index
754 * \return $array of column
755 */
756
757 static function fetch_array($ret, $p_indice = 0,$p_mode=PGSQL_ASSOC)
758 {
759 return pg_fetch_array($ret, $p_indice,$p_mode);
760 }
761
762 /**
763 * \brief wrapper for the function pg_fetch_all
764 * \param $ret is the result of pg_exec (exec_sql)
765 * \return double array (row x col ) or false
766 */
767
768 static function fetch_all($ret)
769 {
770 return pg_fetch_all($ret,PGSQL_ASSOC);
771 }
772
773 /**
774 * \brief wrapper for the function pg_fetch_all
775 * \param $ret is the result of pg_exec (exec_sql)
776 * \param $p_row is the indice of the row
777 * \param $p_col is the indice of the col
778 * \return a string or an integer
779 */
780
781 static function fetch_result($ret, $p_row = 0, $p_col = 0)
782 {
783 return pg_fetch_result($ret, $p_row, $p_col);
784 }
785
786 /**
787 * \brief wrapper for the function pg_fetch_row
788 * \param $ret is the result of pg_exec (exec_sql)
789 * \param $p_row is the indice of the row
790 * \return an array indexed from 0
791 */
792 static function fetch_row($ret, $p_row)
793 {
794 return pg_fetch_row($ret, $p_row);
795 }
796
797 /**
798 * \brief wrapper for the function pg_lo_unlink
799 * \param $p_oid is the of oid
800 * \return return the result of the operation
801 */
802
803 function lo_unlink($p_oid)
804 {
805 if (!$this->exist_blob($p_oid)) return;
806 return pg_lo_unlink($this->db, $p_oid);
807 }
808
809 /**\brief wrapper for the function pg_prepare
810 * \param $p_string string name for pg_prepare function
811 * \param $p_sql is the sql to prepare
812 * \return return the result of the operation
813 */
814
815 function prepare($p_string, $p_sql)
816 {
817 return pg_prepare($this->db, $p_string, $p_sql);
818 }
819
820 /**
821 * \brief wrapper for the function pg_execute
822 * \param $p_string string name of the stmt given in pg_prepare function
823 * \param $p_array contains the variables
824 * \note set this->ret to the return of pg_execute
825 * \return return the result of the operation,
826 */
827
828 function execute($p_string, $p_array)
829 {
830 $this->ret = pg_execute($this->db, $p_string, $p_array);
831 return $this->ret;
832 }
833
834 /**
835 * \brief wrapper for the function pg_lo_export
836 * \param $p_oid is the oid of the log
837 * \param $tmp_file is the file
838 * \return result of the operation
839 */
840
841 function lo_export($p_oid, $tmp_file)
842 {
843 return pg_lo_export($this->db, $p_oid, $tmp_file);
844 }
845
846 /**
847 * \brief wrapper for the function pg_lo_export
848 * \param $p_filename is the filename
849 * \param $tmp is the file
850 * \return result of the operation
851 */
852
853 function lo_import($p_filename)
854 {
855 return pg_lo_import($this->db, $p_filename);
856 }
857
858 /**
859 * \brief wrapper for the function pg_escape_string
860 * \param $p_string is the string to escape
861 * \return escaped string
862 */
863
864 static function escape_string($p_string)
865 {
866 static $cn=null;
867 if ( $cn==null) $cn=new Database();
868 return pg_escape_string($cn->db,$p_string);
869 }
870
871 /**
872 * \brief wrapper for the function pg_close
873 */
874
875 function close()
876 {
877 if ($this->is_open) pg_close($this->db);
878 $this->is_open = FALSE;
879 }
880
881 /**
882 * \brief
883 * \param
884 * \return
885 * \note
886 * \see
887 */
888
889 function __toString()
890 {
891 return "database ";
892 }
893
894 static function test_me()
895 {
896
897 }
898 /**
899 * @brief get the transaction status :
900 * The status can be
901 * - PGSQL_TRANSACTION_IDLE (currently idle),
902 * - PGSQL_TRANSACTION_ACTIVE (a command is in progress),
903 * - PGSQL_TRANSACTION_INTRANS (idle, in a valid transaction block),
904 * - PGSQL_TRANSACTION_INERROR (idle, in a failed transaction block).
905 * - PGSQL_TRANSACTION_UNKNOWN is reported if the connection is bad.
906 * - PGSQL_TRANSACTION_ACTIVE is reported only when a query has been sent to the server
907 * and not yet completed.
908 * * @return PGSQL_TRANSACTION_IDLE | PGSQL_TRANSACTION_ACTIVE | PGSQL_TRANSACTION_INTRANS | PGSQL_TRANSACTION_INERROR | PGSQL_TRANSACTION_UNKNOWN | PGSQL_TRANSACTION_ACTIVE
909 */
910 function status()
911 {
912 return pg_transaction_status($this->db);
913 }
914
915
916 /**
917 * @brief Find all lob and remove those which are not used by any tables
918 *
919 */
921 {
922 // find all columns of type lob
923 $sql = "
924 select table_schema,table_name,column_name
925 from
926 information_schema.columns
927 where table_schema not in ('information_schema','pg_catalog')
928 and data_type='oid'";
929 $all_lob = "
930 select oid,'N' as used from pg_largeobject_metadata
931 ";
932 $a_table = $this->get_array($sql);
933 $a_lob = $this->get_array($all_lob);
934 if ($a_table == false || $a_lob == false) return;
935 // for each lob
936 $nb_lob = count($a_lob);
937 $nb_table = count($a_table);
938 for ($i = 0; $i < $nb_lob; $i++) {
939 $lob = $a_lob[$i]['oid'];
940 if ($a_lob[$i]['used'] == 'Y') continue;
941 for ($j = 0; $j < $nb_table; $j++) {
942 if ($a_lob[$i]['used'] == 'Y') continue;
943 $check = $this->get_value(" select count(*) from " .
944 $a_table[$j]['table_schema'] . "." . $a_table[$j]['table_name'] .
945 " where " .
946 $a_table[$j]['column_name'] . "=$1", array($lob));
947 if ($check != 0)
948 $a_lob[$i]['used'] = 'Y';
949
950 }
951 }
952 for ($i = 0; $i < $nb_lob; $i++) {
953 if ($a_lob[$i]['used'] == 'Y') continue;
954 $this->lo_unlink($a_lob[$i]['oid']);
955 }
956 }
957
958 /**
959 * @brief Check if a prepared statement already exists or not
960 * @param string $query_name name of the prepared query
961 * @return boolean false is not yet prepared
962 */
963 function is_prepare($query_name)
964 {
965 $nb_prepared = $this->get_value("select count(*) from pg_prepared_statements where name=$1", [$query_name]);
966 if ($nb_prepared == 0) return FALSE;
967 return TRUE;
968 }
969
970 /**
971 * @brief with the handle of a successull query, echo each row into CSV and
972 * send it directly
973 * @param type $ret handle to a query
974 * @param type $aheader double array, each item of the array contains
975 * a key type (num) and a key title
976 */
977 function query_to_csv($ret, $aheader)
978 {
979 $csv = new Noalyss_Csv("db-query");
980 $a_header = [];
981 for ($i = 0; $i < count($aheader); $i++) {
982 $a_header[] = $aheader[$i]['title'];
983 }
984 $csv->write_header($a_header);
985
986 // fetch all the rows
987 for ($i = 0; $i < Database::num_row($ret); $i++) {
989 // for each rows, for each value
990 for ($e = 0; $e < count($row) / 2; $e++) {
991 switch ($aheader[$e]['type']) {
992 case 'num':
993 $csv->add($row[$e], "number");
994 break;
995 default:
996 $csv->add($row[$e]);
997 }
998 }
999 $csv->write();
1000 }
1001 }
1002 /**
1003 * @brief Returns the number of columns in a ret
1004 * @param handler $p_ret handler to a query
1005 */
1006 static function nb_column($p_ret) {
1007 return pg_num_fields($p_ret);
1008 }
1009 /**
1010 * @brief FInd if a SQL Select has a SQL stmt to inject or damage Data
1011 * When a SELECT SQL string is build, this string could contain a SQL attempt to damage data,
1012 *so the statement DELETE TRUNCATE ... are forbidden. Throw an exception EXC_INVALID
1013 *
1014 */
1015 function search_sql_inject($p_sql)
1016 {
1017 $forbid_sql=array("update","delete","truncate","insert");
1018 // protect against SQL inject
1019 foreach ($forbid_sql as $forbid_key) {
1020 if (stripos($p_sql,$forbid_key) !== false)
1021 {
1022 throw new Exception(_("Possible SQL inject"),EXC_INVALID);
1023 }
1024
1025 }
1026 }
1027
1028 /**
1029 * @brief clear a prepare stmt
1030 * @see DatabaseCore::is_prepare
1031 * @see DatabaseCore::execute
1032 * @see DatabaseCore::prepare
1033 * @param $sql_name name of the prepare SQL
1034 */
1035 function clear_prepare($sql_name)
1036 {
1037 pg_exec($this->db,sprintf('DEALLOCATE "%s"'),DatabaseCore::escape_string($sql_name));
1038 }
1039 /**
1040 * @brief clear all prepare stmt
1041 * @see DatabaseCore::is_prepare
1042 * @see DatabaseCore::execute
1043 * @see DatabaseCore::prepare
1044 */
1046 {
1047 pg_exec($this->db,'DEALLOCATE ALL');
1048 }
1049}
1050
1051/* test::test_me(); */
echo_error($p_log, $p_line="", $p_message="")
log error into the /tmp/noalyss_error.log it doesn't work on windows
Definition: ac_common.php:169
record_log($p_message)
Record an error message into the log file of the server.
Definition: ac_common.php:1342
catch(Exception $exc) if(! $g_user->can_write_action($ag_id)) $r
h( $row[ 'oa_description'])
$idx
$ex
Definition: balance.inc.php:45
This class allow you to connect to the postgresql database, execute sql, retrieve data.
commit()
Commit the transaction.
start()
: start a transaction
close()
wrapper for the function pg_close
get_array($p_sql, $p_array=null)
purpose return the result of a sql statment in a array
set_encoding($p_charset)
make_list($sql, $p_array=null)
create a string containing the value separated by comma for use in a SQL in statement
static fetch_all($ret)
wrapper for the function pg_fetch_all
alter_seq($p_name, $min)
alter the sequence value
$db
database connection
static escape_string($p_string)
wrapper for the function pg_escape_string
exist_column($col, $table, $schema)
Check if a column exists in a table.
lo_export($p_oid, $tmp_file)
wrapper for the function pg_lo_export
static fetch_result($ret, $p_row=0, $p_col=0)
wrapper for the function pg_fetch_all
$sql
last SQL stmt executed
execute($p_string, $p_array)
wrapper for the function pg_execute
rollback()
rollback the current transaction
is_prepare($query_name)
Check if a prepared statement already exists or not.
get_value($p_sql, $p_array=null)
return the value of the sql, the sql will return only one value with the value
size($p_ret=null)
return the number of rows found by the last query, or the number of rows from $p_ret
get_sql()
last SQL stmt executed
count($p_ret=null)
synomym for size()
exist_sequence($p_name)
test if a sequence exist
fetch($p_indice)
fetch the $p_indice array from the last query
get_next_seq($p_seq)
get the next sequence value
clear_all_prepare()
clear all prepare stmt
make_array($p_sql, $p_null=0, $p_array=null)
make a array with the sql.
exist_blob($p_oid)
check if the large object exists
static fetch_row($ret, $p_row)
wrapper for the function pg_fetch_row
clear_prepare($sql_name)
clear a prepare stmt
lo_import($p_filename)
wrapper for the function pg_lo_export
search_sql_inject($p_sql)
FInd if a SQL Select has a SQL stmt to inject or damage Data When a SELECT SQL string is build,...
static fetch_array($ret, $p_indice=0, $p_mode=PGSQL_ASSOC)
wrapper for the function pg_fetch_array
status()
get the transaction status : The status can be
get_affected()
return the number of rows affected by the previous query
get_current_seq($p_seq)
get the current sequence value
create_sequence($p_name, $min=1)
Create a sequence.
exec_sql($p_string, $p_array=null)
send a sql string to the database
lo_unlink($p_oid)
wrapper for the function pg_lo_unlink
set_sql($sql)
last SQL stmt executed
clean_orphan_lob()
Find all lob and remove those which are not used by any tables.
__construct($p_user, $p_password, $p_dbname, $p_host, $p_port)
static num_row($ret)
wrapper for the function pg_num_rows
get_name()
return the name of the current database
execute_script($script)
Execute a sql script.
exist_database($p_name)
Count the database name in a system view.
query_to_csv($ret, $aheader)
with the handle of a successull query, echo each row into CSV and send it directly
count_sql($p_sql, $p_array=null)
Count the number of row returned by a sql statement.
exist_table($p_name, $p_schema='public')
test if a table exist
prepare($p_string, $p_sql)
wrapper for the function pg_prepare
static nb_column($p_ret)
Returns the number of columns in a ret.
get_row($p_sql, $p_array=NULL)
Returns only one row from a query.
contains the class for connecting to Noalyss
Manage the CSV : manage files and write CSV record.
const EXC_INVALID
Definition: constant.php:346
$Res
$new_name
$SecUser db
print
Type of printing.
$check
$table
Definition: menu.inc.php:103
$script
Definition: popup.php:125