diff --git a/app/Models/Build.php b/app/Models/Build.php index 4c9066d539..65a198db76 100644 --- a/app/Models/Build.php +++ b/app/Models/Build.php @@ -211,6 +211,14 @@ public function basicWarnings(): HasMany ->where('type', self::TYPE_WARN); } + /** + * @return HasMany + */ + public function richAlerts(): HasMany + { + return $this->hasMany(RichBuildAlert::class, 'buildid'); + } + /** * @return HasMany */ diff --git a/app/Models/RichBuildAlert.php b/app/Models/RichBuildAlert.php index ba08bd1f40..0a24521ecb 100644 --- a/app/Models/RichBuildAlert.php +++ b/app/Models/RichBuildAlert.php @@ -9,8 +9,10 @@ use Illuminate\Database\Eloquent\Relations\HasOne; /** + * @property int $id * @property int $buildid * @property int $detailsid + * @property string $workingdirectory * @property string $sourcefile * @property int $newstatus * @@ -25,11 +27,13 @@ class RichBuildAlert extends Model protected $fillable = [ 'buildid', 'detailsid', + 'workingdirectory', 'sourcefile', 'newstatus', ]; protected $casts = [ + 'id' => 'integer', 'buildid' => 'integer', 'detailsid' => 'integer', 'newstatus' => 'integer', diff --git a/app/Utils/SubmissionUtils.php b/app/Utils/SubmissionUtils.php index a56eb0cc6e..e6a0e466ad 100644 --- a/app/Utils/SubmissionUtils.php +++ b/app/Utils/SubmissionUtils.php @@ -18,6 +18,7 @@ use App\Http\Submission\Handlers\TestingJUnitHandler; use App\Http\Submission\Handlers\UpdateHandler; use App\Http\Submission\Handlers\UploadHandler; +use App\Models\RichBuildAlert; use CDash\Database; use CDash\Model\Build; use CDash\Model\BuildUpdate; @@ -155,6 +156,9 @@ public static function compute_error_difference($buildid, $previousbuildid, $war { $pdo = Database::getInstance()->getPdo(); + $build = \App\Models\Build::findOrFail((int) $buildid); + $previous_build = \App\Models\Build::findOrFail((int) $previousbuildid); + // Look at the difference positive and negative test errors DB::update(' UPDATE builderror @@ -181,62 +185,37 @@ public static function compute_error_difference($buildid, $previousbuildid, $war // Recurring buildfailures are represented by the buildfailuredetails table. // Get a list of buildfailuredetails IDs for the current build and the // previous build. - $current_failures = []; - $previous_failures = []; - $stmt = $pdo->prepare( - 'SELECT bf.detailsid FROM buildfailure AS bf - LEFT JOIN buildfailuredetails AS bfd ON (bf.detailsid=bfd.id) - WHERE bf.buildid=:buildid AND bfd.type=:type'); - $stmt->bindValue(':buildid', $buildid); - $stmt->bindValue(':type', $warning); - pdo_execute($stmt); - while ($row = $stmt->fetch()) { - $current_failures[] = $row['detailsid']; - } + $current_failures = $build->richAlerts() + ->whereRelation('details', 'type', $warning) + ->pluck('detailsid')->toArray(); - $stmt = $pdo->prepare( - 'SELECT bf.detailsid FROM buildfailure AS bf - LEFT JOIN buildfailuredetails AS bfd ON (bf.detailsid=bfd.id) - WHERE bf.buildid=:previousbuildid AND bfd.type=:type'); - $stmt->bindValue(':previousbuildid', $previousbuildid); - $stmt->bindValue(':type', $warning); - pdo_execute($stmt); - while ($row = $stmt->fetch()) { - $previous_failures[] = $row['detailsid']; - } + $previous_failures = $previous_build->richAlerts() + ->whereRelation('details', 'type', $warning) + ->pluck('detailsid')->toArray(); // Check if any of these are new failures and mark them accordingly. foreach ($current_failures as $failure) { if (!in_array($failure, $previous_failures)) { - $stmt = $pdo->prepare( - 'UPDATE buildfailure SET newstatus=1 - WHERE buildid=:buildid AND detailsid=:detailsid'); - $stmt->bindValue(':buildid', $buildid); - $stmt->bindValue(':detailsid', $failure); - pdo_execute($stmt); + RichBuildAlert::where([ + 'buildid' => $buildid, + 'detailsid' => $failure, + ])->update([ + 'newstatus' => 1, + ]); } } // Maybe we can get that from the query (don't know). - $stmt = $pdo->prepare( - 'SELECT COUNT(*) FROM builderror - WHERE buildid=:buildid AND type=:type AND newstatus=1'); - $stmt->bindValue(':buildid', $buildid); - $stmt->bindValue(':type', $warning); - pdo_execute($stmt); - $positives_array = $stmt->fetch(); - $npositives = $positives_array[0]; + $npositives = $build->basicAlerts() + ->where('type', $warning) + ->where('newstatus', 1) + ->count(); - $stmt = $pdo->prepare( - 'SELECT COUNT(*) FROM buildfailure AS bf - LEFT JOIN buildfailuredetails AS bfd ON (bf.detailsid=bfd.id) - WHERE bf.buildid=:buildid AND bfd.type=:type AND bf.newstatus=1'); - $stmt->bindValue(':buildid', $buildid); - $stmt->bindValue(':type', $warning); - pdo_execute($stmt); - $positives_array = $stmt->fetch(); - $npositives += $positives_array[0]; + $npositives += $build->richAlerts() + ->where('newstatus', 1) + ->whereRelation('details', 'type', $warning) + ->count(); // Count how many build defects were fixed since the previous build. $stmt = $pdo->prepare(' diff --git a/app/cdash/app/Model/BuildFailure.php b/app/cdash/app/Model/BuildFailure.php index 9c749c0561..a4ee17e905 100644 --- a/app/cdash/app/Model/BuildFailure.php +++ b/app/cdash/app/Model/BuildFailure.php @@ -17,6 +17,9 @@ namespace CDash\Model; +use App\Models\Build; +use App\Models\RichBuildAlert; +use App\Models\RichBuildAlertDetails; use App\Utils\RepositoryUtils; use CDash\Database; use Illuminate\Support\Facades\DB; @@ -60,7 +63,7 @@ public function AddArgument($argument): void $this->Arguments[] = $argument; } - public function InsertLabelAssociations($id): void + protected function InsertLabelAssociations($id): void { if (empty($this->Labels)) { return; @@ -102,34 +105,26 @@ public function Insert(): bool $db = Database::getInstance(); // Get details ID if it already exists, otherwise insert a new row. - $detailsResult = $db->executePreparedSingleRow(' - SELECT id FROM buildfailuredetails WHERE crc32=? - ', [$crc32]); - if ($detailsResult && array_key_exists('id', $detailsResult)) { - $detailsId = (int) $detailsResult['id']; - } else { - $detailsId = DB::table('buildfailuredetails') - ->insertGetId([ - 'type' => (int) $this->Type, - 'stdoutput' => $stdOutput, - 'stderror' => $stdError, - 'exitcondition' => $exitCondition, - 'language' => $language, - 'targetname' => $targetName, - 'outputfile' => $outputFile, - 'outputtype' => $outputType, - 'crc32' => $crc32, - ]); - } - - $id = DB::table('buildfailure') - ->insertGetId([ - 'buildid' => (int) $this->BuildId, - 'detailsid' => $detailsId, - 'workingdirectory' => $workingDirectory, - 'sourcefile' => $sourceFile, - 'newstatus' => 0, - ]); + $failureDetails = RichBuildAlertDetails::firstOrCreate([ + 'crc32' => $crc32, + ], [ + 'type' => (int) $this->Type, + 'stdoutput' => $stdOutput, + 'stderror' => $stdError, + 'exitcondition' => $exitCondition, + 'language' => $language, + 'targetname' => $targetName, + 'outputfile' => $outputFile, + 'outputtype' => $outputType, + ]); + + /** @var RichBuildAlert $failure */ + $failure = Build::findOrFail((int) $this->BuildId)->richAlerts()->create([ + 'detailsid' => $failureDetails->id, + 'workingdirectory' => $workingDirectory, + 'sourcefile' => $sourceFile, + 'newstatus' => 0, + ]); // Insert the arguments $argumentids = []; @@ -161,7 +156,7 @@ public function Insert(): bool $i = 0; foreach ($argumentids as $argumentid) { $query .= '(?, ?, ?),'; - $params[] = (int) $id; + $params[] = $failure->id; $params[] = (int) $argumentid; $params[] = $i; $i++; @@ -171,7 +166,7 @@ public function Insert(): bool return false; } - $this->InsertLabelAssociations($id); + $this->InsertLabelAssociations($failure->id); return true; } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e7c6b5a00c..d12babdc9b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -6630,19 +6630,13 @@ parameters: count: 5 path: app/Utils/RepositoryUtils.php - - - rawMessage: 'Binary operation "+=" between mixed and mixed results in an error.' - identifier: assignOp.invalid - count: 1 - path: app/Utils/SubmissionUtils.php - - rawMessage: ''' Call to deprecated function pdo_execute(): v2.5.0 01/22/2018 ''' identifier: function.deprecated - count: 6 + count: 1 path: app/Utils/SubmissionUtils.php - @@ -6660,28 +6654,22 @@ parameters: count: 2 path: app/Utils/SubmissionUtils.php - - - rawMessage: Cannot access offset 'detailsid' on mixed. - identifier: offsetAccess.nonOffsetAccessible - count: 2 - path: app/Utils/SubmissionUtils.php - - rawMessage: Cannot access offset 0 on mixed. identifier: offsetAccess.nonOffsetAccessible - count: 3 + count: 1 path: app/Utils/SubmissionUtils.php - rawMessage: 'Cannot call method bindValue() on PDOStatement|false.' identifier: method.nonObject - count: 13 + count: 3 path: app/Utils/SubmissionUtils.php - rawMessage: 'Cannot call method fetch() on PDOStatement|false.' identifier: method.nonObject - count: 5 + count: 1 path: app/Utils/SubmissionUtils.php - @@ -6738,12 +6726,6 @@ parameters: count: 1 path: app/Utils/SubmissionUtils.php - - - rawMessage: 'Only booleans are allowed in a while condition, mixed given.' - identifier: while.condNotBoolean - count: 2 - path: app/Utils/SubmissionUtils.php - - rawMessage: 'Only numeric types are allowed in +, int<0, max>|false given on the left side.' identifier: plus.leftNonNumeric @@ -6753,7 +6735,7 @@ parameters: - rawMessage: 'Parameter #1 $stmt of function pdo_execute expects PDOStatement, (PDOStatement|false) given.' identifier: argument.type - count: 6 + count: 1 path: app/Utils/SubmissionUtils.php - @@ -9879,7 +9861,7 @@ parameters: 04/22/2023 Use Laravel query builder or Eloquent instead ''' identifier: method.deprecated - count: 2 + count: 1 path: app/cdash/app/Model/BuildFailure.php - @@ -9969,12 +9951,6 @@ parameters: count: 1 path: app/cdash/app/Model/BuildFailure.php - - - rawMessage: 'Only booleans are allowed in &&, array|false|null given on the left side.' - identifier: booleanAnd.leftNotBoolean - count: 1 - path: app/cdash/app/Model/BuildFailure.php - - rawMessage: Property CDash\Model\BuildFailure::$Arguments has no type specified. identifier: missingType.property