Newer
Older
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
* *
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
* Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
\***************************************************************************/
// infos :
// il ne faut pas avoir de PDO::CONSTANTE dans ce fichier sinon php4 se tue !
// idem, il ne faut pas de $obj->toto()->toto sinon php4 se tue !
# todo : get/set_caracteres ?
/*
*
* regroupe le maximum de fonctions qui peuvent cohabiter
* D'abord les fonctions d'abstractions de SPIP
*
*/
function req_sqlite_dist($addr, $port, $login, $pass, $db='', $prefixe='', $sqlite_version=''){
static $last_connect = array();
// si provient de selectdb
// un code pour etre sur que l'on vient de select_db()
if (strpos($db, $code = '@selectdb@')!==false) {
foreach (array('addr','port','login','pass','prefixe') as $a){
$$a = $last_connect[$a];
}
$db = str_replace($code, '', $db);
}
/*
* En sqlite, seule l'adresse du fichier est importante.
cerdic
a validé
* Ce sera $db le nom,
* le path est $addr
* (_DIR_DB si $addr est vide)
cerdic
a validé
// determiner le dossier de la base : $addr ou _DIR_DB
$f = _DIR_DB;
if ($addr AND strpos($addr,'/')!==false)
cerdic
a validé
$f = rtrim($addr,'/').'/';
// un nom de base demande et impossible d'obtenir la base, on s'en va
cerdic
a validé
if ($db AND !is_file($f .= $db . '.sqlite') AND !is_writable(dirname($f)))
// charger les modules sqlite au besoin
if (!_sqlite_charger_version($sqlite_version)) {
spip_log("Impossible de trouver/charger le module SQLite ($sqlite_version)!");
return false;
}
// chargement des constantes
// il ne faut pas definir les constantes avant d'avoir charge les modules sqlite
$define = "spip_sqlite".$sqlite_version."_constantes";
$define();
$ok = false;
if (!$db){
// si installation -> base temporaire tant qu'on ne connait pas son vrai nom
if (defined('_ECRIRE_INSTALL') && _ECRIRE_INSTALL){
// creation d'une base temporaire pour le debut d'install
$db = "_sqlite".$sqlite_version."_install";
$tmp = _DIR_DB . $db . ".sqlite";
marcimat
a validé
if ($sqlite_version == 3) {
marcimat
a validé
} else {
$ok = $link = sqlite_open($tmp, _SQLITE_CHMOD, $err);
marcimat
a validé
}
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// sinon, on arrete finalement
} else {
return false;
}
} else {
// Ouvrir (eventuellement creer la base)
// si pas de version fourni, on essaie la 3, sinon la 2
if ($sqlite_version == 3) {
$ok = $link = new PDO("sqlite:$f");
} else {
$ok = $link = sqlite_open($f, _SQLITE_CHMOD, $err);
}
}
if (!$ok){
spip_log("Impossible d'ouvrir la base de donnee SQLite ($sqlite_version) : $f ");
return false;
}
if ($link) {
$last_connect = array (
'addr' => $addr,
'port' => $port,
'login' => $login,
'pass' => $pass,
'db' => $db,
'prefixe' => $prefixe,
);
}
return array(
'db' => $db,
'prefixe' => $prefixe ? $prefixe : $db,
'link' => $link,
);
}
// Fonction de requete generale, munie d'une trace a la demande
cerdic
a validé
function spip_sqlite_query($query, $serveur='',$requeter=true) {
#spip_log("spip_sqlite_query() > $query");
_sqlite_init();
$requete = new sqlite_traiter_requete($query, $serveur);
$requete->traduire_requete(); // mysql -> sqlite
cerdic
a validé
if (!$requeter) return $requete->query;
return $requete->executer_requete();
}
/* ordre alphabetique pour les autres */
cerdic
a validé
function spip_sqlite_alter($query, $serveur='',$requeter=true){
cerdic
a validé
$query = spip_sqlite_query("ALTER $query",$serveur,false);
/*
* la il faut faire les transformations
* si ALTER TABLE x (DROP|CHANGE) y
*
* 1) recuperer "ALTER TABLE table "
* 2) spliter les sous requetes (,)
* 3) faire chaque requete independemment
*/
// 1
if (preg_match("/\s*(ALTER(\s*IGNORE)?\s*TABLE\s*([^\s]*))\s*(.*)?/is", $query, $regs)){
$debut = $regs[1];
$table = $regs[3];
$suite = $regs[4];
spip_log("SQLite : Probleme de ALTER TABLE mal forme dans $query", 'sqlite');
return false;
// 2
// il faudrait une regexp pour eviter de spliter ADD PRIMARY KEY (colA, colB)
// tout en cassant "ADD PRIMARY KEY (colA, colB), ADD INDEX (chose)"... en deux
// ou revoir l'api de sql_alter en creant un
// sql_alter_table($table,array($actions));
$todo = explode(',', $suite);
// on remet les morceaux dechires ensembles... que c'est laid !
$todo2 = array(); $i=0;
while ($do = array_shift($todo)) {
$todo2[$i] = isset($todo2[$i]) ? $todo2[$i] . "," . $do : $do;
$o=(false!==strpos($do,"("));
$f=(false!==strpos($do,")"));
if ($o AND !$f) $ouverte=true;
// 3
$resultats = array();
$do = trim($do);
if (!preg_match('/(DROP PRIMARY KEY|DROP INDEX|DROP COLUMN|DROP'
.'|CHANGE COLUMN|CHANGE|MODIFY|RENAME TO|RENAME'
.'|ADD PRIMARY KEY|ADD INDEX|ADD COLUMN|ADD'
.')\s*([^\s]*)\s*(.*)?/', $do, $matches)){
spip_log("SQLite : Probleme de ALTER TABLE, utilisation non reconnue dans : $do \n(requete d'origine : $query)", 'sqlite');
return false;
}
$cle = strtoupper($matches[1]);
$colonne_origine = $matches[2];
$colonne_destination = '';
$def = $matches[3];
switch($cle){
// suppression d'un index
case 'DROP INDEX':
$nom_index = $colonne_origine;
spip_sqlite_drop_index($nom_index, $table, $serveur);
break;
// suppression d'une pk
case 'DROP PRIMARY KEY':
if (!_sqlite_modifier_table(
$table,
$colonne_origine,
array('key'=>array('PRIMARY KEY'=>'')),
$serveur)){
return false;
}
break;
// suppression d'une colonne
case 'DROP COLUMN':
case 'DROP':
if (!_sqlite_modifier_table(
$table,
array($colonne_origine=>""),
'',
$serveur)){
return false;
}
break;
case 'CHANGE COLUMN':
case 'CHANGE':
// recuperer le nom de la future colonne
$def = trim($def);
$colonne_destination = substr($def, 0, strpos($def,' '));
$def = substr($def, strlen($colonne_destination)+1);
if (!_sqlite_modifier_table(
$table,
array($colonne_origine=>$colonne_destination),
array('field'=>array($colonne_destination=>$def)),
$serveur)){
return false;
}
break;
case 'MODIFY':
if (!_sqlite_modifier_table(
$table,
$colonne_origine,
$serveur)){
return false;
}
break;
// pas geres en sqlite2
case 'RENAME':
$do = "RENAME TO" . substr($do,6);
case 'RENAME TO':
if (_sqlite_is_version(3, '', $serveur)){
$requete = new sqlite_traiter_requete("$debut $do", $serveur);
if (!$requete->executer_requete()){
spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite');
return false;
}
// artillerie lourde pour sqlite2 !
} else {
$table_dest = trim(substr($do, 9));
if (!_sqlite_modifier_table(array($table=>$table_dest), '', '', $serveur)){
spip_log("SQLite : Erreur ALTER TABLE / RENAME : $query", 'sqlite');
return false;
}
}
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// ajout d'une pk
case 'ADD PRIMARY KEY':
$pk = trim(substr($do,16));
$pk = ($pk[0]=='(') ? substr($pk,1,-1) : $pk;
if (!_sqlite_modifier_table(
$table,
$colonne_origine,
array('key'=>array('PRIMARY KEY'=>$pk)),
$serveur)){
return false;
}
break;
// ajout d'un index
case 'ADD INDEX':
// peut etre "(colonne)" ou "nom_index (colonnes)"
// bug potentiel si qqn met "(colonne, colonne)"
//
// nom_index (colonnes)
if ($def) {
$colonnes = substr($def,1,-1);
$nom_index = $colonne_origine;
}
else {
// (colonne)
if ($colonne_origine[0] == "(") {
$colonnes = substr($colonne_origine,1,-1);
if (false!==strpos(",",$colonnes)) {
spip_log("SQLite : Erreur, impossible de creer un index sur plusieurs colonnes"
." sans qu'il ait de nom ($table, ($colonnes))", 'sqlite');
break;
} else {
$nom_index = $colonnes;
}
}
// nom_index
else {
$nom_index = $colonnes = $colonne_origine ;
}
}
spip_sqlite_create_index($nom_index, $table, $colonnes, $serveur);
break;
// pas geres en sqlite2
case 'ADD COLUMN':
$do = "ADD".substr($do, 10);
case 'ADD':
default:
$do = $matches[1];
}
if (_sqlite_is_version(3, '', $serveur)){
$requete = new sqlite_traiter_requete("$debut $do", $serveur);
if (!$requete->executer_requete()){
spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite');
return false;
}
break;
// artillerie lourde pour sqlite2 !
} else {
$def = trim(substr($do, 3));
$colonne_ajoutee = substr($def, 0, strpos($def,' '));
$def = substr($def, strlen($colonne_ajoutee)+1);
if (!_sqlite_modifier_table($table, array($colonne_ajoutee), array('field'=>array($colonne_ajoutee=>$def)), $serveur)){
spip_log("SQLite : Erreur ALTER TABLE / ADD : $query", 'sqlite');
return false;
}
}
break;
}
// tout est bon, ouf !
spip_log("SQLite ($serveur) : Changements OK : $debut $do");
}
spip_log("SQLite ($serveur) : fin ALTER TABLE OK !");
return true;
}
// Fonction de creation d'une table SQL nommee $nom
cerdic
a validé
function spip_sqlite_create($nom, $champs, $cles, $autoinc=false, $temporary=false, $serveur='',$requeter=true) {
$query = _sqlite_requete_create($nom, $champs, $cles, $autoinc, $temporary, $ifnotexists=true, $serveur, $requeter);
if (!$query) return false;
$res = spip_sqlite_query($query, $serveur, $requeter);
// SQLite ne cree pas les KEY sur les requetes CREATE TABLE
// il faut donc les faire creer ensuite
if (!$requeter) return $res;
$ok = $res ? true : false;
if ($ok) {
foreach($cles as $k=>$v) {
if (strpos($k, "KEY ") === 0) {
$index = preg_replace("/KEY +/", '',$k);
$ok &= $res = spip_sqlite_create_index($index, $nom, $v, $serveur);
}
}
}
return $ok ? true : false;
/**
* Fonction pour creer une base de donnees SQLite
*
* @param string $nom le nom de la base (sans l'extension de fichier)
* @param string $serveur le nom de la connexion
* @param string $option options
*
* @return bool true si la base est creee.
**/
function spip_sqlite_create_base($nom, $serveur='', $option=true) {
cerdic
a validé
$f = $nom . '.sqlite';
if (strpos($nom, "/")===false)
$f = _DIR_DB . $f;
if (_sqlite_is_version(2, '', $serveur)) {
$ok = new sqlite_open($f, _SQLITE_CHMOD, $err);
} else {
$ok = new PDO("sqlite:$f");
}
if ($ok) {
unset($ok);
return true;
}
unset($ok);
return false;
}
// Fonction de creation d'une vue SQL nommee $nom
function spip_sqlite_create_view($nom, $query_select, $serveur='',$requeter=true) {
if (!$query_select) return false;
// vue deja presente
if (sql_showtable($nom, false, $serveur)) {
spip_log("Echec creation d'une vue sql ($nom) car celle-ci existe deja (serveur:$serveur)");
return false;
}
$query = "CREATE VIEW $nom AS ". $query_select;
return spip_sqlite_query($query, $serveur, $requeter);
}
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
/**
* Fonction de creation d'un INDEX
*
* @param string $nom : nom de l'index
* @param string $table : table sql de l'index
* @param string/array $champs : liste de champs sur lesquels s'applique l'index
* @param string $serveur : nom de la connexion sql utilisee
* @param bool $requeter : true pour executer la requete ou false pour retourner le texte de la requete
*
* @return bool ou requete
*/
function spip_sqlite_create_index($nom, $table, $champs, $serveur='', $requeter=true) {
if (!($nom OR $table OR $champs)) {
spip_log("Champ manquant pour creer un index sqlite ($nom, $table, (".join(',',$champs)."))");
return false;
}
// SQLite ne differentie pas noms des index en fonction des tables
// il faut donc creer des noms uniques d'index pour une base sqlite
$nom = $table.'_'.$nom;
// enlever d'eventuelles parentheses deja presentes sur champs
if (!is_array($champs)){
if ($champs[0]=="(") $champs = substr($champs,1,-1);
$champs = array($champs);
}
$query = "CREATE INDEX $nom ON $table (" . join(',',$champs) . ")";
$res = spip_sqlite_query($query, $serveur, $requeter);
if (!$requeter) return $res;
if ($res)
// en PDO/sqlite3, il faut calculer le count par une requete count(*)
// pour les resultats de SELECT
// cela est fait sans spip_sqlite_query()
cerdic
a validé
function spip_sqlite_count($r, $serveur='',$requeter=true) {
if (!$r) return 0;
if (_sqlite_is_version(3, '', $serveur)){
// select ou autre (insert, update,...) ?
if (isset($r->spipSqliteRowCount)) {
// Ce compte est faux s'il y a des limit dans la requete :(
// il retourne le nombre d'enregistrements sans le limit
return $r->spipSqliteRowCount;
} else {
return $r->rowCount();
}
} else {
return sqlite_num_rows($r);
}
}
function spip_sqlite_countsel($from = array(), $where = array(), $groupby = '', $having = array(), $serveur='',$requeter=true) {
$c = !$groupby ? '*' : ('DISTINCT ' . (is_string($groupby) ? $groupby : join(',', $groupby)));
$r = spip_sqlite_select("COUNT($c)", $from, $where,'', '', $limit,
cerdic
a validé
$having, $serveur, $requeter);
if ((is_resource($r) or is_object($r)) && $requeter) { // ressource : sqlite2, object : sqlite3
if (_sqlite_is_version(3,'',$serveur)){
list($r) = spip_sqlite_fetch($r, SPIP_SQLITE3_NUM, $serveur);
} else {
list($r) = spip_sqlite_fetch($r, SPIP_SQLITE2_NUM, $serveur);
}
}
return $r;
}
cerdic
a validé
function spip_sqlite_delete($table, $where='', $serveur='',$requeter=true) {
return spip_sqlite_query(
_sqlite_calculer_expression('DELETE FROM', $table, ',')
. _sqlite_calculer_expression('WHERE', $where),
cerdic
a validé
$serveur, $requeter);
cerdic
a validé
function spip_sqlite_drop_table($table, $exist='', $serveur='',$requeter=true) {
/* simuler le IF EXISTS - version 2 */
if ($exist && _sqlite_is_version(2, '', $serveur)){
$a = spip_sqlite_showtable($table, $serveur);
if (!$a) return true;
$exist = '';
}
if (spip_sqlite_query("DROP TABLE$exist $table", $serveur, $requeter))
return true;
else
return false;
// supprime une vue
function spip_sqlite_drop_view($view, $exist='', $serveur='',$requeter=true) {
if ($exist) $exist =" IF EXISTS";
/* simuler le IF EXISTS - version 2 */
if ($exist && _sqlite_is_version(2, '', $serveur)){
$a = spip_sqlite_showtable($view, $serveur);
if (!$a) return true;
$exist = '';
}
return spip_sqlite_query("DROP VIEW$exist $view", $serveur, $requeter);
}
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
/**
* Fonction de suppression d'un INDEX
*
* @param string $nom : nom de l'index
* @param string $table : table sql de l'index
* @param string $serveur : nom de la connexion sql utilisee
* @param bool $requeter : true pour executer la requete ou false pour retourner le texte de la requete
*
* @return bool ou requete
*/
function spip_sqlite_drop_index($nom, $table, $serveur='', $requeter=true) {
if (!($nom OR $table)) {
spip_log("Champ manquant pour supprimer un index sqlite ($nom, $table)");
return false;
}
// SQLite ne differentie pas noms des index en fonction des tables
// il faut donc creer des noms uniques d'index pour une base sqlite
$index = $table.'_'.$nom;
$exist =" IF EXISTS";
/* simuler le IF EXISTS - version 2 */
if (_sqlite_is_version(2, '', $serveur)){
$a = spip_sqlite_showtable($table, $serveur);
if (!isset($a['key']['KEY '.$nom])) return true;
$exist = '';
}
$query = "DROP INDEX$exist $index";
return spip_sqlite_query($query, $serveur, $requeter);
}
marcimat
a validé
/**
* Retourne la derniere erreur generee
*
* @param $serveur nom de la connexion
* @return string erreur eventuelle
**/
marcimat
a validé
function spip_sqlite_error($serveur='') {
marcimat
a validé
if (_sqlite_is_version(3, $link)) {
$errs = $link->errorInfo();
$s = '';
foreach($errs as $n=>$e){
$s .= "\n$n : $e";
}
} elseif ($link) {
$s = sqlite_error_string(sqlite_last_error($link));
} else {
$s = ": aucune ressource sqlite (link)";
}
if ($s) spip_log("$s - $query", 'sqlite');
return $s;
}
marcimat
a validé
/**
* Retourne le numero de la derniere erreur SQL
* (sauf que SQLite semble ne connaitre que 0 ou 1)
*
* @param $serveur nom de la connexion
* @return int 0 pas d'erreur / 1 une erreur
**/
marcimat
a validé
function spip_sqlite_errno($serveur='') {
$link = _sqlite_link($serveur);
if (_sqlite_is_version(3, $link)){
$t = $link->errorInfo();
$s = $t[1];
} elseif ($link) {
$s = sqlite_last_error($link);
} else {
$s = ": aucune ressource sqlite (link)";
}
if ($s) spip_log("Erreur sqlite $s");
return $s ? 1 : 0;
cerdic
a validé
function spip_sqlite_explain($query, $serveur='',$requeter=true){
if (strpos(ltrim($query), 'SELECT') !== 0) return array();
$requete = new sqlite_traiter_requete("$query", $serveur);
$requete->traduire_requete(); // mysql -> sqlite
$requete->query = 'EXPLAIN ' . $requete->query;
cerdic
a validé
if (!$requeter) return $requete;
// on ne trace pas ces requetes, sinon on obtient un tracage sans fin...
$requete->tracer = false;
$r = $requete->executer_requete();
return $r ? spip_sqlite_fetch($r, null, $serveur) : false; // hum ? etrange ca... a verifier
}
cerdic
a validé
function spip_sqlite_fetch($r, $t='', $serveur='',$requeter=true) {
$link = _sqlite_link($serveur);
if (!$t) {
if (_sqlite_is_version(3, $link)) {
$t = SPIP_SQLITE3_ASSOC;
} else {
$t = SPIP_SQLITE2_ASSOC;
}
}
if (_sqlite_is_version(3, $link)){
if ($r) $retour = $r->fetch($t);
} elseif ($r) {
$retour = sqlite_fetch_array($r, $t);
}
// les version 2 et 3 parfois renvoie des 'table.titre' au lieu de 'titre' tout court ! pff !
// suppression de 'table.' pour toutes les cles (c'est un peu violent !)
if ($retour){
$new = array();
foreach ($retour as $cle=>$val){
if (($pos = strpos($cle, '.'))!==false){
$cle = substr($cle,++$pos);
}
$new[$cle] = $val;
}
$retour = &$new;
}
return $retour;
}
cerdic
a validé
function spip_sqlite_seek($r, $row_number, $serveur='',$requeter=true) {
if ($r){
$link = _sqlite_link($serveur);
if (_sqlite_is_version(3, $link)){
// encore un truc de bien fichu : PDO ne PEUT PAS faire de seek ou de rewind...
// je me demande si pour sqlite 3 il ne faudrait pas mieux utiliser
// les nouvelles fonctions sqlite3_xx (mais encore moins presentes...)
return false;
cerdic
a validé
}
else {
return sqlite_seek($r, $row_number);
cerdic
a validé
}
}
}
function spip_sqlite_free(&$r, $serveur='',$requeter=true) {
unset($r);
return true;
//return sqlite_free_result($r);
}
cerdic
a validé
function spip_sqlite_get_charset($charset=array(), $serveur='',$requeter=true){
//$c = !$charset ? '' : (" LIKE "._q($charset['charset']));
//return spip_sqlite_fetch(sqlite_query(_sqlite_link($serveur), "SHOW CHARACTER SET$c"), NULL, $serveur);
}
cerdic
a validé
function spip_sqlite_in($val, $valeurs, $not='', $serveur='',$requeter=true) {
$n = $i = 0;
$in_sql ="";
while ($n = strpos($valeurs, ',', $n+1)) {
if ((++$i) >= 255) {
$in_sql .= "($val $not IN (" .
substr($valeurs, 0, $n) .
"))\n" .
($not ? "AND\t" : "OR\t");
$valeurs = substr($valeurs, $n+1);
$i = $n = 0;
}
}
$in_sql .= "($val $not IN ($valeurs))";
return "($in_sql)";
}
cerdic
a validé
function spip_sqlite_insert($table, $champs, $valeurs, $desc='', $serveur='',$requeter=true) {
$connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0];
$prefixe = $connexion['prefixe'];
$sqlite = $connexion['link'];
$db = $connexion['db'];
if ($prefixe) $table = preg_replace('/^spip/', $prefixe, $table);
if (isset($_GET['var_profile'])) {
include_spip('public/tracer');
$t = trace_query_start();
} else $t = 0 ;
$query="INSERT OR REPLACE INTO $table ".($champs?"$champs VALUES $valeurs":"DEFAULT VALUES");
marcimat
a validé
marcimat
a validé
if (_sqlite_is_version(3, $sqlite)) $nb = $sqlite->lastInsertId();
else $nb = sqlite_last_insert_rowid($sqlite);
} else $nb = 0;
return $t ? trace_query_end($query, $t, $nb, $serveur) : $nb;
cerdic
a validé
function spip_sqlite_insertq($table, $couples=array(), $desc=array(), $serveur='',$requeter=true) {
if (!$desc) $desc = description_table($table);
if (!$desc) die("$table insertion sans description");
$fields = isset($desc['field'])?$desc['field']:array();
foreach ($couples as $champ => $val) {
$couples[$champ]= _sqlite_calculer_cite($val, $fields[$champ]);
}
// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
// si aucun champ donne pour l'insertion, on en cherche un avec un DEFAULT
// sinon sqlite3 ne veut pas inserer
$cles = $valeurs = "";
if (count($couples)) {
$cles = "(".join(',',array_keys($couples)).")";
$valeurs = "(".join(',', $couples).")";
}
return spip_sqlite_insert($table, $cles , $valeurs , $desc, $serveur, $requeter);
function spip_sqlite_insertq_multi($table, $tab_couples=array(), $desc=array(), $serveur='',$requeter=true) {
foreach ($tab_couples as $couples) {
$retour = spip_sqlite_insertq($table, $couples, $desc, $serveur, $requeter);
}
// renvoie le dernier id d'autoincrement ajoute
return $retour;
}
cerdic
a validé
function spip_sqlite_listdbs($serveur='',$requeter=true) {
_sqlite_init();
if (!is_dir($d = substr(_DIR_DB,0,-1))){
return array();
}
include_spip('inc/flock');
$bases = preg_files($d, $pattern = '(.*)\.sqlite$');
$bds = array();
foreach($bases as $b){
// pas de bases commencant pas sqlite
// (on s'en sert pour l'installation pour simuler la presence d'un serveur)
// les bases sont de la forme _sqliteX_tmp_spip_install.sqlite
if (strpos($b, '_sqlite')) continue;
$bds[] = preg_replace(";.*/$pattern;iS",'$1', $b);
}
return $bds;
}
function spip_sqlite_multi ($objet, $lang) {
$r = "PREG_REPLACE("
. $objet
. ",'<multi>.*[\[]"
. $lang
. "[\]]([^\[]*).*</multi>', '$1') AS multi";
return $r;
}
marcimat
a validé
/**
* Optimise une table SQL
* Note: Sqlite optimise TOUTE un fichier sinon rien.
* On evite donc 2 traitements sur la meme base dans un hit.
*
* @param $table nom de la table a optimiser
* @param $serveur nom de la connexion
* @param $requeter effectuer la requete ? sinon retourner son code
* @return bool|string true / false / requete
**/
marcimat
a validé
function spip_sqlite_optimize($table, $serveur='', $requeter=true) {
static $do = false;
if ($requeter and $do) {return true;}
if ($requeter) { $do = true; }
return spip_sqlite_query("VACUUM", $serveur, $requeter);
}
// avoir le meme comportement que _q()
function spip_sqlite_quote($v, $type=''){
if (strncmp($v,'0x',2)==0 AND ctype_xdigit(substr($v,2))) return hexdec(substr($v,2));
if ($type === 'int' AND !$v) return '0';
if (is_array($v)) return join(",", array_map('spip_sqlite_quote', $v));
if (function_exists('sqlite_escape_string')) {
return "'" . sqlite_escape_string($v) . "'";
}
// trouver un link sqlite3 pour faire l'echappement
foreach ($GLOBALS['connexions'] as $s) {
if (_sqlite_is_version(3, $l = $s['link'])){
return $l->quote($v);
}
}
}
marcimat
a validé
/**
* Tester si une date est proche de la valeur d'un champ
*
* @param string $champ le nom du champ a tester
* @param int $interval valeur de l'interval : -1, 4, ...
* @param string $unite utite utilisee (DAY, MONTH, YEAR, ...)
* @return string expression SQL
**/
function spip_sqlite_date_proche($champ, $interval, $unite)
{
$op = $interval > 0 ? '>' : '<';
return "($champ $op datetime('" . date("Y-m-d H:i:s") . "', '$interval $unite'))";
function spip_sqlite_replace($table, $couples, $desc=array(), $serveur='',$requeter=true) {
if (!$desc) $desc = description_table($table);
if (!$desc) die("$table insertion sans description");
$fields = isset($desc['field'])?$desc['field']:array();
foreach ($couples as $champ => $val) {
$couples[$champ]= _sqlite_calculer_cite($val, $fields[$champ]);
}
// recherche de champs 'timestamp' pour mise a jour auto de ceux-ci
$couples = _sqlite_ajouter_champs_timestamp($table, $couples, $desc, $serveur);
return spip_sqlite_query("REPLACE INTO $table (" . join(',',array_keys($couples)) . ') VALUES (' .join(',',$couples) . ')', $serveur);
}
function spip_sqlite_replace_multi($table, $tab_couples, $desc=array(), $serveur='',$requeter=true) {
// boucler pour trainter chaque requete independemment
foreach ($tab_couples as $couples){
$retour = spip_sqlite_replace($table, $couples, $desc, $serveur,$requeter);
}
// renvoie le dernier id
return $retour;
cerdic
a validé
function spip_sqlite_select($select, $from, $where='', $groupby='', $orderby='', $limit='', $having='', $serveur='',$requeter=true) {
// version() n'est pas connu de sqlite
$select = str_replace('version()', 'sqlite_version()',$select);
// recomposer from
$from = (!is_array($from) ? $from : _sqlite_calculer_select_as($from));
$query =
_sqlite_calculer_expression('SELECT', $select, ', ')
. _sqlite_calculer_expression('FROM', $from, ', ')
. _sqlite_calculer_expression('WHERE', $where)
. _sqlite_calculer_expression('GROUP BY', $groupby, ',')
. _sqlite_calculer_expression('HAVING', $having)
. ($orderby ? ("\nORDER BY " . _sqlite_calculer_order($orderby)) :'')
. ($limit ? "\nLIMIT $limit" : '');
marcimat
a validé
return spip_sqlite_query($query, $serveur, $requeter);
cerdic
a validé
function spip_sqlite_selectdb($db, $serveur='',$requeter=true) {
_sqlite_init();
// interdire la creation d'une nouvelle base,
// sauf si on est dans l'installation
if (!is_file($f = _DIR_DB . $db . '.sqlite')
&& (!defined('_ECRIRE_INSTALL') || !_ECRIRE_INSTALL))
return false;
// se connecter a la base indiquee
// avec les identifiants connus
$index = $serveur ? $serveur : 0;
if ($link = spip_connect_db('', '', '', '', '@selectdb@' . $db , $serveur, '', '')){
if (($db==$link['db']) && $GLOBALS['connexions'][$index] = $link)
return $db;
} else {
spip_log("Impossible de selectionner la base $db", 'sqlite');
return false;
}
}
cerdic
a validé
function spip_sqlite_set_charset($charset, $serveur='',$requeter=true){
#spip_log("changement de charset sql : "."SET NAMES "._q($charset));
# return spip_sqlite_query("SET NAMES ". spip_sqlite_quote($charset), $serveur); //<-- Passe pas !
}
cerdic
a validé
function spip_sqlite_showbase($match, $serveur='',$requeter=true){
// type est le type d'entrée : table / index / view
// on ne retourne que les tables (?) et non les vues...
return spip_sqlite_query("SELECT name FROM sqlite_master WHERE type='table' AND tbl_name LIKE '$match'", $serveur, $requeter);
cerdic
a validé
function spip_sqlite_showtable($nom_table, $serveur='',$requeter=true){
marcimat
a validé
. ' (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_%'"
cerdic
a validé
$a = spip_sqlite_query($query, $serveur, $requeter);
cerdic
a validé
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 {
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.