2
0
forked from Wavyzz/dolibarr

Merge branch 'develop' into qual/db/typing

This commit is contained in:
Laurent Destailleur
2024-03-21 12:46:25 +01:00
committed by GitHub
8 changed files with 247 additions and 168 deletions

View File

@@ -1068,51 +1068,63 @@ class DoliDBPgsql extends DoliDB
public function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null)
{
// phpcs:enable
// FIXME: $fulltext_keys parameter is unused
// @TODO: $fulltext_keys parameter is unused
$sqlfields = array();
$sqlk = array();
$sqluq = array();
// cles recherchees dans le tableau des descriptions (fields) : type,value,attribute,null,default,extra
// ex. : $fields['rowid'] = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
$sql = "create table ".$table."(";
// Keys found into the array $fields: type,value,attribute,null,default,extra
// ex. : $fields['rowid'] = array(
// 'type'=>'int' or 'integer',
// 'value'=>'11',
// 'null'=>'not null',
// 'extra'=> 'auto_increment'
// );
$sql = "CREATE TABLE ".$this->sanitize($table)."(";
$i = 0;
$sqlfields = array();
foreach ($fields as $field_name => $field_desc) {
$sqlfields[$i] = $field_name." ";
$sqlfields[$i] .= $field_desc['type'];
if (preg_match("/^[^\s]/i", $field_desc['value'])) {
$sqlfields[$i] .= "(".$field_desc['value'].")";
} elseif (preg_match("/^[^\s]/i", $field_desc['attribute'])) {
$sqlfields[$i] .= " ".$field_desc['attribute'];
} elseif (preg_match("/^[^\s]/i", $field_desc['default'])) {
if (preg_match("/null/i", $field_desc['default'])) {
$sqlfields[$i] .= " default ".$field_desc['default'];
$sqlfields[$i] = $this->sanitize($field_name)." ";
$sqlfields[$i] .= $this->sanitize($field_desc['type']);
if (!is_null($field_desc['value']) && $field_desc['value'] !== '') {
$sqlfields[$i] .= "(".$this->sanitize($field_desc['value']).")";
}
if (!is_null($field_desc['attribute']) && $field_desc['attribute'] !== '') {
$sqlfields[$i] .= " ".$this->sanitize($field_desc['attribute']);
}
if (!is_null($field_desc['default']) && $field_desc['default'] !== '') {
if (in_array($field_desc['type'], array('tinyint', 'smallint', 'int', 'double'))) {
$sqlfields[$i] .= " DEFAULT ".((float) $field_desc['default']);
} elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP') {
$sqlfields[$i] .= " DEFAULT ".$this->sanitize($field_desc['default']);
} else {
$sqlfields[$i] .= " default '".$this->escape($field_desc['default'])."'";
$sqlfields[$i] .= " DEFAULT '".$this->escape($field_desc['default'])."'";
}
} elseif (preg_match("/^[^\s]/i", $field_desc['null'])) {
$sqlfields[$i] .= " ".$field_desc['null'];
} elseif (preg_match("/^[^\s]/i", $field_desc['extra'])) {
$sqlfields[$i] .= " ".$field_desc['extra'];
}
if (!is_null($field_desc['null']) && $field_desc['null'] !== '') {
$sqlfields[$i] .= " ".$this->sanitize($field_desc['null'], 0, 0, 1);
}
if (!is_null($field_desc['extra']) && $field_desc['extra'] !== '') {
$sqlfields[$i] .= " ".$this->sanitize($field_desc['extra']);
}
$i++;
}
if ($primary_key != "") {
$pk = "primary key(".$primary_key.")";
$pk = "PRIMARY KEY(".$this->sanitize($primary_key).")";
}
if (is_array($unique_keys)) {
$i = 0;
foreach ($unique_keys as $key => $value) {
$sqluq[$i] = "UNIQUE KEY '".$key."' ('".$this->escape($value)."')";
$sqluq[$i] = "UNIQUE KEY '".$this->sanitize($key)."' ('".$this->escape($value)."')";
$i++;
}
}
if (is_array($keys)) {
$i = 0;
foreach ($keys as $key => $value) {
$sqlk[$i] = "KEY ".$key." (".$value.")";
$sqlk[$i] = "KEY ".$this->sanitize($key)." (".$value.")";
$i++;
}
}
@@ -1120,15 +1132,15 @@ class DoliDBPgsql extends DoliDB
if ($primary_key != "") {
$sql .= ",".$pk;
}
if (is_array($unique_keys)) {
if ($unique_keys != "") {
$sql .= ",".implode(',', $sqluq);
}
if (is_array($keys)) {
$sql .= ",".implode(',', $sqlk);
}
$sql .= ") type=".$type;
$sql .= ")";
//$sql .= " engine=".$this->sanitize($type);
dol_syslog($sql, LOG_DEBUG);
if (!$this->query($sql)) {
return -1;
} else {
@@ -1148,7 +1160,7 @@ class DoliDBPgsql extends DoliDB
// phpcs:enable
$tmptable = preg_replace('/[^a-z0-9\.\-\_]/i', '', $table);
$sql = "DROP TABLE ".$tmptable;
$sql = "DROP TABLE ".$this->sanitize($tmptable);
if (!$this->query($sql)) {
return -1;
@@ -1157,31 +1169,6 @@ class DoliDBPgsql extends DoliDB
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Create a user to connect to database
*
* @param string $dolibarr_main_db_host Ip server
* @param string $dolibarr_main_db_user Name of user to create
* @param string $dolibarr_main_db_pass Password of user to create
* @param string $dolibarr_main_db_name Database name where user must be granted
* @return int Return integer <0 if KO, >=0 if OK
*/
public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
{
// phpcs:enable
// Note: using ' on user does not works with pgsql
$sql = "CREATE USER ".$this->escape($dolibarr_main_db_user)." with password '".$this->escape($dolibarr_main_db_pass)."'";
dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
$resql = $this->query($sql);
if (!$resql) {
return -1;
}
return 1;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Return a pointer of line with description of a table or field
@@ -1219,30 +1206,32 @@ class DoliDBPgsql extends DoliDB
// phpcs:enable
// cles recherchees dans le tableau des descriptions (field_desc) : type,value,attribute,null,default,extra
// ex. : $field_desc = array('type'=>'int','value'=>'11','null'=>'not null','extra'=> 'auto_increment');
$sql = "ALTER TABLE ".$table." ADD ".$field_name." ";
$sql .= $field_desc['type'];
if (preg_match("/^[^\s]/i", $field_desc['value'])) {
if (!in_array($field_desc['type'], array('smallint', 'int', 'date', 'datetime')) && $field_desc['value']) {
$sql .= "(".$field_desc['value'].")";
$sql = "ALTER TABLE ".$this->sanitize($table)." ADD ".$this->sanitize($field_name)." ";
$sql .= $this->sanitize($field_desc['type']);
if (isset($field_desc['value']) && preg_match("/^[^\s]/i", $field_desc['value'])) {
if (!in_array($field_desc['type'], array('tinyint', 'smallint', 'int', 'date', 'datetime')) && $field_desc['value']) {
$sql .= "(".$this->sanitize($field_desc['value']).")";
}
}
if (preg_match("/^[^\s]/i", $field_desc['attribute'])) {
$sql .= " ".$field_desc['attribute'];
if (isset($field_desc['attribute']) && preg_match("/^[^\s]/i", $field_desc['attribute'])) {
$sql .= " ".$this->sanitize($field_desc['attribute']);
}
if (preg_match("/^[^\s]/i", $field_desc['null'])) {
if (isset($field_desc['null']) && preg_match("/^[^\s]/i", $field_desc['null'])) {
$sql .= " ".$field_desc['null'];
}
if (preg_match("/^[^\s]/i", $field_desc['default'])) {
if (preg_match("/null/i", $field_desc['default'])) {
$sql .= " default ".$field_desc['default'];
if (isset($field_desc['default']) && preg_match("/^[^\s]/i", $field_desc['default'])) {
if (in_array($field_desc['type'], array('tinyint', 'smallint', 'int', 'double'))) {
$sql .= " DEFAULT ".((float) $field_desc['default']);
} elseif ($field_desc['default'] == 'null' || $field_desc['default'] == 'CURRENT_TIMESTAMP') {
$sql .= " DEFAULT ".$this->sanitize($field_desc['default']);
} else {
$sql .= " default '".$this->escape($field_desc['default'])."'";
$sql .= " DEFAULT '".$this->escape($field_desc['default'])."'";
}
}
if (preg_match("/^[^\s]/i", $field_desc['extra'])) {
$sql .= " ".$field_desc['extra'];
if (isset($field_desc['extra']) && preg_match("/^[^\s]/i", $field_desc['extra'])) {
$sql .= " ".$this->escape($field_desc['extra'], 0, 0, 1);
}
$sql .= " ".$field_position;
$sql .= " ".$this->escape($field_position, 0, 0, 1);
dol_syslog($sql, LOG_DEBUG);
if (!$this -> query($sql)) {
@@ -1263,30 +1252,30 @@ class DoliDBPgsql extends DoliDB
public function DDLUpdateField($table, $field_name, $field_desc)
{
// phpcs:enable
$sql = "ALTER TABLE ".$table;
$sql .= " ALTER COLUMN ".$this->escape($field_name)." TYPE ".$field_desc['type'];
$sql = "ALTER TABLE ".$this->sanitize($table);
$sql .= " ALTER COLUMN ".$this->sanitize($field_name)." TYPE ".$this->sanitize($field_desc['type']);
if (preg_match("/^[^\s]/i", $field_desc['value'])) {
if (!in_array($field_desc['type'], array('smallint', 'int', 'date', 'datetime')) && $field_desc['value']) {
$sql .= "(".$field_desc['value'].")";
$sql .= "(".$this->sanitize($field_desc['value']).")";
}
}
if ($field_desc['null'] == 'not null' || $field_desc['null'] == 'NOT NULL') {
// 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
if ($field_desc['type'] == 'varchar' || $field_desc['type'] == 'text') {
$sqlbis = "UPDATE ".$table." SET ".$this->escape($field_name)." = '".$this->escape(isset($field_desc['default']) ? $field_desc['default'] : '')."' WHERE ".$this->escape($field_name)." IS NULL";
$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";
$this->query($sqlbis);
} elseif ($field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') {
$sqlbis = "UPDATE ".$table." SET ".$this->escape($field_name)." = ".((int) $this->escape(isset($field_desc['default']) ? $field_desc['default'] : 0))." WHERE ".$this->escape($field_name)." IS NULL";
} elseif (in_array($field_desc['type'], array('tinyint', 'smallint', 'int', 'double'))) {
$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";
$this->query($sqlbis);
}
}
if (isset($field_desc['default']) && $field_desc['default'] != '') {
if ($field_desc['type'] == 'double' || $field_desc['type'] == 'tinyint' || $field_desc['type'] == 'int') {
$sql .= " DEFAULT ".$this->escape($field_desc['default']);
} elseif ($field_desc['type'] != 'text') {
$sql .= " DEFAULT '".$this->escape($field_desc['default'])."'"; // Default not supported on text fields
if (in_array($field_desc['type'], array('tinyint', 'smallint', 'int', 'double'))) {
$sql .= ", ALTER COLUMN ".$this->sanitize($field_name)." SET DEFAULT ".((float) $field_desc['default']);
} elseif ($field_desc['type'] != 'text') { // Default not supported on text fields ?
$sql .= ", ALTER COLUMN ".$this->sanitize($field_name)." SET DEFAULT '".$this->escape($field_desc['default'])."'";
}
}
@@ -1310,7 +1299,7 @@ class DoliDBPgsql extends DoliDB
// phpcs:enable
$tmp_field_name = preg_replace('/[^a-z0-9\.\-\_]/i', '', $field_name);
$sql = "ALTER TABLE ".$table." DROP COLUMN ".$tmp_field_name;
$sql = "ALTER TABLE ".$this->sanitize($table)." DROP COLUMN ".$this->sanitize($tmp_field_name);
if (!$this->query($sql)) {
$this->error = $this->lasterror();
return -1;
@@ -1318,6 +1307,31 @@ class DoliDBPgsql extends DoliDB
return 1;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Create a user to connect to database
*
* @param string $dolibarr_main_db_host Ip server
* @param string $dolibarr_main_db_user Name of user to create
* @param string $dolibarr_main_db_pass Password of user to create
* @param string $dolibarr_main_db_name Database name where user must be granted
* @return int Return integer <0 if KO, >=0 if OK
*/
public function DDLCreateUser($dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_pass, $dolibarr_main_db_name)
{
// phpcs:enable
// Note: using ' on user does not works with pgsql
$sql = "CREATE USER ".$this->sanitize($dolibarr_main_db_user)." with password '".$this->escape($dolibarr_main_db_pass)."'";
dol_syslog(get_class($this)."::DDLCreateUser", LOG_DEBUG); // No sql to avoid password in log
$resql = $this->query($sql);
if (!$resql) {
return -1;
}
return 1;
}
/**
* Return charset used to store data in database
*