Passed
Pull Request — master (#17)
by Gordon
02:56
created

BulkIndexingHelper::bulkIndex()   C

Complexity

Conditions 11
Paths 40

Size

Total Lines 89
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 51
c 1
b 0
f 0
dl 0
loc 89
rs 6.9224
cc 11
nc 40
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types = 1);
2
3
/**
4
 * Created by PhpStorm.
5
 * User: gordon
6
 * Date: 25/3/2561
7
 * Time: 17:01 น.
8
 */
9
10
namespace Suilven\FreeTextSearch\Helper;
11
12
use League\CLImate\CLImate;
13
use SilverStripe\CMS\Model\SiteTree;
14
use SilverStripe\Core\Config\Config;
15
use SilverStripe\ORM\DB;
16
use SilverStripe\SiteConfig\SiteConfig;
17
use Suilven\FreeTextSearch\Factory\BulkIndexerFactory;
18
use Suilven\FreeTextSearch\Indexes;
19
20
class BulkIndexingHelper
21
{
22
    /** @param bool $dirty Set this to true to only index 'dirty' DataObjects, false to reindex all */
23
    public function bulkIndex(string $indexName, bool $dirty = false, ?CLImate $climate = null): void
24
    {
25
        $indexes = new Indexes();
26
        $index = $indexes->getIndex($indexName);
27
28
        /** @var string $clazz */
29
        $clazz = $index->getClass();
30
31
32
        $startTime = \microtime(true);
33
34
        if (!(\is_null($climate))) {
35
            $climate->border('*');
36
            $climate->green()->bold('Indexing sitetree');
37
            $climate->border();
38
        }
39
40
        $filters = ['ShowInSearch' => true];
41
        if ($dirty) {
42
            $filters['IsDirtyFreeTextSearch'] = true;
43
        }
44
45
        $nDocuments = SiteTree::get()->filter($filters)->count();
46
47
        if ($nDocuments > 0) {
48
            $config = SiteConfig::current_site_config();
49
50
            // * @phpstan-ignore-next-line
51
            $bulkSize = $config->BulkSize;
52
            $pages = 1+\round($nDocuments / $bulkSize);
53
            $progress = !\is_null($climate)
54
                ? $climate->progress()->total($nDocuments)
55
                : null;
56
57
            if (!\is_null($climate)) {
58
                $climate->green('Pages: ' . $pages);
59
                $climate->green()->info('Indexing ' . $nDocuments .' objects');
60
            }
61
62
            $factory = new BulkIndexerFactory();
63
            $bulkIndexer = $factory->getBulkIndexer();
64
            $bulkIndexer->setIndex($indexName);
65
66
            for ($i = 0; $i < $pages; $i++) {
67
                $dataObjects = $clazz::get()->limit($bulkSize, $i*$bulkSize)->filter($filters);
68
                foreach ($dataObjects as $do) {
69
                    // Note this adds data to the payload, doesn't actually indexing against the 4rd party search engine
70
                    $bulkIndexer->addDataObject($do);
71
                }
72
73
                // index objects up to configured bulk size
74
                $bulkIndexer->indexDataObjects();
75
                $current = $bulkSize * ($i+1);
76
                if ($current > $nDocuments) {
77
                    $current = $nDocuments;
78
                }
79
                if (\is_null($progress)) {
80
                    continue;
81
                }
82
83
                $progress->current($current);
84
            }
85
        }
86
87
88
        $endTime = \microtime(true);
89
        $delta = $endTime-$startTime;
90
91
        $rate = \round($nDocuments / $delta, 2);
92
93
        $elapsedStr = \round($delta, 2);
94
95
        if (!\is_null($climate)) {
96
            $climate->bold()->blue()->inline("{$nDocuments}");
97
            $climate->blue()->inline(' objects indexed in ');
98
            $climate->bold()->blue()->inline("{$elapsedStr}");
99
            $climate->blue()->inline('s, ');
100
            $climate->bold()->blue()->inline("{$rate}");
101
            $climate->blue(' per second ');
102
        }
103
104
        $clazz = $index->getClass();
105
        $table = Config::inst()->get($clazz, 'table_name');
106
107
108
        DB::query("UPDATE \"{$table}\" SET \"IsDirtyFreeTextSearch\" = 0");
109
110
        // @todo How to get the table name from versions?
111
        DB::query("UPDATE \"{$table}_Live\" SET \"IsDirtyFreeTextSearch\" = 0");
112
    }
113
}
114