Skip to content

Commit

Permalink
refactor: 💡 Split into traits and drop stale versions support
Browse files Browse the repository at this point in the history
  • Loading branch information
mpyw committed Mar 15, 2023
1 parent 55f5151 commit e0fd4e5
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 201 deletions.
37 changes: 11 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,28 @@ jobs:
strategy:
matrix:
php: [8.1, '8.0', 7.4, 7.3]
php: ['8.0', 8.1, 8.2]
lib:
- { laravel: ^9.0, eager: ^1.7 }
- { laravel: ^8.0, eager: ^1.6 }
- { laravel: ^7.0, eager: ^1.5 }
- { laravel: ^6.0, eager: ^1.4 }
# - { laravel: ^11.0 }
- { laravel: ^10.0 }
- { laravel: ^9.0 }
flags: [--prefer-lowest, '']
db: [mysql-5.7, mysql-8.0, pgsql, sqlite, sqlsrv]
exclude:
- { php: 8.0, lib: { laravel: ^10.0 } }
# - { php: 8.0, lib: { laravel: ^11.0 } }
- { php: 8.1, flags: --prefer-lowest } # Error about #[\ReturnTypeWillChange]
- { php: 8.1, lib: { laravel: ^7.0, eager: ^1.5 } }
- { php: 8.1, lib: { laravel: ^6.0, eager: ^1.4 } }
- { php: 7.4, lib: { laravel: ^9.0, eager: ^1.7 } }
- { php: 7.3, lib: { laravel: ^9.0, eager: ^1.7 } }
- { php: 7.3, lib: { laravel: ^6.0, eager: ^1.4 }, db: sqlsrv } # Unknown Error about Carbon
# - { php: 8.1, lib: { laravel: ^11.0 } }

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: xdebug

- name: Set up MySQL 8.0
if: matrix.db == 'mysql-8.0'
run: |
mysql \
--host=127.0.0.1 \
--port=3307 \
--user=root \
--password=testing <<< "
ALTER USER 'testing'@'%' IDENTIFIED WITH mysql_native_password BY 'testing';
"
- name: Set up SQLServer
if: matrix.db == 'sqlsrv'
run: |
Expand All @@ -113,16 +99,15 @@ jobs:
- name: Adjust Package Versions
run: |
composer require "laravel/framework:${{ matrix.lib.laravel }}" --dev --no-update ${{ matrix.flags }}
composer require "staudenmeir/eloquent-eager-limit:${{ matrix.lib.eager }}" --no-update ${{ matrix.flags }}
composer update ${{ matrix.flags }}
- name: Show Important Package Versions
id: package-versions
run: |
composer show | grep -E '(^awobaz/compoships)|(^staudenmeir/eloquent-eager-limit)|(^laravel/framework)|(^orchestra/testbench)|(^phpunit/phpunit)'
echo '::set-output name=compoships::'$(composer show | grep -E '^(awobaz/compoships)' | awk '{print $2}')
echo '::set-output name=eloquent-eager-limit::'$(composer show | grep -E '^(staudenmeir/eloquent-eager-limit)' | awk '{print $2}')
echo '::set-output name=laravel::'$(composer show | grep -E '^(laravel/framework)' | awk '{print $2}')
echo 'name=compoships::'$(composer show | grep -E '^(awobaz/compoships)' | awk '{print $2}') > "$GITHUB_OUTPUT"
echo 'name=eloquent-eager-limit::'$(composer show | grep -E '^(staudenmeir/eloquent-eager-limit)' | awk '{print $2}') > "$GITHUB_OUTPUT"
echo 'name=laravel::'$(composer show | grep -E '^(laravel/framework)' | awk '{print $2}') > "$GITHUB_OUTPUT"
- name: Prepare Database Config
run: mv tests/config/database.github.php tests/config/database.php
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/vendor/
/.idea/
.php_cs.cache
.phpunit.result.cache
/.phpunit.cache/
composer.lock
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

## Requirements

- PHP: `^7.3 || ^8.0`
- Laravel: `^6.0 || ^7.0 || ^8.0 || ^9.0`
- PHP: `^8.0`
- Laravel: `^9.0 || ^10.0`
- [Compoships](https://github.com/topclaudy/compoships): `^2.0.4`
- [Eloquent Eager Limit](https://github.com/staudenmeir/eloquent-eager-limit): `^1.4`
- [Eloquent Eager Limit](https://github.com/staudenmeir/eloquent-eager-limit): `^1.7.1`

## Installing

Expand Down
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@
}
},
"require": {
"php": "^7.3 || ^8.0",
"illuminate/database": "^6.0 || ^7.0 || ^8.0 || ^9.0",
"illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0",
"php": "^8.0",
"illuminate/database": "^9.0 || ^10.0 || ^11.0",
"illuminate/support": "^9.0 || ^10.0 || ^11.0",
"awobaz/compoships": "^2.0.4",
"staudenmeir/eloquent-eager-limit": "^1.4"
"staudenmeir/eloquent-eager-limit": "^1.7.1"
},
"require-dev": {
"orchestra/testbench": "*",
"orchestra/testbench-core": "^4.9 || ^5.9 || >=6.6",
"orchestra/testbench-core": ">=7.0",
"phpunit/phpunit": ">=9.5",
"nesbot/carbon": "^2.62.1",
"ext-json": "*"
},
"minimum-stability": "dev",
Expand Down
21 changes: 6 additions & 15 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
bootstrap="vendor/autoload.php"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix="Test.php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
</phpunit>
64 changes: 2 additions & 62 deletions src/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,9 @@
namespace Mpyw\ComposhipsEagerLimit\Database\Query;

use Awobaz\Compoships\Database\Query\Builder as ComposhipsBuilder;
use Mpyw\ComposhipsEagerLimit\Database\Query\Concerns\BuildsGroupLimitQueriesByMultipleColumnPartition;

/**
* Class Builder
*
* @mixin \Staudenmeir\EloquentEagerLimit\Builder
*/
class Builder extends ComposhipsBuilder
{
/**
* The maximum number of records to return per group.
*
* @var array
*/
public $groupLimit;

/**
* Add a "group limit" clause to the query.
*
* @param int $value
* @param string $column
* @return $this
*/
public function groupLimit($value, $column)
{
if ($value >= 0) {
$this->groupLimit = compact('value', 'column');
}

return $this;
}

/**
* Execute the query as a "select" statement.
*
* @param array $columns
* @return \Illuminate\Support\Collection
*/
public function get($columns = ['*'])
{
$items = parent::get($columns);

if (!$this->groupLimit) {
return $items;
}

$keys = ['laravel_row'];

if (is_array($this->groupLimit['column'])) {
foreach ($this->groupLimit['column'] as $i => $column) {
$keys[] = "@laravel_partition_$i := " . $this->grammar->wrap(last(explode('.', $column)));
$keys[] = "@laravel_partition_$i := " . $this->grammar->wrap('pivot_' . last(explode('.', $column)));
}
} else {
$keys[] = '@laravel_partition := ' . $this->grammar->wrap(last(explode('.', $this->groupLimit['column'])));
$keys[] = '@laravel_partition := ' . $this->grammar->wrap('pivot_' . last(explode('.', $this->groupLimit['column'])));
}

foreach ($items as $item) {
foreach ($keys as $key) {
unset($item->$key);
}
}

return $items;
}
use BuildsGroupLimitQueriesByMultipleColumnPartition;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Mpyw\ComposhipsEagerLimit\Database\Query\Concerns;

use Staudenmeir\EloquentEagerLimit\Traits\BuildsGroupLimitQueries;

/**
* Trait BuildsGroupLimitQueriesByMultipleColumnPartition
*
* @mixin \Illuminate\Database\Query\Builder
*/
trait BuildsGroupLimitQueriesByMultipleColumnPartition
{
use BuildsGroupLimitQueries;

/**
* Execute the query as a "select" statement.
*
* @param array $columns
* @return \Illuminate\Support\Collection
*/
public function get($columns = ['*'])
{
$items = parent::get($columns);

if (!$this->groupLimit) {
return $items;
}

$keys = ['laravel_row'];

if (is_array($this->groupLimit['column'])) {
foreach ($this->groupLimit['column'] as $i => $column) {
$keys[] = "@laravel_partition_$i := " . $this->grammar->wrap(last(explode('.', $column)));
$keys[] = "@laravel_partition_$i := " . $this->grammar->wrap('pivot_' . last(explode('.', $column)));
}
} else {
$keys[] = '@laravel_partition := ' . $this->grammar->wrap(last(explode('.', $this->groupLimit['column'])));
$keys[] = '@laravel_partition := ' . $this->grammar->wrap('pivot_' . last(explode('.', $this->groupLimit['column'])));
}

foreach ($items as $item) {
foreach ($keys as $key) {
unset($item->$key);
}
}

return $items;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

namespace Mpyw\ComposhipsEagerLimit\Database\Query\Grammar\Concerns;

use Staudenmeir\EloquentEagerLimit\Grammars\Traits\CompilesGroupLimit;

/**
* Trait CompilesGroupLimitByMultipleColumnPartition
*/
trait CompilesGroupLimitByMultipleColumnPartition
{
use CompilesGroupLimit;

/**
* Compile a row number clause.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Mpyw\ComposhipsEagerLimit\Database\Query\Grammar\Concerns;

/**
* Trait CompilesGroupLimitByMultipleColumnPartitionWithInternalRenameAsParent
*
* @internal
*/
trait CompilesGroupLimitByMultipleColumnPartitionWithInternalRenameAsParent
{
use CompilesGroupLimitByMultipleColumnPartition {
compileRowNumber as compileRowNumberParent;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Mpyw\ComposhipsEagerLimit\Database\Query\Grammar\Concerns;

use Illuminate\Database\Query\Builder;
use Staudenmeir\EloquentEagerLimit\Grammars\Traits\CompilesMySqlGroupLimit;

/**
* Trait CompilesMySqlGroupLimitByMultipleColumnPartition
*
* @mixin \Illuminate\Database\Query\Grammars\MySqlGrammar
*/
trait CompilesMySqlGroupLimitByMultipleColumnPartition
{
use CompilesMySqlGroupLimit, CompilesGroupLimitByMultipleColumnPartition {
CompilesGroupLimitByMultipleColumnPartition::compileRowNumber insteadof CompilesMySqlGroupLimit;
CompilesMySqlGroupLimit::compileGroupLimit insteadof CompilesGroupLimitByMultipleColumnPartition;
}

/**
* Compile a group limit clause for MySQL < 8.0.
*
* Derived from https://softonsofa.com/tweaking-eloquent-relations-how-to-get-n-related-models-per-parent/.
*
* @param \Illuminate\Database\Query\Builder|\Mpyw\ComposhipsEagerLimit\Database\Query\Builder $query
* @return string
*/
protected function compileLegacyGroupLimit(Builder $query)
{
$limit = (int)$query->groupLimit['value'] + (int)$query->offset;
$offset = $query->offset;

$query->offset = null;
$query->orders = (array)$query->orders;

$partitionExpressions = [];
$partitionAssignments = [];
$partitionInitializations = [];
$partitionOrders = [];

if (is_array($query->groupLimit['column'])) {
foreach ($query->groupLimit['column'] as $i => $column) {
$wrappedColumn = $this->wrap(last(explode('.', $column)));

$partitionExpressions[] = "@laravel_partition_$i = $wrappedColumn";
$partitionAssignments[] = "@laravel_partition_$i := $wrappedColumn";
$partitionInitializations[] = "@laravel_partition_$i := 0";
$partitionOrders[] = ['column' => $column, 'direction' => 'asc'];
}
} else {
$wrappedColumn = $this->wrap(last(explode('.', $query->groupLimit['column'])));

$partitionExpressions[] = "@laravel_partition = $wrappedColumn";
$partitionAssignments[] = "@laravel_partition := $wrappedColumn";
$partitionInitializations[] = '@laravel_partition := 0';
$partitionOrders[] = ['column' => $query->groupLimit['column'], 'direction' => 'asc'];
}

$partition = sprintf(
', @laravel_row := if(%s, @laravel_row + 1, 1) as laravel_row, %s',
implode(' and ', $partitionExpressions),
implode(', ', $partitionAssignments)
);

array_splice($query->orders, 0, 0, $partitionOrders);

$components = $this->compileComponents($query);

$sql = $this->concatenate($components);

$from = sprintf(
'(select @laravel_row := 0, %s) as laravel_vars, (%s) as laravel_table',
implode(', ', $partitionInitializations),
$sql
);

$sql = 'select laravel_table.*' . $partition . ' from ' . $from . ' having laravel_row <= ' . $limit;

if ($offset !== null) {
$sql .= ' and laravel_row > ' . (int)$offset;
}

return $sql . ' order by laravel_row';
}
}
Loading

0 comments on commit e0fd4e5

Please sign in to comment.