diff --git a/app/Manager/Tag.php b/app/Manager/Tag.php index 4457980d9..664c4393e 100644 --- a/app/Manager/Tag.php +++ b/app/Manager/Tag.php @@ -147,7 +147,7 @@ class Tag extends \Gazelle\BaseManager { UPDATE tags SET TagType = 'genre' WHERE ID = ? - ", $tag->id() + ", $tag->id ); } else { // Tag doesn't exist yet: create it @@ -212,20 +212,25 @@ class Tag extends \Gazelle\BaseManager { return $list; } - protected function replace(\Gazelle\Tag $old, \Gazelle\Tag $new, \Gazelle\User $user): int { + protected function replace( + \Gazelle\Tag $old, + \Gazelle\Tag $new, + \Gazelle\User $user, + Request $requestMan = new Request(), + ): int { // When replacing a tag that exists, there is a chance that a tgroup or // request might already have the tag. We therefore only add the tag if // it is missing, and then we can remove the current tag uses. self::$db->prepared_query(" SELECT DISTINCT RequestID FROM requests_tags WHERE TagID = ? - ", $old->id() + ", $old->id ); $affectedRequests = self::$db->collect(0); self::$db->prepared_query(" SELECT DISTINCT GroupID FROM torrents_tags WHERE TagID = ? - ", $old->id() + ", $old->id ); $affectedTGroups = self::$db->collect(0); @@ -236,7 +241,7 @@ class Tag extends \Gazelle\BaseManager { FROM torrents_tags curr LEFT JOIN torrents_tags merge ON (merge.GroupID = curr.GroupID AND merge.TagID = ?) WHERE curr.TagID = ? AND merge.TagID IS NULL - ", $new->id(), $user->id, $new->id(), $old->id() + ", $new->id, $user->id, $new->id, $old->id ); $changed = self::$db->affected_rows(); @@ -247,7 +252,7 @@ class Tag extends \Gazelle\BaseManager { FROM artists_tags curr LEFT JOIN artists_tags merge ON (merge.ArtistID = curr.ArtistID AND merge.TagID = ?) WHERE curr.TagID = ? AND merge.TagID IS NULL - ', $new->id(), $user->id, $new->id(), $old->id() + ', $new->id, $user->id, $new->id, $old->id ); $changed += self::$db->affected_rows(); @@ -258,9 +263,10 @@ class Tag extends \Gazelle\BaseManager { FROM requests_tags curr LEFT JOIN requests_tags merge ON (merge.RequestID = curr.RequestID AND merge.TagID = ?) WHERE curr.TagID = ? AND merge.TagID IS NULL - ", $new->id(), $new->id(), $old->id() + ", $new->id, $new->id, $old->id ); $changed += self::$db->affected_rows(); + $requestMan->findById($new->id)?->relayTag(); // regenerate usage count for replacement tag self::$db->prepared_query(" @@ -271,7 +277,7 @@ class Tag extends \Gazelle\BaseManager { + (SELECT count(*) FROM torrents_tags WHERE TagID = ?) ) WHERE ID = ? - ", $new->id(), $new->id(), $new->id(), $new->id() + ", $new->id, $new->id, $new->id, $new->id ); // update cache and sphinx @@ -304,7 +310,12 @@ class Tag extends \Gazelle\BaseManager { * have (alt.rock.indie.rock and alt.rock) in which case only (indie.rock) * needs to be applied, and the old tag removed. */ - public function rename(\Gazelle\Tag $tag, array $replacement, \Gazelle\User $user): int { + public function rename( + \Gazelle\Tag $tag, + array $replacement, + \Gazelle\User $user, + Request $requestMan = new Request(), + ): int { if (count($replacement) > 1) { return $this->split($tag, $replacement, $user); } @@ -312,25 +323,10 @@ class Tag extends \Gazelle\BaseManager { self::$db->begin_transaction(); $changed = $this->replace($tag, $replacement[0], $user); self::$db->prepared_query(" - DELETE t, at, rt, tt - FROM tags t - LEFT JOIN artists_tags at ON (at.TagID = t.ID) - LEFT JOIN requests_tags rt ON (rt.TagID = t.ID) - LEFT JOIN torrents_tags tt ON (tt.TagID = t.ID) - WHERE t.ID = ? - ", $tag->id() + SELECT RequestID FROM requests_tags WHERE TagID = ? + ", $tag->id ); - self::$db->commit(); - return $changed; - } - - public function split(\Gazelle\Tag $tag, array $replacement, \Gazelle\User $user): int { - $totalChanged = 0; - self::$db->begin_transaction(); - foreach ($replacement as $name) { - $totalChanged += $this->replace($tag, $name, $user); - } - + $reqList = self::$db->collect(0); self::$db->prepared_query(" DELETE t, at, rt, tt FROM tags t @@ -338,9 +334,44 @@ class Tag extends \Gazelle\BaseManager { LEFT JOIN requests_tags rt ON (rt.TagID = t.ID) LEFT JOIN torrents_tags tt ON (tt.TagID = t.ID) WHERE t.ID = ? - ", $tag->id() + ", $tag->id ); self::$db->commit(); + foreach ($reqList as $id) { + $requestMan->findById($id)?->relayTag(); + } + return $changed; + } + + public function split( + \Gazelle\Tag $tag, + array $replacement, + \Gazelle\User $user, + Request $requestMan = new Request(), + ): int { + $totalChanged = 0; + self::$db->begin_transaction(); + foreach ($replacement as $name) { + $totalChanged += $this->replace($tag, $name, $user); + } + self::$db->prepared_query(" + SELECT RequestID FROM requests_tags WHERE TagID = ? + ", $tag->id + ); + $reqList = self::$db->collect(0); + self::$db->prepared_query(" + DELETE t, at, rt, tt + FROM tags t + LEFT JOIN artists_tags at ON (at.TagID = t.ID) + LEFT JOIN requests_tags rt ON (rt.TagID = t.ID) + LEFT JOIN torrents_tags tt ON (tt.TagID = t.ID) + WHERE t.ID = ? + ", $tag->id + ); + self::$db->commit(); + foreach ($reqList as $id) { + $requestMan->findById($id)?->relayTag(); + } return $totalChanged; } @@ -380,7 +411,7 @@ class Tag extends \Gazelle\BaseManager { self::$db->begin_transaction(); self::$db->prepared_query(" DELETE FROM requests_tags WHERE RequestID = ? - ", $request->id() + ", $request->id ); $affected = 0; foreach (array_unique($tagList) as $name) { @@ -390,6 +421,7 @@ class Tag extends \Gazelle\BaseManager { } } self::$db->commit(); + $request->relayTag(); $request->updateSphinx(); return $affected; } diff --git a/app/Request.php b/app/Request.php index 953cbb9d9..2581124b3 100644 --- a/app/Request.php +++ b/app/Request.php @@ -584,6 +584,12 @@ class Request extends BaseObject implements CategoryHasArtist { VALUES (?, ?, ?) ", $this->id, $user->id, $bounty ); + $this->pg()->executeParams(' + insert into request_vote + (id_request_vote, id_request, id_user, bounty) + values ($1, $2, $3, $4) + ', self::$db->inserted_id(), $this->id, $user->id, $bounty + ); self::$db->prepared_query(" UPDATE requests SET LastVote = now() @@ -756,6 +762,11 @@ class Request extends BaseObject implements CategoryHasArtist { ", $this->id, $user->id ); $affected = self::$db->affected_rows(); + $this->pg()->executeParams(' + delete from request vote + where id_request = $1 and id_user = $2 + ', $this->id, $user->id + ); if ($affected) { $this->informRequestFillerReduction($bounty, $admin); $user->auditTrail()->addEvent( @@ -788,6 +799,11 @@ class Request extends BaseObject implements CategoryHasArtist { ", $this->id, $user->id ); $affected = self::$db->affected_rows(); + $this->pg()->executeParams(' + delete from request vote + where id_request = $1 and id_user = $2 + ', $this->id, $user->id + ); if ($affected) { $this->informRequestFillerReduction($bounty, $admin); $user->auditTrail()->addEvent( @@ -892,6 +908,23 @@ class Request extends BaseObject implements CategoryHasArtist { return $affected; } + public function relayTag(): int { + $this->pg()->cnxrw()->beginTransaction(); + $this->pg()->executeParams(' + delete from request_tag where id_request = $1 + ', $this->id + ); + $result = $this->pg()->executeParams(' + insert into request_tag (id_request, id_tag) + select "RequestID", "TagID" + from relay.requests_tags + where "RequestID" = $1 + ', $this->id + ); + $this->pg()->cnxrw()->commit(); + return $result->getAffectedRows(); + } + public function remove(): int { self::$db->begin_transaction(); self::$db->prepared_query("DELETE FROM requests_votes WHERE RequestID = ?", $this->id); @@ -921,6 +954,14 @@ class Request extends BaseObject implements CategoryHasArtist { } self::$cache->delete_value(sprintf(Manager\Request::ID_KEY, $this->id)); $this->flush(); + $this->pg()->executeParams(' + delete from request_tag where id_request = $1 + ', $this->id + ); + $this->pg()->executeParams(' + delete from request where id_request = $1 + ', $this->id + ); return $affected; } } diff --git a/app/Tag.php b/app/Tag.php index 6ef60dc2c..7a222c2db 100644 --- a/app/Tag.php +++ b/app/Tag.php @@ -79,6 +79,7 @@ class Tag extends BaseObject { WHERE ID = ? ", $this->id ); + $request->relayTag(); $request->updateSphinx(); return $affected; } diff --git a/misc/pg-migrations/20250525000000_relay_request_misc_tables.php b/misc/pg-migrations/20250525000000_relay_request_misc_tables.php new file mode 100644 index 000000000..312c9d770 --- /dev/null +++ b/misc/pg-migrations/20250525000000_relay_request_misc_tables.php @@ -0,0 +1,40 @@ +query(" + create table request_tag ( + id_request int not null, + id_tag int not null, + primary key (id_request, id_tag) + ) + "); + $this->query(" + create index reqt_t_idx on request_tag (id_tag) + "); + $this->query(" + create table request_vote ( + id_request_vote int not null primary key generated by default as identity, + id_request int not null, + id_user int not null, + bounty bigint not null, + created timestamptz not null default current_timestamp + ) + "); + $this->query(" + create index reqv_r_idx on request_vote (id_request) + "); + $this->query(" + create index reqv_u_idx on request_vote (id_user) + "); + } + + public function down(): void { + $this->table('request_tag')->drop()->save(); + $this->table('request_vote')->drop()->save(); + } +}