diff --git a/src/applications/fact/extract/PhabricatorFactUpdateIterator.php b/src/applications/fact/extract/PhabricatorFactUpdateIterator.php index be93cf62c1..bdea82dc4d 100644 --- a/src/applications/fact/extract/PhabricatorFactUpdateIterator.php +++ b/src/applications/fact/extract/PhabricatorFactUpdateIterator.php @@ -33,7 +33,6 @@ final class PhabricatorFactUpdateIterator extends PhutilBufferedIterator { public function __construct(LiskDAO $object) { $this->set = new LiskDAOSet(); $this->object = $object->putInSet($this->set); - $this->position = '0:0'; } public function setPosition($position) { @@ -46,7 +45,11 @@ final class PhabricatorFactUpdateIterator extends PhutilBufferedIterator { } protected function getCursorFromObject($object) { - return $object->getDateModified().':'.$object->getID(); + if ($object->hasProperty('dateModified')) { + return $object->getDateModified().':'.$object->getID(); + } else { + return $object->getID(); + } } public function key() { @@ -54,32 +57,50 @@ final class PhabricatorFactUpdateIterator extends PhutilBufferedIterator { } protected function loadPage() { - list($after_epoch, $after_id) = explode(':', $this->cursor); - $this->set->clearSet(); - // NOTE: We ignore recent updates because once we process an update we'll - // never process rows behind it again. We need to read only rows which - // we're sure no new rows will be inserted behind. If we read a row that - // was updated on the current second, another update later on in this second - // could affect an object with a lower ID, and we'd skip that update. To - // avoid this, just ignore any rows which have been updated in the last few - // seconds. This also reduces the amount of work we need to do if an object - // is repeatedly updated; we will just look at the end state without - // processing the intermediate states. Finally, this gives us reasonable - // protections against clock skew between the machine the daemon is running - // on and any machines performing writes. + if ($this->object->hasProperty('dateModified')) { + if ($this->cursor) { + list($after_epoch, $after_id) = explode(':', $this->cursor); + } else { + $after_epoch = 0; + $after_id = 0; + } - $page = $this->object->loadAllWhere( - '((dateModified > %d) OR (dateModified = %d AND id > %d)) - AND (dateModified < %d - %d) - ORDER BY dateModified ASC, id ASC LIMIT %d', - $after_epoch, - $after_epoch, - $after_id, - time(), - $this->ignoreUpdatesDuration, - $this->getPageSize()); + // NOTE: We ignore recent updates because once we process an update we'll + // never process rows behind it again. We need to read only rows which + // we're sure no new rows will be inserted behind. If we read a row that + // was updated on the current second, another update later on in this + // second could affect an object with a lower ID, and we'd skip that + // update. To avoid this, just ignore any rows which have been updated in + // the last few seconds. This also reduces the amount of work we need to + // do if an object is repeatedly updated; we will just look at the end + // state without processing the intermediate states. Finally, this gives + // us reasonable protections against clock skew between the machine the + // daemon is running on and any machines performing writes. + + $page = $this->object->loadAllWhere( + '((dateModified > %d) OR (dateModified = %d AND id > %d)) + AND (dateModified < %d - %d) + ORDER BY dateModified ASC, id ASC LIMIT %d', + $after_epoch, + $after_epoch, + $after_id, + time(), + $this->ignoreUpdatesDuration, + $this->getPageSize()); + } else { + if ($this->cursor) { + $after_id = $this->cursor; + } else { + $after_id = 0; + } + + $page = $this->object->loadAllWhere( + 'id > %d ORDER BY id ASC LIMIT %d', + $after_id, + $this->getPageSize()); + } if ($page) { $this->cursor = $this->getCursorFromObject(end($page)); diff --git a/src/applications/repository/storage/PhabricatorRepositoryCommit.php b/src/applications/repository/storage/PhabricatorRepositoryCommit.php index 433b439dc8..ce178d5678 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryCommit.php +++ b/src/applications/repository/storage/PhabricatorRepositoryCommit.php @@ -102,6 +102,11 @@ final class PhabricatorRepositoryCommit extends PhabricatorRepositoryDAO { return $result; } + public function getDateCreated() { + // This is primarily to make analysis of commits with the Fact engine work. + return $this->getEpoch(); + } + /** * Synchronize a commit's overall audit status with the individual audit * triggers. @@ -144,6 +149,4 @@ final class PhabricatorRepositoryCommit extends PhabricatorRepositoryDAO { return $this->setAuditStatus($status); } - - } diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php index 47092515ea..0342982a1f 100644 --- a/src/infrastructure/storage/lisk/LiskDAO.php +++ b/src/infrastructure/storage/lisk/LiskDAO.php @@ -647,7 +647,7 @@ abstract class LiskDAO { // already determined it's not valid. We don't need to check again. continue; } - $valid_properties[$k] = (bool)$this->checkProperty($k); + $valid_properties[$k] = $this->hasProperty($k); if (!$valid_properties[$k]) { continue; } @@ -896,6 +896,18 @@ abstract class LiskDAO { } + /** + * Test if a property exists. + * + * @param string Property name. + * @return bool True if the property exists. + * @task info + */ + public function hasProperty($property) { + return (bool)$this->checkProperty($property); + } + + /** * Retrieve a list of all object properties. This list only includes * properties that are declared as protected, and it is expected that