31require_once DOL_DOCUMENT_ROOT.
'/core/db/DoliDB.class.php';
44 const LABEL =
'MySQL or MariaDB';
67 if (!empty(
$conf->db->character_set)) {
68 $this->forcecharset =
$conf->db->character_set;
70 if (!empty(
$conf->db->dolibarr_main_db_collation)) {
71 $this->forcecollate =
$conf->db->dolibarr_main_db_collation;
74 $this->database_user = $user;
75 $this->database_host = $host;
76 $this->database_port = $port;
78 $this->transaction_opened = 0;
82 if (!class_exists(
'mysqli')) {
83 $this->connected =
false;
85 $this->
error =
"Mysqli PHP functions for using Mysqli driver are not available in this version of PHP. Try to use another driver.";
86 dol_syslog(get_class($this).
"::DoliDBMysqli : Mysqli PHP functions for using Mysqli driver are not available in this version of PHP. Try to use another driver.", LOG_ERR);
90 $this->connected =
false;
92 $this->
error = $langs->trans(
"ErrorWrongHostParameter");
93 dol_syslog(get_class($this).
"::DoliDBMysqli : Connect error, wrong host parameters", LOG_ERR);
98 $this->db = $this->
connect($host, $user, $pass,
'', $port);
100 if ($this->db && empty($this->db->connect_errno)) {
101 $this->connected =
true;
104 $this->connected =
false;
106 $this->
error = empty($this->db) ?
'Failed to connect' : $this->db->connect_error;
107 dol_syslog(get_class($this).
"::DoliDBMysqli Connect error: ".$this->
error, LOG_ERR);
110 $disableforcecharset = 0;
113 if ($this->connected && $name) {
115 $this->database_selected =
true;
116 $this->database_name = $name;
120 $clientmustbe = empty(
$conf->db->character_set) ?
'utf8' : (
string)
$conf->db->character_set;
121 if (preg_match(
'/latin1/', $clientmustbe)) {
122 $clientmustbe =
'utf8';
125 if (empty($disableforcecharset) && $this->db->character_set_name() != $clientmustbe) {
127 dol_syslog(get_class($this).
"::DoliDBMysqli You should set the \$dolibarr_main_db_character_set and \$dolibarr_main_db_collation for the PHP to the same as the database default, so to ".$this->db->character_set_name().
" or upgrade database default to ".$clientmustbe.
".", LOG_WARNING);
134 $this->db->set_charset($clientmustbe);
136 print
'Failed to force character_set_client to '.$clientmustbe.
" (according to setup) to match the one of the server database.<br>\n";
137 print $e->getMessage();
139 if ($clientmustbe !=
'utf8') {
140 print
'Edit conf/conf.php file to set a charset "utf8"';
141 if ($clientmustbe !=
'utf8mb4') {
142 print
' or "utf8mb4"';
144 print
' instead of "'.$clientmustbe.
'".'.
"\n";
149 $collation = (empty(
$conf) ?
'utf8_unicode_ci' : (
string)
$conf->db->dolibarr_main_db_collation);
150 if (preg_match(
'/latin1/', $collation)) {
151 $collation =
'utf8_unicode_ci';
154 if (!preg_match(
'/general/', $collation)) {
155 $this->db->query(
"SET collation_connection = ".$collation);
159 $this->database_selected =
false;
160 $this->database_name =
'';
163 dol_syslog(get_class($this).
"::DoliDBMysqli : Select_db error ".$this->
error, LOG_ERR);
167 $this->database_selected =
false;
169 if ($this->connected) {
171 $clientmustbe = empty(
$conf->db->character_set) ?
'utf8' : (
string)
$conf->db->character_set;
172 if (preg_match(
'/latin1/', $clientmustbe)) {
173 $clientmustbe =
'utf8';
175 if (preg_match(
'/utf8mb4/', $clientmustbe)) {
176 $clientmustbe =
'utf8';
179 if (empty($disableforcecharset) && $this->db->character_set_name() != $clientmustbe) {
180 $this->db->set_charset($clientmustbe);
182 $collation = (
string)
$conf->db->dolibarr_main_db_collation;
183 if (preg_match(
'/latin1/', $collation)) {
184 $collation =
'utf8_unicode_ci';
186 if (preg_match(
'/utf8mb4/', $collation)) {
187 $collation =
'utf8_unicode_ci';
190 if (!preg_match(
'/general/', $collation)) {
191 $this->db->query(
"SET collation_connection = ".$collation);
208 return " ".($mode == 1 ?
'FORCE' :
'USE').
" INDEX(".preg_replace(
'/[^a-z0-9_]/',
'', $nameofindex).
")";
235 dol_syslog(get_class($this).
"::select_db database=".$database, LOG_DEBUG);
238 $result = $this->db->select_db($database);
257 public function connect($host, $login, $passwd, $name, $port = 0)
259 dol_syslog(get_class($this).
"::connect host=$host, port=$port, login=$login, passwd=--hidden--, name=$name", LOG_DEBUG);
265 if (!class_exists(
'mysqli')) {
269 if (strpos($host,
'ssl://') === 0) {
270 $tmp =
new mysqliDoli($host, $login, $passwd, $name, $port);
272 $tmp =
new mysqli($host, $login, $passwd, $name, $port);
275 dol_syslog(get_class($this).
"::connect failed", LOG_DEBUG);
287 return $this->db->server_info;
297 return $this->db->client_info;
310 if ($this->transaction_opened > 0) {
311 dol_syslog(get_class($this).
"::close Closing a connection with an opened transaction depth=".$this->transaction_opened, LOG_ERR);
313 $this->connected =
false;
314 return $this->db->close();
331 public function query($query, $usesavepoint = 0,
$type =
'auto', $result_mode = 0)
333 global $dolibarr_main_db_readonly;
335 $query = trim($query);
343 if (!in_array($query, array(
'BEGIN',
'COMMIT',
'ROLLBACK'))) {
344 $SYSLOG_SQL_LIMIT = 10000;
345 dol_syslog(
'sql='.substr($query, 0, $SYSLOG_SQL_LIMIT), LOG_DEBUG);
351 if (!empty($dolibarr_main_db_readonly)) {
352 if (preg_match(
'/^(INSERT|UPDATE|REPLACE|DELETE|CREATE|ALTER|TRUNCATE|DROP)/i', $query)) {
353 $this->
lasterror =
'Application in read-only mode';
361 $ret = $this->db->query($query, $result_mode);
363 dol_syslog(get_class($this).
"::query Exception in query instead of returning an error: ".$e->getMessage(), LOG_ERR);
367 if (!preg_match(
"/^COMMIT/i", $query) && !preg_match(
"/^ROLLBACK/i", $query)) {
375 dol_syslog(get_class($this).
"::query SQL Error query: ".$query, LOG_ERR);
377 dol_syslog(get_class($this).
"::query SQL Error message: ".$this->
lasterrno.
" ".$this->lasterror.self::getCallerInfoString(), LOG_ERR);
387 $this->_results = $ret;
400 $backtrace = debug_backtrace();
402 if (count($backtrace) >= 1) {
403 $trace = $backtrace[1];
404 if (isset($trace[
'file'], $trace[
'line'])) {
405 $msg =
" From {$trace['file']}:{$trace['line']}.";
422 if (!is_object($resultset)) {
423 $resultset = $this->_results;
425 return $resultset->fetch_object();
440 if (!is_object($resultset)) {
441 $resultset = $this->_results;
443 return $resultset->fetch_array();
457 if (!is_bool($resultset)) {
458 if (!is_object($resultset)) {
459 $resultset = $this->_results;
461 return $resultset->fetch_row();
480 if (!is_object($resultset)) {
481 $resultset = $this->_results;
483 return isset($resultset->num_rows) ? $resultset->num_rows : 0;
498 if (!is_object($resultset)) {
499 $resultset = $this->_results;
503 return $this->db->affected_rows;
512 public function free($resultset =
null)
515 if (!is_object($resultset)) {
516 $resultset = $this->_results;
519 if (is_object($resultset)) {
520 $resultset->free_result();
532 return $this->db->real_escape_string((
string) $stringtoencode);
544 return str_replace(array(
'\\',
'_',
'%'), array(
'\\\\',
'\_',
'\%'), (
string) $stringtoencode);
554 if (!$this->connected) {
556 return 'DB_ERROR_FAILED_TO_CONNECT';
559 $errorcode_map = array(
560 1004 =>
'DB_ERROR_CANNOT_CREATE',
561 1005 =>
'DB_ERROR_CANNOT_CREATE',
562 1006 =>
'DB_ERROR_CANNOT_CREATE',
563 1007 =>
'DB_ERROR_ALREADY_EXISTS',
564 1008 =>
'DB_ERROR_CANNOT_DROP',
565 1022 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
566 1025 =>
'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
567 1044 =>
'DB_ERROR_ACCESSDENIED',
568 1046 =>
'DB_ERROR_NODBSELECTED',
569 1048 =>
'DB_ERROR_CONSTRAINT',
570 1050 =>
'DB_ERROR_TABLE_ALREADY_EXISTS',
571 1051 =>
'DB_ERROR_NOSUCHTABLE',
572 1054 =>
'DB_ERROR_NOSUCHFIELD',
573 1060 =>
'DB_ERROR_COLUMN_ALREADY_EXISTS',
574 1061 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
575 1062 =>
'DB_ERROR_RECORD_ALREADY_EXISTS',
576 1064 =>
'DB_ERROR_SYNTAX',
577 1068 =>
'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
578 1075 =>
'DB_ERROR_CANT_DROP_PRIMARY_KEY',
579 1091 =>
'DB_ERROR_NOSUCHFIELD',
580 1100 =>
'DB_ERROR_NOT_LOCKED',
581 1136 =>
'DB_ERROR_VALUE_COUNT_ON_ROW',
582 1146 =>
'DB_ERROR_NOSUCHTABLE',
583 1215 =>
'DB_ERROR_CANNOT_ADD_FOREIGN_KEY_CONSTRAINT',
584 1216 =>
'DB_ERROR_NO_PARENT',
585 1217 =>
'DB_ERROR_CHILD_EXISTS',
586 1396 =>
'DB_ERROR_USER_ALREADY_EXISTS',
587 1451 =>
'DB_ERROR_CHILD_EXISTS',
588 1826 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS'
591 if (isset($errorcode_map[$this->db->errno])) {
592 return $errorcode_map[$this->db->errno];
594 $errno = $this->db->errno;
595 return ($errno ?
'DB_ERROR_'.$errno :
'0');
606 if (!$this->connected) {
608 return 'Not connected. Check setup parameters in conf/conf.php file and your mysql client and server versions';
610 return $this->db->error;
625 return $this->db->insert_id;
636 public function encrypt($fieldorvalue, $withQuotes = 1)
641 $cryptType = (!empty(
$conf->db->dolibarr_main_db_encryption) ?
$conf->db->dolibarr_main_db_encryption : 0);
644 $cryptKey = (!empty(
$conf->db->dolibarr_main_db_cryptkey) ?
$conf->db->dolibarr_main_db_cryptkey :
'');
646 $escapedstringwithquotes = ($withQuotes ?
"'" :
"").$this->
escape($fieldorvalue).($withQuotes ?
"'" :
"");
648 if ($cryptType && !empty($cryptKey)) {
649 if ($cryptType == 2) {
650 $escapedstringwithquotes =
"AES_ENCRYPT(".$escapedstringwithquotes.
", '".$this->
escape($cryptKey).
"')";
651 } elseif ($cryptType == 1) {
652 $escapedstringwithquotes =
"DES_ENCRYPT(".$escapedstringwithquotes.
", '".$this->
escape($cryptKey).
"')";
656 return $escapedstringwithquotes;
670 $cryptType = (!empty(
$conf->db->dolibarr_main_db_encryption) ?
$conf->db->dolibarr_main_db_encryption : 0);
673 $cryptKey = (!empty(
$conf->db->dolibarr_main_db_cryptkey) ?
$conf->db->dolibarr_main_db_cryptkey :
'');
677 if ($cryptType && !empty($cryptKey)) {
678 if ($cryptType == 2) {
679 $return =
'AES_DECRYPT('.$value.
',\''.$cryptKey.
'\')
';
680 } elseif ($cryptType == 1) {
681 $return = 'DES_DECRYPT(
'.$value.',\
''.$cryptKey.
'\')
';
689 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
695 public function DDLGetConnectId()
698 $resql = $this->query('SELECT CONNECTION_ID()
');
700 $row = $this->fetch_row($resql);
707 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
719 public function DDLCreateDb($database, $charset = '
', $collation = '', $owner = '')
722 if (empty($charset)) {
723 $charset = $this->forcecharset;
725 if (empty($collation)) {
726 $collation = $this->forcecollate;
729 // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci
730 $sql = "CREATE DATABASE `".$this->escape($database)."`";
731 $sql .= " DEFAULT CHARACTER SET `".$this->escape($charset)."` DEFAULT COLLATE `".$this->escape($collation)."`";
733 dol_syslog($sql, LOG_DEBUG);
734 $ret = $this->query($sql);
736 // We try again for compatibility with Mysql < 4.1.1
737 $sql = "CREATE DATABASE `".$this->escape($database)."`";
738 dol_syslog($sql, LOG_DEBUG);
739 $ret = $this->query($sql);
745 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
753 public function DDLListTables($database, $table = '
')
756 $listtables = array();
760 $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i
', '', $table);
762 $like = "LIKE '".$this->escape($tmptable)."'";
764 $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $database);
766 $sql = "SHOW TABLES FROM `".$tmpdatabase."` ".$like.";";
768 $result = $this->query($sql);
770 while ($row = $this->fetch_row($result)) {
771 $listtables[] = $row[0];
777 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
785 public function DDLListTablesFull($database, $table = '
')
788 $listtables = array();
792 $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i
', '', $table);
794 $like = "LIKE '".$this->escape($tmptable)."'";
796 $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $database);
798 $sql = "SHOW FULL TABLES FROM `".$tmpdatabase."` ".$like.";";
800 $result = $this->query($sql);
802 while ($row = $this->fetch_row($result)) {
803 $listtables[] = $row;
809 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
816 public function DDLInfoTable($table)
819 $infotables = array();
821 $sanitizedtmptable = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $table);
823 $sql = "SHOW FULL COLUMNS FROM ".$sanitizedtmptable.";";
825 dol_syslog($sql, LOG_DEBUG);
826 $result = $this->query($sql);
828 while ($row = $this->fetch_row($result)) {
829 $infotables[] = $row;
835 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
848 public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
851 // @TODO: $fulltext_keys parameter is unused
861 // Keys found into the array $fields: type,value,attribute,null,default,extra
862 // ex. : $fields['rowid
'] = array(
863 // 'type'=>'int' or 'integer
',
865 // 'null'=>'not
null',
866 // 'extra
'=> 'auto_increment
'
868 $sql = "CREATE TABLE ".$this->sanitize($table)."(";
870 $sqlfields = array();
871 foreach ($fields as $field_name => $field_desc) {
872 $sqlfields[$i] = $this->sanitize($field_name)." ";
873 $sqlfields[$i] .= $this->sanitize($field_desc['type']);
874 if (isset($field_desc['value
']) && $field_desc['value
'] !== '') {
875 $sqlfields[$i] .= "(".$this->sanitize($field_desc['value
']).")";
877 if (isset($field_desc['attribute
']) && $field_desc['attribute
'] !== '') {
878 $sqlfields[$i] .= " ".$this->sanitize($field_desc['attribute
'], 0, 0, 1); // Allow space to accept attributes like "ON UPDATE CURRENT_TIMESTAMP"
880 if (isset($field_desc['default']) && $field_desc['default'] !== '') {
881 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
882 $sqlfields[$i] .= " DEFAULT ".((float) $field_desc['default']);
883 } elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP
') {
884 $sqlfields[$i] .= " DEFAULT ".$this->sanitize($field_desc['default']);
886 $sqlfields[$i] .= " DEFAULT '".$this->escape($field_desc['default'])."'";
889 if (isset($field_desc['null']) && $field_desc['null'] !== '') {
890 $sqlfields[$i] .= " ".$this->sanitize($field_desc['null'], 0, 0, 1);
892 if (isset($field_desc['extra
']) && $field_desc['extra
'] !== '') {
893 $sqlfields[$i] .= " ".$this->sanitize($field_desc['extra
'], 0, 0, 1);
895 if (!empty($primary_key) && $primary_key == $field_name) {
896 $sqlfields[$i] .= " AUTO_INCREMENT PRIMARY KEY"; // mysql instruction that will be converted by driver late
901 if (is_array($unique_keys)) {
903 foreach ($unique_keys as $key => $value) {
904 $sqluq[$i] = "UNIQUE KEY '".$this->sanitize($key)."' ('".$this->escape($value)."')";
908 if (is_array($keys)) {
910 foreach ($keys as $key => $value) {
911 $sqlk[$i] = "KEY ".$this->sanitize($key)." (".$value.")";
915 $sql .= implode(',
', $sqlfields);
916 if (!is_array($unique_keys) && $unique_keys != "") {
917 $sql .= ",".implode(',
', $sqluq);
919 if (is_array($keys)) {
920 $sql .= ",".implode(',
', $sqlk);
923 $sql .= " engine=".$this->sanitize($type);
925 if (!$this->query($sql)) {
932 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
939 public function DDLDropTable($table)
942 $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $table);
944 $sql = "DROP TABLE ".$this->sanitize($tmptable);
946 if (!$this->query($sql)) {
953 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
961 public function DDLDescTable($table, $field = "")
964 $sql = "DESC ".$this->sanitize($table)." ".$this->sanitize($field);
966 dol_syslog(get_class($this)."::DDLDescTable ".$sql, LOG_DEBUG);
967 $this->_results = $this->query($sql);
968 return $this->_results;
971 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
981 public function DDLAddField($table, $field_name, $field_desc, $field_position = "")
984 // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
985 // ex. : $field_desc = array('
type'=>'int','value
'=>'11
','null'=>'not
null','extra
'=> 'auto_increment
');
986 $sql = "ALTER TABLE ".$this->sanitize($table)." ADD ".$this->sanitize($field_name)." ";
988 if ($field_desc['type'] !== 'datetimegmt
') {
989 $sql .= $this->sanitize($field_desc['type']);
994 if (in_array($field_desc['type'], array('double', 'int', 'varchar
')) && array_key_exists('value
', $field_desc) && !empty($field_desc['value
'])) {
995 $sql .= "(".$this->sanitize($field_desc['value
']).")";
997 if (isset($field_desc['attribute
']) && preg_match("/^[^\s]/i", $field_desc['attribute
'])) {
998 $sql .= " ".$this->sanitize($field_desc['attribute
']);
1000 if (isset($field_desc['null']) && preg_match("/^[^\s]/i", $field_desc['null'])) {
1001 if ($field_desc['null'] == 'NOT NULL
') {
1002 $sql .= " ".$this->sanitize($field_desc['null'], 0, 0, 1);
1004 $sql .= " ".$this->sanitize($field_desc['null']);
1007 if (isset($field_desc['default']) && preg_match("/^[^\s]/i", $field_desc['default'])) {
1008 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
1009 $sql .= " DEFAULT ".((float) $field_desc['default']);
1010 } elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP
') {
1011 $sql .= " DEFAULT ".$this->sanitize($field_desc['default']);
1013 $sql .= " DEFAULT '".$this->escape($field_desc['default'])."'";
1016 if (isset($field_desc['extra
']) && preg_match("/^[^\s]/i", $field_desc['extra
'])) {
1017 $sql .= " ".$this->sanitize($field_desc['extra
'], 0, 0, 1);
1019 $sql .= " ".$this->sanitize($field_position, 0, 0, 1);
1021 dol_syslog(get_class($this)."::DDLAddField ".$sql, LOG_DEBUG);
1022 if ($this->query($sql)) {
1028 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1037 public function DDLUpdateField($table, $field_name, $field_desc)
1040 $sql = "ALTER TABLE ".$this->sanitize($table);
1041 $sql .= " MODIFY COLUMN ".$this->sanitize($field_name)." ";
1043 if ($field_desc['
type'] !== 'datetimegmt
') {
1044 $sql .= $this->sanitize($field_desc['type']);
1049 if (in_array($field_desc['type'], array('double', 'int', 'varchar
')) && array_key_exists('value
', $field_desc) && !empty($field_desc['value
'])) {
1050 $sql .= "(".$this->sanitize($field_desc['value
']).")";
1052 if (isset($field_desc['null']) && ($field_desc['null'] == 'not
null' || $field_desc['null'] == 'NOT NULL
')) {
1053 // We will try to change format of column to NOT NULL. To be sure the ALTER works, we try to update fields that are NULL
1054 if ($field_desc['type'] == 'varchar
' || $field_desc['type'] == 'text
') {
1055 $sqlbis = "UPDATE ".$this->sanitize($table)." SET ".$this->sanitize($field_name)." = '".$this->escape(isset($field_desc['default']) ? $field_desc['default'] : '')."' WHERE ".$this->sanitize($field_name)." IS NULL";
1056 $this->query($sqlbis);
1057 } elseif (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
1058 $sqlbis = "UPDATE ".$this->sanitize($table)." SET ".$this->sanitize($field_name)." = ".((float) $this->escape(isset($field_desc['default']) ? $field_desc['default'] : 0))." WHERE ".$this->sanitize($field_name)." IS NULL";
1059 $this->query($sqlbis);
1062 $sql .= " NOT NULL";
1065 if (isset($field_desc['default']) && $field_desc['default'] != '') {
1066 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
1067 $sql .= " DEFAULT ".((float) $field_desc['default']);
1068 } elseif ($field_desc['type'] != 'text
') {
1069 $sql .= " DEFAULT '".$this->escape($field_desc['default'])."'"; // Default not supported on text fields
1074 dol_syslog(get_class($this)."::DDLUpdateField ".$sql, LOG_DEBUG);
1075 if (!$this->query($sql)) {
1082 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1090 public function DDLDropField($table, $field_name)
1093 $tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $field_name);
1095 $sql = "ALTER TABLE ".$this->sanitize($table)." DROP COLUMN `".$this->sanitize($tmp_field_name)."`";
1096 if ($this->query($sql)) {
1099 $this->error = $this->lasterror();
1104 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1114 public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
1117 $sql = "CREATE USER '
".$this->escape($dolibarr_main_db_user)."' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'";
1118 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1119 $resql = $this->query($sql);
1121 if ($this->lasterrno != 'DB_ERROR_USER_ALREADY_EXISTS
') {
1124 // If user already exists, we continue to set permissions
1125 dol_syslog(get_class($this)."::DDLCreateUser sql=".$sql, LOG_WARNING);
1129 // Redo with localhost forced (sometimes user is created on %)
1130 $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'@'localhost
' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'";
1131 $resql = $this->query($sql);
1133 $sql = "GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."'";
1134 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1135 $resql = $this->query($sql);
1137 $this->error = "Connected user not allowed to GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."'";
1141 $sql = "FLUSH Privileges";
1143 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1144 $resql = $this->query($sql);
1159 public function getDefaultCharacterSetDatabase()
1161 $resql = $this->query("SHOW VARIABLES LIKE 'character_set_database
'");
1163 // version Mysql < 4.1.1
1164 return $this->forcecharset;
1166 $liste = $this->fetch_array($resql);
1167 $tmpval = $liste['Value
'];
1177 public function getListOfCharacterSet()
1179 $resql = $this->query('SHOW CHARSET
');
1183 while ($obj = $this->fetch_object($resql)) {
1184 $liste[$i]['charset
'] = $obj->Charset;
1188 $this->free($resql);
1190 // version Mysql < 4.1.1
1202 public function getDefaultCollationDatabase()
1204 $resql = $this->query("SHOW VARIABLES LIKE 'collation_database
'");
1206 // version Mysql < 4.1.1
1207 return $this->forcecollate;
1209 $liste = $this->fetch_array($resql);
1210 $tmpval = $liste['Value
'];
1220 public function getListOfCollation()
1222 $resql = $this->query('SHOW COLLATION
');
1226 while ($obj = $this->fetch_object($resql)) {
1227 $liste[$i]['collation
'] = $obj->Collation;
1230 $this->free($resql);
1232 // version Mysql < 4.1.1
1243 public function getPathOfDump()
1245 $fullpathofdump = '/pathtomysqldump/mysqldump
';
1247 $resql = $this->query("SHOW VARIABLES LIKE 'basedir
'");
1249 $liste = $this->fetch_array($resql);
1250 $basedir = $liste['Value
'];
1251 $fullpathofdump = $basedir.(preg_match('/\/$/
', $basedir) ? '' : '/
').'bin/mysqldump
';
1253 return $fullpathofdump;
1261 public function getPathOfRestore()
1263 $fullpathofimport = '/pathtomysql/mysql
';
1265 $resql = $this->query("SHOW VARIABLES LIKE 'basedir
'");
1267 $liste = $this->fetch_array($resql);
1268 $basedir = $liste['Value
'];
1269 $fullpathofimport = $basedir.(preg_match('/\/$/
', $basedir) ? '' : '/
').'bin/mysql
';
1271 return $fullpathofimport;
1280 public function getServerParametersValues($filter = '
')
1284 $sql = 'SHOW VARIABLES
';
1286 $sql .= " LIKE '".$this->escape($filter)."'";
1288 $resql = $this->query($sql);
1290 while ($obj = $this->fetch_object($resql)) {
1291 $result[$obj->Variable_name] = $obj->Value;
1304 public function getServerStatusValues($filter = '
')
1308 $sql = 'SHOW STATUS
';
1310 $sql .= " LIKE '".$this->escape($filter)."'";
1312 $resql = $this->query($sql);
1314 while ($obj = $this->fetch_object($resql)) {
1315 $result[$obj->Variable_name] = $obj->Value;
1328 public function getNextAutoIncrementId($table)
1330 // Request to get last status of table
1331 $sql = "SHOW TABLE STATUS LIKE '
".$this->escape($table)."'";
1332 $result = $this->query($sql);
1335 $obj = $this->fetch_object($result);
1336 if ($obj && isset($obj->Auto_increment)) {
1337 return (int) $obj->Auto_increment;
1350 public function prepare($sql)
1352 if (!$this->connected) {
1353 $this->lasterror = 'Not connected to database
';
1356 $stmt = $this->db->prepare($sql);
1357 if ($stmt === false) {
1358 $this->lasterror = $this->db->error;
1359 $this->lastqueryerror = $sql;
1367if (class_exists('mysqli
')) {
1371 class mysqliDoli extends mysqli
1384 public function __construct($host, $user, $pass, $name, $port = 0, $socket = "") // @phpstan-ignore constructor.unusedParameter
1387 if (PHP_VERSION_ID >= 80100) {
1388 parent::__construct();
1390 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
1393 if (strpos($host, 'ssl:
1394 $host = substr($host, 6);
1395 parent::options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, 0);
1397 parent::ssl_set(
null,
null,
"",
null,
null);
1398 $flags = MYSQLI_CLIENT_SSL;
1400 parent::real_connect($host, $user, $pass, $name, $port, $socket, $flags);
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()
Class to manage Dolibarr database access for a MySQL database using the MySQLi extension.
fetch_array($resultset)
Return data as an array.
__construct($type, $host, $user, $pass, $name='', $port=0)
Constructor.
free($resultset=null)
Free the last pointer resultset used by this connection.
escapeforlike($stringtoencode)
Escape a string to insert data into a like.
num_rows($resultset)
Return number of lines for result of a SELECT.
hintindex($nameofindex, $mode=1)
Return SQL string to force an index.
const VERSIONMIN
Version min database.
error()
Return description of last error.
escape($stringtoencode)
Escape a string to insert data.
getVersion()
Return version of database server.
fetch_object($resultset)
Returns the current line (as an object) for the resultset cursor.
encrypt($fieldorvalue, $withQuotes=1)
Encrypt sensitive data in database Warning: This function includes the escape and add the SQL simple ...
convertSQLFromMysql($line, $type='ddl')
Convert a SQL request in Mysql syntax to native syntax.
affected_rows($resultset)
Return the number of lines in the result of a request INSERT, DELETE or UPDATE.
select_db($database)
Select a database.
decrypt($value)
Decrypt sensitive data in database.
fetch_row($resultset)
Return data as an array.
last_insert_id($tab, $fieldid='rowid')
Get last ID after an insert INSERT.
const LABEL
Database label.
query($query, $usesavepoint=0, $type='auto', $result_mode=0)
Execute a SQL request and return the resultset.
connect($host, $login, $passwd, $name, $port=0)
Connect to server.
errno()
Return generic error code of last operation.
static getCallerInfoString()
Get caller info.
getDriverInfo()
Return version of database client driver.
close()
Close database connection.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...