Passed
Pull Request — master (#33)
by Serhii
04:37
created

DefaultImportSource   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
dl 0
loc 96
ccs 47
cts 47
cp 1
rs 10
c 1
b 0
f 0
wmc 11

8 Methods

Rating   Name   Duplication   Size   Complexity  
A chunked() 0 31 4
A model() 0 3 1
A get() 0 3 1
A newQuery() 0 16 1
A searchableAs() 0 3 1
A __construct() 0 4 1
A syncWithSearchUsing() 0 3 1
A syncWithSearchUsingQueue() 0 3 1
1
<?php
2
3
namespace Matchish\ScoutElasticSearch\Searchable;
4
5
use Matchish\ScoutElasticSearch\Database\Scopes\ChunkScope;
6
7
class DefaultImportSource implements ImportSource
8
{
9
    const DEFAULT_CHUNK_SIZE = 500;
10
11
    private $className;
12
    private $scopes;
13
14
    /**
15
     * DefaultImportSource constructor.
16
     * @param string $className
17
     * @param array $scopes
18
     */
19 26
    public function __construct(string $className, array $scopes = [])
20
    {
21 26
        $this->className = $className;
22 26
        $this->scopes = $scopes;
23 26
    }
24
25 12
    public function syncWithSearchUsingQueue()
26
    {
27 12
        return $this->model()->syncWithSearchUsingQueue();
28
    }
29
30 12
    public function syncWithSearchUsing()
31
    {
32 12
        return $this->model()->syncWithSearchUsing();
33
    }
34
35 19
    public function searchableAs(): string
36
    {
37 19
        return $this->model()->searchableAs();
38
    }
39
40 18
    public function chunked()
41
    {
42 18
        $query = $this->newQuery();
43 18
        $searchable = $this->model();
44 18
        $totalSearchables = $query->count();
45 18
        if ($totalSearchables) {
46 13
            $chunkSize = (int) config('scout.chunk.searchable', self::DEFAULT_CHUNK_SIZE);
47 13
            $cloneQuery = clone $query;
48 13
            $cloneQuery->joinSub('SELECT @row :=0, 1 as temp', 'r', 'r.temp', 'r.temp')
49 13
                ->selectRaw("@row := @row +1 AS rownum, {$searchable->getKeyName()}");
50 13
            $ids = \DB::query()->fromSub($cloneQuery, 'ranked')->whereRaw("rownum %{$chunkSize} =0")->pluck($searchable->getKeyName());
51 13
            $pairs = [];
52 13
            $lastId = null;
53 13
            foreach ($ids as $id) {
54 11
                if ($lastId) {
55 6
                    $pairs[] = [$lastId, $id];
56
                } else {
57 11
                    $pairs[] = [null, $id];
58
                }
59 11
                $lastId = $id;
60
            }
61 13
            $pairs[] = [$lastId, null];
62
63
            return collect($pairs)->map(function ($pair) {
64 13
                [$start, $end] = $pair;
65 13
                $chunkScope = new ChunkScope($start, $end);
66
67 13
                return new static($this->className, array_merge($this->scopes, [$chunkScope]));
68 13
            });
69
        } else {
70 13
            return collect();
71
        }
72
    }
73
74
    /**
75
     * @return mixed
76
     */
77 26
    private function model()
78
    {
79 26
        return new $this->className;
80
    }
81
82 22
    private function newQuery()
83
    {
84 22
        $query = $this->model()->newQuery();
85 22
        $softDelete = config('scout.soft_delete', false);
86
        $query
87
            ->when($softDelete, function ($query) {
88 2
                return $query->withTrashed();
89 22
            })
90 22
            ->orderBy($this->model()->getKeyName());
91 22
        $scopes = $this->scopes;
92
93
        return collect($scopes)->reduce(function ($instance, $scope) {
94 12
            $instance->withGlobalScope(get_class($scope), $scope);
95
96 12
            return $instance;
97 22
        }, $query);
98
    }
99
100 16
    public function get()
101
    {
102 16
        return $this->newQuery()->get();
103
    }
104
}
105