diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index da152dcc..f29f2fc7 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -1002,7 +1002,9 @@ class CoreRequestBuilder { $qb->selectAlias('sa.id', 'streamaction_id') ->selectAlias('sa.actor_id', 'streamaction_actor_id') ->selectAlias('sa.stream_id', 'streamaction_stream_id') - ->selectAlias('sa.values', 'streamaction_values'); + ->selectAlias('sa.liked', 'streamaction_liked') + ->selectAlias('sa.boosted', 'streamaction_boosted') + ->selectAlias('sa.replied', 'streamaction_replied'); $orX = $expr->orX(); $orX->add($expr->eq('sa.stream_id_prim', $pf . '.id_prim')); diff --git a/lib/Db/SocialCrossQueryBuilder.php b/lib/Db/SocialCrossQueryBuilder.php index 713b479c..86932c93 100644 --- a/lib/Db/SocialCrossQueryBuilder.php +++ b/lib/Db/SocialCrossQueryBuilder.php @@ -385,7 +385,9 @@ class SocialCrossQueryBuilder extends SocialCoreQueryBuilder { $this->selectAlias('sa.id', 'streamaction_id') ->selectAlias('sa.actor_id', 'streamaction_actor_id') ->selectAlias('sa.stream_id', 'streamaction_stream_id') - ->selectAlias('sa.values', 'streamaction_values'); + ->selectAlias('sa.liked', 'streamaction_liked') + ->selectAlias('sa.boosted', 'streamaction_boosted') + ->selectAlias('sa.replied', 'streamaction_replied'); } @@ -403,7 +405,9 @@ class SocialCrossQueryBuilder extends SocialCoreQueryBuilder { $this->selectAlias($alias . '.id', 'streamaction_id') ->selectAlias($alias . '.actor_id', 'streamaction_actor_id') ->selectAlias($alias . '.stream_id', 'streamaction_stream_id') - ->selectAlias($alias . '.values', 'streamaction_values'); + ->selectAlias($alias . '.liked', 'streamaction_liked') + ->selectAlias($alias . '.boosted', 'streamaction_boosted') + ->selectAlias($alias . '.replied', 'streamaction_replied'); $orX = $expr->orX(); $orX->add($expr->eq($alias . '.stream_id_prim', $pf . '.id_prim')); diff --git a/lib/Db/SocialLimitsQueryBuilder.php b/lib/Db/SocialLimitsQueryBuilder.php index 283fffbb..f543294a 100644 --- a/lib/Db/SocialLimitsQueryBuilder.php +++ b/lib/Db/SocialLimitsQueryBuilder.php @@ -186,6 +186,16 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { } + /** + * @param string $streamId + * @param string $alias + * + * @return void + */ + public function limitToStreamIdPrim(string $streamId, string $alias = '') { + $this->limitToDBField('stream_id_prim', $streamId, false, $alias); + } + /** * Limit the request to the FollowId * diff --git a/lib/Db/StreamActionsRequest.php b/lib/Db/StreamActionsRequest.php index f0a31fef..fa77bd25 100644 --- a/lib/Db/StreamActionsRequest.php +++ b/lib/Db/StreamActionsRequest.php @@ -55,11 +55,6 @@ class StreamActionsRequest extends StreamActionsRequestBuilder { ->setValue('actor_id_prim', $qb->createNamedParameter($qb->prim($action->getActorId()))) ->setValue('stream_id', $qb->createNamedParameter($action->getStreamId())) ->setValue('stream_id_prim', $qb->createNamedParameter($qb->prim($action->getStreamId()))) - ->setValue( - 'values', $qb->createNamedParameter( - json_encode($values, JSON_UNESCAPED_SLASHES) - ) - ) ->setValue('liked', $qb->createNamedParameter(($liked) ? 1 : 0)) ->setValue('boosted', $qb->createNamedParameter(($boosted) ? 1 : 0)) ->setValue('replied', $qb->createNamedParameter(($replied) ? 1 : 0)); @@ -68,24 +63,26 @@ class StreamActionsRequest extends StreamActionsRequestBuilder { } - /** - * Create a new Queue in the database. - */ public function update(StreamAction $action): int { $qb = $this->getStreamActionUpdateSql(); - $values = $action->getValues(); - $liked = $this->getBool(StreamAction::LIKED, $values, false); - $boosted = $this->getBool(StreamAction::BOOSTED, $values, false); - $replied = $this->getBool(StreamAction::REPLIED, $values, false); + // update entry/field in database, based only on affected action + // to avoid race condition on 2 different actions + foreach($action->getAffected() as $entry) { + $field = match ($entry) { + StreamAction::LIKED => 'liked', + StreamAction::BOOSTED => 'boosted', + StreamAction::REPLIED => 'replied', + default => '' + }; - $qb->set('values', $qb->createNamedParameter(json_encode($values, JSON_UNESCAPED_SLASHES))) - ->set('liked', $qb->createNamedParameter(($liked) ? 1 : 0)) - ->set('boosted', $qb->createNamedParameter(($boosted) ? 1 : 0)) - ->set('replied', $qb->createNamedParameter(($replied) ? 1 : 0)); + if ($field !== '') { + $qb->set($field, $qb->createNamedParameter(($action->getValueBool($entry)) ? 1 : 0)); + } + } - $this->limitToActorId($qb, $action->getActorId()); - $this->limitToStreamId($qb, $action->getStreamId()); + $qb->limitToActorIdPrim($qb->prim($action->getActorId())); + $qb->limitToStreamIdPrim($qb->prim($action->getStreamId())); return $qb->executeStatement(); } diff --git a/lib/Db/StreamActionsRequestBuilder.php b/lib/Db/StreamActionsRequestBuilder.php index dc7159a0..f76a51f3 100644 --- a/lib/Db/StreamActionsRequestBuilder.php +++ b/lib/Db/StreamActionsRequestBuilder.php @@ -77,7 +77,10 @@ class StreamActionsRequestBuilder extends CoreRequestBuilder { $qb = $this->getQueryBuilder(); /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select('sa.id', 'sa.actor_id', 'sa.stream_id', 'sa.values') + $qb->select( + 'sa.id', 'sa.actor_id', 'sa.stream_id', + 'sa.boosted', 'sa.liked', 'sa.replied' + ) ->from(self::TABLE_STREAM_ACTIONS, 'sa'); $this->defaultSelectAlias = 'sa'; diff --git a/lib/Db/StreamRequestBuilder.php b/lib/Db/StreamRequestBuilder.php index ee1b5862..8071e733 100644 --- a/lib/Db/StreamRequestBuilder.php +++ b/lib/Db/StreamRequestBuilder.php @@ -232,6 +232,8 @@ class StreamRequestBuilder extends CoreRequestBuilder { } $action = $this->parseStreamActionsLeftJoin($data); + $item->setAction($action); + if ($item->hasCache()) { $cache = $item->getCache(); try { @@ -244,7 +246,7 @@ class StreamRequestBuilder extends CoreRequestBuilder { } } - $item->setAction($action); + if ($item->getType() === Announce::TYPE) { $item->setAttributedTo($this->get('following_actor_id', $data, '')); } diff --git a/lib/Model/ActivityPub/Stream.php b/lib/Model/ActivityPub/Stream.php index 03714965..b79496e9 100644 --- a/lib/Model/ActivityPub/Stream.php +++ b/lib/Model/ActivityPub/Stream.php @@ -529,12 +529,8 @@ class Stream extends ACore implements IQueryRow, JsonSerializable { $this->setLanguage($this->get('language', $data)); $action = new StreamAction(); - $action->setValues( - [ - StreamAction::LIKED => $this->getBool('favourited', $data), - StreamAction::BOOSTED => $this->getBool('reblogged', $data) - ] - ); + $action->updateValueBool(StreamAction::LIKED, $this->getBool('favourited', $data)); + $action->updateValueBool(StreamAction::BOOSTED, $this->getBool('reblogged', $data)); $this->setAction($action); try { diff --git a/lib/Model/StreamAction.php b/lib/Model/StreamAction.php index 0018c74d..57a26449 100644 --- a/lib/Model/StreamAction.php +++ b/lib/Model/StreamAction.php @@ -44,7 +44,6 @@ class StreamAction implements JsonSerializable { use TArrayTools; use TStringTools; - public const LIKED = 'liked'; public const BOOSTED = 'boosted'; public const REPLIED = 'replied'; @@ -53,7 +52,12 @@ class StreamAction implements JsonSerializable { private string $actorId = ''; private string $streamId = ''; private array $values = []; - + private array $affected = []; + private array $accepted = [ + self::LIKED, + self::BOOSTED, + self::REPLIED + ]; /** * StreamAction constructor. @@ -95,14 +99,23 @@ class StreamAction implements JsonSerializable { public function updateValue(string $key, string $value): void { $this->values[$key] = $value; + if (in_array($key, $this->accepted) && !in_array($key, $this->affected)) { + $this->affected[] = $key; + } } public function updateValueInt(string $key, int $value): void { $this->values[$key] = $value; + if (in_array($key, $this->accepted) && !in_array($key, $this->affected)) { + $this->affected[] = $key; + } } public function updateValueBool(string $key, bool $value): void { $this->values[$key] = $value; + if (in_array($key, $this->accepted) && !in_array($key, $this->affected)) { + $this->affected[] = $key; + } } public function hasValue(string $key): bool { @@ -125,10 +138,8 @@ class StreamAction implements JsonSerializable { return $this->values; } - public function setValues(array $values): StreamAction { - $this->values = $values; - - return $this; + public function getAffected(): array { + return $this->affected; } public function setDefaultValues(array $default): StreamAction { @@ -146,7 +157,11 @@ class StreamAction implements JsonSerializable { $this->setId($this->getInt('id', $data, 0)); $this->setActorId($this->get('actor_id', $data, '')); $this->setStreamId($this->get('stream_id', $data, '')); - $this->setValues($this->getArray('values', $data, [])); + $this->values = [ + self::LIKED => $this->getBool('liked', $data), + self::BOOSTED => $this->getBool('boosted', $data), + self::REPLIED => $this->getBool('replied', $data) + ]; } public function jsonSerialize(): array {