forked from GNUsocial/gnu-social
[DATABASE] Update "modified" in Managed_DataObject instead of a DBMS trigger
Instead of relying on the MariaDB's ON UPDATE CURRENT_TIMESTAMP trigger update "modified" attributes in Managed_DataObject. Every raw query that needs adjusting is adjusted, as they won't update "modified" automatically anymore. The main goal behind this change is to fix "modified" updates on PostgreSQL.
This commit is contained in:
@@ -760,9 +760,12 @@ class File extends Managed_DataObject
|
||||
if ($file instanceof File) {
|
||||
throw new ServerException('URL already exists in DB');
|
||||
}
|
||||
$sql = 'UPDATE %1$s SET urlhash = %2$s, url = %3$s WHERE urlhash = %4$s;';
|
||||
$result = $this->query(sprintf(
|
||||
$sql,
|
||||
<<<'END'
|
||||
UPDATE %1$s
|
||||
SET urlhash = %2$s, url = %3$s, modified = CURRENT_TIMESTAMP
|
||||
WHERE urlhash = %4$s;
|
||||
END,
|
||||
$this->tableName(),
|
||||
$this->_quote((string)self::hashurl($url)),
|
||||
$this->_quote((string)$url),
|
||||
@@ -939,7 +942,7 @@ class File extends Managed_DataObject
|
||||
}
|
||||
}
|
||||
echo "...and now all the non-duplicates which are longer than 191 characters...\n";
|
||||
$file->query('UPDATE file SET url=LEFT(url, 191) WHERE LENGTH(url)>191');
|
||||
$file->query('UPDATE file SET url = LEFT(url, 191) WHERE LENGTH(url) > 191');
|
||||
|
||||
echo "\n...now running hacky pre-schemaupdate change for $table:";
|
||||
// We have to create a urlhash that is _not_ the primary key,
|
||||
@@ -973,7 +976,7 @@ class File extends Managed_DataObject
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
$tablefix->query(sprintf(
|
||||
'UPDATE %1$s SET urlhash = %2$s;',
|
||||
'UPDATE %1$s SET urlhash = %2$s, modified = CURRENT_TIMESTAMP;',
|
||||
$tablefix->escapedTableName(),
|
||||
$url_sha256
|
||||
));
|
||||
|
@@ -468,7 +468,7 @@ class File_redirection extends Managed_DataObject
|
||||
throw new ServerException('Unknown DB type selected.');
|
||||
}
|
||||
$tablefix->query(sprintf(
|
||||
'UPDATE %1$s SET urlhash = %2$s;',
|
||||
'UPDATE %1$s SET urlhash = %2$s, modified = CURRENT_TIMESTAMP;',
|
||||
$tablefix->escapedTableName(),
|
||||
$url_sha256
|
||||
));
|
||||
|
@@ -74,15 +74,20 @@ class Local_group extends Managed_DataObject
|
||||
public function setNickname($nickname)
|
||||
{
|
||||
$this->decache();
|
||||
$modified = common_sql_now();
|
||||
$result = $this->query(sprintf(
|
||||
'UPDATE local_group SET nickname = %1$s WHERE group_id = %2$d;',
|
||||
<<<'END'
|
||||
UPDATE local_group SET nickname = %1$s, modified = %2$s
|
||||
WHERE group_id = %3$d;
|
||||
END,
|
||||
$this->_quote($nickname),
|
||||
$this->_quote($modified),
|
||||
$this->group_id
|
||||
));
|
||||
|
||||
if ($result) {
|
||||
$this->nickname = $nickname;
|
||||
$this->fixupTimestamps();
|
||||
$this->modified = $modified;
|
||||
$this->encache();
|
||||
} else {
|
||||
common_log_db_error($local, 'UPDATE', __FILE__);
|
||||
|
@@ -522,6 +522,25 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
return $aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute defined as "timestamp" to CURRENT_TIMESTAMP.
|
||||
* This is hooked in update() and updateWithKeys() to update "modified".
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function updateAutoTimestamps(): void
|
||||
{
|
||||
$table = static::schemaDef();
|
||||
foreach ($table['fields'] as $name => $col) {
|
||||
if ($col['type'] === 'timestamp'
|
||||
&& !array_key_exists('default', $col)
|
||||
&& !isset($this->$name)) {
|
||||
$this->$name = common_sql_now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update() won't write key columns, so we have to do it ourselves.
|
||||
* This also automatically calls "update" _before_ it sets the keys.
|
||||
@@ -548,6 +567,10 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
// do it in a transaction
|
||||
$this->query('START TRANSACTION');
|
||||
|
||||
// ON UPDATE CURRENT_TIMESTAMP behaviour
|
||||
// @fixme Should the value be reverted back if transaction failed?
|
||||
$this->updateAutoTimestamps();
|
||||
|
||||
$parts = [];
|
||||
foreach ($this->keys() as $k) {
|
||||
$v = $this->table()[$k];
|
||||
@@ -664,12 +687,25 @@ abstract class Managed_DataObject extends Memcached_DataObject
|
||||
public function insert()
|
||||
{
|
||||
$this->onInsert();
|
||||
return parent::insert();
|
||||
$result = parent::insert();
|
||||
|
||||
// Make this object aware of the changed "modified" attribute.
|
||||
// Sets it approximately to the same value as DEFAULT CURRENT_TIMESTAMP
|
||||
// just did (@fixme).
|
||||
if ($result) {
|
||||
$this->updateAutoTimestamps();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function update($dataObject=false)
|
||||
public function update($dataObject = false)
|
||||
{
|
||||
$this->onUpdate($dataObject);
|
||||
|
||||
// ON UPDATE CURRENT_TIMESTAMP behaviour
|
||||
// @fixme Should the value be reverted back if transaction failed?
|
||||
$this->updateAutoTimestamps();
|
||||
|
||||
return parent::update($dataObject);
|
||||
}
|
||||
}
|
||||
|
@@ -443,7 +443,6 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
{
|
||||
$result = parent::insert();
|
||||
if ($result) {
|
||||
$this->fixupTimestamps();
|
||||
$this->encache(); // in case of cached negative lookups
|
||||
}
|
||||
return $result;
|
||||
@@ -456,7 +455,6 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
$result = parent::update($dataObject);
|
||||
if ($result !== false) {
|
||||
$this->fixupTimestamps();
|
||||
$this->encache();
|
||||
}
|
||||
return $result;
|
||||
@@ -931,22 +929,6 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
return $c->delete($cacheKey);
|
||||
}
|
||||
|
||||
public function fixupTimestamps()
|
||||
{
|
||||
// Fake up timestamp columns
|
||||
$columns = $this->table();
|
||||
foreach ($columns as $name => $type) {
|
||||
if ($type & DB_DATAOBJECT_MYSQLTIMESTAMP) {
|
||||
$this->$name = common_sql_now();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function debugDump()
|
||||
{
|
||||
common_debug("debugDump: " . common_log_objstring($this));
|
||||
}
|
||||
|
||||
public function raiseError($message, $type = null, $behavior = null)
|
||||
{
|
||||
$id = get_class($this);
|
||||
|
@@ -3243,7 +3243,11 @@ class Notice extends Managed_DataObject
|
||||
unset($notice);
|
||||
$notice = new Notice();
|
||||
$notice->query(sprintf(
|
||||
'UPDATE %1$s SET %2$s = NULL WHERE id IN (%3$s)',
|
||||
<<<'END'
|
||||
UPDATE %1$s
|
||||
SET %2$s = NULL, modified = CURRENT_TIMESTAMP
|
||||
WHERE id IN (%3$s)
|
||||
END,
|
||||
$notice->escapedTableName(),
|
||||
$field,
|
||||
implode(',', $ids)
|
||||
|
@@ -86,6 +86,7 @@ class Oauth_application_user extends Managed_DataObject
|
||||
return true;
|
||||
}
|
||||
$toupdate = implode(', ', $parts);
|
||||
$toupdate .= ', modified = CURRENT_TIMESTAMP';
|
||||
|
||||
$table = $this->tableName();
|
||||
$tableName = $this->escapedTableName();
|
||||
|
@@ -292,14 +292,16 @@ class Profile_tag extends Managed_DataObject
|
||||
public static function moveTag($orig, $new)
|
||||
{
|
||||
$tags = new Profile_tag();
|
||||
$qry = "UPDATE profile_tag SET tag = '%s', tagger = '%s' " .
|
||||
"WHERE tag = '%s' AND tagger = '%s'";
|
||||
$result = $tags->query(sprintf(
|
||||
$qry,
|
||||
$tags->escape($new->tag),
|
||||
$tags->escape($new->tagger),
|
||||
$tags->escape($orig->tag),
|
||||
$tags->escape($orig->tagger)
|
||||
<<<'END'
|
||||
UPDATE profile_tag
|
||||
SET tag = %1$s, tagger = %2$s, modified = CURRENT_TIMESTAMP
|
||||
WHERE tag = %3$s AND tagger = %4$s
|
||||
END,
|
||||
$tags->_quote($new->tag),
|
||||
$tags->_quote($new->tagger),
|
||||
$tags->_quote($orig->tag),
|
||||
$tags->_quote($orig->tagger)
|
||||
));
|
||||
|
||||
if ($result === false) {
|
||||
|
@@ -104,11 +104,22 @@ class Queue_item extends Managed_DataObject
|
||||
*/
|
||||
public function releaseClaim()
|
||||
{
|
||||
// DB_DataObject doesn't let us save nulls right now
|
||||
$sql = sprintf("UPDATE queue_item SET claimed=NULL WHERE id=%d", $this->getID());
|
||||
$this->query($sql);
|
||||
$modified = common_sql_now();
|
||||
// @fixme Consider $this->sqlValue('NULL')
|
||||
$ret = $this->query(sprintf(
|
||||
<<<'END'
|
||||
UPDATE queue_item
|
||||
SET claimed = NULL, modified = %1$s
|
||||
WHERE id = %2$d
|
||||
END,
|
||||
$this->_quote($modified),
|
||||
$this->getID()
|
||||
));
|
||||
|
||||
$this->claimed = null;
|
||||
$this->encache();
|
||||
if ($ret) {
|
||||
$this->claimed = null;
|
||||
$this->modified = $modified;
|
||||
$this->encache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user