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' : $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 = $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);
337 if (!in_array($query, array(
'BEGIN',
'COMMIT',
'ROLLBACK'))) {
338 $SYSLOG_SQL_LIMIT = 10000;
339 dol_syslog(
'sql='.substr($query, 0, $SYSLOG_SQL_LIMIT), LOG_DEBUG);
345 if (!empty($dolibarr_main_db_readonly)) {
346 if (preg_match(
'/^(INSERT|UPDATE|REPLACE|DELETE|CREATE|ALTER|TRUNCATE|DROP)/i', $query)) {
347 $this->
lasterror =
'Application in read-only mode';
355 $ret = $this->db->query($query, $result_mode);
357 dol_syslog(get_class($this).
"::query Exception in query instead of returning an error: ".$e->getMessage(), LOG_ERR);
361 if (!preg_match(
"/^COMMIT/i", $query) && !preg_match(
"/^ROLLBACK/i", $query)) {
369 dol_syslog(get_class($this).
"::query SQL Error query: ".$query, LOG_ERR);
371 dol_syslog(get_class($this).
"::query SQL Error message: ".$this->
lasterrno.
" ".$this->lasterror.self::getCallerInfoString(), LOG_ERR);
375 $this->_results = $ret;
388 $backtrace = debug_backtrace();
390 if (count($backtrace) >= 1) {
391 $trace = $backtrace[1];
392 if (isset($trace[
'file'], $trace[
'line'])) {
393 $msg =
" From {$trace['file']}:{$trace['line']}.";
410 if (!is_object($resultset)) {
411 $resultset = $this->_results;
413 return $resultset->fetch_object();
428 if (!is_object($resultset)) {
429 $resultset = $this->_results;
431 return $resultset->fetch_array();
445 if (!is_bool($resultset)) {
446 if (!is_object($resultset)) {
447 $resultset = $this->_results;
449 return $resultset->fetch_row();
468 if (!is_object($resultset)) {
469 $resultset = $this->_results;
471 return isset($resultset->num_rows) ? $resultset->num_rows : 0;
486 if (!is_object($resultset)) {
487 $resultset = $this->_results;
491 return $this->db->affected_rows;
500 public function free($resultset =
null)
503 if (!is_object($resultset)) {
504 $resultset = $this->_results;
507 if (is_object($resultset)) {
508 $resultset->free_result();
520 return $this->db->real_escape_string((
string) $stringtoencode);
532 return str_replace(array(
'\\',
'_',
'%'), array(
'\\\\',
'\_',
'\%'), (
string) $stringtoencode);
542 if (!$this->connected) {
544 return 'DB_ERROR_FAILED_TO_CONNECT';
547 $errorcode_map = array(
548 1004 =>
'DB_ERROR_CANNOT_CREATE',
549 1005 =>
'DB_ERROR_CANNOT_CREATE',
550 1006 =>
'DB_ERROR_CANNOT_CREATE',
551 1007 =>
'DB_ERROR_ALREADY_EXISTS',
552 1008 =>
'DB_ERROR_CANNOT_DROP',
553 1022 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
554 1025 =>
'DB_ERROR_NO_FOREIGN_KEY_TO_DROP',
555 1044 =>
'DB_ERROR_ACCESSDENIED',
556 1046 =>
'DB_ERROR_NODBSELECTED',
557 1048 =>
'DB_ERROR_CONSTRAINT',
558 1050 =>
'DB_ERROR_TABLE_ALREADY_EXISTS',
559 1051 =>
'DB_ERROR_NOSUCHTABLE',
560 1054 =>
'DB_ERROR_NOSUCHFIELD',
561 1060 =>
'DB_ERROR_COLUMN_ALREADY_EXISTS',
562 1061 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS',
563 1062 =>
'DB_ERROR_RECORD_ALREADY_EXISTS',
564 1064 =>
'DB_ERROR_SYNTAX',
565 1068 =>
'DB_ERROR_PRIMARY_KEY_ALREADY_EXISTS',
566 1075 =>
'DB_ERROR_CANT_DROP_PRIMARY_KEY',
567 1091 =>
'DB_ERROR_NOSUCHFIELD',
568 1100 =>
'DB_ERROR_NOT_LOCKED',
569 1136 =>
'DB_ERROR_VALUE_COUNT_ON_ROW',
570 1146 =>
'DB_ERROR_NOSUCHTABLE',
571 1215 =>
'DB_ERROR_CANNOT_ADD_FOREIGN_KEY_CONSTRAINT',
572 1216 =>
'DB_ERROR_NO_PARENT',
573 1217 =>
'DB_ERROR_CHILD_EXISTS',
574 1396 =>
'DB_ERROR_USER_ALREADY_EXISTS',
575 1451 =>
'DB_ERROR_CHILD_EXISTS',
576 1826 =>
'DB_ERROR_KEY_NAME_ALREADY_EXISTS'
579 if (isset($errorcode_map[$this->db->errno])) {
580 return $errorcode_map[$this->db->errno];
582 $errno = $this->db->errno;
583 return ($errno ?
'DB_ERROR_'.$errno :
'0');
594 if (!$this->connected) {
596 return 'Not connected. Check setup parameters in conf/conf.php file and your mysql client and server versions';
598 return $this->db->error;
613 return $this->db->insert_id;
624 public function encrypt($fieldorvalue, $withQuotes = 1)
629 $cryptType = (!empty($conf->db->dolibarr_main_db_encryption) ? $conf->db->dolibarr_main_db_encryption : 0);
632 $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey) ? $conf->db->dolibarr_main_db_cryptkey :
'');
634 $escapedstringwithquotes = ($withQuotes ?
"'" :
"").$this->
escape($fieldorvalue).($withQuotes ?
"'" :
"");
636 if ($cryptType && !empty($cryptKey)) {
637 if ($cryptType == 2) {
638 $escapedstringwithquotes =
"AES_ENCRYPT(".$escapedstringwithquotes.
", '".$this->
escape($cryptKey).
"')";
639 } elseif ($cryptType == 1) {
640 $escapedstringwithquotes =
"DES_ENCRYPT(".$escapedstringwithquotes.
", '".$this->
escape($cryptKey).
"')";
644 return $escapedstringwithquotes;
658 $cryptType = (!empty($conf->db->dolibarr_main_db_encryption) ? $conf->db->dolibarr_main_db_encryption : 0);
661 $cryptKey = (!empty($conf->db->dolibarr_main_db_cryptkey) ? $conf->db->dolibarr_main_db_cryptkey :
'');
665 if ($cryptType && !empty($cryptKey)) {
666 if ($cryptType == 2) {
667 $return =
'AES_DECRYPT('.$value.
',\''.$cryptKey.
'\')
';
668 } elseif ($cryptType == 1) {
669 $return = 'DES_DECRYPT(
'.$value.',\
''.$cryptKey.
'\')
';
677 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
683 public function DDLGetConnectId()
686 $resql = $this->query('SELECT CONNECTION_ID()
');
688 $row = $this->fetch_row($resql);
695 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
707 public function DDLCreateDb($database, $charset = '
', $collation = '', $owner = '')
710 if (empty($charset)) {
711 $charset = $this->forcecharset;
713 if (empty($collation)) {
714 $collation = $this->forcecollate;
717 // ALTER DATABASE dolibarr_db DEFAULT CHARACTER SET latin DEFAULT COLLATE latin1_swedish_ci
718 $sql = "CREATE DATABASE `".$this->escape($database)."`";
719 $sql .= " DEFAULT CHARACTER SET `".$this->escape($charset)."` DEFAULT COLLATE `".$this->escape($collation)."`";
721 dol_syslog($sql, LOG_DEBUG);
722 $ret = $this->query($sql);
724 // We try again for compatibility with Mysql < 4.1.1
725 $sql = "CREATE DATABASE `".$this->escape($database)."`";
726 dol_syslog($sql, LOG_DEBUG);
727 $ret = $this->query($sql);
733 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
741 public function DDLListTables($database, $table = '
')
744 $listtables = array();
748 $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i
', '', $table);
750 $like = "LIKE '".$this->escape($tmptable)."'";
752 $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $database);
754 $sql = "SHOW TABLES FROM `".$tmpdatabase."` ".$like.";";
756 $result = $this->query($sql);
758 while ($row = $this->fetch_row($result)) {
759 $listtables[] = $row[0];
765 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
773 public function DDLListTablesFull($database, $table = '
')
776 $listtables = array();
780 $tmptable = preg_replace('/[^a-z0-9\.\-\_%]/i
', '', $table);
782 $like = "LIKE '".$this->escape($tmptable)."'";
784 $tmpdatabase = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $database);
786 $sql = "SHOW FULL TABLES FROM `".$tmpdatabase."` ".$like.";";
788 $result = $this->query($sql);
790 while ($row = $this->fetch_row($result)) {
791 $listtables[] = $row;
797 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
804 public function DDLInfoTable($table)
807 $infotables = array();
809 $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $table);
811 $sql = "SHOW FULL COLUMNS FROM ".$tmptable.";";
813 dol_syslog($sql, LOG_DEBUG);
814 $result = $this->query($sql);
816 while ($row = $this->fetch_row($result)) {
817 $infotables[] = $row;
823 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
836 public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
839 // @TODO: $fulltext_keys parameter is unused
849 // Keys found into the array $fields: type,value,attribute,null,default,extra
850 // ex. : $fields['rowid
'] = array(
851 // 'type'=>'int' or 'integer
',
853 // 'null'=>'not
null',
854 // 'extra
'=> 'auto_increment
'
856 $sql = "CREATE TABLE ".$this->sanitize($table)."(";
858 $sqlfields = array();
859 foreach ($fields as $field_name => $field_desc) {
860 $sqlfields[$i] = $this->sanitize($field_name)." ";
861 $sqlfields[$i] .= $this->sanitize($field_desc['type']);
862 if (isset($field_desc['value
']) && $field_desc['value
'] !== '') {
863 $sqlfields[$i] .= "(".$this->sanitize($field_desc['value
']).")";
865 if (isset($field_desc['attribute
']) && $field_desc['attribute
'] !== '') {
866 $sqlfields[$i] .= " ".$this->sanitize($field_desc['attribute
'], 0, 0, 1); // Allow space to accept attributes like "ON UPDATE CURRENT_TIMESTAMP"
868 if (isset($field_desc['default']) && $field_desc['default'] !== '') {
869 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
870 $sqlfields[$i] .= " DEFAULT ".((float) $field_desc['default']);
871 } elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP
') {
872 $sqlfields[$i] .= " DEFAULT ".$this->sanitize($field_desc['default']);
874 $sqlfields[$i] .= " DEFAULT '".$this->escape($field_desc['default'])."'";
877 if (isset($field_desc['null']) && $field_desc['null'] !== '') {
878 $sqlfields[$i] .= " ".$this->sanitize($field_desc['null'], 0, 0, 1);
880 if (isset($field_desc['extra
']) && $field_desc['extra
'] !== '') {
881 $sqlfields[$i] .= " ".$this->sanitize($field_desc['extra
'], 0, 0, 1);
883 if (!empty($primary_key) && $primary_key == $field_name) {
884 $sqlfields[$i] .= " AUTO_INCREMENT PRIMARY KEY"; // mysql instruction that will be converted by driver late
889 if (is_array($unique_keys)) {
891 foreach ($unique_keys as $key => $value) {
892 $sqluq[$i] = "UNIQUE KEY '".$this->sanitize($key)."' ('".$this->escape($value)."')";
896 if (is_array($keys)) {
898 foreach ($keys as $key => $value) {
899 $sqlk[$i] = "KEY ".$this->sanitize($key)." (".$value.")";
903 $sql .= implode(',
', $sqlfields);
904 if (!is_array($unique_keys) && $unique_keys != "") {
905 $sql .= ",".implode(',
', $sqluq);
907 if (is_array($keys)) {
908 $sql .= ",".implode(',
', $sqlk);
911 $sql .= " engine=".$this->sanitize($type);
913 if (!$this->query($sql)) {
920 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
927 public function DDLDropTable($table)
930 $tmptable = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $table);
932 $sql = "DROP TABLE ".$this->sanitize($tmptable);
934 if (!$this->query($sql)) {
941 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
949 public function DDLDescTable($table, $field = "")
952 $sql = "DESC ".$this->sanitize($table)." ".$this->sanitize($field);
954 dol_syslog(get_class($this)."::DDLDescTable ".$sql, LOG_DEBUG);
955 $this->_results = $this->query($sql);
956 return $this->_results;
959 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
969 public function DDLAddField($table, $field_name, $field_desc, $field_position = "")
972 // cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
973 // ex. : $field_desc = array('
type'=>'int','value
'=>'11
','null'=>'not
null','extra
'=> 'auto_increment
');
974 $sql = "ALTER TABLE ".$this->sanitize($table)." ADD ".$this->sanitize($field_name)." ";
976 if ($field_desc['type'] !== 'datetimegmt
') {
977 $sql .= $this->sanitize($field_desc['type']);
982 if (isset($field_desc['value
']) && preg_match("/^[^\s]/i", $field_desc['value
'])) {
983 if (!in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'date', 'datetime
', 'datetimegmt
')) && $field_desc['value
']) {
984 $sql .= "(".$this->sanitize($field_desc['value
']).")";
987 if (isset($field_desc['attribute
']) && preg_match("/^[^\s]/i", $field_desc['attribute
'])) {
988 $sql .= " ".$this->sanitize($field_desc['attribute
']);
990 if (isset($field_desc['null']) && preg_match("/^[^\s]/i", $field_desc['null'])) {
991 if ($field_desc['null'] == 'NOT NULL
') {
992 $sql .= " ".$this->sanitize($field_desc['null'], 0, 0, 1);
994 $sql .= " ".$this->sanitize($field_desc['null']);
997 if (isset($field_desc['default']) && preg_match("/^[^\s]/i", $field_desc['default'])) {
998 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
999 $sql .= " DEFAULT ".((float) $field_desc['default']);
1000 } elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP
') {
1001 $sql .= " DEFAULT ".$this->sanitize($field_desc['default']);
1003 $sql .= " DEFAULT '".$this->escape($field_desc['default'])."'";
1006 if (isset($field_desc['extra
']) && preg_match("/^[^\s]/i", $field_desc['extra
'])) {
1007 $sql .= " ".$this->sanitize($field_desc['extra
'], 0, 0, 1);
1009 $sql .= " ".$this->sanitize($field_position, 0, 0, 1);
1011 dol_syslog(get_class($this)."::DDLAddField ".$sql, LOG_DEBUG);
1012 if ($this->query($sql)) {
1018 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1027 public function DDLUpdateField($table, $field_name, $field_desc)
1030 $sql = "ALTER TABLE ".$this->sanitize($table);
1031 $sql .= " MODIFY COLUMN ".$this->sanitize($field_name)." ";
1033 if ($field_desc['
type'] !== 'datetimegmt
') {
1034 $sql .= $this->sanitize($field_desc['type']);
1039 if (in_array($field_desc['type'], array('double', 'tinyint
', 'int', 'varchar
')) && array_key_exists('value
', $field_desc) && $field_desc['value
']) {
1040 $sql .= "(".$this->sanitize($field_desc['value
']).")";
1042 if (isset($field_desc['null']) && ($field_desc['null'] == 'not
null' || $field_desc['null'] == 'NOT NULL
')) {
1043 // 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
1044 if ($field_desc['type'] == 'varchar
' || $field_desc['type'] == 'text
') {
1045 $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";
1046 $this->query($sqlbis);
1047 } elseif (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
1048 $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";
1049 $this->query($sqlbis);
1052 $sql .= " NOT NULL";
1055 if (isset($field_desc['default']) && $field_desc['default'] != '') {
1056 if (in_array($field_desc['type'], array('tinyint
', 'smallint
', 'int', 'double'))) {
1057 $sql .= " DEFAULT ".((float) $field_desc['default']);
1058 } elseif ($field_desc['type'] != 'text
') {
1059 $sql .= " DEFAULT '".$this->escape($field_desc['default'])."'"; // Default not supported on text fields
1063 dol_syslog(get_class($this)."::DDLUpdateField ".$sql, LOG_DEBUG);
1064 if (!$this->query($sql)) {
1071 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1079 public function DDLDropField($table, $field_name)
1082 $tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i
', '', $field_name);
1084 $sql = "ALTER TABLE ".$this->sanitize($table)." DROP COLUMN `".$this->sanitize($tmp_field_name)."`";
1085 if ($this->query($sql)) {
1088 $this->error = $this->lasterror();
1093 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1103 public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
1106 $sql = "CREATE USER '
".$this->escape($dolibarr_main_db_user)."' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'";
1107 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1108 $resql = $this->query($sql);
1110 if ($this->lasterrno != 'DB_ERROR_USER_ALREADY_EXISTS
') {
1113 // If user already exists, we continue to set permissions
1114 dol_syslog(get_class($this)."::DDLCreateUser sql=".$sql, LOG_WARNING);
1118 // Redo with localhost forced (sometimes user is created on %)
1119 $sql = "CREATE USER '".$this->escape($dolibarr_main_db_user)."'@'localhost
' IDENTIFIED BY '".$this->escape($dolibarr_main_db_pass)."'";
1120 $resql = $this->query($sql);
1122 $sql = "GRANT ALL PRIVILEGES ON ".$this->escape($dolibarr_main_db_name).".* TO '".$this->escape($dolibarr_main_db_user)."'@'".$this->escape($dolibarr_main_db_host)."'";
1123 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
1124 $resql = $this->query($sql);
1126 $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)."'";
1130 $sql = "FLUSH Privileges";
1132 dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG);
1133 $resql = $this->query($sql);
1148 public function getDefaultCharacterSetDatabase()
1150 $resql = $this->query("SHOW VARIABLES LIKE 'character_set_database
'");
1152 // version Mysql < 4.1.1
1153 return $this->forcecharset;
1155 $liste = $this->fetch_array($resql);
1156 $tmpval = $liste['Value
'];
1166 public function getListOfCharacterSet()
1168 $resql = $this->query('SHOW CHARSET
');
1172 while ($obj = $this->fetch_object($resql)) {
1173 $liste[$i]['charset
'] = $obj->Charset;
1177 $this->free($resql);
1179 // version Mysql < 4.1.1
1191 public function getDefaultCollationDatabase()
1193 $resql = $this->query("SHOW VARIABLES LIKE 'collation_database
'");
1195 // version Mysql < 4.1.1
1196 return $this->forcecollate;
1198 $liste = $this->fetch_array($resql);
1199 $tmpval = $liste['Value
'];
1209 public function getListOfCollation()
1211 $resql = $this->query('SHOW COLLATION
');
1215 while ($obj = $this->fetch_object($resql)) {
1216 $liste[$i]['collation
'] = $obj->Collation;
1219 $this->free($resql);
1221 // version Mysql < 4.1.1
1232 public function getPathOfDump()
1234 $fullpathofdump = '/pathtomysqldump/mysqldump
';
1236 $resql = $this->query("SHOW VARIABLES LIKE 'basedir
'");
1238 $liste = $this->fetch_array($resql);
1239 $basedir = $liste['Value
'];
1240 $fullpathofdump = $basedir.(preg_match('/\/$/
', $basedir) ? '' : '/
').'bin/mysqldump
';
1242 return $fullpathofdump;
1250 public function getPathOfRestore()
1252 $fullpathofimport = '/pathtomysql/mysql
';
1254 $resql = $this->query("SHOW VARIABLES LIKE 'basedir
'");
1256 $liste = $this->fetch_array($resql);
1257 $basedir = $liste['Value
'];
1258 $fullpathofimport = $basedir.(preg_match('/\/$/
', $basedir) ? '' : '/
').'bin/mysql
';
1260 return $fullpathofimport;
1269 public function getServerParametersValues($filter = '
')
1273 $sql = 'SHOW VARIABLES
';
1275 $sql .= " LIKE '".$this->escape($filter)."'";
1277 $resql = $this->query($sql);
1279 while ($obj = $this->fetch_object($resql)) {
1280 $result[$obj->Variable_name] = $obj->Value;
1293 public function getServerStatusValues($filter = '
')
1297 $sql = 'SHOW STATUS
';
1299 $sql .= " LIKE '".$this->escape($filter)."'";
1301 $resql = $this->query($sql);
1303 while ($obj = $this->fetch_object($resql)) {
1304 $result[$obj->Variable_name] = $obj->Value;
1317 public function getNextAutoIncrementId($table)
1319 // Request to get last status of table
1320 $sql = "SHOW TABLE STATUS LIKE '
".$this->escape($table)."'";
1321 $result = $this->query($sql);
1324 $obj = $this->fetch_object($result);
1325 if ($obj && isset($obj->Auto_increment)) {
1326 return (int) $obj->Auto_increment;
1339 public function prepare($sql)
1341 if (!$this->connected) {
1342 $this->lasterror = 'Not connected to database
';
1345 $stmt = $this->db->prepare($sql);
1346 if ($stmt === false) {
1347 $this->lasterror = $this->db->error;
1348 $this->lastqueryerror = $sql;
1356if (class_exists('mysqli
')) {
1360 class mysqliDoli extends mysqli
1373 public function __construct($host, $user, $pass, $name, $port = 0, $socket = "")
1376 if (PHP_VERSION_ID >= 80100) {
1377 parent::__construct();
1379 // @phan-suppress-next-line PhanDeprecatedFunctionInternal
1382 if (strpos($host, 'ssl:
1383 $host = substr($host, 6);
1384 parent::options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT,
false);
1386 parent::ssl_set(
null,
null,
"",
null,
null);
1387 $flags = MYSQLI_CLIENT_SSL;
1389 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)
Libere le dernier resultset utilise sur cette 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.
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right PaymentTypeShortLIQ right SELECT p pos_change as p datep as date
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]]]',...