Skip to content

Commit

Permalink
Set up Project<->Build Eloquent relationship (#1756)
Browse files Browse the repository at this point in the history
This PR introduces Eloquent relationships between the `Project` model
and the `Build` model.

I used the new relationships to replace a few existing SQL queries in
the legacy project model as examples, but by no means did I attempt to
locate and refactor every possible place where the relationships can be
used. I expect to gradually use them more through my work in other PRs.
  • Loading branch information
williamjallen committed Oct 23, 2023
1 parent 9087ca0 commit 8dec5f2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 38 deletions.
2 changes: 1 addition & 1 deletion app/Http/Controllers/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function userPageContent(): JsonResponse
$project_response['role'] = $project_row['role']; // 0 is normal user, 1 is maintainer, 2 is administrator
$project_response['name'] = $Project->Name;
$project_response['name_encoded'] = urlencode($Project->Name);
$project_response['nbuilds'] = $Project->GetTotalNumberOfBuilds();
$project_response['nbuilds'] = $Project->GetNumberOfBuilds();
$project_response['average_builds'] = round($Project->GetBuildsDailyAverage(gmdate(FMT_DATETIME, time() - (3600 * 24 * 7)), gmdate(FMT_DATETIME)), 2);
$project_response['success'] = $Project->GetNumberOfPassingBuilds($start, gmdate(FMT_DATETIME));
$project_response['error'] = $Project->GetNumberOfErrorBuilds($start, gmdate(FMT_DATETIME));
Expand Down
27 changes: 27 additions & 0 deletions app/Models/Build.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -38,6 +39,8 @@
* @property string $uuid
* @property string $changeid
*
* @method static Builder betweenDates(?Carbon $starttime, ?Carbon $endtime)
*
* @mixin Builder<Build>
*/
class Build extends Model
Expand Down Expand Up @@ -114,4 +117,28 @@ public function notes(): BelongsToMany
return $this->belongsToMany(Note::class, 'build2note', 'buildid', 'noteid')
->withPivot('time');
}

/**
* @return BelongsTo<Project, self>
*/
public function project(): BelongsTo
{
return $this->belongsTo(Project::class, 'id', 'projectid');
}

/**
* Adds a betweenDates() query builder filter method...
*
* @param Builder<self> $query
*/
public function scopeBetweenDates(Builder $query, ?Carbon $starttime, ?Carbon $endtime): void
{
if ($starttime !== null) {
$query->where('starttime', '>', $starttime);
}

if ($endtime !== null) {
$query->where('endtime', '<=', $endtime);
}
}
}
12 changes: 12 additions & 0 deletions app/Models/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,16 @@ public function buildgroups(): HasMany
{
return $this->hasMany(BuildGroup::class, 'projectid', 'id');
}

/**
* @return HasMany<Build>
*/
public function builds(): HasMany
{
return $this->hasMany(Build::class, 'projectid', 'id')
->where(function ($query) {
$query->where('parentid', 0)
->orWhere('parentid', -1);
});
}
}
50 changes: 13 additions & 37 deletions app/cdash/app/Model/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ public function ExistsByName(string $name): bool
}

/** Get the logo id */
public function GetLogoId(): int
private function GetLogoId(): int
{
if (!$this->Filled) {
$this->Fill();
Expand Down Expand Up @@ -688,35 +688,15 @@ public function GetLastSubmission(): string|false
throw new RuntimeException('ID not set for project');
}

$build = DB::select('
SELECT starttime
FROM build
WHERE projectid=?
ORDER BY starttime DESC
LIMIT 1
', [(int) $this->Id]);
$starttime = EloquentProject::findOrFail((int) $this->Id)
->builds()
->max('starttime');

if ($build === []) {
if ($starttime === null) {
return false;
}

return date(FMT_DATETIMESTD, strtotime($build[0]->starttime . 'UTC'));
}

/** Get the total number of builds for a project*/
public function GetTotalNumberOfBuilds(): int
{
if (!$this->Id) {
throw new RuntimeException('ID not set for project');
}

return (int) DB::select('
SELECT count(*) AS c
FROM build
WHERE
parentid IN (-1, 0)
AND projectid=?
', [(int) $this->Id])[0]->c;
return date(FMT_DATETIMESTD, strtotime($starttime . 'UTC'));
}

/** Get the number of builds given a date range */
Expand All @@ -726,21 +706,18 @@ public function GetNumberOfBuilds(string|null $startUTCdate = null, string|null
throw new RuntimeException('ID not set for project');
}

// Construct our query given the optional parameters of this function.
$sql = 'SELECT COUNT(build.id) AS c
FROM build
WHERE projectid = ? AND parentid IN (-1, 0)';
$query_params = [(int) $this->Id];
if ($startUTCdate !== null) {
$sql .= ' AND build.starttime > ?';
$query_params[] = $startUTCdate;
$startUTCdate = Carbon::parse($startUTCdate);
}

if ($endUTCdate !== null) {
$sql .= ' AND build.starttime <= ?';
$query_params[] = $endUTCdate;
$endUTCdate = Carbon::parse($endUTCdate);
}

return (int) DB::select($sql, $query_params)[0]->c;
return EloquentProject::findOrFail((int) $this->Id)
->builds()
->betweenDates($startUTCdate, $endUTCdate)
->count();
}

/** Get the number of builds given per day */
Expand Down Expand Up @@ -1202,7 +1179,6 @@ public function GetSubProjectGroups(): array
*/
public function ConvertToJSON(): array
{
$config = Config::getInstance();
$response = [];
$clone = new \ReflectionObject($this);
$properties = $clone->getProperties(\ReflectionProperty::IS_PUBLIC);
Expand Down
25 changes: 25 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3262,6 +3262,16 @@ parameters:
count: 1
path: app/Models/BuildTest.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\Build\\>\\:\\:orWhere\\(\\)\\.$#"
count: 1
path: app/Models/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\Build\\>\\:\\:where\\(\\)\\.$#"
count: 2
path: app/Models/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\SubProject\\>\\:\\:orWhere\\(\\)\\.$#"
count: 1
Expand Down Expand Up @@ -9373,6 +9383,21 @@ parameters:
count: 1
path: app/cdash/app/Model/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\Build\\>\\:\\:betweenDates\\(\\)\\.$#"
count: 1
path: app/cdash/app/Model/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\Build\\>\\:\\:count\\(\\)\\.$#"
count: 1
path: app/cdash/app/Model/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\Build\\>\\:\\:max\\(\\)\\.$#"
count: 1
path: app/cdash/app/Model/Project.php

-
message: "#^Dynamic call to static method Illuminate\\\\Database\\\\Eloquent\\\\Relations\\\\HasMany\\<App\\\\Models\\\\SubProject\\>\\:\\:count\\(\\)\\.$#"
count: 1
Expand Down

0 comments on commit 8dec5f2

Please sign in to comment.