Example #1
0
function spip_sqlite_showtable($nom_table, $serveur = '', $requeter = true)
{
    $query = 'SELECT sql, type FROM' . ' (SELECT * FROM sqlite_master UNION ALL' . ' SELECT * FROM sqlite_temp_master)' . " WHERE tbl_name LIKE '{$nom_table}'" . " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'" . ' ORDER BY substr(type,2,1), name';
    $a = spip_sqlite_query($query, $serveur, $requeter);
    if (!$a) {
        return "";
    }
    if (!$requeter) {
        return $a;
    }
    if (!($a = spip_sqlite_fetch($a, null, $serveur))) {
        return "";
    }
    $vue = $a['type'] == 'view';
    // table | vue
    // c'est une table
    // il faut parser le create
    if (!$vue) {
        if (!preg_match("/^[^(),]*\\((([^()]*(\\([^()]*\\))?[^()]*)*)\\)[^()]*\$/", array_shift($a), $r)) {
            return "";
        } else {
            $desc = $r[1];
            // extraction d'une KEY éventuelle en prenant garde de ne pas
            // relever un champ dont le nom contient KEY (ex. ID_WHISKEY)
            if (preg_match("/^(.*?),([^,]*KEY[ (].*)\$/s", $desc, $r)) {
                $namedkeys = $r[2];
                $desc = $r[1];
            } else {
                $namedkeys = "";
            }
            $fields = array();
            $keys = array();
            // enlever les contenus des valeurs DEFAULT 'xxx' qui pourraient perturber
            // par exemple s'il contiennent une virgule.
            // /!\ cela peut aussi echapper le nom des champs si la table a eu des operations avec SQLite Manager !
            list($desc, $echaps) = query_echappe_textes($desc);
            // separer toutes les descriptions de champs, separes par des virgules
            # /!\ explode peut exploser aussi DECIMAL(10,2) !
            foreach (explode(",", $desc) as $v) {
                preg_match("/^\\s*([^\\s]+)\\s+(.*)/", $v, $r);
                // Les cles de champs peuvent etre entourees
                // de guillements doubles " , simples ', graves ` ou de crochets [ ],  ou rien.
                // http://www.sqlite.org/lang_keywords.html
                $k = strtolower(query_reinjecte_textes($r[1], $echaps));
                // champ, "champ", [champ]...
                if ($char = strpbrk($k[0], '\'"[`')) {
                    $k = trim($k, $char);
                    if ($char == '[') {
                        $k = rtrim($k, ']');
                    }
                }
                $def = query_reinjecte_textes($r[2], $echaps);
                // valeur du champ
                # rustine pour DECIMAL(10,2)
                if (false !== strpos($k, ')')) {
                    $fields[$k_precedent] .= ',' . $k . ' ' . $def;
                    continue;
                }
                $fields[$k] = $def;
                $k_precedent = $k;
                // la primary key peut etre dans une des descriptions de champs
                // et non en fin de table, cas encore decouvert avec Sqlite Manager
                if (stripos($r[2], 'PRIMARY KEY') !== false) {
                    $keys['PRIMARY KEY'] = $k;
                }
            }
            // key inclues dans la requete
            foreach (preg_split('/\\)\\s*,?/', $namedkeys) as $v) {
                if (preg_match("/^\\s*([^(]*)\\((.*)\$/", $v, $r)) {
                    $k = str_replace("`", '', trim($r[1]));
                    $t = trim(strtolower(str_replace("`", '', $r[2])), '"');
                    if ($k && !isset($keys[$k])) {
                        $keys[$k] = $t;
                    } else {
                        $keys[] = $t;
                    }
                }
            }
            // sinon ajouter les key index
            $query = 'SELECT name,sql FROM' . ' (SELECT * FROM sqlite_master UNION ALL' . ' SELECT * FROM sqlite_temp_master)' . " WHERE tbl_name LIKE '{$nom_table}'" . " AND type='index' AND name NOT LIKE 'sqlite_%'" . 'ORDER BY substr(type,2,1), name';
            $a = spip_sqlite_query($query, $serveur, $requeter);
            while ($r = spip_sqlite_fetch($a, null, $serveur)) {
                $key = str_replace($nom_table . '_', '', $r['name']);
                // enlever le nom de la table ajoute a l'index
                $colonnes = preg_replace(',.*\\((.*)\\).*,', '$1', $r['sql']);
                $keys['KEY ' . $key] = $colonnes;
            }
        }
        // c'est une vue, on liste les champs disponibles simplement
    } else {
        if ($res = sql_fetsel('*', $nom_table, '', '', '', '1', '', $serveur)) {
            // limit 1
            $fields = array();
            foreach ($res as $c => $v) {
                $fields[$c] = '';
            }
            $keys = array();
        } else {
            return "";
        }
    }
    return array('field' => $fields, 'key' => $keys);
}
Example #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;
}
Example #3
0
function spip_sqlite_showtable($nom_table, $serveur='',$requeter=true){
	
	$query = 
			'SELECT sql, type FROM'
   			. ' (SELECT * FROM sqlite_master UNION ALL'
   			. ' SELECT * FROM sqlite_temp_master)'
			. " WHERE tbl_name LIKE '$nom_table'"
			. " AND type!='meta' AND sql NOT NULL AND name NOT LIKE 'sqlite_%'"
			. ' ORDER BY substr(type,2,1), name';
	
	$a = spip_sqlite_query($query, $serveur, $requeter);
	if (!$a) return "";
	if (!$requeter) return $a;
	if (!($a = spip_sqlite_fetch($a, null, $serveur))) return "";
	$vue = ($a['type'] == 'view'); // table | vue

	// c'est une table
	// il faut parser le create
	if (!$vue) {
		if (!preg_match("/^[^(),]*\((([^()]*(\([^()]*\))?[^()]*)*)\)[^()]*$/", array_shift($a), $r))
			return "";
		else {
			$dec = $r[1];
			if (preg_match("/^(.*?),([^,]*KEY.*)$/s", $dec, $r)) {
				$namedkeys = $r[2];
				$dec = $r[1];
			}
			else 
				$namedkeys = "";

			$fields = array();
			foreach (explode(",",$dec) as $v) {
				preg_match("/^\s*([^\s]+)\s+(.*)/",$v,$r);
				// trim car 'Sqlite Manager' (plugin Firefox) utilise des guillemets
				// lorsqu'on modifie une table avec cet outil.
				// possible que d'autres fassent de meme.
				$fields[ trim(strtolower($r[1]),'"') ] = $r[2];
			}
			// key inclues dans la requete
			$keys = array();
			foreach(preg_split('/\)\s*,?/',$namedkeys) as $v) {
				if (preg_match("/^\s*([^(]*)\((.*)$/",$v,$r)) {
					$k = str_replace("`", '', trim($r[1]));
					$t = trim(strtolower(str_replace("`", '', $r[2])), '"');
					if ($k && !isset($keys[$k])) $keys[$k] = $t; else $keys[] = $t;
				}
			}
			// sinon ajouter les key index
			$query = 
				'SELECT name,sql FROM'
				. ' (SELECT * FROM sqlite_master UNION ALL'
				. ' SELECT * FROM sqlite_temp_master)'
				. " WHERE tbl_name LIKE '$nom_table'"
				. " AND type='index' AND name NOT LIKE 'sqlite_%'"
				. 'ORDER BY substr(type,2,1), name';
			$a = spip_sqlite_query($query, $serveur, $requeter);
			while ($r = spip_sqlite_fetch($a, null, $serveur)) {
				$key = str_replace($nom_table.'_','',$r['name']); // enlever le nom de la table ajoute a l'index
				$colonnes = preg_replace(',.*\((.*)\).*,','$1',$r['sql']);
				$keys['KEY '.$key] = $colonnes;
			}			
		}
	// c'est une vue, on liste les champs disponibles simplement
	} else {
		if ($res = sql_fetsel('*',$nom_table,'','','','1','',$serveur)){ // limit 1
			$fields = array();
			foreach($res as $c=>$v) $fields[$c]='';
			$keys = array();		
		} else {	
			return "";	
		}
	}
	return array('field' => $fields, 'key' => $keys);
	
}