Skip to content

Commit

Permalink
Speeding up sorting.
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisThompsonTLDR committed Sep 17, 2018
1 parent 7a32257 commit 5c14aa2
Showing 1 changed file with 67 additions and 39 deletions.
106 changes: 67 additions & 39 deletions src/Traits/LaramanController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ trait LaramanController
// default sort direction
public $order = 'desc';

private $dbSortable = false;

// the page
public $page = 1;

Expand Down Expand Up @@ -147,6 +149,11 @@ public function index(Request $request)

$builder = $model::query();

// can the database handle sorting
if (in_array($sort, Schema::getColumnListing($builder->getModel()->getTable()))) {
$this->dbSortable = true;
}

// scope it from the controller
$builder = $this->scope($builder);

Expand Down Expand Up @@ -279,71 +286,92 @@ public function index(Request $request)

$sort = null;
}
} else {
if ($this->dbSortable) {
$builder->orderBy($sort, $order);
}
}

// build a faker paginator
$paginator = $builder->paginate($limit);

$key = $builder->getModel()->getKeyName();

// chunk the results and get just the data we need
$tmpRows = collect([]);
if ($this->dbSortable) {
$rows = collect($paginator->items());
}
// only run this if the db wasn't able to sort the records
else {
$key = $builder->getModel()->getKeyName();

$builder->chunk($this->chunk, function ($rows) use (&$tmpRows, $key, $sort, $counts, $related) {
foreach ($rows as $row) {
$record = [];
$record[$key] = $row->{$key};
// chunk the results and get just the data we need
$tmpRows = collect([]);

$builder->chunk($this->chunk, function ($rows) use (&$tmpRows, $key, $sort, $counts, $related) {
// sort is on a `count` formatter field
$countSort = false;
if ($counts->contains($sort)) {
$record[$sort . 'Count'] = $row->{$sort}->count();
$countSort = true;
}

$record['_laraman_sort'] = null;

$containsSort = false;
if (str_contains($sort, '.')) {
$relateIt = explode('.', $sort);
$containsSort = true;
}

foreach ($rows as $row) {
$record = [];
$record[$key] = $row->{$key};

if (count($relateIt) > 1) {
$record['_laraman_sort'] = $row->{$relateIt[0]}->{$relateIt[1]};
// sort is on a `count` formatter field
if ($countSort) {
$record[$sort . 'Count'] = $row->{$sort}->count();
}
} else {
$record['_laraman_sort'] = $row->{$sort};

$record['_laraman_sort'] = null;

if ($containsSort) {
$relateIt = explode('.', $sort);

if (count($relateIt) > 1 && isset($row->{$relateIt[0]}->{$relateIt[1]})) {
$record['_laraman_sort'] = $row->{$relateIt[0]}->{$relateIt[1]};
}
} else {
$record['_laraman_sort'] = $row->{$sort};
}

$tmpRows->push($record);
}
});

$tmpRows->push($record);
// sort them only if not searching
if ($sort) {
$sortMethod = 'sortBy' . (($order == 'desc') ? 'Desc' : '');
$tmpRows = $tmpRows->$sortMethod('_laraman_sort', SORT_NATURAL|SORT_FLAG_CASE);
}
});

// sort them only if not searching
if ($sort) {
$sortMethod = 'sortBy' . (($order == 'desc') ? 'Desc' : '');
$tmpRows = $tmpRows->$sortMethod('_laraman_sort', SORT_NATURAL|SORT_FLAG_CASE);
}
// slice them
$ids = $tmpRows->slice($offset, $limit)->pluck($key);

// slice them
$ids = $tmpRows->slice($offset, $limit)->pluck($key);

// start a new builder for the real query
$builder = $model::query();

// start a new builder for the real query
$builder = $model::query();
// eager load
$related->each(function ($row) use ($builder) {
$pieces = array_slice(explode('.', $row['field']), 0, -1);

// eager load
$related->each(function ($row) use ($builder) {
$pieces = array_slice(explode('.', $row['field']), 0, -1);
$builder->with(implode('.', $pieces));
});

$builder->with(implode('.', $pieces));
});
if ($ids->count() > 0) {
$builder->whereIn($key, $ids)
->orderByRaw('FIELD(' . $key . ', ' . $ids->implode(',') . ')');
} else {
$builder->whereRaw('1 = 0');
}

if ($ids->count() > 0) {
$builder->whereIn($key, $ids)
->orderByRaw('FIELD(' . $key . ', ' . $ids->implode(',') . ')');
} else {
$builder->whereRaw('1 = 0');
$rows = $builder->get();
}

$rows = $builder->get();

$rows = $rows->map(function($row) use ($model, $fields, $related, $location, $buttons) {
$new = [];

Expand Down

0 comments on commit 5c14aa2

Please sign in to comment.