Subversion Repositories Applications.framework

Rev

Rev 288 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
269 jpm 1
<?php
2
class CacheSqlite {
3
	/**
282 jpm 4
	 * Options disponibles :
269 jpm 5
	 *
282 jpm 6
	 * ====> (string) stockage_chemin :
7
	 * Chemin vers le fichier contenant la base SQLite.
8
	 *
269 jpm 9
	 *
282 jpm 10
	 * ====> (int) defragmentation_auto :
11
	 * - Désactive / Régler le processus de défragmentation automatique
12
	 * - Le processus de défragmentation automatiques réduit la taille du fichier contenant la base de données
13
	 *   quand un ajout ou une suppression de cache est réalisée :
14
	 *	 0			   => pas de défragmentation automatique
15
	 *	 1			   => défragmentation automatique systématique
16
	 *	 x (integer) > 1 => défragmentation automatique toutes les 1 fois (au hasard) sur x ajout ou suppression de cache
269 jpm 17
	 *
282 jpm 18
	 * @var array options disponibles
269 jpm 19
	 */
20
	protected $options = array(
21
		'stockage_chemin' => null,
22
		'defragmentation_auto' => 10
23
	);
24
 
25
	/**
26
	 * DB ressource
27
	 *
28
	 * @var mixed $db
29
	 */
30
	private $bdd = null;
31
 
32
	/**
33
	 * Boolean to store if the structure has benn checked or not
34
	 *
35
	 * @var boolean $structure_ok
36
	 */
37
	private $structure_ok = false;
38
 
39
	private $Cache = null;
40
 
41
	/**
42
	 * Constructor
43
	 *
44
	 * @param  array $options Associative array of options
45
	 * @throws Zend_cache_Exception
46
	 * @return void
47
	 */
48
	public function __construct(array $options = array(), Cache $cache) {
49
		$this->Cache = $cache;
50
		if (extension_loaded('sqlite')) {
282 jpm 51
			$this->initialiserOptionsParConfig();
269 jpm 52
			$this->setOptions($options);
53
		} else {
54
			$e = "Impossible d'utiliser le cache SQLITE car l'extenssion 'sqlite' n'est pas chargée dans l'environnement PHP courrant.";
55
			trigger_error($e, E_USER_ERROR);
56
		}
57
	}
58
 
282 jpm 59
	private function initialiserOptionsParConfig() {
60
		while (list($nom, $valeur) = each($this->options)) {
61
			if (Config::existe($nom)) {
62
				$this->options[$nom] = Config::get($nom);
63
			}
64
		}
65
	}
66
 
269 jpm 67
	/**
68
	 * Destructor
69
	 *
70
	 * @return void
71
	 */
72
	public function __destruct() {
73
		@sqlite_close($this->getConnexion());
74
	}
75
 
76
	private function setOptions($options) {
77
		while (list($nom, $valeur) = each($options)) {
78
			if (!is_string($nom)) {
79
				trigger_error("Nom d'option incorecte : $nom", E_USER_WARNING);
80
			}
81
			$nom = strtolower($nom);
82
			if (array_key_exists($nom, $this->options)) {
83
				$this->options[$nom] = $valeur;
84
			}
85
		}
86
	}
87
 
88
	public function setEmplacement($emplacement) {
89
	 	if (extension_loaded('sqlite')) {
90
			$this->options['stockage_chemin'] = $emplacement;
91
		} else {
92
			trigger_error("Impossible d'utiliser le mode de sotckage SQLite car l'extenssion 'sqlite' n'est pas chargé dans ".
93
				"l'environnement PHP courrant.", E_USER_ERROR);
94
		}
95
	}
96
 
97
	/**
98
	 * Test if a cache is available for the given id and (if yes) return it (false else)
99
	 *
100
	 * @param  string  $id					 Cache id
101
	 * @param  boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
102
	 * @return string|false Cached datas
103
	 */
104
	public function charger($id, $ne_pas_tester_validiter_du_cache = false) {
105
		$this->verifierEtCreerStructureBdd();
106
		$requete = "SELECT content FROM cache WHERE id = '$id'".
107
			(($ne_pas_tester_validiter_du_cache) ? '' : ' AND (expire = 0 OR expire > '.time().')');
108
		$resultat = $this->requeter($requete);
109
		$ligne = @sqlite_fetch_array($resultat);
110
		return ($ligne) ? $ligne['content'] : false;
111
	}
112
 
113
	/**
114
	 * Test if a cache is available or not (for the given id)
115
	 *
116
	 * @param string $id Cache id
117
	 * @return mixed|false (a cache is not available) or "last modified" timestamp (int) of the available cache record
118
	 */
119
	public function tester($id) {
120
		$this->verifierEtCreerStructureBdd();
121
		$requete = "SELECT lastModified FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
122
		$resultat = $this->requeter($requete);
123
		$ligne = @sqlite_fetch_array($resultat);
124
		return ($ligne) ? ((int) $ligne['lastModified']) : false;
125
	}
126
 
127
	/**
128
	 * Save some string datas into a cache record
129
	 *
130
	 * Note : $data is always "string" (serialization is done by the
131
	 * core not by the backend)
132
	 *
133
	 * @param  string $data			 Datas to cache
134
	 * @param  string $id			   Cache id
135
	 * @param  array  $tags			 Array of strings, the cache record will be tagged by each string entry
136
	 * @param  int	$specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime)
137
	 * @throws Zend_Cache_Exception
138
	 * @return boolean True if no problem
139
	 */
140
	public function sauver($donnees, $id, $tags = array(), $duree_vie_specifique = false) {
141
		$this->verifierEtCreerStructureBdd();
290 gduche 142
 
143
		//FIXME : si l'extension n'est pas installée, le cache passe tout de même par cette fonction et s'arrête à cet endroit.
269 jpm 144
		$donnees = @sqlite_escape_string($donnees);
145
		$timestamp_courrant = time();
146
		$expiration = $this->Cache->getTimestampExpiration($duree_vie_specifique);
147
 
148
		$this->requeter("DELETE FROM cache WHERE id = '$id'");
149
		$sql = "INSERT INTO cache (id, content, lastModified, expire) VALUES ('$id', '$donnees', $timestamp_courrant, $expiration)";
150
		$resultat = $this->requeter($sql);
151
		if (!$resultat) {
152
			// TODO : ajouter un log sauver() : impossible de stocker le cache d'id '$id'
153
			Debug::printr("sauver() : impossible de stocker le cache d'id '$id'");
154
			$resultat =  false;
155
		} else {
156
			$resultat = true;
157
			foreach ($tags as $tag) {
158
				$resultat = $this->enregisterTag($id, $tag) && $resultat;
159
			}
160
		}
161
		return $resultat;
162
	}
163
 
164
	/**
165
	 * Remove a cache record
166
	 *
167
	 * @param  string $id Cache id
168
	 * @return boolean True if no problem
169
	 */
170
	public function supprimer($id) {
171
		$this->verifierEtCreerStructureBdd();
172
		$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM cache WHERE id = '$id'");
173
		$resultat_nbre = @sqlite_fetch_single($resultat);
174
		$suppression_cache = $this->requeter("DELETE FROM cache WHERE id = '$id'");
175
		$suppression_tags = $this->requeter("DELETE FROM tag WHERE id = '$id'");
176
		$this->defragmenterAutomatiquement();
177
		return ($resultat_nbre && $suppression_cache && $suppression_tags);
178
	}
179
 
180
	/**
181
	 * Clean some cache records
182
	 *
183
	 * Available modes are :
184
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
185
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
186
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
187
	 *											   ($tags can be an array of strings or a single string)
188
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
189
	 *											   ($tags can be an array of strings or a single string)
190
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
191
	 *											   ($tags can be an array of strings or a single string)
192
	 *
193
	 * @param  string $mode Clean mode
194
	 * @param  array  $tags Array of tags
195
	 * @return boolean True if no problem
196
	 */
197
	public function nettoyer($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
198
		$this->verifierEtCreerStructureBdd();
199
		$retour = $this->nettoyerSqlite($mode, $tags);
200
		$this->defragmenterAutomatiquement();
201
		return $retour;
202
	}
203
 
204
	/**
205
	 * Return an array of stored cache ids
206
	 *
207
	 * @return array array of stored cache ids (string)
208
	 */
209
	public function getIds() {
210
		$this->verifierEtCreerStructureBdd();
211
		$resultat = $this->requeter('SELECT id FROM cache WHERE (expire = 0 OR expire > '.time().')');
212
		$retour = array();
213
		while ($id = @sqlite_fetch_single($resultat)) {
214
			$retour[] = $id;
215
		}
216
		return $retour;
217
	}
218
 
219
	/**
220
	 * Return an array of stored tags
221
	 *
222
	 * @return array array of stored tags (string)
223
	 */
224
	public function getTags() {
225
		$this->verifierEtCreerStructureBdd();
226
		$resultat = $this->requeter('SELECT DISTINCT(name) AS name FROM tag');
227
		$retour = array();
228
		while ($id = @sqlite_fetch_single($resultat)) {
229
			$retour[] = $id;
230
		}
231
		return $retour;
232
	}
233
 
234
	/**
235
	 * Return an array of stored cache ids which match given tags
236
	 *
237
	 * In case of multiple tags, a logical AND is made between tags
238
	 *
239
	 * @param array $tags array of tags
240
	 * @return array array of matching cache ids (string)
241
	 */
242
	public function getIdsAvecLesTags($tags = array()) {
243
		$this->verifierEtCreerStructureBdd();
244
		$premier = true;
245
		$ids = array();
246
		foreach ($tags as $tag) {
247
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name='$tag'");
248
			if ($resultat) {
249
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
250
				$ids_tmp = array();
251
				foreach ($lignes as $ligne) {
252
					$ids_tmp[] = $ligne['id'];
253
				}
254
				if ($premier) {
255
					$ids = $ids_tmp;
256
					$premier = false;
257
				} else {
258
					$ids = array_intersect($ids, $ids_tmp);
259
				}
260
			}
261
		}
262
 
263
		$retour = array();
264
		if (count($ids) > 0) {
265
			foreach ($ids as $id) {
266
				$retour[] = $id;
267
			}
268
		}
269
		return $retour;
270
	}
271
 
272
	/**
273
	 * Return an array of stored cache ids which don't match given tags
274
	 *
275
	 * In case of multiple tags, a logical OR is made between tags
276
	 *
277
	 * @param array $tags array of tags
278
	 * @return array array of not matching cache ids (string)
279
	 */
280
	public function getIdsSansLesTags($tags = array()) {
281
		$this->verifierEtCreerStructureBdd();
282
		$resultat = $this->requeter('SELECT id FROM cache');
283
		$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
284
		$retour = array();
285
		foreach ($lignes as $ligne) {
286
			$id = $ligne['id'];
287
			$correspondance = false;
288
			foreach ($tags as $tag) {
289
				$resultat = $this->requeter("SELECT COUNT(*) AS nbr FROM tag WHERE name = '$tag' AND id = '$id'");
290
				if ($resultat) {
291
					$nbre = (int) @sqlite_fetch_single($resultat);
292
					if ($nbre > 0) {
293
						$correspondance = true;
294
					}
295
				}
296
			}
297
			if (!$correspondance) {
298
				$retour[] = $id;
299
			}
300
		}
301
		return $retour;
302
	}
303
 
304
	/**
305
	 * Return an array of stored cache ids which match any given tags
306
	 *
307
	 * In case of multiple tags, a logical AND is made between tags
308
	 *
309
	 * @param array $tags array of tags
310
	 * @return array array of any matching cache ids (string)
311
	 */
312
	public function getIdsAvecUnTag($tags = array()) {
313
		$this->verifierEtCreerStructureBdd();
314
		$premier = true;
315
		$ids = array();
316
		foreach ($tags as $tag) {
317
			$resultat = $this->requeter("SELECT DISTINCT(id) AS id FROM tag WHERE name = '$tag'");
318
			if ($resultat) {
319
				$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
320
				$ids_tmp = array();
321
				foreach ($lignes as $ligne) {
322
					$ids_tmp[] = $ligne['id'];
323
				}
324
				if ($premier) {
325
					$ids = $ids_tmp;
326
					$premier = false;
327
				} else {
328
					$ids = array_merge($ids, $ids_tmp);
329
				}
330
			}
331
		}
332
 
333
		$retour = array();
334
		if (count($ids) > 0) {
335
			foreach ($ids as $id) {
336
				$retour[] = $id;
337
			}
338
		}
339
		return $retour;
340
	}
341
 
342
	/**
343
	 * Return the filling percentage of the backend storage
344
	 *
345
	 * @throws Zend_Cache_Exception
346
	 * @return int integer between 0 and 100
347
	 */
348
	public function getPourcentageRemplissage() {
349
		$dossier = dirname($this->options['stockage_chemin']);
350
		$libre = disk_free_space($dossier);
351
		$total = disk_total_space($dossier);
352
 
353
		$pourcentage = 0;
354
		if ($total == 0) {
355
			trigger_error("Impossible d'utiliser la fonction disk_total_space", E_USER_WARNING);
356
		} else {
357
			$pourcentage = ($libre >= $total) ? 100 : ((int) (100. * ($total - $libre) / $total));
358
		}
359
		return $pourcentage;
360
	}
361
 
362
	/**
363
	 * Return an array of metadatas for the given cache id
364
	 *
365
	 * The array must include these keys :
366
	 * - expire : the expire timestamp
367
	 * - tags : a string array of tags
368
	 * - mtime : timestamp of last modification time
369
	 *
370
	 * @param string $id cache id
371
	 * @return array array of metadatas (false if the cache id is not found)
372
	 */
373
	public function getMetadonnees($id) {
374
		$this->verifierEtCreerStructureBdd();
375
		$tags = array();
376
		$resultat = $this->requeter("SELECT name FROM tag WHERE id = '$id'");
377
		if ($resultat) {
378
			$lignes = @sqlite_fetch_all($resultat, SQLITE_ASSOC);
379
			foreach ($lignes as $ligne) {
380
				$tags[] = $ligne['name'];
381
			}
382
		}
383
		$resultat = $this->requeter("SELECT lastModified, expire FROM cache WHERE id = '$id'");
384
		if ($resultat) {
385
			$ligne = @sqlite_fetch_array($resultat, SQLITE_ASSOC);
386
			$resultat = array(
387
				'tags' => $tags,
388
				'mtime' => $ligne['lastModified'],
389
				'expiration' => $ligne['expire']);
390
		} else {
391
			$resultat = false;
392
		}
393
		return $resultat;
394
	}
395
 
396
	/**
397
	 * Give (if possible) an extra lifetime to the given cache id
398
	 *
399
	 * @param string $id cache id
400
	 * @param int $extraLifetime
401
	 * @return boolean true if ok
402
	 */
403
	public function ajouterSupplementDureeDeVie($id, $supplement_duree_de_vie) {
404
		$this->verifierEtCreerStructureBdd();
405
		$augmentation = false;
406
		$requete = "SELECT expire FROM cache WHERE id = '$id' AND (expire = 0 OR expire > ".time().')';
407
		$resultat = $this->requeter($requete);
408
		if ($resultat) {
409
			$expiration = @sqlite_fetch_single($resultat);
410
			$nouvelle_expiration = $expiration + $supplement_duree_de_vie;
411
			$resultat = $this->requeter('UPDATE cache SET lastModified = '.time().", expire = $nouvelle_expiration WHERE id = '$id'");
412
			$augmentation = ($resultat) ? true : false;
413
		}
414
		return $augmentation;
415
	}
416
 
417
	/**
418
	 * Return the connection resource
419
	 *
420
	 * If we are not connected, the connection is made
421
	 *
422
	 * @throws Zend_Cache_Exception
423
	 * @return resource Connection resource
424
	 */
425
	private function getConnexion() {
426
		if (!is_resource($this->bdd)) {
427
			if ($this->options['stockage_chemin'] === null) {
428
				$e = "L'emplacement du chemin vers le fichier de la base de données SQLite n'a pas été défini";
429
				trigger_error($e, E_USER_ERROR);
430
			} else {
431
				$this->bdd = sqlite_open($this->options['stockage_chemin']);
432
				if (!(is_resource($this->bdd))) {
433
					$e = "Impossible d'ouvrir le fichier '".$this->options['stockage_chemin']."' de la base de données SQLite.";
434
					trigger_error($e, E_USER_ERROR);
435
					$this->bdd = null;
436
				}
437
			}
438
		}
439
		return $this->bdd;
440
	}
441
 
442
	/**
443
	 * Execute une requête SQL sans afficher de messages d'erreur.
444
	 *
445
	 * @param string $requete requête SQL
446
	 * @return mixed|false resultats de la requête
447
	 */
448
	private function requeter($requete) {
449
		$bdd = $this->getConnexion();
450
		//Debug::printr($requete);
451
		$resultat = (is_resource($bdd)) ? @sqlite_query($bdd, $requete, SQLITE_ASSOC, $e_sqlite) : false;
452
		if (is_resource($bdd) && ! $resultat) {
453
			Debug::printr("Erreur SQLITE :\n$e_sqlite\nPour la requête :\n$requete\nRessource : $bdd");
454
		}
455
		return $resultat;
456
	}
457
 
458
	/**
459
	 * Deal with the automatic vacuum process
460
	 *
461
	 * @return void
462
	 */
463
	private function defragmenterAutomatiquement() {
464
		if ($this->options['defragmentation_auto'] > 0) {
465
			$rand = rand(1, $this->options['defragmentation_auto']);
466
			if ($rand == 1) {
467
				$this->requeter('VACUUM');
468
				@sqlite_close($this->getConnexion());
469
			}
470
		}
471
	}
472
 
473
	/**
474
	 * Register a cache id with the given tag
475
	 *
476
	 * @param  string $id  Cache id
477
	 * @param  string $tag Tag
478
	 * @return boolean True if no problem
479
	 */
480
	private function enregisterTag($id, $tag) {
481
		$requete_suppression = "DELETE FROM tag WHERE name = '$tag' AND id = '$id'";
482
		$resultat = $this->requeter($requete_suppression);
483
		$requete_insertion = "INSERT INTO tag(name,id) VALUES ('$tag','$id')";
484
		$resultat = $this->requeter($requete_insertion);
485
		if (!$resultat) {
486
			// TODO : ajouter un log -> impossible d'enregistrer le tag=$tag pour le cache id=$id");
487
			Debug::printr("Impossible d'enregistrer le tag=$tag pour le cache id=$id");
488
		}
489
		return ($resultat) ? true : false;
490
	}
491
 
492
	/**
493
	 * Build the database structure
494
	 *
495
	 * @return false
496
	 */
497
	private function creerStructure() {
498
		$this->requeter('DROP INDEX IF EXISTS tag_id_index');
499
		$this->requeter('DROP INDEX IF EXISTS tag_name_index');
500
		$this->requeter('DROP INDEX IF EXISTS cache_id_expire_index');
501
		$this->requeter('DROP TABLE IF EXISTS version');
502
		$this->requeter('DROP TABLE IF EXISTS cache');
503
		$this->requeter('DROP TABLE IF EXISTS tag');
504
		$this->requeter('CREATE TABLE version (num INTEGER PRIMARY KEY)');
505
		$this->requeter('CREATE TABLE cache(id TEXT PRIMARY KEY, content BLOB, lastModified INTEGER, expire INTEGER)');
506
		$this->requeter('CREATE TABLE tag (name TEXT, id TEXT)');
507
		$this->requeter('CREATE INDEX tag_id_index ON tag(id)');
508
		$this->requeter('CREATE INDEX tag_name_index ON tag(name)');
509
		$this->requeter('CREATE INDEX cache_id_expire_index ON cache(id, expire)');
510
		$this->requeter('INSERT INTO version (num) VALUES (1)');
511
	}
512
 
513
	/**
514
	 * Check if the database structure is ok (with the good version)
515
	 *
516
	 * @return boolean True if ok
517
	 */
518
	private function verifierBddStructureVersion() {
519
		$version_ok = false;
520
		$resultat = $this->requeter('SELECT num FROM version');
521
		if ($resultat) {
522
			$ligne = @sqlite_fetch_array($resultat);
523
			if ($ligne) {
524
				if (((int) $ligne['num']) == 1) {
525
					$version_ok = true;
526
				} else {
527
					// TODO : ajouter un log CacheSqlite::verifierBddStructureVersion() : vielle version de la structure de la base de données de cache détectée => le cache est entrain d'être supprimé
528
				}
529
			}
530
		}
531
		return $version_ok;
532
	}
533
 
534
	/**
535
	 * Clean some cache records
536
	 *
537
	 * Available modes are :
538
	 * Zend_Cache::CLEANING_MODE_ALL (default)	=> remove all cache entries ($tags is not used)
539
	 * Zend_Cache::CLEANING_MODE_OLD			  => remove too old cache entries ($tags is not used)
540
	 * Zend_Cache::CLEANING_MODE_MATCHING_TAG	 => remove cache entries matching all given tags
541
	 *											   ($tags can be an array of strings or a single string)
542
	 * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags}
543
	 *											   ($tags can be an array of strings or a single string)
544
	 * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags
545
	 *											   ($tags can be an array of strings or a single string)
546
	 *
547
	 * @param  string $mode Clean mode
548
	 * @param  array  $tags Array of tags
549
	 * @return boolean True if no problem
550
	 */
551
	private function nettoyerSqlite($mode = Cache::NETTOYAGE_MODE_TOUS, $tags = array()) {
552
		$nettoyage_ok = false;
553
		switch ($mode) {
554
			case Cache::NETTOYAGE_MODE_TOUS:
555
				$suppression_cache = $this->requeter('DELETE FROM cache');
556
				$suppression_tag = $this->requeter('DELETE FROM tag');
557
				$nettoyage_ok = $suppression_cache && $suppression_tag;
558
				break;
559
			case Cache::NETTOYAGE_MODE_EXPIRATION:
560
				$mktime = time();
561
				$suppression_tag = $this->requeter("DELETE FROM tag WHERE id IN (SELECT id FROM cache WHERE expire > 0 AND expire <= $mktime)");
562
				$suppression_cache = $this->requeter("DELETE FROM cache WHERE expire > 0 AND expire <= $mktime");
563
				return $suppression_tag && $suppression_cache;
564
				break;
565
			case Cache::NETTOYAGE_MODE_AVEC_LES_TAGS:
566
				$ids = $this->getIdsAvecLesTags($tags);
567
				$resultat = true;
568
				foreach ($ids as $id) {
569
					$resultat = $this->supprimer($id) && $resultat;
570
				}
571
				return $resultat;
572
				break;
573
			case Cache::NETTOYAGE_MODE_SANS_LES_TAGS:
574
				$ids = $this->getIdsSansLesTags($tags);
575
				$resultat = true;
576
				foreach ($ids as $id) {
577
					$resultat = $this->supprimer($id) && $resultat;
578
				}
579
				return $resultat;
580
				break;
581
			case Cache::NETTOYAGE_MODE_AVEC_UN_TAG:
582
				$ids = $this->getIdsAvecUnTag($tags);
583
				$resultat = true;
584
				foreach ($ids as $id) {
585
					$resultat = $this->supprimer($id) && $resultat;
586
				}
587
				return $resultat;
588
				break;
589
			default:
590
				break;
591
		}
592
		return $nettoyage_ok;
593
	}
594
 
595
	/**
596
	 * Check if the database structure is ok (with the good version), if no : build it
597
	 *
598
	 * @throws Zend_Cache_Exception
599
	 * @return boolean True if ok
600
	 */
601
	private function verifierEtCreerStructureBdd() {
602
		if (! $this->structure_ok) {
603
			if (! $this->verifierBddStructureVersion()) {
604
				$this->creerStructure();
605
				if (! $this->verifierBddStructureVersion()) {
606
					$e = "Impossible de construire la base de données de cache dans ".$this->options['stockage_chemin'];
607
					trigger_error($e, E_USER_WARNING);
608
					$this->structure_ok = false;
609
				}
610
			}
611
			$this->structure_ok = true;
612
		}
613
		return $this->structure_ok;
614
	}
615
 
616
}
617
?>