Passed
Pull Request — master (#17)
by Gordon
03:48
created

BulkIndexingHelper::bulkIndex()   C

Complexity

Conditions 11
Paths 40

Size

Total Lines 91
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 52
c 1
b 0
f 0
dl 0
loc 91
rs 6.9006
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
        \error_log('N DOCUMENTS: ' . $nDocuments);
48
49
        if ($nDocuments > 0) {
50
            $config = SiteConfig::current_site_config();
51
52
            // * @phpstan-ignore-next-line
53
            $bulkSize = $config->BulkSize;
54
            $pages = 1+\round($nDocuments / $bulkSize);
55
            $progress = !\is_null($climate)
56
                ? $climate->progress()->total($nDocuments)
57
                : null;
58
59
            if (!\is_null($climate)) {
60
                $climate->green('Pages: ' . $pages);
61
                $climate->green()->info('Indexing ' . $nDocuments .' objects');
62
            }
63
64
            $factory = new BulkIndexerFactory();
65
            $bulkIndexer = $factory->getBulkIndexer();
66
            $bulkIndexer->setIndex($indexName);
67
68
            for ($i = 0; $i < $pages; $i++) {
69
                $dataObjects = $clazz::get()->limit($bulkSize, $i*$bulkSize)->filter($filters);
70
                foreach ($dataObjects as $do) {
71
                    // Note this adds data to the payload, doesn't actually indexing against the 4rd party search engine
72
                    $bulkIndexer->addDataObject($do);
73
                }
74
75
                // index objects up to configured bulk size
76
                $bulkIndexer->indexDataObjects();
77
                $current = $bulkSize * ($i+1);
78
                if ($current > $nDocuments) {
79
                    $current = $nDocuments;
80
                }
81
                if (\is_null($progress)) {
82
                    continue;
83
                }
84
85
                $progress->current($current);
86
            }
87
        }
88
89
90
        $endTime = \microtime(true);
91
        $delta = $endTime-$startTime;
92
93
        $rate = \round($nDocuments / $delta, 2);
94
95
        $elapsedStr = \round($delta, 2);
96
97
        if (!\is_null($climate)) {
98
            $climate->bold()->blue()->inline("{$nDocuments}");
99
            $climate->blue()->inline(' objects indexed in ');
100
            $climate->bold()->blue()->inline("{$elapsedStr}");
101
            $climate->blue()->inline('s, ');
102
            $climate->bold()->blue()->inline("{$rate}");
103
            $climate->blue(' per second ');
104
        }
105
106
        $clazz = $index->getClass();
107
        $table = Config::inst()->get($clazz, 'table_name');
108
109
110
        DB::query("UPDATE \"{$table}\" SET \"IsDirtyFreeTextSearch\" = 0");
111
112
        // @todo How to get the table name from versions?
113
        DB::query("UPDATE \"{$table}_Live\" SET \"IsDirtyFreeTextSearch\" = 0");
114
    }
115
}
116