/** * Creer la requete pour la creation d'une table * retourne la requete pour utilisation par sql_create() et sql_alter() * * http://doc.spip.org/@_sqlite_requete_create * * @param $nom * @param $champs * @param $cles * @param bool $autoinc * @param bool $temporary * @param bool $_ifnotexists * @param string $serveur * @param bool $requeter * @return bool|string */ function _sqlite_requete_create($nom, $champs, $cles, $autoinc = false, $temporary = false, $_ifnotexists = true, $serveur = '', $requeter = true) { $query = $keys = $s = $p = ''; // certains plugins declarent les tables (permet leur inclusion dans le dump) // sans les renseigner (laisse le compilo recuperer la description) if (!is_array($champs) || !is_array($cles)) { return; } // sqlite ne gere pas KEY tout court dans une requete CREATE TABLE // il faut passer par des create index // Il gere par contre primary key ! // Soit la PK est definie dans les cles, soit dans un champs $c = ""; // le champ de cle primaire if (!isset($cles[$pk = "PRIMARY KEY"]) or !($c = $cles[$pk])) { foreach ($champs as $k => $v) { if (false !== stripos($v, $pk)) { $c = $k; // on n'en a plus besoin dans field, vu que defini dans key $champs[$k] = preg_replace("/{$pk}/is", '', $champs[$k]); break; } } } if ($c) { $keys = "\n\t\t{$pk} ({$c})"; } $champs = _sqlite_remplacements_definitions_table($champs, $autoinc); foreach ($champs as $k => $v) { $query .= "{$s}\n\t\t{$k} {$v}"; $s = ","; } $ifnotexists = ""; if ($_ifnotexists) { // simuler le IF NOT EXISTS - version 2 if (_sqlite_is_version(2, '', $serveur)) { $a = spip_sqlite_showtable($nom, $serveur); if ($a) { return false; } } else { $ifnotexists = ' IF NOT EXISTS'; } } $temporary = $temporary ? ' TEMPORARY' : ''; $q = "CREATE{$temporary} TABLE{$ifnotexists} {$nom} ({$query}" . ($keys ? ",{$keys}" : '') . ")\n"; return $q; }
/** * Creer la requete pour la creation d'une table * retourne la requete pour utilisation par sql_create() et sql_alter() * * http://code.spip.net/@_sqlite_requete_create * * @param $nom * @param $champs * @param $cles * @param bool $autoinc * @param bool $temporary * @param bool $_ifnotexists * @param string $serveur * @param bool $requeter * @return bool|string */ function _sqlite_requete_create($nom, $champs, $cles, $autoinc = false, $temporary = false, $_ifnotexists = true, $serveur = '', $requeter = true) { $query = $keys = $s = $p = ''; // certains plugins declarent les tables (permet leur inclusion dans le dump) // sans les renseigner (laisse le compilo recuperer la description) if (!is_array($champs) || !is_array($cles)) { return; } // sqlite ne gere pas KEY tout court dans une requete CREATE TABLE // il faut passer par des create index // Il gere par contre primary key ! // Soit la PK est definie dans les cles, soit dans un champs $c = ""; // le champ de cle primaire if (!isset($cles[$pk = "PRIMARY KEY"]) or !($c = $cles[$pk])) { foreach ($champs as $k => $v) { if (false !== stripos($v, $pk)) { $c = $k; // on n'en a plus besoin dans field, vu que defini dans key $champs[$k] = preg_replace("/{$pk}/is", '', $champs[$k]); break; } } } if ($c) { $keys = "\n\t\t{$pk} ({$c})"; } // Pas de DEFAULT 0 sur les cles primaires en auto-increment if (isset($champs[$c]) and stripos($champs[$c], "default 0") !== false) { $champs[$c] = trim(str_ireplace("default 0", "", $champs[$c])); } $champs = _sqlite_remplacements_definitions_table($champs, $autoinc ? $c : false); foreach ($champs as $k => $v) { $query .= "{$s}\n\t\t{$k} {$v}"; $s = ","; } $ifnotexists = ""; if ($_ifnotexists) { $version = spip_sqlite_fetch(spip_sqlite_query("select sqlite_version() AS sqlite_version", $serveur), '', $serveur); if (!function_exists('spip_version_compare')) { include_spip('plugins/installer'); } if ($version and spip_version_compare($version['sqlite_version'], '3.3.0', '>=')) { $ifnotexists = ' IF NOT EXISTS'; } else { /* simuler le IF EXISTS - version 2 et sqlite < 3.3a */ $a = spip_sqlite_showtable($table, $serveur); if (isset($a['key']['KEY ' . $nom])) { return true; } } } $temporary = $temporary ? ' TEMPORARY' : ''; $q = "CREATE{$temporary} TABLE{$ifnotexists} {$nom} ({$query}" . ($keys ? ",{$keys}" : '') . ")\n"; return $q; }
/** * Mise à jour des bdd SQLite pour réparer les collation des champs texte * pour les passer en NOCASE * * @uses base_lister_toutes_tables() * @uses _sqlite_remplacements_definitions_table() **/ function maj_collation_sqlite() { include_spip('base/dump'); $tables = base_lister_toutes_tables(); // rien a faire si base non sqlite if (strncmp($GLOBALS['connexions'][0]['type'], 'sqlite', 6) !== 0) { return; } $trouver_table = charger_fonction('trouver_table', 'base'); // forcer le vidage de cache $trouver_table(''); // cas particulier spip_auteurs : retablir le collate binary sur le login $desc = $trouver_table("spip_auteurs"); spip_log("spip_auteurs : " . var_export($desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE); if (stripos($desc['field']['login'], "BINARY") === false) { spip_log("Retablir champ login BINARY sur table spip_auteurs", "maj"); sql_alter("table spip_auteurs change login login VARCHAR(255) BINARY"); $trouver_table(''); $new_desc = $trouver_table("spip_auteurs"); spip_log("Apres conversion spip_auteurs : " . var_export($new_desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE); } foreach ($tables as $table) { if (time() >= _TIME_OUT) { return; } if ($desc = $trouver_table($table)) { $desc_collate = _sqlite_remplacements_definitions_table($desc['field']); if ($d = array_diff($desc['field'], $desc_collate)) { spip_log("Table {$table} COLLATE incorrects", "maj"); // cas particulier spip_urls : // supprimer les doublons avant conversion sinon echec (on garde les urls les plus recentes) if ($table == 'spip_urls') { // par date DESC pour conserver les urls les plus recentes $data = sql_allfetsel("*", "spip_urls", '', '', 'date DESC'); $urls = array(); foreach ($data as $d) { $key = $d['id_parent'] . "::" . strtolower($d['url']); if (!isset($urls[$key])) { $urls[$key] = true; } else { spip_log("Suppression doublon dans spip_urls avant conversion : " . serialize($d), "maj." . _LOG_INFO_IMPORTANTE); sql_delete("spip_urls", "id_parent=" . sql_quote($d['id_parent']) . " AND url=" . sql_quote($d['url'])); } } } foreach ($desc['field'] as $field => $type) { if ($desc['field'][$field] !== $desc_collate[$field]) { spip_log("Conversion COLLATE table {$table}", "maj." . _LOG_INFO_IMPORTANTE); sql_alter("table {$table} change {$field} {$field} " . $desc_collate[$field]); $trouver_table(''); $new_desc = $trouver_table($table); spip_log("Apres conversion {$table} : " . var_export($new_desc['field'], true), "maj." . _LOG_INFO_IMPORTANTE); continue 2; // inutile de continuer pour cette table : un seul alter remet tout a jour en sqlite } } } } } // forcer le vidage de cache $trouver_table(''); }