33require_once DOL_DOCUMENT_ROOT.
'/core/db/DoliDB.class.php';
 
   58  public $unescapeslashquot = 
false;
 
   62  public $standard_conforming_strings = 
false;
 
   86    if (!empty(
$conf->db->character_set)) {
 
   87      $this->forcecharset = 
$conf->db->character_set;
 
   89    if (!empty(
$conf->db->dolibarr_main_db_collation)) {
 
   90      $this->forcecollate = 
$conf->db->dolibarr_main_db_collation;
 
   93    $this->database_user = $user;
 
   94    $this->database_host = $host;
 
   95    $this->database_port = $port;
 
   97    $this->transaction_opened = 0;
 
  101    if (!function_exists(
"pg_connect")) {
 
  102      $this->connected = 
false;
 
  104      $this->
error = 
"Pgsql PHP functions are not available in this version of PHP";
 
  105      dol_syslog(get_class($this).
"::DoliDBPgsql : Pgsql PHP functions are not available in this version of PHP", LOG_ERR);
 
  110      $this->connected = 
false;
 
  112      $this->
error = $langs->trans(
"ErrorWrongHostParameter");
 
  113      dol_syslog(get_class($this).
"::DoliDBPgsql : Erreur Connect, wrong host parameters", LOG_ERR);
 
  119    $this->db = $this->
connect($host, $user, $pass, $name, $port);
 
  122      $this->connected = 
true;
 
  126      $this->connected = 
false;
 
  128      $this->
error = 
'Host, login or password incorrect';
 
  129      dol_syslog(get_class($this).
"::DoliDBPgsql : Erreur Connect ".$this->
error.
'. Failed to connect to host='.$host.
' port='.$port.
' user='.$user, LOG_ERR);
 
  133    if ($this->connected && $name) {
 
  135        $this->database_selected = 
true;
 
  136        $this->database_name = $name;
 
  139        $this->database_selected = 
false;
 
  140        $this->database_name = 
'';
 
  143        dol_syslog(get_class($this).
"::DoliDBPgsql : Erreur Select_db ".$this->
error, LOG_ERR);
 
  147      $this->database_selected = 
false;
 
 
  165    if (preg_match(
'/^--\s\$Id/i', $line)) {
 
  169    if (preg_match(
'/^#/i', $line) || preg_match(
'/^$/i', $line) || preg_match(
'/^--/i', $line)) {
 
  175      $line = preg_replace(
'/GROUP_CONCAT/i', 
'STRING_AGG', $line);
 
  176      $line = preg_replace(
'/ SEPARATOR/i', 
',', $line);
 
  177      $line = preg_replace(
'/STRING_AGG\(([^,\)]+)\)/i', 
'STRING_AGG(\\1, \',\')', $line);
 
  180      if (
$type == 
'auto') {
 
  181        if (preg_match(
'/ALTER TABLE/i', $line)) {
 
  183        } elseif (preg_match(
'/CREATE TABLE/i', $line)) {
 
  185        } elseif (preg_match(
'/DROP TABLE/i', $line)) {
 
  190      $line = preg_replace(
'/ as signed\)/i', 
' as integer)', $line);
 
  192      if (
$type == 
'dml') {
 
  195        $line = preg_replace(
'/\s/', 
' ', $line); 
 
  198        if (preg_match(
'/(ISAM|innodb)/i', $line)) { 
 
  199          $line = preg_replace(
'/\)[\s\t]*type[\s\t]*=[\s\t]*(MyISAM|innodb).*;/i', 
');', $line);
 
  200          $line = preg_replace(
'/\)[\s\t]*engine[\s\t]*=[\s\t]*(MyISAM|innodb).*;/i', 
');', $line);
 
  201          $line = preg_replace(
'/,$/', 
'', $line);
 
  205        if (preg_match(
'/[\s\t\(]*(\w*)[\s\t]+int.*auto_increment/i', $line, $reg)) {
 
  206          $newline = preg_replace(
'/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+int.*auto_increment[^,]*/i', 
'\\1 \\2 SERIAL PRIMARY KEY', $line);
 
  211        if (preg_match(
'/[\s\t\(]*(\w*)[\s\t]+bigint.*auto_increment/i', $line, $reg)) {
 
  212          $newline = preg_replace(
'/([\s\t\(]*)([a-zA-Z_0-9]*)[\s\t]+bigint.*auto_increment[^,]*/i', 
'\\1 \\2 BIGSERIAL PRIMARY KEY', $line);
 
  218        $line = preg_replace(
'/tinyint\(?[0-9]*\)?/', 
'smallint', $line);
 
  219        $line = preg_replace(
'/tinyint/i', 
'smallint', $line);
 
  222        $line = preg_replace(
'/(int\w+|smallint|bigint)\s+unsigned/i', 
'\\1', $line);
 
  225        $line = preg_replace(
'/\w*blob/i', 
'text', $line);
 
  228        $line = preg_replace(
'/tinytext/i', 
'text', $line);
 
  229        $line = preg_replace(
'/mediumtext/i', 
'text', $line);
 
  230        $line = preg_replace(
'/longtext/i', 
'text', $line);
 
  232        $line = preg_replace(
'/text\([0-9]+\)/i', 
'text', $line);
 
  236        $line = preg_replace(
'/datetime not null/i', 
'datetime', $line);
 
  237        $line = preg_replace(
'/datetime/i', 
'timestamp', $line);
 
  240        $line = preg_replace(
'/^double/i', 
'numeric', $line);
 
  241        $line = preg_replace(
'/(\s*)double/i', 
'\\1numeric', $line);
 
  243        $line = preg_replace(
'/^float/i', 
'numeric', $line);
 
  244        $line = preg_replace(
'/(\s*)float/i', 
'\\1numeric', $line);
 
  248        $line = preg_replace(
'/(\s*)tms(\s*)timestamp/i', 
'\\1tms timestamp without time zone DEFAULT now() NOT NULL', $line);
 
  251        $line = preg_replace(
'/(\s*)DEFAULT(\s*)CURRENT_TIMESTAMP/i', 
'\\1', $line);
 
  254        $line = preg_replace(
'/(\s*)ON(\s*)UPDATE(\s*)CURRENT_TIMESTAMP/i', 
'\\1', $line);
 
  257        if (preg_match(
'/unique index\s*\((\w+\s*,\s*\w+)\)/i', $line)) {
 
  258          $line = preg_replace(
'/unique index\s*\((\w+\s*,\s*\w+)\)/i', 
'UNIQUE\(\\1\)', $line);
 
  262        $line = preg_replace(
'/\sAFTER [a-z0-9_]+/i', 
'', $line);
 
  265        $line = preg_replace(
'/ALTER TABLE [a-z0-9_]+\s+DROP INDEX/i', 
'DROP INDEX', $line);
 
  268        if (preg_match(
'/ALTER TABLE ([a-z0-9_]+)\s+CHANGE(?: COLUMN)? ([a-z0-9_]+) ([a-z0-9_]+)(.*)$/i', $line, $reg)) {
 
  269          $line = 
"-- ".$line.
" replaced by --\n";
 
  270          $line .= 
"ALTER TABLE ".$reg[1].
" RENAME COLUMN ".$reg[2].
" TO ".$reg[3];
 
  274        if (preg_match(
'/ALTER TABLE ([a-z0-9_]+)\s+MODIFY(?: COLUMN)? ([a-z0-9_]+) (.*)$/i', $line, $reg)) {
 
  275          $line = 
"-- ".$line.
" replaced by --\n";
 
  277          $newreg3 = preg_replace(
'/ DEFAULT NULL/i', 
'', $newreg3);
 
  278          $newreg3 = preg_replace(
'/ NOT NULL/i', 
'', $newreg3);
 
  279          $newreg3 = preg_replace(
'/ NULL/i', 
'', $newreg3);
 
  280          $newreg3 = preg_replace(
'/ DEFAULT 0/i', 
'', $newreg3);
 
  281          $newreg3 = preg_replace(
'/ DEFAULT \'?[0-9a-zA-Z_@]*\'?/i', 
'', $newreg3);
 
  282          $line .= 
"ALTER TABLE ".$reg[1].
" ALTER COLUMN ".$reg[2].
" TYPE ".$newreg3;
 
  288        if (preg_match(
'/ALTER\s+TABLE\s*(.*)\s*ADD\s+PRIMARY\s+KEY\s*(.*)\s*\((.*)$/i', $line, $reg)) {
 
  289          $line = 
"-- ".$line.
" replaced by --\n";
 
  290          $line .= 
"ALTER TABLE ".$reg[1].
" ADD PRIMARY KEY (".$reg[3];
 
  295        if (preg_match(
'/ALTER\s+TABLE\s*(.*)\s*DROP\s+PRIMARY\s+KEY\s*([^;]+)$/i', $line, $reg)) {
 
  296          $line = 
"-- ".$line.
" replaced by --\n";
 
  297          $line .= 
"ALTER TABLE ".$reg[1].
" DROP CONSTRAINT ".$reg[2];
 
  302        if (preg_match(
'/ALTER\s+TABLE\s*(.*)\s*DROP\s+FOREIGN\s+KEY\s*(.*)$/i', $line, $reg)) {
 
  303          $line = 
"-- ".$line.
" replaced by --\n";
 
  304          $line .= 
"ALTER TABLE ".$reg[1].
" DROP CONSTRAINT ".$reg[2];
 
  309        if (preg_match(
'/ALTER\s+TABLE\s+(.*)\s*ADD CONSTRAINT\s+(.*)\s*FOREIGN\s+KEY\s*(.*)$/i', $line, $reg)) {
 
  310          $line = preg_replace(
'/;$/', 
'', $line);
 
  311          $line .= 
" DEFERRABLE INITIALLY IMMEDIATE;";
 
  316        if (preg_match(
'/ALTER\s+TABLE\s*(.*)\s*ADD\s+(UNIQUE INDEX|INDEX|UNIQUE)\s+(.*)\s*\(([\w,\s]+)\)/i', $line, $reg)) {
 
  317          $fieldlist = $reg[4];
 
  319          $tablename = $reg[1];
 
  320          $line = 
"-- ".$line.
" replaced by --\n";
 
  321          $line .= 
"CREATE ".(preg_match(
'/UNIQUE/', $reg[2]) ? 
'UNIQUE ' : 
'').
"INDEX ".$idxname.
" ON ".$tablename.
" (".$fieldlist.
")";
 
  327      $line = str_replace(
' LIKE \'', 
' ILIKE \'', $line, $count_like);
 
  330        $line = preg_replace(
'/\s+(\(+\s*)([a-zA-Z0-9\-\_\.]+) ILIKE /', 
' \1unaccent(\2) ILIKE ', $line);
 
  333      $line = str_replace(
' LIKE BINARY \'', 
' LIKE \'', $line);
 
  336      $line = preg_replace(
'/^INSERT IGNORE/', 
'INSERT', $line);
 
  340      if (preg_match(
'/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i', $line, $reg)) {
 
  341        if ($reg[1] == $reg[2]) { 
 
  342          $line = preg_replace(
'/DELETE FROM ([a-z_]+) USING ([a-z_]+), ([a-z_]+)/i', 
'DELETE FROM \\1 USING \\3', $line);
 
  347      $line = preg_replace(
'/FROM\s*\((([a-z_]+)\s+as\s+([a-z_]+)\s*)\)/i', 
'FROM \\1', $line);
 
  351      $line = preg_replace(
'/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i', 
'FROM \\1, \\2', $line);
 
  355      $line = preg_replace(
'/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i', 
'FROM \\1, \\2, \\3', $line);
 
  359      $line = preg_replace(
'/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i', 
'FROM \\1, \\2, \\3, \\4', $line);
 
  363      $line = preg_replace(
'/FROM\s*\(([a-z_]+\s+as\s+[a-z_]+)\s*,\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*),\s*([a-z_]+\s+as\s+[a-z_]+\s*)\)/i', 
'FROM \\1, \\2, \\3, \\4, \\5', $line);
 
  370      if ($unescapeslashquot) {
 
  371        $line = preg_replace(
"/\\\'/", 
"''", $line);
 
 
  392    if ($database == $this->database_name) {
 
 
  410  public function connect($host, $login, $passwd, $name, $port = 0)
 
  417    $host = str_replace(array(
"\\", 
"'"), array(
"\\\\", 
"\\'"), $host);
 
  418    $login = str_replace(array(
"\\", 
"'"), array(
"\\\\", 
"\\'"), $login);
 
  419    $passwd = str_replace(array(
"\\", 
"'"), array(
"\\\\", 
"\\'"), $passwd);
 
  420    $name = str_replace(array(
"\\", 
"'"), array(
"\\\\", 
"\\'"), $name);
 
  421    $port = str_replace(array(
"\\", 
"'"), array(
"\\\\", 
"\\'"), (
string) $port);
 
  428    if ((!empty($host) && $host == 
"socket") && !defined(
'NOLOCALSOCKETPGCONNECT')) {
 
  429      $con_string = 
"dbname='".$name.
"' user='".$login.
"' password='".$passwd.
"'"; 
 
  431        $this->db = @pg_connect($con_string);
 
  438    if (empty($this->db)) {
 
  446      $con_string = 
"host='".$host.
"' port='".$port.
"' dbname='".$name.
"' user='".$login.
"' password='".$passwd.
"'";
 
  448        $this->db = @pg_connect($con_string);
 
  450        print $e->getMessage();
 
  456      $this->database_name = $name;
 
  457      pg_set_error_verbosity($this->db, PGSQL_ERRORS_VERBOSE); 
 
  458      pg_query($this->db, 
"set datestyle = 'ISO, YMD';");
 
 
  471    $resql = $this->
query(
'SHOW server_version');
 
  474      return $liste[
'server_version'];
 
 
  486    return 'pgsql php driver';
 
 
  498      if ($this->transaction_opened > 0) {
 
  499        dol_syslog(get_class($this).
"::close Closing a connection with an opened transaction depth=".$this->transaction_opened, LOG_ERR);
 
  501      $this->connected = 
false;
 
  502      return pg_close($this->db);
 
 
  516  public function query($query, $usesavepoint = 0, 
$type = 
'auto', $result_mode = 0)
 
  518    global $dolibarr_main_db_readonly;
 
  520    $query = trim($query);
 
  523    $query = $this->
convertSQLFromMysql($query, 
$type, ($this->unescapeslashquot && $this->standard_conforming_strings));
 
  530        if (preg_match(
'/([^\'])([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9])/', $query)) {
 
  531          $query = preg_replace(
'/([^\'])([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9])/', 
'\\1\'\\2\'', $query);
 
  532          dol_syslog(
"Warning: Bad formed request converted into ".$query, LOG_WARNING);
 
  539    if ($usesavepoint && $this->transaction_opened) {
 
  540      @pg_query($this->db, 
'SAVEPOINT mysavepoint');
 
  543    if (!in_array($query, array(
'BEGIN', 
'COMMIT', 
'ROLLBACK'))) {
 
  544      $SYSLOG_SQL_LIMIT = 10000; 
 
  545      dol_syslog(
'sql='.substr($query, 0, $SYSLOG_SQL_LIMIT), LOG_DEBUG);
 
  551    if (!empty($dolibarr_main_db_readonly)) {
 
  552      if (preg_match(
'/^(INSERT|UPDATE|REPLACE|DELETE|CREATE|ALTER|TRUNCATE|DROP)/i', $query)) {
 
  553        $this->
lasterror = 
'Application in read-only mode';
 
  560    $ret = @pg_query($this->db, $query);
 
  563    if (!preg_match(
"/^COMMIT/i", $query) && !preg_match(
"/^ROLLBACK/i", $query)) { 
 
  565        if ($this->
errno() != 
'DB_ERROR_25P02') { 
 
  571            dol_syslog(get_class($this).
"::query SQL Error query: ".$query, LOG_ERR); 
 
  573          dol_syslog(get_class($this).
"::query SQL Error message: ".$this->
lasterror.
" (".$this->lasterrno.
")", LOG_ERR);
 
  574          dol_syslog(get_class($this).
"::query SQL Error usesavepoint = ".$usesavepoint, LOG_ERR);
 
  577        if ($usesavepoint && $this->transaction_opened) { 
 
  578          @pg_query($this->db, 
'ROLLBACK TO SAVEPOINT mysavepoint');
 
  582      $this->_results = $ret;
 
 
  599    if (!is_resource($resultset) && !is_object($resultset)) {
 
  600      $resultset = $this->_results;
 
  602    return pg_fetch_object($resultset);
 
 
  616    if (!is_resource($resultset) && !is_object($resultset)) {
 
  617      $resultset = $this->_results;
 
  619    return pg_fetch_array($resultset);
 
 
  633    if (!is_resource($resultset) && !is_object($resultset)) {
 
  634      $resultset = $this->_results;
 
  636    return pg_fetch_row($resultset);  
 
 
  651    if (!is_resource($resultset) && !is_object($resultset)) {
 
  652      $resultset = $this->_results;
 
  654    return pg_num_rows($resultset);
 
 
  669    if (!is_resource($resultset) && !is_object($resultset)) {
 
  670      $resultset = $this->_results;
 
  674    return pg_affected_rows($resultset);
 
 
  684  public function free($resultset = 
null)
 
  687    if (!is_resource($resultset) && !is_object($resultset)) {
 
  688      $resultset = $this->_results;
 
  691    if (is_resource($resultset) || is_object($resultset)) {
 
  692      pg_free_result($resultset);
 
 
  704  public function plimit($limit = 0, $offset = 0)
 
  711      $limit = 
$conf->liste_limit;
 
  714      return " LIMIT ".$limit.
" OFFSET ".$offset.
" ";
 
  716      return " LIMIT $limit ";
 
 
  729    return pg_escape_string($this->db, $stringtoencode);
 
 
  740    return str_replace(array(
'\\', 
'_', 
'%'), array(
'\\\\', 
'\_', 
'\%'), (
string) $stringtoencode);
 
 
  751  public function ifsql($test, $resok, $resko)
 
  753    return '(CASE WHEN '.$test.
' THEN '.$resok.
' ELSE '.$resko.
' END)';
 
 
  764  public function regexpsql($subject, $pattern, $sqlstring = 0)
 
  767      return "(". $subject .
" ~ '" . $this->
escape($pattern) . 
"')";
 
  770    return "('". $this->
escape($subject) .
"' ~ '" . $this->
escape($pattern) . 
"')";
 
 
  781    if (!$this->connected) {
 
  783      return 'DB_ERROR_FAILED_TO_CONNECT';
 
  786      $errorcode_map = array(
 
  787      1004 => 
'DB_ERROR_CANNOT_CREATE',
 
  788      1005 => 
'DB_ERROR_CANNOT_CREATE',
 
  789      1006 => 
'DB_ERROR_CANNOT_CREATE',
 
  790      1007 => 
'DB_ERROR_ALREADY_EXISTS',
 
  791      1008 => 
'DB_ERROR_CANNOT_DROP',
 
  792      1025 => 
'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
 
  793      1044 => 
'DB_ERROR_ACCESSDENIED',
 
  794      1046 => 
'DB_ERROR_NODBSELECTED',
 
  795      1048 => 
'DB_ERROR_CONSTRAINT',
 
  796      '42P07' => 
'DB_ERROR_TABLE_OR_KEY_ALREADY_EXISTS',
 
  797      '42703' => 
'DB_ERROR_NOSUCHFIELD',
 
  798      1060 => 
'DB_ERROR_COLUMN_ALREADY_EXISTS',
 
  799      42701 => 
'DB_ERROR_COLUMN_ALREADY_EXISTS',
 
  800      '42710' => 
'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
 
  801      '23505' => 
'DB_ERROR_RECORD_ALREADY_EXISTS',
 
  802      '42704' => 
'DB_ERROR_NO_INDEX_TO_DROP', 
 
  803      '42601' => 
'DB_ERROR_SYNTAX',
 
  804      '42P16' => 
'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
 
  805      1075 => 
'DB_ERROR_CANT_DROP_PRIMARY_KEY',
 
  806      1091 => 
'DB_ERROR_NOSUCHFIELD',
 
  807      1100 => 
'DB_ERROR_NOT_LOCKED',
 
  808      1136 => 
'DB_ERROR_VALUE_COUNT_ON_ROW',
 
  809      '42P01' => 
'DB_ERROR_NOSUCHTABLE',
 
  810      '23503' => 
'DB_ERROR_NO_PARENT',
 
  811      1217 => 
'DB_ERROR_CHILD_EXISTS',
 
  812      1451 => 
'DB_ERROR_CHILD_EXISTS',
 
  813      '42P04' => 
'DB_DATABASE_ALREADY_EXISTS' 
  816      $errorlabel = pg_last_error($this->db);
 
  819      if (preg_match(
'/: *([0-9P]+):/', $errorlabel, $reg)) {
 
  820        $errorcode = $reg[1];
 
  821        if (isset($errorcode_map[$errorcode])) {
 
  822          return $errorcode_map[$errorcode];
 
  825      $errno = $errorcode ? $errorcode : $errorlabel;
 
  826      return ($errno ? 
'DB_ERROR_'.$errno : 
'0');
 
 
  845    return pg_last_error($this->db);
 
 
  860    $result = pg_query($this->db, 
"SELECT currval('".$tab.
"_".$fieldid.
"_seq')");
 
  862      print pg_last_error($this->db);
 
  866    $row = pg_fetch_result($result, 0, 0);
 
 
  878  public function encrypt($fieldorvalue, $withQuotes = 1)
 
  888    $return = $fieldorvalue;
 
  889    return ($withQuotes ? 
"'" : 
"").$this->
escape($return).($withQuotes ? 
"'" : 
"");
 
 
  940  public function DDLCreateDb($database, $charset = 
'', $collation = 
'', $owner = 
'')
 
  943    if (empty($charset)) {
 
  946    if (empty($collation)) {
 
  954    $sql = 
"CREATE DATABASE ".$this->escape($database).
" OWNER '".$this->
escape($owner).
"' ENCODING '".$this->
escape($charset).
"'";
 
  957    $ret = $this->
query($sql);
 
 
  973    $listtables = array();
 
  977      $tmptable = preg_replace(
'/[^a-z0-9\.\-\_%]/i', 
'', $table);
 
  979      $escapedlike = 
" AND table_name LIKE '".$this->escape($tmptable).
"'";
 
  981    $result = pg_query($this->db, 
"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'".$escapedlike.
" ORDER BY table_name");
 
  983      while ($row = $this->
fetch_row($result)) {  
 
  984        $listtables[] = $row[0];
 
 
 1001    $listtables = array();
 
 1005      $tmptable = preg_replace(
'/[^a-z0-9\.\-\_%]/i', 
'', $table);
 
 1007      $escapedlike = 
" AND table_name LIKE '".$this->escape($tmptable).
"'";
 
 1009    $result = pg_query($this->db, 
"SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = 'public'".$escapedlike.
" ORDER BY table_name");
 
 1011      while ($row = $this->
fetch_row($result)) {  
 
 1012        $listtables[] = $row;
 
 
 1028    $infotables = array();
 
 1031    $sql .= 
" infcol.column_name as 'Column',";
 
 1032    $sql .= 
" CASE WHEN infcol.character_maximum_length IS NOT NULL THEN infcol.udt_name || '('||infcol.character_maximum_length||')'";
 
 1033    $sql .= 
"   ELSE infcol.udt_name";
 
 1034    $sql .= 
" END as 'Type',";
 
 1035    $sql .= 
" infcol.collation_name as 'Collation',";
 
 1036    $sql .= 
" infcol.is_nullable as 'Null',";
 
 1037    $sql .= 
" '' as 'Key',";
 
 1038    $sql .= 
" infcol.column_default as 'Default',";
 
 1039    $sql .= 
" '' as 'Extra',";
 
 1040    $sql .= 
" '' as 'Privileges'";
 
 1041    $sql .= 
" FROM information_schema.columns infcol";
 
 1042    $sql .= 
" WHERE table_schema = 'public' ";
 
 1043    $sql .= 
" AND table_name = '".$this->escape($table).
"'";
 
 1044    $sql .= 
" ORDER BY ordinal_position;";
 
 1046    $result = $this->
query($sql);
 
 1048      while ($row = $this->
fetch_row($result)) {
 
 1049        $infotables[] = $row;
 
 
 1069  public function DDLCreateTable($table, $fields, $primary_key, 
$type, $unique_keys = 
null, $fulltext_keys = 
null, $keys = 
null)
 
 1084    $sql = 
"CREATE TABLE ".$this->sanitize($table).
"(";
 
 1086    $sqlfields = array();
 
 1087    foreach ($fields as $field_name => $field_desc) {
 
 1088      $sqlfields[$i] = $this->
sanitize($field_name).
" ";
 
 1089      $sqlfields[$i] .= $this->
sanitize($field_desc[
'type']);
 
 1090      if (isset($field_desc[
'value']) && $field_desc[
'value'] !== 
'') {
 
 1091        $sqlfields[$i] .= 
"(".$this->sanitize($field_desc[
'value']).
")";
 
 1093      if (isset($field_desc[
'attribute']) && $field_desc[
'attribute'] !== 
'') {
 
 1094        $sqlfields[$i] .= 
" ".$this->sanitize($field_desc[
'attribute']);
 
 1096      if (isset($field_desc[
'default']) && $field_desc[
'default'] !== 
'') {
 
 1097        if (in_array($field_desc[
'type'], array(
'tinyint', 
'smallint', 
'int', 
'double'))) {
 
 1098          $sqlfields[$i] .= 
" DEFAULT ".((float) $field_desc[
'default']);
 
 1099        } elseif ($field_desc[
'default'] == 
'null' || $field_desc[
'default'] == 
'CURRENT_TIMESTAMP') {
 
 1100          $sqlfields[$i] .= 
" DEFAULT ".$this->sanitize($field_desc[
'default']);
 
 1102          $sqlfields[$i] .= 
" DEFAULT '".$this->escape($field_desc[
'default']).
"'";
 
 1105      if (isset($field_desc[
'null']) && $field_desc[
'null'] !== 
'') {
 
 1106        $sqlfields[$i] .= 
" ".$this->sanitize($field_desc[
'null'], 0, 0, 1);
 
 1108      if (isset($field_desc[
'extra']) && $field_desc[
'extra'] !== 
'') {
 
 1109        $sqlfields[$i] .= 
" ".$this->sanitize($field_desc[
'extra'], 0, 0, 1);
 
 1111      if (!empty($primary_key) && $primary_key == $field_name) {
 
 1112        $sqlfields[$i] .= 
" AUTO_INCREMENT PRIMARY KEY";  
 
 1117    if (is_array($unique_keys)) {
 
 1119      foreach ($unique_keys as $key => $value) {
 
 1120        $sqluq[$i] = 
"UNIQUE KEY '".$this->sanitize($key).
"' ('".$this->
escape($value).
"')";
 
 1124    if (is_array($keys)) {
 
 1126      foreach ($keys as $key => $value) {
 
 1127        $sqlk[$i] = 
"KEY ".$this->sanitize($key).
" (".$value.
")";
 
 1131    $sql .= implode(
', ', $sqlfields);
 
 1132    if ($unique_keys != 
"") {
 
 1133      $sql .= 
",".implode(
',', $sqluq);
 
 1135    if (is_array($keys)) {
 
 1136      $sql .= 
",".implode(
',', $sqlk);
 
 1141    if (!$this->
query($sql, 1)) {
 
 
 1158    $tmptable = preg_replace(
'/[^a-z0-9\.\-\_]/i', 
'', $table);
 
 1160    $sql = 
"DROP TABLE ".$this->sanitize($tmptable);
 
 1162    if (!$this->
query($sql, 1)) {
 
 
 1180    $sql = 
"SELECT attname FROM pg_attribute, pg_type WHERE typname = '".$this->escape($table).
"' AND attrelid = typrelid";
 
 1181    $sql .= 
" AND attname NOT IN ('cmin', 'cmax', 'ctid', 'oid', 'tableoid', 'xmin', 'xmax')";
 
 1183      $sql .= 
" AND attname = '".$this->escape($field).
"'";
 
 1187    $this->_results = $this->
query($sql);
 
 1188    return $this->_results;
 
 
 1201  public function DDLAddField($table, $field_name, $field_desc, $field_position = 
"")
 
 1206    $sql = 
"ALTER TABLE ".$this->sanitize($table).
" ADD ".$this->
sanitize($field_name).
" ";
 
 1207    $sql .= $this->
sanitize($field_desc[
'type']);
 
 1208    if (isset($field_desc[
'value']) && preg_match(
"/^[^\s]/i", $field_desc[
'value'])) {
 
 1209      if (!in_array($field_desc[
'type'], array(
'tinyint', 
'smallint', 
'int', 
'date', 
'datetime')) && $field_desc[
'value']) {
 
 1210        $sql .= 
"(".$this->sanitize($field_desc[
'value']).
")";
 
 1213    if (isset($field_desc[
'attribute']) && preg_match(
"/^[^\s]/i", $field_desc[
'attribute'])) {
 
 1214      $sql .= 
" ".$this->sanitize($field_desc[
'attribute']);
 
 1216    if (isset($field_desc[
'null']) && preg_match(
"/^[^\s]/i", $field_desc[
'null'])) {
 
 1217      $sql .= 
" ".$this->sanitize($field_desc[
'null']);
 
 1219    if (isset($field_desc[
'default']) && preg_match(
"/^[^\s]/i", $field_desc[
'default'])) {
 
 1220      if (in_array($field_desc[
'type'], array(
'tinyint', 
'smallint', 
'int', 
'double'))) {
 
 1221        $sql .= 
" DEFAULT ".((float) $field_desc[
'default']);
 
 1222      } elseif ($field_desc[
'default'] == 
'null' || $field_desc[
'default'] == 
'CURRENT_TIMESTAMP') {
 
 1223        $sql .= 
" DEFAULT ".$this->sanitize($field_desc[
'default']);
 
 1225        $sql .= 
" DEFAULT '".$this->escape($field_desc[
'default']).
"'";
 
 1228    if (isset($field_desc[
'extra']) && preg_match(
"/^[^\s]/i", $field_desc[
'extra'])) {
 
 1229      $sql .= 
" ".$this->sanitize($field_desc[
'extra'], 0, 0, 1);
 
 1231    $sql .= 
" ".$this->sanitize($field_position, 0, 0, 1);
 
 1234    if (!$this -> 
query($sql)) {
 
 
 1252    $sql = 
"ALTER TABLE ".$this->sanitize($table);
 
 1253    $sql .= 
" ALTER COLUMN ".$this->sanitize($field_name).
" TYPE ".$this->
sanitize($field_desc[
'type']);
 
 1254    if (isset($field_desc[
'value']) && preg_match(
"/^[^\s]/i", $field_desc[
'value'])) {
 
 1255      if (!in_array($field_desc[
'type'], array(
'smallint', 
'int', 
'date', 
'datetime')) && $field_desc[
'value']) {
 
 1256        $sql .= 
"(".$this->sanitize($field_desc[
'value']).
")";
 
 1260    if (isset($field_desc[
'null']) && ($field_desc[
'null'] == 
'not null' || $field_desc[
'null'] == 
'NOT NULL')) {
 
 1262      if ($field_desc[
'type'] == 
'varchar' || $field_desc[
'type'] == 
'text') {
 
 1263        $sqlbis = 
"UPDATE ".$this->sanitize($table).
" SET ".$this->
escape($field_name).
" = '".$this->
escape(isset($field_desc[
'default']) ? $field_desc[
'default'] : 
'').
"' WHERE ".$this->
escape($field_name).
" IS NULL";
 
 1264        $this->
query($sqlbis);
 
 1265      } elseif (in_array($field_desc[
'type'], array(
'tinyint', 
'smallint', 
'int', 
'double'))) {
 
 1266        $sqlbis = 
"UPDATE ".$this->sanitize($table).
" SET ".$this->
escape($field_name).
" = ".((float) $this->
escape(isset($field_desc[
'default']) ? $field_desc[
'default'] : 0)).
" WHERE ".$this->
escape($field_name).
" IS NULL";
 
 1267        $this->
query($sqlbis);
 
 1271    if (isset($field_desc[
'default']) && $field_desc[
'default'] != 
'') {
 
 1272      if (in_array($field_desc[
'type'], array(
'tinyint', 
'smallint', 
'int', 
'double'))) {
 
 1273        $sql .= 
", ALTER COLUMN ".$this->sanitize($field_name).
" SET DEFAULT ".((float) $field_desc[
'default']);
 
 1274      } elseif ($field_desc[
'type'] != 
'text') {  
 
 1275        $sql .= 
", ALTER COLUMN ".$this->sanitize($field_name).
" SET DEFAULT '".$this->
escape($field_desc[
'default']).
"'";
 
 1280    if (!$this->
query($sql)) {
 
 
 1297    $tmp_field_name = preg_replace(
'/[^a-z0-9\.\-\_]/i', 
'', $field_name);
 
 1299    $sql = 
"ALTER TABLE ".$this->sanitize($table).
" DROP COLUMN ".$this->
sanitize($tmp_field_name);
 
 1300    if (!$this->
query($sql)) {
 
 
 1317  public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
 
 1321    $sql = 
"CREATE USER ".$this->sanitize($dolibarr_main_db_user).
" with password '".$this->
escape($dolibarr_main_db_pass).
"'";
 
 1323    dol_syslog(get_class($this).
"::DDLCreateUser", LOG_DEBUG); 
 
 1324    $resql = $this->
query($sql);
 
 
 1339    $resql = $this->
query(
'SHOW SERVER_ENCODING');
 
 1342      return $liste[
'server_encoding'];
 
 
 1355    $resql = $this->
query(
'SHOW SERVER_ENCODING');
 
 1360        $liste[$i][
'charset'] = $obj->server_encoding;
 
 1361        $liste[$i][
'description'] = 
'Default database charset';
 
 1364      $this->
free($resql);
 
 
 1378    $resql = $this->
query(
'SHOW LC_COLLATE');
 
 1381      return $liste[
'lc_collate'];
 
 
 1394    $resql = $this->
query(
'SHOW LC_COLLATE');
 
 1399        $liste[$i][
'collation'] = $obj->lc_collate;
 
 1402      $this->
free($resql);
 
 
 1416    $fullpathofdump = 
'/pathtopgdump/pg_dump';
 
 1418    if (file_exists(
'/usr/bin/pg_dump')) {
 
 1419      $fullpathofdump = 
'/usr/bin/pg_dump';
 
 1422      $resql = $this->
query(
'SHOW data_directory');
 
 1425        $basedir = $liste[
'data_directory'];
 
 1426        $fullpathofdump = preg_replace(
'/data$/', 
'bin', $basedir).
'/pg_dump';
 
 1430    return $fullpathofdump;
 
 
 1443    $fullpathofdump = 
'/pathtopgrestore/'.$tool;
 
 1445    if (file_exists(
'/usr/bin/'.$tool)) {
 
 1446      $fullpathofdump = 
'/usr/bin/'.$tool;
 
 1449      $resql = $this->
query(
'SHOW data_directory');
 
 1452        $basedir = $liste[
'data_directory'];
 
 1453        $fullpathofdump = preg_replace(
'/data$/', 
'bin', $basedir).
'/'.$tool;
 
 1457    return $fullpathofdump;
 
 
 1470    $resql = 
'select name,setting from pg_settings';
 
 1472      $resql .= 
" WHERE name = '".$this->escape($filter).
"'";
 
 1474    $resql = $this->
query($resql);
 
 1477        $result[$obj->name] = $obj->setting;
 
 
 
Class to manage Dolibarr database access.
lastqueryerror()
Return last query in error.
lasterror()
Return last error label.
lasterrno()
Return last error code.
lastquery()
Return last request executed with query()
sanitize($stringtosanitize, $allowsimplequote=0, $allowsequals=0, $allowsspace=0, $allowschars=1)
Sanitize a string for SQL forging.
Class to drive a PostgreSQL database for Dolibarr.
errno()
Renvoie le code erreur generique de l'operation precedente.
DDLListTablesFull($database, $table='')
List tables into a database.
DDLGetConnectId()
Return connection ID.
num_rows($resultset)
Return number of lines for result of a SELECT.
const VERSIONMIN
Version min database.
__construct($type, $host, $user, $pass, $name='', $port=0)
Constructor.
DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
Create a user to connect to database.
DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys=null, $fulltext_keys=null, $keys=null)
Create a table into database.
DDLDropTable($table)
Drop a table into database.
DDLUpdateField($table, $field_name, $field_desc)
Update format of a field into a table.
getPathOfDump()
Return full path of dump program.
select_db($database)
Select a database PostgreSQL does not have an equivalent for mysql_select_db Only compare if the chos...
getServerStatusValues($filter='')
Return value of server status.
plimit($limit=0, $offset=0)
Define limits and offset of request.
decrypt($value)
Decrypt sensitive data in database.
error()
Renvoie le texte de l'erreur pgsql de l'operation precedente.
escape($stringtoencode)
Escape a string to insert data.
query($query, $usesavepoint=0, $type='auto', $result_mode=0)
Convert request to PostgreSQL syntax, execute it and return the resultset.
fetch_object($resultset)
Returns the current line (as an object) for the resultset cursor.
close()
Close database connection.
encrypt($fieldorvalue, $withQuotes=1)
Encrypt sensitive data in database Warning: This function includes the escape and add the SQL simple ...
getListOfCharacterSet()
Return list of available charset that can be used to store data in database.
fetch_array($resultset)
Return datas as an array.
last_insert_id($tab, $fieldid='rowid')
Get last ID after an insert INSERT.
getPathOfRestore()
Return full path of restore program.
DDLAddField($table, $field_name, $field_desc, $field_position="")
Create a new field into table.
DDLInfoTable($table)
List information of columns in a table.
connect($host, $login, $passwd, $name, $port=0)
Connection to server.
getVersion()
Return version of database server.
escapeforlike($stringtoencode)
Escape a string to insert data into a like.
affected_rows($resultset)
Return the number of lines in the result of a request INSERT, DELETE or UPDATE.
DDLDropField($table, $field_name)
Drop a field from table.
regexpsql($subject, $pattern, $sqlstring=0)
Format a SQL REGEXP.
DDLCreateDb($database, $charset='', $collation='', $owner='')
Create a new database Do not use function xxx_create_db (xxx=mysql, ...) as they are deprecated We fo...
const LABEL
Database label.
getListOfCollation()
Return list of available collation that can be used for database.
getDriverInfo()
Return version of database client driver.
free($resultset=null)
Libere le dernier resultset utilise sur cette connection.
DDLDescTable($table, $field="")
Return a pointer of line with description of a table or field.
ifsql($test, $resok, $resko)
Format a SQL IF.
getDefaultCollationDatabase()
Return collation used in database.
convertSQLFromMysql($line, $type='auto', $unescapeslashquot=false)
Convert a SQL request in Mysql syntax to native syntax.
getDefaultCharacterSetDatabase()
Return charset used to store data in database.
$forcecollate
Collate used to force collate when creating database.
fetch_row($resultset)
Return datas as an array.
getServerParametersValues($filter='')
Return value of server parameters.
DDLListTables($database, $table='')
List tables into a database.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...