Bug #21017 » 0011903_v6.patch
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 (
|
- « Previous
- 1
- …
- 3
- 4
- 5
- Next »