Feature #22836 » 14655_02.diff
tests/t3lib/cache/backend/t3lib_cache_backend_pdobackendtestcase.php (revision 0) | ||
---|---|---|
<?php
|
||
/***************************************************************
|
||
* Copyright notice
|
||
*
|
||
* (c) 2010 Christian Kuhn <lolli@schwarzbu.ch>
|
||
* All rights reserved
|
||
*
|
||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||
* free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* The GNU General Public License can be found at
|
||
* http://www.gnu.org/copyleft/gpl.html.
|
||
*
|
||
* This script is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* This copyright notice MUST APPEAR in all copies of the script!
|
||
***************************************************************/
|
||
/**
|
||
* Testcase for the PDO cache backend
|
||
*
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
* @package TYPO3
|
||
* @subpackage tests
|
||
* @version $Id$
|
||
*/
|
||
class t3lib_cache_backend_PdoBackendTestCase extends tx_phpunit_testcase {
|
||
/**
|
||
* Backup of global variable EXEC_TIME
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $backupGlobalVariables;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $fixtureFolder;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $fixtureDB;
|
||
/**
|
||
* Sets up this testcase
|
||
*
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function setUp() {
|
||
if (!extension_loaded('pdo_sqlite')) {
|
||
$this->markTestSkipped('pdo_sqlite extension was not available');
|
||
}
|
||
$this->backupGlobalVariables = array(
|
||
'EXEC_TIME' => $GLOBALS['EXEC_TIME'],
|
||
);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @expectedException t3lib_cache_Exception
|
||
*/
|
||
public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
|
||
$backend = t3lib_div::makeInstance('t3lib_cache_backend_PdoBackend');
|
||
$data = 'Some data';
|
||
$identifier = 'MyIdentifier';
|
||
$backend->set($identifier, $data);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function itIsPossibleToSetAndCheckExistenceInCache() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$identifier = 'MyIdentifier';
|
||
$backend->set($identifier, $data);
|
||
$this->assertTrue($backend->has($identifier));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function itIsPossibleToSetAndGetEntry() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$identifier = 'MyIdentifier';
|
||
$backend->set($identifier, $data);
|
||
$fetchedData = $backend->get($identifier);
|
||
$this->assertEquals($data, $fetchedData);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function itIsPossibleToRemoveEntryFromCache() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$identifier = 'MyIdentifier';
|
||
$backend->set($identifier, $data);
|
||
$backend->remove($identifier);
|
||
$this->assertFalse($backend->has($identifier));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function itIsPossibleToOverwriteAnEntryInTheCache() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$identifier = 'MyIdentifier';
|
||
$backend->set($identifier, $data);
|
||
$otherData = 'some other data';
|
||
$backend->set($identifier, $otherData);
|
||
$fetchedData = $backend->get($identifier);
|
||
$this->assertEquals($otherData, $fetchedData);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function findIdentifiersByTagFindsSetEntries() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$entryIdentifier = 'MyIdentifier';
|
||
$backend->set($entryIdentifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
|
||
$retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag1');
|
||
$this->assertEquals($entryIdentifier, $retrieved[0]);
|
||
$retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
|
||
$this->assertEquals($entryIdentifier, $retrieved[0]);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function findIdentifiersByTagsFindsSetEntries() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$entryIdentifier = 'MyIdentifier';
|
||
$backend->set($entryIdentifier . 'A', $data, array('UnitTestTag%tag1'));
|
||
$backend->set($entryIdentifier . 'B', $data, array('UnitTestTag%tag2'));
|
||
$backend->set($entryIdentifier . 'C', $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
|
||
$backend->set($entryIdentifier . 'D', $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2', 'UnitTestTag%tag3'));
|
||
$retrieved = $backend->findIdentifiersByTags(array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
|
||
$this->assertFalse(in_array($entryIdentifier . 'A', $retrieved));
|
||
$this->assertFalse(in_array($entryIdentifier . 'B', $retrieved));
|
||
$this->assertTrue(in_array($entryIdentifier . 'C', $retrieved));
|
||
$this->assertTrue(in_array($entryIdentifier . 'D', $retrieved));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function setRemovesTagsFromPreviousSet() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'Some data';
|
||
$entryIdentifier = 'MyIdentifier';
|
||
$backend->set($entryIdentifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
|
||
$backend->set($entryIdentifier, $data, array('UnitTestTag%tag3'));
|
||
$retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
|
||
$this->assertEquals(array(), $retrieved);
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function hasReturnsFalseIfTheEntryDoesntExist() {
|
||
$backend = $this->setUpBackend();
|
||
$identifier = 'NonExistingIdentifier';
|
||
$this->assertFalse($backend->has($identifier));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Jul Jensen <julle@typo3.org>
|
||
*/
|
||
public function removeReturnsFalseIfTheEntryDoesntExist() {
|
||
$backend = $this->setUpBackend();
|
||
$identifier = 'NonExistingIdentifier';
|
||
$this->assertFalse($backend->remove($identifier));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Robert Lemke <robert@typo3.org>
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function flushByTagRemovesCacheEntriesWithSpecifiedTag() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'some data' . microtime();
|
||
$backend->set('PdoBackendTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
|
||
$backend->set('PdoBackendTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'));
|
||
$backend->set('PdoBackendTest3', $data, array('UnitTestTag%test'));
|
||
$backend->flushByTag('UnitTestTag%special');
|
||
$this->assertTrue($backend->has('PdoBackendTest1'), 'PdoBackendTest1');
|
||
$this->assertFalse($backend->has('PdoBackendTest2'), 'PdoBackendTest2');
|
||
$this->assertTrue($backend->has('PdoBackendTest3'), 'PdoBackendTest3');
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function flushByTagsRemovesCacheEntriesWithSpecifiedTags() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'some data' . microtime();
|
||
$backend->set('PdoBackendTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
|
||
$backend->set('PdoBackendTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special1'));
|
||
$backend->set('PdoBackendTest3', $data, array('UnitTestTag%test', 'UnitTestTag%special2'));
|
||
$backend->set('PdoBackendTest4', $data, array('UnitTestTag%test', 'UnitTestTag%special2'));
|
||
$backend->flushByTags(array('UnitTestTag%special1','UnitTestTag%special2'));
|
||
$this->assertTrue($backend->has('PdoBackendTest1'));
|
||
$this->assertFalse($backend->has('PdoBackendTest2'));
|
||
$this->assertFalse($backend->has('PdoBackendTest3'));
|
||
$this->assertFalse($backend->has('PdoBackendTest4'));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function flushRemovesAllCacheEntries() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'some data' . microtime();
|
||
$backend->set('PdoBackendTest1', $data);
|
||
$backend->set('PdoBackendTest2', $data);
|
||
$backend->set('PdoBackendTest3', $data);
|
||
$backend->flush();
|
||
$this->assertFalse($backend->has('PdoBackendTest1'), 'PdoBackendTest1');
|
||
$this->assertFalse($backend->has('PdoBackendTest2'), 'PdoBackendTest2');
|
||
$this->assertFalse($backend->has('PdoBackendTest3'), 'PdoBackendTest3');
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function flushRemovesOnlyOwnEntries() {
|
||
$thisCache = $this->getMock('t3lib_cache_frontend_Frontend', array(), array(), '', FALSE);
|
||
$thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
|
||
$thisBackend = $this->setUpBackend();
|
||
$thisBackend->setCache($thisCache);
|
||
$thatCache = $this->getMock('t3lib_cache_frontend_Frontend', array(), array(), '', FALSE);
|
||
$thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
|
||
$thatBackend = $this->setUpBackend();
|
||
$thatBackend->setCache($thatCache);
|
||
$thisBackend->set('thisEntry', 'Hello');
|
||
$thatBackend->set('thatEntry', 'World!');
|
||
$thatBackend->flush();
|
||
$this->assertEquals('Hello', $thisBackend->get('thisEntry'));
|
||
$this->assertFalse($thatBackend->has('thatEntry'));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Ingo Renner <ingo@typo3.org>
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function collectGarbageReallyRemovesAnExpiredCacheEntry() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'some data' . microtime();
|
||
$entryIdentifier = 'BackendPDORemovalTest';
|
||
$backend->set($entryIdentifier, $data, array(), 1);
|
||
$this->assertTrue($backend->has($entryIdentifier));
|
||
$GLOBALS['EXEC_TIME'] += 2;
|
||
$backend->collectGarbage();
|
||
$this->assertFalse($backend->has($entryIdentifier));
|
||
}
|
||
/**
|
||
* @test
|
||
* @author Ingo Renner <ingo@typo3.org>
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function collectGarbageReallyRemovesAllExpiredCacheEntries() {
|
||
$backend = $this->setUpBackend();
|
||
$data = 'some data' . microtime();
|
||
$entryIdentifier = 'BackendPDORemovalTest';
|
||
$backend->set($entryIdentifier . 'A', $data, array(), NULL);
|
||
$backend->set($entryIdentifier . 'B', $data, array(), 10);
|
||
$backend->set($entryIdentifier . 'C', $data, array(), 1);
|
||
$backend->set($entryIdentifier . 'D', $data, array(), 1);
|
||
$this->assertTrue($backend->has($entryIdentifier . 'A'));
|
||
$this->assertTrue($backend->has($entryIdentifier . 'B'));
|
||
$this->assertTrue($backend->has($entryIdentifier . 'C'));
|
||
$this->assertTrue($backend->has($entryIdentifier . 'D'));
|
||
$GLOBALS['EXEC_TIME'] += 2;
|
||
$backend->collectGarbage();
|
||
$this->assertTrue($backend->has($entryIdentifier . 'A'));
|
||
$this->assertTrue($backend->has($entryIdentifier . 'B'));
|
||
$this->assertFalse($backend->has($entryIdentifier . 'C'));
|
||
$this->assertFalse($backend->has($entryIdentifier . 'D'));
|
||
}
|
||
/**
|
||
* Sets up the PDO backend used for testing
|
||
*
|
||
* @return t3lib_cache_backend_PdoBackend
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
protected function setUpBackend() {
|
||
$this->fixtureFolder = sys_get_temp_dir() . '/' . 'typo3pdobackendtest/';
|
||
t3lib_div::mkdir_deep(sys_get_temp_dir() . '/', 'typo3pdobackendtest/');
|
||
$this->fixtureDB = uniqid('Cache') . '.db';
|
||
$pdoHelper = t3lib_div::makeInstance('t3lib_PdoHelper', 'sqlite:' . $this->fixtureFolder . $this->fixtureDB, '', '');
|
||
$pdoHelper->importSql(PATH_t3lib . 'cache/backend/resources/ddl.sql');
|
||
$mockCache = $this->getMock('t3lib_cache_frontend_Frontend', array(), array(), '', FALSE);
|
||
$mockCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('TestCache'));
|
||
$backendOptions = array(
|
||
'dataSourceName' => 'sqlite:' . $this->fixtureFolder . $this->fixtureDB,
|
||
'username' => '',
|
||
'password' => '',
|
||
);
|
||
$backend = t3lib_div::makeInstance('t3lib_cache_backend_PdoBackend', $backendOptions);
|
||
$backend->setCache($mockCache);
|
||
return $backend;
|
||
}
|
||
/**
|
||
* Clean up after the tests
|
||
*
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function tearDown() {
|
||
if ($this->fixtureDB) {
|
||
t3lib_div::rmdir($this->fixtureFolder, TRUE);
|
||
}
|
||
foreach ($this->backupGlobalVariables as $key => $data) {
|
||
$GLOBALS[$key] = $data;
|
||
}
|
||
}
|
||
}
|
||
?>
|
t3lib/config_default.php (working copy) | ||
---|---|---|
't3lib_cache_backend_FileBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_filebackend.php:t3lib_cache_backend_FileBackend',
|
||
't3lib_cache_backend_GlobalsBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_globalsbackend.php:t3lib_cache_backend_GlobalsBackend',
|
||
't3lib_cache_backend_MemcachedBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_memcachedbackend.php:t3lib_cache_backend_MemcachedBackend',
|
||
't3lib_cache_backend_PdoBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_pdobackend.php:t3lib_cache_backend_PdoBackend',
|
||
't3lib_cache_backend_ApcBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_apcbackend.php:t3lib_cache_backend_ApcBackend',
|
||
't3lib_cache_backend_NullBackend' => 't3lib/cache/backend/class.t3lib_cache_backend_nullbackend.php:t3lib_cache_backend_NullBackend'
|
||
),
|
t3lib/cache/backend/resources/ddl.sql (revision 0) | ||
---|---|---|
BEGIN;
|
||
CREATE TABLE "cache" (
|
||
"identifier" VARCHAR(250) NOT NULL,
|
||
"cache" VARCHAR(250) NOT NULL,
|
||
"scope" CHAR(12) NOT NULL,
|
||
"created" INTEGER UNSIGNED NOT NULL,
|
||
"lifetime" INTEGER UNSIGNED DEFAULT '0' NOT NULL,
|
||
"content" TEXT,
|
||
PRIMARY KEY ("identifier", "cache", "scope")
|
||
);
|
||
CREATE TABLE "tags" (
|
||
"identifier" VARCHAR(250) NOT NULL,
|
||
"cache" VARCHAR(250) NOT NULL,
|
||
"scope" CHAR(12) NOT NULL,
|
||
"tag" VARCHAR(250) NOT NULL
|
||
);
|
||
CREATE INDEX "identifier" ON "tags" ("identifier", "cache", "scope");
|
||
CREATE INDEX "tag" ON "tags" ("tag");
|
||
COMMIT;
|
t3lib/cache/backend/class.t3lib_cache_backend_pdobackend.php (revision 0) | ||
---|---|---|
<?php
|
||
/***************************************************************
|
||
* Copyright notice
|
||
*
|
||
* (c) 2010 Christian Kuhn <lolli@schwarzbu.ch>
|
||
* All rights reserved
|
||
*
|
||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||
* free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* The GNU General Public License can be found at
|
||
* http://www.gnu.org/copyleft/gpl.html.
|
||
*
|
||
* This script is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* This copyright notice MUST APPEAR in all copies of the script!
|
||
***************************************************************/
|
||
/**
|
||
* A PDO database cache backend
|
||
*
|
||
* @package TYPO3
|
||
* @subpackage t3lib_cache
|
||
* @api
|
||
* @scope prototype
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
* @version $Id$
|
||
*/
|
||
class t3lib_cache_backend_PdoBackend extends t3lib_cache_backend_AbstractBackend {
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $dataSourceName;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $username;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $password;
|
||
/**
|
||
* Used to seperate stored data by user, SAPI, context, ...
|
||
* @var string
|
||
*/
|
||
protected $scope;
|
||
/**
|
||
* @var PDO
|
||
*/
|
||
protected $databaseHandle;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $pdoDriver;
|
||
/**
|
||
* Constructs this backend
|
||
*
|
||
* @param mixed $options Configuration options - depends on the actual backend
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function __construct(array $options = array()) {
|
||
parent::__construct($options);
|
||
$this->connect();
|
||
}
|
||
/**
|
||
* Sets the DSN to use
|
||
*
|
||
* @param string $DSN The DSN to use for connecting to the DB
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function setDataSourceName($DSN) {
|
||
$this->dataSourceName = $DSN;
|
||
}
|
||
/**
|
||
* Sets the username to use
|
||
*
|
||
* @param string $username The username to use for connecting to the DB
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function setUsername($username) {
|
||
$this->username = $username;
|
||
}
|
||
/**
|
||
* Sets the password to use
|
||
*
|
||
* @param string $password The password to use for connecting to the DB
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function setPassword($password) {
|
||
$this->password = $password;
|
||
}
|
||
/**
|
||
* Initializes the identifier prefix when setting the cache.
|
||
*
|
||
* @param t3lib_cache_frontend_Frontend $cache
|
||
* @return void
|
||
* @author Robert Lemke <robert@typo3.org>
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function setCache(t3lib_cache_frontend_Frontend $cache) {
|
||
parent::setCache($cache);
|
||
$processUser = extension_loaded('posix') ? posix_getpwuid(posix_geteuid()) : array('name' => 'default');
|
||
$this->scope = t3lib_div::shortMD5(PATH_site . $processUser['name'], 12);
|
||
}
|
||
/**
|
||
* Saves data in the cache.
|
||
*
|
||
* @param string $entryIdentifier An identifier for this specific cache entry
|
||
* @param string $data The data to be stored
|
||
* @param array $tags Tags to associate with this cache entry
|
||
* @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
|
||
* @return void
|
||
* @throws t3lib_cache_Exception if no cache frontend has been set.
|
||
* @throws t3lib_cache_exception_InvalidData if $data is not a string
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
|
||
if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
|
||
throw new t3lib_cache_Exception(
|
||
'No cache frontend has been set yet via setCache().',
|
||
1259515600
|
||
);
|
||
}
|
||
if (!is_string($data)) {
|
||
throw new t3lib_cache_exception_InvalidData(
|
||
'The specified data is of type "' . gettype($data) . '" but a string is expected.',
|
||
1259515601
|
||
);
|
||
}
|
||
if ($this->has($entryIdentifier)) {
|
||
$this->remove($entryIdentifier);
|
||
}
|
||
$lifetime = ($lifetime === NULL) ? $this->defaultLifetime : $lifetime;
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'INSERT INTO "cache" ("identifier", "scope", "cache", "created", "lifetime", "content") VALUES (?, ?, ?, ?, ?, ?)'
|
||
);
|
||
$result = $statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier, $GLOBALS['EXEC_TIME'], $lifetime, $data)
|
||
);
|
||
if ($result === FALSE) {
|
||
throw new t3lib_cache_Exception(
|
||
'The cache entry "' . $entryIdentifier . '" could not be written.',
|
||
1259530791
|
||
);
|
||
}
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'INSERT INTO "tags" ("identifier", "scope", "cache", "tag") VALUES (?, ?, ?, ?)'
|
||
);
|
||
foreach ($tags as $tag) {
|
||
$result = $statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier, $tag)
|
||
);
|
||
if ($result === FALSE) {
|
||
throw new t3lib_cache_Exception(
|
||
'The tag "' . $tag . ' for cache entry "' . $entryIdentifier . '" could not be written.',
|
||
1259530751
|
||
);
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Loads data from the cache.
|
||
*
|
||
* @param string $entryIdentifier An identifier which describes the cache entry to load
|
||
* @return mixed The cache entry's content as a string or FALSE if the cache entry could not be loaded
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function get($entryIdentifier) {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'SELECT "content" FROM "cache" WHERE "identifier"=? AND "scope"=? AND "cache"=?' . $this->getNotExpiredStatement()
|
||
);
|
||
$statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier)
|
||
);
|
||
return $statementHandle->fetchColumn();
|
||
}
|
||
/**
|
||
* Checks if a cache entry with the specified identifier exists.
|
||
*
|
||
* @param string $entryIdentifier An identifier specifying the cache entry
|
||
* @return boolean TRUE if such an entry exists, FALSE if not
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function has($entryIdentifier) {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'SELECT COUNT("identifier") FROM "cache" WHERE "identifier"=? AND "scope"=? AND "cache"=?' . $this->getNotExpiredStatement()
|
||
);
|
||
$statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier)
|
||
);
|
||
return ($statementHandle->fetchColumn() > 0);
|
||
}
|
||
/**
|
||
* Removes all cache entries matching the specified identifier.
|
||
* Usually this only affects one entry but if - for what reason ever -
|
||
* old entries for the identifier still exist, they are removed as well.
|
||
*
|
||
* @param string $entryIdentifier Specifies the cache entry to remove
|
||
* @return boolean TRUE if (at least) an entry could be removed or FALSE if no entry was found
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function remove($entryIdentifier) {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "tags" WHERE "identifier"=? AND "scope"=? AND "cache"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier)
|
||
);
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "cache" WHERE "identifier"=? AND "scope"=? AND "cache"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($entryIdentifier, $this->scope, $this->cacheIdentifier)
|
||
);
|
||
return ($statementHandle->rowCount() > 0);
|
||
}
|
||
/**
|
||
* Removes all cache entries of this cache.
|
||
*
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function flush() {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "tags" WHERE "scope"=? AND "cache"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier)
|
||
);
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "cache" WHERE "scope"=? AND "cache"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier)
|
||
);
|
||
}
|
||
/**
|
||
* Removes all cache entries of this cache which are tagged by the specified tag.
|
||
*
|
||
* @param string $tag The tag the entries must have
|
||
* @return void
|
||
* @author Robert Lemke <robert@typo3.org>
|
||
* @api
|
||
*/
|
||
public function flushByTag($tag) {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "cache" WHERE "scope"=? AND "cache"=? AND "identifier" IN (SELECT "identifier" FROM "tags" WHERE "scope"=? AND "cache"=? AND "tag"=?)'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier,$this->scope, $this->cacheIdentifier, $tag)
|
||
);
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "tags" WHERE "scope"=? AND "cache"=? AND "tag"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier, $tag)
|
||
);
|
||
}
|
||
/**
|
||
* Removes all cache entries of this cache which are tagged by the specified tags.
|
||
* This method doesn't exist in FLOW3, but is mandatory for TYPO3v4.
|
||
*
|
||
* @TODO: Make smarter
|
||
* @param array $tags The tags the entries must have
|
||
* @return void
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function flushBytags(array $tags) {
|
||
foreach($tags as $tag) {
|
||
$this->flushByTag($tag);
|
||
}
|
||
}
|
||
/**
|
||
* Finds and returns all cache entry identifiers which are tagged by the
|
||
* specified tag.
|
||
*
|
||
* @param string $tag The tag to search for
|
||
* @return array An array with identifiers of all matching entries. An empty array if no entries matched
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function findIdentifiersByTag($tag) {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'SELECT "identifier" FROM "tags" WHERE "scope"=? AND "cache"=? AND "tag"=?'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier, $tag)
|
||
);
|
||
return $statementHandle->fetchAll(PDO::FETCH_COLUMN);
|
||
}
|
||
/**
|
||
* Finds and returns all cache entry identifiers which are tagged with
|
||
* all of the specified tags.
|
||
* This method doesn't exist in FLOW3, but is mandatory for TYPO3v4.
|
||
*
|
||
* @TODO: Make smarter
|
||
* @param array $tags Tags to search for
|
||
* @return array An array with identifiers of all matching entries. An empty array if no entries matched
|
||
* @author Christian Kuhn <lolli@schwarzbu.ch>
|
||
*/
|
||
public function findIdentifiersByTags(array $tags) {
|
||
$taggedEntries = array();
|
||
$foundEntries = array();
|
||
foreach ($tags as $tag) {
|
||
$taggedEntries[$tag] = $this->findIdentifiersByTag($tag);
|
||
}
|
||
$intersectedTaggedEntries = call_user_func_array('array_intersect', $taggedEntries);
|
||
foreach ($intersectedTaggedEntries as $entryIdentifier) {
|
||
if ($this->has($entryIdentifier)) {
|
||
$foundEntries[$entryIdentifier] = $entryIdentifier;
|
||
}
|
||
}
|
||
return $foundEntries;
|
||
}
|
||
/**
|
||
* Does garbage collection
|
||
*
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @api
|
||
*/
|
||
public function collectGarbage() {
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "tags" WHERE "scope"=? AND "cache"=? AND "identifier" IN ' .
|
||
'(SELECT "identifier" FROM "cache" WHERE "scope"=? AND "cache"=? AND "lifetime" > 0 AND "created" + "lifetime" < ' . $GLOBALS['EXEC_TIME'] . ')'
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier, $this->scope, $this->cacheIdentifier)
|
||
);
|
||
$statementHandle = $this->databaseHandle->prepare(
|
||
'DELETE FROM "cache" WHERE "scope"=? AND "cache"=? AND "lifetime" > 0 AND "created" + "lifetime" < ' . $GLOBALS['EXEC_TIME']
|
||
);
|
||
$statementHandle->execute(
|
||
array($this->scope, $this->cacheIdentifier)
|
||
);
|
||
}
|
||
/**
|
||
* Returns an SQL statement that evaluates to true if the entry is not expired.
|
||
*
|
||
* @return string
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
protected function getNotExpiredStatement() {
|
||
return ' AND ("lifetime" = 0 OR "created" + "lifetime" >= ' . $GLOBALS['EXEC_TIME'] . ')';
|
||
}
|
||
/**
|
||
* Connect to the database
|
||
*
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
protected function connect() {
|
||
try {
|
||
$splitdsn = explode(':', $this->dataSourceName, 2);
|
||
$this->pdoDriver = $splitdsn[0];
|
||
if ($this->pdoDriver === 'sqlite' && !file_exists($splitdsn[1])) {
|
||
$this->createCacheTables();
|
||
}
|
||
$this->databaseHandle = t3lib_div::makeInstance('PDO', $this->dataSourceName, $this->username, $this->password);
|
||
$this->databaseHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||
if ($this->pdoDriver === 'mysql') {
|
||
$this->databaseHandle->exec('SET SESSION sql_mode=\'ANSI\';');
|
||
}
|
||
} catch (PDOException $e) {
|
||
# $this->createCacheTables();
|
||
}
|
||
}
|
||
/**
|
||
* Creates the tables needed for the cache backend.
|
||
*
|
||
* @return void
|
||
* @throws RuntimeException if something goes wrong
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
protected function createCacheTables() {
|
||
try {
|
||
$pdoHelper = t3lib_div::makeInstance('t3lib_PdoHelper', $this->dataSourceName, $this->username, $this->password);
|
||
$pdoHelper->importSql(PATH_t3lib . 'cache/backend/resources/ddl.sql');
|
||
} catch (PDOException $e) {
|
||
throw new RuntimeException(
|
||
'Could not create cache tables with DSN "' . $this->dataSourceName . '". PDO error: ' . $e->getMessage(),
|
||
1259576985
|
||
);
|
||
}
|
||
}
|
||
}
|
||
if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/cache/backend/class.t3lib_cache_backend_pdobackend.php']) {
|
||
include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/cache/backend/class.t3lib_cache_backend_pdobackend.php']);
|
||
}
|
||
?>
|
t3lib/core_autoload.php (working copy) | ||
---|---|---|
't3lib_cache_backend_filebackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_filebackend.php',
|
||
't3lib_cache_backend_memcachedbackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_memcachedbackend.php',
|
||
't3lib_cache_backend_nullbackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_nullbackend.php',
|
||
't3lib_cache_backend_pdobackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_pdobackend.php',
|
||
't3lib_cache_backend_transientmemorybackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_transientmemorybackend.php',
|
||
't3lib_cache_backend_backend' => PATH_t3lib . 'cache/backend/interfaces/interface.t3lib_cache_backend_backend.php',
|
||
't3lib_cache_exception_classalreadyloaded' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_classalreadyloaded.php',
|
||
... | ... | |
't3lib_matchcondition_abstract' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_abstract.php',
|
||
't3lib_matchcondition_backend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_backend.php',
|
||
't3lib_matchcondition_frontend' => PATH_t3lib . 'matchcondition/class.t3lib_matchcondition_frontend.php',
|
||
't3lib_pdohelper' => PATH_t3lib . 'class.t3lib_pdohelper.php',
|
||
't3lib_tceforms_suggest' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest.php',
|
||
't3lib_tceforms_suggest_defaultreceiver' => PATH_t3lib . 'tceforms/class.t3lib_tceforms_suggest_defaultreceiver.php',
|
||
't3lib_utility_client' => PATH_t3lib . 'utility/class.t3lib_utility_client.php',
|
t3lib/class.t3lib_pdohelper.php (revision 0) | ||
---|---|---|
<?php
|
||
/***************************************************************
|
||
* Copyright notice
|
||
*
|
||
* (c) 2010 Christian Kuhn <lolli@schwarzbu.ch>
|
||
* All rights reserved
|
||
*
|
||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||
* free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* The GNU General Public License can be found at
|
||
* http://www.gnu.org/copyleft/gpl.html.
|
||
* A copy is found in the textfile GPL.txt and important notices to the license
|
||
* from the author is found in LICENSE.txt distributed with these scripts.
|
||
*
|
||
*
|
||
* This script is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU General Public License for more details.
|
||
*
|
||
* This copyright notice MUST APPEAR in all copies of the script!
|
||
***************************************************************/
|
||
/**
|
||
* A helper class for handling PDO databases
|
||
* Backport of FLOW3 class PdoHelper, last synced version: 3528
|
||
*
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
* @package TYPO3
|
||
* @subpackage t3lib
|
||
* @version $Id$
|
||
* @scope prototype
|
||
*/
|
||
class t3lib_PdoHelper {
|
||
/**
|
||
* @var PDO
|
||
*/
|
||
protected $databaseHandle;
|
||
/**
|
||
* @var string
|
||
*/
|
||
protected $pdoDriver;
|
||
/**
|
||
* Construct the helper instance and set up PDO connection.
|
||
*
|
||
* @param string $dataSourceName
|
||
* @param string $user
|
||
* @param string $password
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function __construct($dataSourceName, $user, $password) {
|
||
$splitdsn = explode(':', $dataSourceName, 2);
|
||
$this->pdoDriver = $splitdsn[0];
|
||
$this->databaseHandle = t3lib_div::makeInstance('PDO', $dataSourceName, $user, $password);
|
||
$this->databaseHandle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||
if ($this->pdoDriver === 'mysql') {
|
||
$this->databaseHandle->exec('SET SESSION sql_mode=\'ANSI_QUOTES\';');
|
||
}
|
||
}
|
||
/**
|
||
* Pumps the SQL into the database. Use for DDL only.
|
||
*
|
||
* Important: key definitions with length specifiers (needed for MySQL) must
|
||
* be given as "field"(xyz) - no space between double quote and parenthesis -
|
||
* so they can be removed automatically.
|
||
*
|
||
* @param string $pathAndFilename
|
||
* @return void
|
||
* @author Karsten Dambekalns <karsten@typo3.org>
|
||
*/
|
||
public function importSql($pathAndFilename) {
|
||
$sql = file($pathAndFilename, FILE_IGNORE_NEW_LINES & FILE_SKIP_EMPTY_LINES);
|
||
// Remove MySQL style key length delimiters (yuck!) if we are not setting up a MySQL db
|
||
if ($this->pdoDriver !== 'mysql') {
|
||
$sql = preg_replace('/"\([0-9]+\)/', '"', $sql);
|
||
}
|
||
$statement = '';
|
||
foreach ($sql as $line) {
|
||
$statement .= ' ' . trim($line);
|
||
if (substr($statement, -1) === ';') {
|
||
$this->databaseHandle->query($statement);
|
||
$statement = '';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_pdohelper.php']) {
|
||
include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_pdohelper.php']);
|
||
}
|
||
?>
|
- « Previous
- 1
- 2
- Next »