summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Echo/includes/mapper/NotificationMapper.php')
-rw-r--r--Echo/includes/mapper/NotificationMapper.php128
1 files changed, 44 insertions, 84 deletions
diff --git a/Echo/includes/mapper/NotificationMapper.php b/Echo/includes/mapper/NotificationMapper.php
index 3e9dc2f6..4e572a78 100644
--- a/Echo/includes/mapper/NotificationMapper.php
+++ b/Echo/includes/mapper/NotificationMapper.php
@@ -23,31 +23,11 @@ class EchoNotificationMapper extends EchoAbstractMapper {
$dbw,
__METHOD__,
function ( IDatabase $dbw, $fname ) use ( $row, $listeners ) {
- // Reset the bundle base if this notification has a display hash
- // the result of this operation is that all previous notifications
- // with the same display hash are set to non-base because new record
- // is becoming the bundle base
- if ( $row['notification_bundle_display_hash'] ) {
- $dbw->update(
- 'echo_notification',
- [ 'notification_bundle_base' => 0 ],
- [
- 'notification_user' => $row['notification_user'],
- 'notification_bundle_display_hash' =>
- $row['notification_bundle_display_hash'],
- 'notification_bundle_base' => 1
- ],
- $fname
- );
- }
-
$row['notification_timestamp'] =
$dbw->timestamp( $row['notification_timestamp'] );
- $res = $dbw->insert( 'echo_notification', $row, $fname );
- if ( $res ) {
- foreach ( $listeners as $listener ) {
- $dbw->onTransactionIdle( $listener );
- }
+ $dbw->insert( 'echo_notification', $row, $fname );
+ foreach ( $listeners as $listener ) {
+ $dbw->onTransactionCommitOrIdle( $listener, $fname );
}
}
) );
@@ -55,7 +35,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
/**
* Extract the offset used for notification list
- * @param string $continue String Used for offset
+ * @param string|null $continue String Used for offset
* @throws MWException
* @return int[]
*/
@@ -84,11 +64,11 @@ class EchoNotificationMapper extends EchoAbstractMapper {
* which is done via a deleteJob
* @param User $user
* @param int $limit
- * @param string $continue Used for offset
+ * @param string|null $continue Used for offset
* @param string[] $eventTypes
* @param Title[]|null $titles If set, only return notifications for these pages.
* To find notifications not associated with any page, add null as an element to this array.
- * @param int $dbSource Use master or slave database
+ * @param int $dbSource Use master or replica database
* @return EchoNotification[]
*/
public function fetchUnreadByUser(
@@ -99,7 +79,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
array $titles = null,
$dbSource = DB_REPLICA
) {
- $conds['notification_read_timestamp'] = null;
+ $conds = [ 'notification_read_timestamp' => null ];
if ( $titles ) {
$conds['event_page_id'] = $this->getIdsForTitles( $titles );
if ( !$conds['event_page_id'] ) {
@@ -117,11 +97,11 @@ class EchoNotificationMapper extends EchoAbstractMapper {
* which is done via a deleteJob
* @param User $user
* @param int $limit
- * @param string $continue Used for offset
+ * @param string|null $continue Used for offset
* @param string[] $eventTypes
* @param Title[]|null $titles If set, only return notifications for these pages.
* To find notifications not associated with any page, add null as an element to this array.
- * @param int $dbSource Use master or slave database
+ * @param int $dbSource Use master or replica database
* @return EchoNotification[]
*/
public function fetchReadByUser(
@@ -147,7 +127,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
*
* @param User $user the user to get notifications for
* @param int $limit The maximum number of notifications to return
- * @param string $continue Used for offset
+ * @param string|null $continue Used for offset
* @param array $eventTypes Event types to load
* @param array $excludeEventIds Event id's to exclude.
* @param Title[]|null $titles If set, only return notifications for these pages.
@@ -193,10 +173,10 @@ class EchoNotificationMapper extends EchoAbstractMapper {
/**
* @param User $user the user to get notifications for
* @param int $limit The maximum number of notifications to return
- * @param string $continue Used for offset
+ * @param string|null $continue Used for offset
* @param array $eventTypes Event types to load
* @param array $conds Additional query conditions.
- * @param int $dbSource Use master or slave database
+ * @param int $dbSource Use master or replica database
* @return EchoNotification[]
*/
protected function fetchByUserInternal(
@@ -220,7 +200,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
// the notification volume is in a reasonable amount for such case. The other option
// is to denormalize notification table with event_type and lookup index.
$conds = [
- 'notification_user' => $user->getID(),
+ 'notification_user' => $user->getId(),
'event_type' => $eventTypes,
'event_deleted' => 0,
] + $conds;
@@ -237,7 +217,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
$res = $dbr->select(
[ 'echo_notification', 'echo_event' ],
- '*',
+ EchoNotification::selectFields(),
$conds,
__METHOD__,
[
@@ -263,7 +243,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
$allNotifications[] = $notification;
}
} catch ( Exception $e ) {
- $id = isset( $row->event_id ) ? $row->event_id : 'unknown event';
+ $id = $row->event_id ?? 'unknown event';
wfDebugLog( 'Echo', __METHOD__ . ": Failed initializing event: $id" );
MWExceptionHandler::logException( $e );
}
@@ -278,47 +258,18 @@ class EchoNotificationMapper extends EchoAbstractMapper {
}
/**
- * Get the last notification in a set of bundle-able notifications by a bundle hash
- * @param User $user
- * @param string $bundleHash The hash used to identify a set of bundle-able notifications
- * @return EchoNotification|false
- */
- public function fetchNewestByUserBundleHash( User $user, $bundleHash ) {
- $dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
-
- $row = $dbr->selectRow(
- [ 'echo_notification', 'echo_event' ],
- [ '*' ],
- [
- 'notification_user' => $user->getId(),
- 'notification_bundle_hash' => $bundleHash
- ],
- __METHOD__,
- [ 'ORDER BY' => 'notification_timestamp DESC', 'LIMIT' => 1 ],
- [
- 'echo_event' => [ 'LEFT JOIN', 'notification_event=event_id' ],
- ]
- );
- if ( $row ) {
- return EchoNotification::newFromRow( $row );
- } else {
- return false;
- }
- }
-
- /**
* Fetch EchoNotifications by user and event IDs.
*
* @param User $user
* @param int[] $eventIds
* @return EchoNotification[]|false
*/
- public function fetchByUserEvents( User $user, $eventIds ) {
+ public function fetchByUserEvents( User $user, array $eventIds ) {
$dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
$result = $dbr->select(
[ 'echo_notification', 'echo_event' ],
- '*',
+ EchoNotification::selectFields(),
[
'notification_user' => $user->getId(),
'notification_event' => $eventIds
@@ -352,7 +303,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
$dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
$row = $dbr->selectRow(
[ 'echo_notification', 'echo_event' ],
- [ '*' ],
+ EchoNotification::selectFields(),
[
'notification_user' => $user->getId(),
'event_deleted' => 0,
@@ -383,38 +334,47 @@ class EchoNotificationMapper extends EchoAbstractMapper {
*/
public function deleteByUserEventOffset( User $user, $eventId ) {
global $wgUpdateRowsPerQuery;
+ $eventMapper = new EchoEventMapper( $this->dbFactory );
$userId = $user->getId();
$dbw = $this->dbFactory->getEchoDb( DB_MASTER );
+ $dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
- $domainId = $dbw->getDomainId();
+ $domainId = $dbw->getDomainID();
- $idsToDelete = $dbw->selectFieldValues(
+ $iterator = new BatchRowIterator(
+ $dbr,
'echo_notification',
'notification_event',
- [
- 'notification_user' => $userId,
- 'notification_event < ' . (int)$eventId
- ],
- __METHOD__
+ $wgUpdateRowsPerQuery
);
- if ( !$idsToDelete ) {
- return true;
- }
- $success = true;
- foreach ( array_chunk( $idsToDelete, $wgUpdateRowsPerQuery ) as $batch ) {
- $success = $dbw->delete(
+ $iterator->addConditions( [
+ 'notification_user' => $userId,
+ 'notification_event < ' . (int)$eventId
+ ] );
+
+ foreach ( $iterator as $batch ) {
+ $eventIds = [];
+ foreach ( $batch as $row ) {
+ $eventIds[] = $row->notification_event;
+ }
+ $dbw->delete(
'echo_notification',
[
'notification_user' => $userId,
- 'notification_event' => $batch,
+ 'notification_event' => $eventIds,
],
__METHOD__
- ) && $success;
+ );
+
+ // Find out which events are now orphaned, i.e. no longer referenced in echo_notifications
+ // (besides the rows we just deleted) or in echo_email_batch, and delete them
+ $eventMapper->deleteOrphanedEvents( $eventIds, $userId, 'echo_notification' );
+
$lbFactory->commitAndWaitForReplication(
__METHOD__, $ticket, [ 'domain' => $domainId ] );
}
- return $success;
+ return true;
}
/**
@@ -423,7 +383,7 @@ class EchoNotificationMapper extends EchoAbstractMapper {
* @param int[] $eventIds
* @return int[]|false
*/
- public function fetchUsersWithNotificationsForEvents( $eventIds ) {
+ public function fetchUsersWithNotificationsForEvents( array $eventIds ) {
$dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
$res = $dbr->select(