From f8b54025133e6d45689bb6a1700d44ffa641ba7b Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 27 Nov 2019 16:18:33 +0100
Subject: [PATCH] allow turning of the coverage based ranking

---
 database/Config.php                        | 10 ++--
 database/Database.php                      | 20 ++++----
 database/backends/BackendFactory.php       |  6 +--
 database/backends/PostgresSmartBackend.php | 54 +++++++++++++---------
 database/backends/SQLiteSmartBackend.php   |  2 +-
 qrs_config.default.php                     |  1 +
 6 files changed, 56 insertions(+), 37 deletions(-)

diff --git a/database/Config.php b/database/Config.php
index 1f4d169..7df6c1e 100644
--- a/database/Config.php
+++ b/database/Config.php
@@ -11,17 +11,19 @@ class Config
     public $database_options;
 
     public $backend;
+    public $enable_ranking;
 
     public $path_prefix;
 
-    public function __construct(string $path_prefix, string $database_connector, string $username, string $password, string $backend, array $options)
+    public function __construct(string $path_prefix, string $database_connector, string $username, string $password, string $backend, array $options, bool $enable_ranking)
     {
         $this->database_connector = $database_connector;
         $this->username = $username;
         $this->password = $password;
-        $this->database_options = $options;
         $this->path_prefix = $path_prefix;
         $this->backend = $backend;
+        $this->database_options = $options;
+        $this->enable_ranking = $enable_ranking;
     }
 
     public static function createFromGlobals()
@@ -34,8 +36,8 @@ class Config
         $options['timeout'] = (defined('qrs_db_option_timeout') && (null !== qrs_db_option_timeout)) ? qrs_db_option_timeout : 5000;
 
         if (defined('qrs_db_connector') && null !== qrs_db_connector)
-            return new Config(qrs_path_prefix, qrs_db_connector, qrs_db_user, qrs_db_pass, qrs_backend, $options);
+            return new Config(qrs_path_prefix, qrs_db_connector, qrs_db_user, qrs_db_pass, qrs_backend, $options, qrs_enable_ranking);
         else
-            return new Config(qrs_path_prefix, 'pgsql:host=' . qrs_db_host . ';port=' . qrs_db_port . ';dbname=' . qrs_db_name . '', qrs_db_user, qrs_db_pass, qrs_backend, $options);
+            return new Config(qrs_path_prefix, 'pgsql:host=' . qrs_db_host . ';port=' . qrs_db_port . ';dbname=' . qrs_db_name . '', qrs_db_user, qrs_db_pass, qrs_backend, $options, qrs_enable_ranking);
     }
 }
diff --git a/database/Database.php b/database/Database.php
index bb4698a..32ddab4 100644
--- a/database/Database.php
+++ b/database/Database.php
@@ -14,20 +14,22 @@ class Database
     private $user;
 
     private $backend;
+    private $enable_ranking;
 
-    private function __construct(string $database_connector, string $username, string $password, string $type, array $options)
+    private function __construct(string $database_connector, string $username, string $password, string $type, array $options, bool $enable_ranking)
     {
-        $this->backend = BackendFactory::create($type, new \PDO($database_connector, $username, $password), $options);
+        $this->backend = BackendFactory::create($type, new \PDO($database_connector, $username, $password), $options, $enable_ranking);
+        $this->enable_ranking = $enable_ranking;
     }
 
     public static function createFromConfig(Config $config): Database
     {
-        return Database::createFromOptions($config->database_connector, $config->username, $config->password, $config->backend, $config->database_options);
+        return Database::createFromOptions($config->database_connector, $config->username, $config->password, $config->backend, $config->database_options, $config->enable_ranking);
     }
 
-    public static function createFromOptions(string $database_connector, string $username, string $password, string $type, array $options): Database
+    public static function createFromOptions(string $database_connector, string $username, string $password, string $type, array $options, bool $enable_ranking): Database
     {
-        return new Database($database_connector, $username, $password, $type, $options);
+        return new Database($database_connector, $username, $password, $type, $options, $enable_ranking);
     }
 
     public function authenticateFromHeader(string $header): bool
@@ -67,10 +69,12 @@ class Database
 
     private function apply_config(\PDOStatement $stmt)
     {
-        $stmt->bindValue(':config_normalization', 4, PDO::PARAM_INT);
+        if ($this->enable_ranking) {
+            $stmt->bindValue(':config_normalization', 4, PDO::PARAM_INT);
+            $stmt->bindValue(':weight_content', 14, PDO::PARAM_INT);
+        }
 
-        $stmt->bindValue(':weight_content', 14, PDO::PARAM_INT);
-        $stmt->bindValue(':weight_type', 16, PDO::PARAM_INT);
+        $stmt->bindValue(':weight_type', 32, PDO::PARAM_INT);
         $stmt->bindValue(':weight_time', 1, PDO::PARAM_INT);
     }
 
