Passed
Push — develop ( 3942cf...102216 )
by Jens
02:30
created

TermFieldLengthNorm::execute()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
nc 6
nop 0
dl 0
loc 20
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * User: jensk
4
 * Date: 1-3-2017
5
 * Time: 13:21
6
 */
7
8
namespace CloudControl\Cms\search\indexer;
9
10
use CloudControl\Cms\search\Indexer;
11
12
13
/**
14
 * Class TermFieldLengthNorm
15
 * Formula = norm(d) = 1 / √numTerms
16
 *
17
 * @package CloudControl\Cms\search\indexer
18
 */
19
class TermFieldLengthNorm
20
{
21
    /**
22
     * @var \PDO
23
     */
24
    protected $dbHandle;
25
26
    /**
27
     * TermFieldLengthNorm constructor.
28
     *
29
     * @param \PDO $dbHandle
30
     */
31
    public function __construct($dbHandle)
32
    {
33
        $this->dbHandle = $dbHandle;
34
    }
35
36
    public function execute()
37
    {
38
        $db = $this->dbHandle;
39
        $db->/** @scrutinizer ignore-call */
40
        sqliteCreateFunction('sqrt', 'sqrt', 1);
41
        $stmt = $this->getStatement($db);
42
        $uniqueFieldsPerDocument = $stmt->fetchAll(\PDO::FETCH_OBJ);
43
        $values = array();
44
        $i = 0;
45
        foreach ($uniqueFieldsPerDocument as $fieldRow) {
46
            $values[] = 'UPDATE term_frequency SET termNorm = 1/sqrt(' . (int)$fieldRow->termCount . ') WHERE documentPath = ' . $db->quote($fieldRow->documentPath) . ' AND field = ' . $db->quote($fieldRow->field) . ';';
47
            $i += 1;
48
            if ($i >= Indexer::SQLITE_MAX_COMPOUND_SELECT) {
49
                $this->executeUpdateTermNorm($values, $db);
50
                $values = array();
51
                $i = 0;
52
            }
53
        }
54
        if (count($values) !== 0) {
55
            $this->executeUpdateTermNorm($values, $db);
56
        }
57
    }
58
59
    /**
60
     * @param array $values
61
     * @param \PDO $db
62
     * @throws \Exception
63
     */
64
    private function executeUpdateTermNorm($values, $db)
65
    {
66
        $sql = 'BEGIN TRANSACTION;' . PHP_EOL;
67
        $sql .= implode(PHP_EOL, $values) . PHP_EOL;
68
        $sql .= 'COMMIT;';
69
        if (($db->exec($sql)) === false) {
70
            $errorInfo = $db->errorInfo();
71
            $errorMsg = $errorInfo[2];
72
            throw new \RuntimeException('SQLite Exception: ' . $errorMsg . ' in SQL: <br /><pre>' . $sql . '</pre>');
73
        }
74
    }
75
76
    /**
77
     * @param \PDO $db
78
     * @return \PDOStatement
79
     * @throws \Exception
80
     */
81
    protected function getStatement($db)
82
    {
83
        $sql = '
84
		SELECT documentPath, field, COUNT(`count`) AS termCount
85
		  FROM term_count
86
	  GROUP BY documentPath, field
87
		';
88
        $stmt = $db->prepare($sql);
89
        if ($stmt === false) {
90
            $errorInfo = $db->errorInfo();
91
            $errorMsg = $errorInfo[2];
92
            throw new \RuntimeException('SQLite Exception: ' . $errorMsg . ' in SQL: <br /><pre>' . $sql . '</pre>');
93
        }
94
        if (($stmt->execute()) === false) {
95
            $errorInfo = $db->errorInfo();
96
            $errorMsg = $errorInfo[2];
97
            throw new \RuntimeException('SQLite Exception: ' . $errorMsg . ' in SQL: <br /><pre>' . $sql . '</pre>');
98
        }
99
        return $stmt;
100
    }
101
}