LCOV - code coverage report
Current view: top level - core/db/sqlite - SPSqliteModuleTextSearch.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 53 70 75.7 %
Date: 2024-05-12 00:16:13 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /**
       2             :  Copyright (c) 2024 Stappler LLC <admin@stappler.dev>
       3             : 
       4             :  Permission is hereby granted, free of charge, to any person obtaining a copy
       5             :  of this software and associated documentation files (the "Software"), to deal
       6             :  in the Software without restriction, including without limitation the rights
       7             :  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       8             :  copies of the Software, and to permit persons to whom the Software is
       9             :  furnished to do so, subject to the following conditions:
      10             : 
      11             :  The above copyright notice and this permission notice shall be included in
      12             :  all copies or substantial portions of the Software.
      13             : 
      14             :  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      17             :  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      18             :  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      19             :  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      20             :  THE SOFTWARE.
      21             :  **/
      22             : 
      23             : #include "SPSqliteDriver.h"
      24             : #include "SPSqliteDriverHandle.h"
      25             : 
      26             : namespace STAPPLER_VERSIONIZED stappler::db::sqlite {
      27             : 
      28        1925 : static void sp_ts_update_xFunc(sqlite3_context *ctx, int nargs, sqlite3_value **args) {
      29        1925 :         DriverHandle *data = (DriverHandle *)sqlite3_user_data(ctx);
      30             : 
      31        1925 :         auto id = sqlite3_value_int64(args[0]);
      32        1925 :         auto blob = BytesView((const uint8_t *)sqlite3_value_blob(args[1]), sqlite3_value_bytes(args[1]));
      33        1925 :         auto scheme = StringView((const char *)sqlite3_value_text(args[2]), sqlite3_value_bytes(args[2]));
      34        1925 :         auto field = StringView((const char *)sqlite3_value_text(args[3]), sqlite3_value_bytes(args[3]));
      35        1925 :         auto target = StringView((const char *)sqlite3_value_text(args[4]), sqlite3_value_bytes(args[4]));
      36        1925 :         auto action = sqlite3_value_int(args[5]);
      37             : 
      38        1925 :         if (action == 1 || action == 2) {
      39         225 :                 auto q = toString("DELETE FROM \"", target, "\" WHERE \"", scheme, "_id\"=", id);
      40         225 :                 Driver_exec(nullptr, data->conn, q);
      41         225 :         }
      42             : 
      43        1925 :         if (action == 2) {
      44         125 :                 return;
      45             :         }
      46             : 
      47        1800 :         bool first = true;
      48        1800 :         StringStream queryStream;
      49        1800 :         queryStream << "INSERT INTO \"" << target << "\"(\"" << scheme << "_id\",\"word\") VALUES ";
      50             : 
      51        1800 :         auto wordsWritten = false;
      52        1800 :         if (auto storage = data->driver->getQueryStorage(scheme)) {
      53        1800 :                 auto it = storage->find(field);
      54        1800 :                 if (it != storage->end()) {
      55        1800 :                         db::FullTextVector *vec = (db::FullTextVector *)it->second;
      56       13575 :                         for (auto &word : vec->words) {
      57       11775 :                                 auto wordId = data->driver->insertWord(Driver::Handle(data), word.first);
      58       11775 :                                 if (first) { first = false; } else { queryStream << ","; }
      59       11775 :                                 queryStream << "(" << id << "," << wordId << ")";
      60             :                         }
      61        1800 :                         wordsWritten = true;
      62             :                 }
      63             :         }
      64             : 
      65        1800 :         if (!wordsWritten) {
      66           0 :                 auto block = data::read<Interface>(blob).getValue(1);
      67           0 :                 if (block.getInteger(0) == 1) {
      68           0 :                         auto &d = data::read<Interface>(blob).getValue(1);
      69           0 :                         for (auto &it : d.asDict()) {
      70           0 :                                 auto wordId = data->driver->insertWord(Driver::Handle(data), it.first);
      71           0 :                                 if (first) { first = false; } else { queryStream << ","; }
      72           0 :                                 queryStream << "(" << id << "," << wordId << ")";
      73           0 :                                 wordsWritten = true;
      74             :                         }
      75             :                 }
      76           0 :         }
      77             : 
      78        1800 :         if (wordsWritten) {
      79        1800 :                 StringView str(queryStream.weak());
      80        1800 :                 Driver_exec(nullptr, data->conn, str);
      81             :         }
      82        1800 : }
      83             : 
      84         250 : static void sp_ts_rank_xFunc(sqlite3_context *ctx, int nargs, sqlite3_value **args) {
      85         250 :         DriverHandle *data = (DriverHandle *)sqlite3_user_data(ctx);
      86         250 :         auto storageData = data->driver->getCurrentQueryStorage();
      87         250 :         if (!storageData) {
      88           0 :                 sqlite3_result_double(ctx, 0.0f);
      89           0 :                 return;
      90             :         }
      91             : 
      92         250 :         auto blob = BytesView((const uint8_t *)sqlite3_value_blob(args[0]), sqlite3_value_bytes(args[0]));
      93         250 :         auto query = StringView((const char *)sqlite3_value_text(args[1]), sqlite3_value_bytes(args[1]));
      94         250 :         auto norm = sqlite3_value_int(args[2]);
      95             : 
      96         250 :         auto it = storageData->find(query);
      97         250 :         if (it == storageData->end()) {
      98           0 :                 sqlite3_result_double(ctx, 0.0f);
      99           0 :                 return;
     100             :         }
     101             : 
     102         250 :         auto q = (TextQueryData *)it->second;
     103         250 :         sqlite3_result_double(ctx, q->query->rankQuery(blob, search::Normalization(norm)));
     104             : }
     105             : 
     106         250 : static void sp_ts_query_valid_xFunc(sqlite3_context *ctx, int nargs, sqlite3_value **args) {
     107         250 :         DriverHandle *data = (DriverHandle *)sqlite3_user_data(ctx);
     108         250 :         auto storageData = data->driver->getCurrentQueryStorage();
     109         250 :         if (!storageData) {
     110           0 :                 sqlite3_result_int(ctx, 0);
     111           0 :                 return;
     112             :         }
     113             : 
     114         250 :         auto blob = BytesView((const uint8_t *)sqlite3_value_blob(args[0]), sqlite3_value_bytes(args[0]));
     115         250 :         auto query = StringView((const char *)sqlite3_value_text(args[1]), sqlite3_value_bytes(args[1]));
     116             : 
     117         250 :         auto it = storageData->find(query);
     118         250 :         if (it == storageData->end()) {
     119           0 :                 sqlite3_result_int(ctx, 0);
     120           0 :                 return;
     121             :         }
     122             : 
     123         250 :         auto q = (TextQueryData *)it->second;
     124         250 :         sqlite3_result_int(ctx, q->query->isMatch(blob) ? 1 : 0);
     125             : }
     126             : 
     127             : }

Generated by: LCOV version 1.14