Skip to content

Commit

Permalink
feat(datatable): remove relationships capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Byrby committed Aug 9, 2023
1 parent 62eb1dd commit fa55890
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 177 deletions.
4 changes: 2 additions & 2 deletions src/Datatable/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public static function add(string $name): self
$column = new self();
$column->name = $name;
$column->isCustom = true;
$column->rawSelect = null;
$column->alias = '';
$column->rawSelect = $name;
$column->alias = $name;
$column->label = ucfirst($column->name);

return $column;
Expand Down
54 changes: 0 additions & 54 deletions src/Datatable/Datatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
namespace Webup\HeliumCore\Datatable;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Livewire\Component;

class Datatable extends Component
Expand Down Expand Up @@ -126,19 +122,6 @@ private function addSelect()
if (! $column->isCustom) {
if ($column->isRaw) {
$this->query->addSelect(DB::raw($column->rawSelect));
} elseif (str_contains($column->name, '.')) {
$relations = explode('.', Str::before($column->name, ':'));
$relationName = $relations[0];
$relationQuery = $this->query->getRelation($relationName);
if ($relationQuery instanceof HasMany || $relationQuery instanceof HasManyThrough || $relationQuery instanceof BelongsToMany) {
$this->query->customWithAggregate($relationName, Str::after($column->name, ':') ?? 'count', $relations[1], $column->alias);
} else {
$this->addSelectWithRelation($column);
// todo gérer les contraintes
// cette ligne est fonctionne pour les HasOne avec contrainte mais le réquete n'est pas géniale
// https://devblogs.microsoft.com/premier-developer/using-join-with-max-to-write-efficient-queries/
// $this->query->custom($relationName, last($relations), $column->alias);
}
} else {
$table = $this->model->getTable();
$col = $column->name;
Expand All @@ -150,30 +133,6 @@ private function addSelect()
}
}

private function addSelectWithRelation($column)
{
$relations = explode('.', Str::before($column->name, ':'));
$relatedQuery = $this->baseQuery();
$table = null;

$last = count($relations) - 1;
foreach ($relations as $i => $relationName) {
$isRelation = $i < $last;
if ($isRelation) {
$table = $relatedQuery->getRelation($relationName)->getRelated()->getTable();
$useThrough = collect($this->query->getQuery()->joins)
->pluck('table')
->contains($table);

$relatedQuery = $this->query->joinRelation($relationName, null, 'left', $useThrough, $relatedQuery);
} else {
$col = $relationName;
$alias = $column->alias;
$this->query->addSelect(DB::raw($table.'.'.$col.' as `'.$alias.'`'));
}
}
}

// todo gérer la recherche avec tous les type de relations
private function addFilters()
{
Expand All @@ -182,19 +141,6 @@ private function addFilters()
foreach (explode(' ', $this->search) as $key => $word) {
$subquery->where(function ($subsubquery) use ($word) {
foreach ($this->getSearchableColumns() as $key => $column) {
// if ($column->isRelation()) {
// $relations = explode('.', Str::before($column->name, ':'));
// $relationName = $relations[0];
// $relationQuery = $this->query->getRelation($relationName);

// if ($relationQuery instanceof HasOne || $relationQuery instanceof BelongsTo) {
// $table = $this->query->getRelationTable($relationName);
// $column = $relations[1];
// return $subsubquery->whereRaw("`$table`.`$column` like '%" . $word . "%'");
// } else {
// return $subsubquery->whereRaw("$column->name like '%" . $word . "%'");
// }
// }
return $subsubquery->whereRaw("$column->name like '%".$word."%'");
}
});
Expand Down
121 changes: 0 additions & 121 deletions src/HeliumCoreServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

namespace Webup\HeliumCore;

use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Expression;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
use Webup\HeliumCore\Commands\Publish;
Expand All @@ -25,122 +22,4 @@ public function configurePackage(Package $package): void
$this->loadRoutesFrom($routes);
}
}

public function registeringPackage()
{
$this->registerDatatableMacros();
}

private function registerDatatableMacros()
{
EloquentBuilder::macro('customWithAggregate', function ($relations, $aggregate, $column, $alias = null) {
if (empty($relations)) {
return $this;
}

$relations = is_array($relations) ? $relations : [$relations];

foreach ($this->parseWithRelations($relations) as $name => $constraints) {
$segments = explode(' ', $name);

if (count($segments) == 3 && Str::lower($segments[1]) == 'as') {
[$name, $alias] = [$segments[0], $segments[2]];
}

$relation = $this->getRelationWithoutConstraints($name);

$table = $relation->getRelated()->newQuery()->getQuery()->from === $this->getQuery()->from
? $relation->getRelationCountHashWithoutIncrementing()
: ($this->query->getConnection()->getTablePrefix() ?? '').$relation->getRelated()->getTable();

$query = $relation->getRelationExistenceAggregatesQuery(
$relation->getRelated()->newQuery(),
$this,
$aggregate,
$table.'.'.($column ?? 'id')
);

$query->callScope($constraints);

$query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();

if (count($query->columns) > 1) {
$query->columns = [$query->columns[0]];
}
$columnAlias = new Expression('`'.($alias ?? collect([$relations, $column])->filter()->flatten()->join('.')).'`');
$this->selectSub($query, $columnAlias);
}

return $this;
});

EloquentBuilder::macro('custom', function ($relations, $column, $alias = null) {
if (empty($relations)) {
return $this;
}

$relations = is_array($relations) ? $relations : [$relations];

foreach ($this->parseWithRelations($relations) as $name => $constraints) {
$segments = explode(' ', $name);

if (count($segments) == 3 && Str::lower($segments[1]) == 'as') {
[$name, $alias] = [$segments[0], $segments[2]];
}

$relation = $this->getRelationWithoutConstraints($name);

$table = $relation->getRelated()->newQuery()->getQuery()->from === $this->getQuery()->from
? $relation->getRelationCountHashWithoutIncrementing()
: ($this->query->getConnection()->getTablePrefix() ?? '').$relation->getRelated()->getTable();

$query = $relation->getRelationExistenceQuery(
$relation->getRelated()->newQuery(),
$this,
$table.'.'.($column ?? 'id')
)->setBindings([], 'select');

$query->callScope($constraints);

$query = $query->mergeConstraintsFrom($relation->getQuery())->toBase();

if (count($query->columns) > 1) {
$query->columns = [$query->columns[0]];
}
$columnAlias = new Expression('`'.($alias ?? collect([$relations, $column])->filter()->flatten()->join('.')).'`');
$this->selectSub($query, $columnAlias);
}

return $this;
});

EloquentBuilder::macro('getRelationTable', function ($name) {
$relation = $this->getRelationWithoutConstraints($name);

$table = $relation->getRelated()->newQuery()->getQuery()->from === $this->getQuery()->from
? $relation->getRelationCountHashWithoutIncrementing()
: ($this->query->getConnection()->getTablePrefix() ?? '').$relation->getRelated()->getTable();

return $table;
});

Relation::macro('getRelationExistenceAggregatesQuery', function (EloquentBuilder $query, EloquentBuilder $parentQuery, $aggregate, $column) {
$distinct_aggregate = new Expression($aggregate."(distinct {$column} separator ', ')");

if ($query->getConnection()->getPDO()->getAttribute(\PDO::ATTR_DRIVER_NAME) === 'sqlite') {
$distinct_aggregate = new Expression($aggregate."(REPLACE(DISTINCT({$column}), '', '') , ', ')");
}

$expression = $aggregate === 'group_concat'

? $distinct_aggregate
: new Expression('COALESCE('.$aggregate."({$column}),0)");

return $this->getRelationExistenceQuery(
$query,
$parentQuery,
$expression
)->setBindings([], 'select');
});
}
}

0 comments on commit fa55890

Please sign in to comment.