Project

General

Profile

Bug #21017 » 0011903_v6.patch

Administrator Admin, 2009-09-21 15:12

View differences:

tests/t3lib/cache/backend/t3lib_cache_backend_dbbackendtestcase.php (Arbeitskopie)
protected $backend;
protected $testingCacheTable;
protected $testingTagsTable;
/**
* Sets up this testcase
......
*/
public function setUp() {
$this->testingCacheTable = 'test_cache_dbbackend';
$this->testingTagsTable = 'test_cache_dbbackend_tags';
$GLOBALS['TYPO3_DB']->sql_query('CREATE TABLE ' . $this->testingCacheTable . ' (
id int(11) unsigned NOT NULL auto_increment,
......
) ENGINE=InnoDB;
');
$GLOBALS['TYPO3_DB']->sql_query('CREATE TABLE ' . $this->testingTagsTable . ' (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(128) DEFAULT \'\' NOT NULL,
tag varchar(128) DEFAULT \'\' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier),
KEY cache_tag (tag)
) ENGINE=InnoDB;
');
$this->backend = t3lib_div::makeInstance(
't3lib_cache_backend_DbBackend',
array('cacheTable' => $this->testingCacheTable)
array(
'cacheTable' => $this->testingCacheTable,
'tagsTable' => $this->testingTagsTable,
)
);
}
......
$entriesFound = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'*',
$this->testingCacheTable,
$this->testingTagsTable,
'identifier = \'' . $entryIdentifier . '\''
);
$tags = explode(',', $entriesFound[0]['tags']);
$tags = array();
$this->assertTrue(is_array($tags) && count($entriesFound) > 0, 'The tags do not exist.');
foreach ($entriesFound as $entry) {
$tags[] = $entry['tag'];
}
$this->assertTrue(count($tags) > 0, 'The tags do not exist.');
$this->assertTrue(in_array('UnitTestTag%tag1', $tags), 'Tag UnitTestTag%tag1 does not exist.');
$this->assertTrue(in_array('UnitTestTag%tag2', $tags), 'Tag UnitTestTag%tag2 does not exist.');
}
......
$this->assertTrue(is_array($entriesFound) && count($entriesFound) > 0, 'The cache entry does not exist.');
sleep(2);
$GLOBALS['EXEC_TIME'] += 2;
$this->backend->collectGarbage();
$entriesFound = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
......
$this->assertTrue(is_array($entriesFound) && count($entriesFound) > 0, 'The cache entries do not exist.');
sleep(2);
$GLOBALS['EXEC_TIME'] += 2;
$this->backend->collectGarbage();
$entriesFound = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
......
$this->backend->set($expiredEntryIdentifier, $expiredData, array(), 1);
sleep(2);
$GLOBALS['EXEC_TIME'] += 2;
$this->assertFalse($this->backend->has($expiredEntryIdentifier), 'has() did not return FALSE.');
}
......
$this->backend->set($expiredEntryIdentifier, $expiredData, array(), 1);
sleep(2);
$GLOBALS['EXEC_TIME'] += 2;
$this->assertEquals($data, $this->backend->get($entryIdentifier), 'The original and the retrieved data don\'t match.');
$this->assertFalse($this->backend->get($expiredEntryIdentifier), 'The expired entry could be loaded.');
......
$this->backend->set('BackendDbTest', 'some data', array('UnitTestTag%special'), 1);
sleep(2);
$GLOBALS['EXEC_TIME'] += 2;
// Not required, but used to update the pre-calculated queries:
$this->backend->setTagsTable($this->testingTagsTable);
$this->assertEquals(array(), $this->backend->findIdentifiersByTag('UnitTestTag%special'));
}
......
/**
* @test
* @author Ingo Renner <ingo@typo3.org>
*/
public function tearDown() {
$GLOBALS['TYPO3_DB']->sql_query(
'DROP TABLE ' . $this->testingCacheTable . ';'
);
$GLOBALS['TYPO3_DB']->sql_query(
'DROP TABLE ' . $this->testingTagsTable . ';'
);
}
}
t3lib/config_default.php (Arbeitskopie)
'cache_hash' => array(
'backend' => 't3lib_cache_backend_DbBackend',
'options' => array(
'cacheTable' => 'cachingframework_cache_hash'
'cacheTable' => 'cachingframework_cache_hash',
'tagsTable' => 'cachingframework_cache_hash_tags',
)
),
'cache_pages' => array(
'backend' => 't3lib_cache_backend_DbBackend',
'options' => array(
'cacheTable' => 'cachingframework_cache_pages'
'cacheTable' => 'cachingframework_cache_pages',
'tagsTable' => 'cachingframework_cache_pages_tags',
)
),
'cache_pagesection' => array(
'backend' => 't3lib_cache_backend_DbBackend',
'options' => array(
'cacheTable' => 'cachingframework_cache_pagesection'
'cacheTable' => 'cachingframework_cache_pagesection',
'tagsTable' => 'cachingframework_cache_pagesection_tags',
)
)
/*
t3lib/stddb/tables.sql (Arbeitskopie)
#
CREATE TABLE cachingframework_cache_hash (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(250) DEFAULT '' NOT NULL,
identifier varchar(128) DEFAULT '' NOT NULL,
crdate int(11) unsigned DEFAULT '0' NOT NULL,
content mediumtext,
tags mediumtext,
lifetime int(11) unsigned DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier)
) ENGINE=InnoDB;
#
# Table structure for table 'cachingframework_cache_hash_tags'
#
CREATE TABLE cachingframework_cache_hash_tags (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(128) DEFAULT '' NOT NULL,
tag varchar(128) DEFAULT '' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier),
KEY cache_tag (tag)
) ENGINE=InnoDB;
#
# Table structure for table 'cache_imagesizes'
#
CREATE TABLE cache_imagesizes (
t3lib/cache/backend/class.t3lib_cache_backend_dbbackend.php (Arbeitskopie)
class t3lib_cache_backend_DbBackend extends t3lib_cache_backend_AbstractBackend {
protected $cacheTable;
protected $tagsTable;
protected $identifierField;
protected $creationField;
protected $lifetimeField;
protected $notExpiredStatement;
protected $tableList;
protected $tableJoin;
/**
* Constructs this backend
*
* @param mixed Configuration options - depends on the actual backend
*/
public function __construct(array $options = array()) {
parent::__construct($options);
if (!$this->cacheTable) {
throw new t3lib_cache_Exception(
'No table to write data to has been set using the setting "cacheTable".',
1253534136
);
}
if (!$this->tagsTable) {
throw new t3lib_cache_Exception(
'No table to write tags to has been set using the setting "tagsTable".',
1253534137
);
}
$this->initializeCommonReferences();
}
/**
* Initializes common references used in this backend.
*
* @return void
*/
protected function initializeCommonReferences() {
$this->identifierField = $this->cacheTable . '.identifier';
$this->creationField = $this->cacheTable . '.crdate';
$this->lifetimeField = $this->cacheTable . '.lifetime';
$this->tableList = $this->cacheTable . ', ' . $this->tagsTable;
$this->tableJoin = $this->identifierField . ' = ' . $this->tagsTable . '.identifier';
$this->notExpiredStatement = '(' . $this->creationField . ' + ' . $this->lifetimeField .
' >= ' . $GLOBALS['EXEC_TIME'] . ' OR ' . $this->lifetimeField . ' = 0)';
}
/**
* Saves data in a cache file.
*
* @param string An identifier for this specific cache entry
......
'identifier' => $entryIdentifier,
'crdate' => $GLOBALS['EXEC_TIME'],
'content' => $data,
'tags' => implode(',', $tags),
'lifetime' => $lifetime
)
);
foreach ($tags as $tag) {
$GLOBALS['TYPO3_DB']->exec_INSERTquery(
$this->tagsTable,
array(
'identifier' => $entryIdentifier,
'tag' => $tag,
)
);
}
}
/**
......
'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->cacheTable)
);
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
$this->tagsTable,
'identifier = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($entryIdentifier, $this->tagsTable)
);
if($GLOBALS['TYPO3_DB']->sql_affected_rows($res) == 1) {
$entryRemoved = true;
}
......
$cacheEntryIdentifiers = array();
$cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'identifier',
$this->cacheTable,
$this->getListQueryForTag($tag) . ' AND (crdate + lifetime >= ' . $GLOBALS['EXEC_TIME'] . ' OR lifetime = 0)'
$this->identifierField,
$this->tableList,
$this->getQueryForTag($tag) .
' AND ' . $this->tableJoin .
' AND ' . $this->notExpiredStatement,
$this->identifierField
);
foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
......
$whereClause = array();
foreach ($tags as $tag) {
$whereClause[] = $this->getListQueryForTag($tag);
$whereClause[] = $this->getQueryForTag($tag);
}
$whereClause[] = '(crdate + lifetime >= ' . $GLOBALS['EXEC_TIME'] . ' OR lifetime = 0)';
$whereClause[] = $this->tableJoin;
$whereClause[] = $this->notExpiredStatement;
$cacheEntryIdentifierRows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'identifier',
$this->cacheTable,
implode(' AND ', $whereClause)
$this->identifierField,
$this->tableList,
implode(' AND ', $whereClause),
$this->identifierField
);
foreach ($cacheEntryIdentifierRows as $cacheEntryIdentifierRow) {
......
*/
public function flush() {
$GLOBALS['TYPO3_DB']->sql_query('TRUNCATE ' . $this->cacheTable);
$GLOBALS['TYPO3_DB']->sql_query('TRUNCATE ' . $this->tagsTable);
}
/**
......
* @return void
*/
public function flushByTag($tag) {
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
$this->cacheTable,
$this->getListQueryForTag($tag)
$GLOBALS['TYPO3_DB']->exec_DELETEmultipleTablesQuery(
$this->tableList,
$this->tableList,
$this->tableJoin .
' AND ' . $this->getQueryForTag($tag)
);
}
......
* @return void
*/
public function flushByTags(array $tags) {
$listQueryConditions = array();
foreach ($tags as $tag) {
$listQueryConditions[$tag] = $this->getListQueryForTag($tag);
if (count($tags)) {
$listQueryConditions = array();
foreach ($tags as $tag) {
$listQueryConditions[$tag] = $this->getQueryForTag($tag);
}
$GLOBALS['TYPO3_DB']->exec_DELETEmultipleTablesQuery(
$this->tableList,
$this->tableList,
$this->tableJoin .
' AND (' . implode(' OR ', $listQueryConditions) . ')'
);
}
$listQuery = implode(' OR ', $listQueryConditions);
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
$this->cacheTable,
$listQuery
);
}
/**
......
* @author Ingo Renner <ingo@typo3.org>
*/
public function collectGarbage() {
$GLOBALS['TYPO3_DB']->exec_DELETEmultipleTablesQuery(
$this->tableList,
$this->tableList,
$this->tableJoin .
' AND ' . $this->cacheTable . '.crdate + ' . $this->cacheTable . '.lifetime < ' . $GLOBALS['EXEC_TIME'] .
' AND ' . $this->cacheTable . '.lifetime > 0'
);
$GLOBALS['TYPO3_DB']->exec_DELETEquery(
$this->cacheTable,
'crdate + lifetime < ' . $GLOBALS['EXEC_TIME'] . ' AND lifetime > 0'
......
}
*/
$this->cacheTable = $cacheTable;
$this->initializeCommonReferences();
}
/**
......
}
/**
* Sets the table where cache tags are stored.
*
* @param string $tagsTabls: Name of the table
* @return void
*/
public function setTagsTable($tagsTable) {
$this->tagsTable = $tagsTable;
$this->initializeCommonReferences();
}
/**
* Gets the table where cache tags are stored.
*
* @return string Name of the table storing tags
*/
public function getTagsTable() {
return $this->tagsTable;
}
/**
* Gets the query to be used for selecting entries by a tag. The asterisk ("*")
* is allowed as a wildcard at the beginning and the end of a tag.
*
......
* @return string the query to be used for selecting entries
* @author Oliver Hader <oliver@typo3.org>
*/
protected function getListQueryForTag($tag) {
return str_replace('*', '%', $GLOBALS['TYPO3_DB']->listQuery('tags', $tag, $this->cacheTable));
protected function getQueryForTag($tag) {
if (strpos($tag, '*') === false) {
$query = $this->tagsTable . '.tag = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($tag, $this->tagsTable);
} else {
$patternForLike = $GLOBALS['TYPO3_DB']->escapeStrForLike(
$GLOBALS['TYPO3_DB']->quoteStr($tag, $this->tagsTable),
$this->tagsTable
);
$query = $this->tagsTable . '.tag LIKE \'' . $patternForLike . '\'';
}
return $query;
}
}
t3lib/class.t3lib_db.php (Arbeitskopie)
}
/**
* Creates and executes a DELETE SQL-statement for multiple tables.
*
* @param string $tablesToDeleteFrom: Name of the tables to delete from
* @param string $tablesReference: Name of the tables references join the results
* @param string $where: WHERE clause, eg. "uid=1". NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself!
* @return pointer MySQL result pointer
*/
public function exec_DELETEmultipleTablesQuery($tablesToDeleteFrom, $tablesReference, $where) {
$res = mysql_query($this->DELETEmultipleTablesQuery($tablesToDeleteFrom, $tablesReference, $where), $this->link);
if ($this->debugOutput) {
$this->debug('exec_DELETEquery');
}
return $res;
}
/**
* Creates and executes a SELECT SQL-statement
* Using this function specifically allow us to handle the LIMIT feature independently of DB.
* Usage count/core: 340
......
}
/**
* Creates a DELETE SQL-statement for multiple tables
* Usage count/core: 3
*
* @param string See exec_DELETEmultipleTablesQuery()
* @param string See exec_DELETEmultipleTablesQuery()
* @param string See exec_DELETEmultipleTablesQuery()
* @return string Full SQL query for DELETE from multiple tables
*/
public function DELETEmultipleTablesQuery($tablesToDeleteFrom, $tablesReference, $where) {
if (is_string($where)) {
// Table and fieldnames should be "SQL-injection-safe" when supplied to this function
$query = 'DELETE ' . $tablesToDeleteFrom . ' FROM ' . $tablesReference .
(strlen($where) > 0 ? ' WHERE ' . $where : '');
if ($this->debugOutput || $this->store_lastBuiltQuery) {
$this->debug_lastBuiltQuery = $query;
}
return $query;
} else {
die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEmultipleTablesQuery() !');
}
}
/**
* Creates a SELECT SQL-statement
* Usage count/core: 11
*
typo3/sysext/cms/ext_tables.sql (Arbeitskopie)
#
CREATE TABLE cachingframework_cache_pages (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(250) DEFAULT '' NOT NULL,
identifier varchar(128) DEFAULT '' NOT NULL,
crdate int(11) unsigned DEFAULT '0' NOT NULL,
content mediumtext,
tags mediumtext,
lifetime int(11) unsigned DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier)
......
#
# Table structure for table 'cachingframework_cache_pages_tags'
#
CREATE TABLE cachingframework_cache_pages_tags (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(128) DEFAULT '' NOT NULL,
tag varchar(128) DEFAULT '' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier),
KEY cache_tag (tag)
) ENGINE=InnoDB;
#
# Table structure for table 'cachingframework_cache_pagesection'
#
CREATE TABLE cachingframework_cache_pagesection (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(250) DEFAULT '' NOT NULL,
identifier varchar(128) DEFAULT '' NOT NULL,
crdate int(11) unsigned DEFAULT '0' NOT NULL,
content mediumtext,
tags mediumtext,
lifetime int(11) unsigned DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier)
......
#
# Table structure for table 'cachingframework_cache_pagesection_tags'
#
CREATE TABLE cachingframework_cache_pagesection_tags (
id int(11) unsigned NOT NULL auto_increment,
identifier varchar(128) DEFAULT '' NOT NULL,
tag varchar(128) DEFAULT '' NOT NULL,
PRIMARY KEY (id),
KEY cache_id (identifier),
KEY cache_tag (tag)
) ENGINE=InnoDB;
#
# Table structure for table 'cache_typo3temp_log'
#
CREATE TABLE cache_typo3temp_log (
(5-5/5)