diff --git a/database/backends/BackendFactory.php b/database/backends/BackendFactory.php
index 2c44f17..ee45ec1 100644
--- a/database/backends/BackendFactory.php
+++ b/database/backends/BackendFactory.php
@@ -8,13 +8,13 @@ require_once 'SQLiteSmartBackend.php';
 class BackendFactory
 {
 
-    public static function create(string $type, \PDO $db, array $options): Backend
+    public static function create(string $type, \PDO $db, array $options, $enable_ranking): Backend
     {
         switch ($type) {
             case 'pgsql-smart':
-                return new PostgresSmartBackend($db, $options);
+                return new PostgresSmartBackend($db, $options, $enable_ranking);
             case 'sqlite-smart':
-                return new SQLiteSmartBackend($db, $options);
+                return new SQLiteSmartBackend($db, $options, $enable_ranking);
             default:
                 return null;
         }
diff --git a/database/backends/PostgresSmartBackend.php b/database/backends/PostgresSmartBackend.php
index 99f6483..9d14e74 100644
--- a/database/backends/PostgresSmartBackend.php
+++ b/database/backends/PostgresSmartBackend.php
@@ -8,13 +8,15 @@ class PostgresSmartBackend implements Backend
 {
     private $db;
     private $options;
+    private $enable_ranking;
 
-    function __construct(\PDO $db, array $options)
+    function __construct(\PDO $db, array $options, bool $enable_ranking)
     {
         $this->db = $db;
         $timeout = $options["timeout"];
         $this->db->exec("SET statement_timeout = $timeout;");
         $this->options = $options;
+        $this->enable_ranking = $enable_ranking;
     }
 
     public function findUser(): \PDOStatement
@@ -31,9 +33,36 @@ class PostgresSmartBackend implements Backend
         return array_key_exists('tsqueryfunction', $this->options) ? $this->options['tsqueryfunction'] : "plainto_tsquery('english', :query)";
     }
 
+    private function rankingFunction(): string
+    {
+        if ($this->enable_ranking) {
+            return "(
+                      (ts_rank_cd(tsv, query, :config_normalization) ^ :weight_content) *
+                      ((CASE
+                        WHEN TYPE IN (1, 4) THEN 1.0
+                        WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.8
+                        WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.6
+                        WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.4
+                        ELSE 0.2 END) ^ :weight_type) *
+                      ((1 / (EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) - EXTRACT(EPOCH FROM time))) ^ :weight_time)
+                    )";
+        } else {
+            return "(
+                      ((CASE
+                        WHEN TYPE IN (1, 4) THEN 1.0
+                        WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.8
+                        WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.6
+                        WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.4
+                        ELSE 0.2 END) ^ :weight_type) *
+                      ((1 / (EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) - EXTRACT(EPOCH FROM time))) ^ :weight_time)
+                    )";
+        }
+    }
+
     public function findInBuffers(): \PDOStatement
     {
         $tsQueryFunction = $this->tsQueryFunction();
+        $rankingFunction = $this->rankingFunction();
         return $this->db->prepare("
             SELECT
               ranked_messages.bufferid,
@@ -70,16 +99,7 @@ class PostgresSmartBackend implements Backend
                     backlog.time,
                     backlog.message,
                     query,
-                    (
-                      (ts_rank_cd(tsv, query, :config_normalization) ^ :weight_content) *
-                      ((CASE
-                        WHEN TYPE IN (1, 4) THEN 1.0
-                        WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.8
-                        WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.6
-                        WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.4
-                        ELSE 0.2 END) ^ :weight_type) *
-                      ((1 / (EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) - EXTRACT(EPOCH FROM TIME))) ^ :weight_time)
-                    ) AS rank_value
+                    $rankingFunction AS rank_value
                   FROM
                     backlog
                     JOIN buffer ON backlog.bufferid = buffer.bufferid
@@ -128,6 +148,7 @@ class PostgresSmartBackend implements Backend
     public function findInBuffer(): \PDOStatement
     {
         $tsQueryFunction = $this->tsQueryFunction();
+        $rankingFunction = $this->rankingFunction();
         return $this->db->prepare("
             SELECT
               matching_messages.messageid,
@@ -145,16 +166,7 @@ class PostgresSmartBackend implements Backend
                  backlog.time,
                  backlog.message,
                  query,
-                 (
-                   (ts_rank_cd(tsv, query, :config_normalization) ^ :weight_content) *
-                   ((CASE
-                     WHEN TYPE IN (1, 4) THEN 1.0
-                     WHEN TYPE IN (2, 1024, 2048, 4096, 16384) THEN 0.8
-                     WHEN TYPE IN (32, 64, 128, 256, 512, 32768, 65536) THEN 0.6
-                     WHEN TYPE IN (8, 16, 8192, 131072) THEN 0.4
-                     ELSE 0.2 END) ^ :weight_type) *
-                   ((1 / (EXTRACT(EPOCH FROM CURRENT_TIMESTAMP) - EXTRACT(EPOCH FROM TIME))) ^ :weight_time)
-                 ) AS rank_value
+                 $rankingFunction AS rank_value
                FROM
                  backlog
                  JOIN buffer ON backlog.bufferid = buffer.bufferid
diff --git a/database/backends/SQLiteSmartBackend.php b/database/backends/SQLiteSmartBackend.php
index fcac6e4..611b6a7 100644
--- a/database/backends/SQLiteSmartBackend.php
+++ b/database/backends/SQLiteSmartBackend.php
@@ -9,7 +9,7 @@ class SQLiteSmartBackend implements Backend
     private $db;
     private $options;
 
-    function __construct(\PDO $db, array $options)
+    function __construct(\PDO $db, array $options, $enable_ranking)
     {
         $this->db = $db;
         $this->options = $options;
diff --git a/qrs_config.default.php b/qrs_config.default.php
index 5bc6425..fd8bc6b 100644
--- a/qrs_config.default.php
+++ b/qrs_config.default.php
@@ -14,5 +14,6 @@ define('qrs_db_option_tsqueryfunction', "plainto_tsquery('english', :query)");
 define('qrs_db_option_timeout', 5000);
 
 define('qrs_backend', 'pgsql-smart');
+define('qrs_enable_ranking', false);
 
 define('qrs_path_prefix', '');
-- 
GitLab