1<?php 2 3namespace App\Repository; 4 5/** 6 * Repository for retrieving data from the bugdb_patchtracker database table. 7 */ 8class PatchRepository 9{ 10 /** 11 * Database handler. 12 * @var \PDO 13 */ 14 private $dbh; 15 16 /** 17 * Parent directory where patches are uploaded. 18 * @var string 19 */ 20 private $uploadsDir; 21 22 /** 23 * Class constructor. 24 */ 25 public function __construct(\PDO $dbh, string $uploadsDir) 26 { 27 $this->dbh = $dbh; 28 $this->uploadsDir = $uploadsDir; 29 } 30 31 /** 32 * Retrieve a list of all patches and their revisions by given bug id. 33 */ 34 public function findAllByBugId(int $bugId): array 35 { 36 $sql = 'SELECT patch, revision, developer 37 FROM bugdb_patchtracker 38 WHERE bugdb_id = ? 39 ORDER BY revision DESC 40 '; 41 42 $statement = $this->dbh->prepare($sql); 43 $statement->execute([$bugId]); 44 45 return $statement->fetchAll(); 46 } 47 48 /** 49 * Retrieve the developer by patch. 50 */ 51 public function findDeveloper(int $bugId, string $patch, int $revision): string 52 { 53 $sql = 'SELECT developer 54 FROM bugdb_patchtracker 55 WHERE bugdb_id = ? AND patch = ? AND revision = ? 56 '; 57 58 $arguments = [$bugId, $patch, $revision]; 59 60 $statement = $this->dbh->prepare($sql); 61 $statement->execute($arguments); 62 63 return $statement->fetch(\PDO::FETCH_NUM)[0]; 64 } 65 66 /** 67 * Retrieve a list of all patches and their revisions. 68 */ 69 public function findRevisions(int $bugId, string $patch): array 70 { 71 $sql = 'SELECT revision 72 FROM bugdb_patchtracker 73 WHERE bugdb_id = ? AND patch = ? 74 ORDER BY revision DESC 75 '; 76 77 $statement = $this->dbh->prepare($sql); 78 $statement->execute([$bugId, $patch]); 79 80 return $statement->fetchAll(); 81 } 82 83 /** 84 * Retrieve the actual contents of the patch. 85 */ 86 public function getPatchContents(int $bugId, string $name, int $revision): string 87 { 88 $sql = 'SELECT bugdb_id 89 FROM bugdb_patchtracker 90 WHERE bugdb_id = ? AND patch = ? AND revision = ? 91 '; 92 93 $statement = $this->dbh->prepare($sql); 94 $statement->execute([$bugId, $name, $revision]); 95 96 if ($statement->fetch(\PDO::FETCH_NUM)[0]) { 97 $contents = @file_get_contents($this->getPatchPath($bugId, $name, $revision)); 98 99 if (!$contents) { 100 throw new \Exception('Cannot retrieve patch revision "'.$revision.'" for patch "'.$name.'"'); 101 } 102 103 return $contents; 104 } 105 106 throw new \Exception('No such patch revision "'.$revision.'", or no such patch "'.$name.'"'); 107 } 108 109 /** 110 * Get absolute patch file name. 111 */ 112 private function getPatchPath(int $bugId, string $name, int $revision): string 113 { 114 return $this->uploadsDir.'/p'.$bugId.'/'.$name.'/'.'p'.$revision.'.patch.txt'; 115 } 116} 117