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 : }
|