Skip to content
Extraits de code Groupes Projets
Valider 54554461 rédigé par marcimat's avatar marcimat
Parcourir les fichiers

Ticket #4974 : proposition pour ne pas créer d’erreurs SQL simplement

pour tester la présence d’une table.
On ajoute une fonction sql_table_exists('nom_de_la_table') pour cela.
parent 8fce1d73
Branches
Étiquettes
Aucune requête de fusion associée trouvée
...@@ -53,7 +53,7 @@ function objet_associable($objet) { ...@@ -53,7 +53,7 @@ function objet_associable($objet) {
$l = ''; $l = '';
if ( if (
$primary = id_table_objet($objet) $primary = id_table_objet($objet)
and $trouver_table($l = $table_sql . '_liens') and $trouver_table($l = $table_sql . '_liens', '', true, ['log_missing' => false])
and !preg_match(',[^\w],', $primary) and !preg_match(',[^\w],', $primary)
and !preg_match(',[^\w],', $l) and !preg_match(',[^\w],', $l)
) { ) {
......
...@@ -1238,6 +1238,49 @@ function sql_showtable($table, $table_spip = false, $serveur = '', $option = tru ...@@ -1238,6 +1238,49 @@ function sql_showtable($table, $table_spip = false, $serveur = '', $option = tru
return $f; return $f;
} }
/**
* Teste si une table SQL existe ou non dans la base
*
* @api
*
* @param string $table
* Nom de la table
* @param bool $table_spip
* true pour remplacer automatiquement « spip » par le vrai préfixe de table
* @param string $serveur
* Nom du connecteur
* @param bool|string $option
* Peut avoir 3 valeurs :
*
* - false : ne pas l'exécuter mais la retourner,
* - true : exécuter la requête
* - 'continue' : ne pas échouer en cas de serveur sql indisponible
* @return bool|string
* - True si la table existe,
* - False sinon,
* - Texte de la requête si demandé,
* - False en cas d'erreur.
**/
function sql_table_exists(string $table, bool $table_spip = true, $serveur = '', $option = true) {
$f = sql_serveur('table_exists', $serveur, $option === 'continue' or $option === false);
if (!is_string($f) or !$f) {
return false;
}
// la globale n'est remplie qu'apres l'appel de sql_serveur.
if ($table_spip) {
$connexion = $GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
$prefixe = $connexion['prefixe'];
$vraie_table = prefixer_table_spip($table, $prefixe);
} else {
$vraie_table = $table;
}
return $f($vraie_table, $serveur, $option !== false);
}
/** /**
* Crée une table dans la base de données * Crée une table dans la base de données
* *
......
...@@ -51,6 +51,10 @@ include_spip('base/objets'); ...@@ -51,6 +51,10 @@ include_spip('base/objets');
* Nom du connecteur * Nom du connecteur
* @param bool $table_spip * @param bool $table_spip
* Indique s'il faut transformer le préfixe de table * Indique s'il faut transformer le préfixe de table
* @param array $options
* - bool log_missing:
* true: (par défaut) pour écrire un log en cas de table absente.
* false: log uniquement en niveau debug.
* @return array|bool * @return array|bool
* false si table introuvable * false si table introuvable
* tableau de description de la table sinon, en particulier : * tableau de description de la table sinon, en particulier :
...@@ -63,7 +67,7 @@ include_spip('base/objets'); ...@@ -63,7 +67,7 @@ include_spip('base/objets');
* *
* *
**/ **/
function base_trouver_table_dist($nom, $serveur = '', $table_spip = true) { function base_trouver_table_dist($nom, $serveur = '', $table_spip = true, array $options = []) {
static $nom_cache_desc_sql = []; static $nom_cache_desc_sql = [];
if ( if (
...@@ -73,6 +77,11 @@ function base_trouver_table_dist($nom, $serveur = '', $table_spip = true) { ...@@ -73,6 +77,11 @@ function base_trouver_table_dist($nom, $serveur = '', $table_spip = true) {
return null; return null;
} }
$options = $options + [
// si false, baissera le niveau de log si une table demandée n’existe pas
'log_missing' => true,
];
$connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0]; $connexion = &$GLOBALS['connexions'][$serveur ? strtolower($serveur) : 0];
$objets_sql = lister_tables_objets_sql('::md5'); $objets_sql = lister_tables_objets_sql('::md5');
...@@ -151,10 +160,15 @@ function base_trouver_table_dist($nom, $serveur = '', $table_spip = true) { ...@@ -151,10 +160,15 @@ function base_trouver_table_dist($nom, $serveur = '', $table_spip = true) {
} }
if (!isset($connexion['tables'][$nom_sql])) { if (!isset($connexion['tables'][$nom_sql])) {
// La *vraie* base a la priorite // La *vraie* base a la priorite
$desc = sql_showtable($nom_sql, $table_spip, $serveur); $exists = sql_table_exists($nom_sql, $table_spip, $serveur);
if (!$desc or !$desc['field']) { if (
!$exists
or !$desc = sql_showtable($nom_sql, $table_spip, $serveur)
or !$desc['field']
) {
if (!$fdesc) { if (!$fdesc) {
spip_log("trouver_table: table inconnue '$serveur' '$nom'", 'base' . _LOG_INFO_IMPORTANTE); $log_level = $options['log_missing'] ? _LOG_INFO_IMPORTANTE : _LOG_DEBUG;
spip_log("trouver_table: table inconnue '$serveur' '$nom'", 'base' . $log_level);
return null; return null;
} }
......
...@@ -129,6 +129,7 @@ $GLOBALS['spip_mysql_functions_1'] = [ ...@@ -129,6 +129,7 @@ $GLOBALS['spip_mysql_functions_1'] = [
'get_charset' => 'spip_mysql_get_charset', 'get_charset' => 'spip_mysql_get_charset',
'showbase' => 'spip_mysql_showbase', 'showbase' => 'spip_mysql_showbase',
'showtable' => 'spip_mysql_showtable', 'showtable' => 'spip_mysql_showtable',
'table_exists' => 'spip_mysql_table_exists',
'update' => 'spip_mysql_update', 'update' => 'spip_mysql_update',
'updateq' => 'spip_mysql_updateq', 'updateq' => 'spip_mysql_updateq',
...@@ -866,6 +867,27 @@ function spip_mysql_repair($table, $serveur = '', $requeter = true) { ...@@ -866,6 +867,27 @@ function spip_mysql_repair($table, $serveur = '', $requeter = true) {
return spip_mysql_query("REPAIR TABLE `$table`", $serveur, $requeter); return spip_mysql_query("REPAIR TABLE `$table`", $serveur, $requeter);
} }
/**
* Indique si une table existe dans la base de données
*
* @param string $table
* Table dont on cherche l’existence
* @param string $serveur
* Connecteur de la base
* @param bool $requeter
* true pour éxecuter la requête
* false pour retourner le texte de la requête.
* @return ressource
* Ressource à utiliser avec sql_fetch()
**/
function spip_mysql_table_exists(string $table, $serveur = '', $requeter = true) {
$r = spip_mysql_query('SHOW TABLES LIKE ' . _q($table), $serveur, $requeter);
if (!$requeter) {
return $r;
}
$res = spip_mysql_fetch($r);
return (bool) $res;
}
define('_MYSQL_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/'); define('_MYSQL_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/');
/** /**
......
...@@ -1693,6 +1693,35 @@ function spip_sqlite_showbase($match, $serveur = '', $requeter = true) { ...@@ -1693,6 +1693,35 @@ function spip_sqlite_showbase($match, $serveur = '', $requeter = true) {
); );
} }
/**
* Indique si une table existe dans la base de données
*
* @param string $table
* Table dont on cherche l’existence
* @param string $serveur
* Connecteur de la base
* @param bool $requeter
* true pour éxecuter la requête
* false pour retourner le texte de la requête.
* @return ressource
* Ressource à utiliser avec sql_fetch()
**/
function spip_sqlite_table_exists(string $table, $serveur = '', $requeter = true) {
$r = spip_sqlite_query(
'SELECT name FROM sqlite_master WHERE'
. ' type=\'table\''
. ' AND name=' . spip_sqlite_quote($table, 'string')
. ' AND name NOT LIKE \'sqlite_%\'',
$serveur,
$requeter
);
if (!$requeter) {
return $r;
}
$res = spip_sqlite_fetch($r);
return (bool) $res;
}
define('_SQLITE_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/'); define('_SQLITE_RE_SHOW_TABLE', '/^[^(),]*\(((?:[^()]*\((?:[^()]*\([^()]*\))?[^()]*\)[^()]*)*[^()]*)\)[^()]*$/');
/** /**
* Obtient la description d'une table ou vue SQLite * Obtient la description d'une table ou vue SQLite
...@@ -2434,6 +2463,7 @@ function _sqlite_ref_fonctions() { ...@@ -2434,6 +2463,7 @@ function _sqlite_ref_fonctions() {
'get_charset' => 'spip_sqlite_get_charset', 'get_charset' => 'spip_sqlite_get_charset',
'showbase' => 'spip_sqlite_showbase', 'showbase' => 'spip_sqlite_showbase',
'showtable' => 'spip_sqlite_showtable', 'showtable' => 'spip_sqlite_showtable',
'table_exists' => 'spip_sqlite_table_exists',
'update' => 'spip_sqlite_update', 'update' => 'spip_sqlite_update',
'updateq' => 'spip_sqlite_updateq', 'updateq' => 'spip_sqlite_updateq',
'preferer_transaction' => 'spip_sqlite_preferer_transaction', 'preferer_transaction' => 'spip_sqlite_preferer_transaction',
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter