예제 #1
0
/**
 * 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;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
/**
 * 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('');
}