1 | /* |
2 | This file is part of the KDE Baloo project. |
3 | SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.1-or-later |
6 | */ |
7 | |
8 | #include "documentdb.h" |
9 | #include "doctermscodec.h" |
10 | #include "enginedebug.h" |
11 | |
12 | using namespace Baloo; |
13 | |
14 | DocumentDB::DocumentDB(MDB_dbi dbi, MDB_txn* txn) |
15 | : m_txn(txn) |
16 | , m_dbi(dbi) |
17 | { |
18 | Q_ASSERT(txn != nullptr); |
19 | Q_ASSERT(dbi != 0); |
20 | } |
21 | |
22 | DocumentDB::~DocumentDB() |
23 | { |
24 | } |
25 | |
26 | MDB_dbi DocumentDB::create(const char* name, MDB_txn* txn) |
27 | { |
28 | MDB_dbi dbi = 0; |
29 | const int rc = mdb_dbi_open(txn, name, MDB_CREATE | MDB_INTEGERKEY, dbi: &dbi); |
30 | if (rc) { |
31 | qCWarning(ENGINE) << "DocumentDB::create" << name << mdb_strerror(err: rc); |
32 | return 0; |
33 | } |
34 | |
35 | return dbi; |
36 | } |
37 | |
38 | MDB_dbi DocumentDB::open(const char* name, MDB_txn* txn) |
39 | { |
40 | MDB_dbi dbi = 0; |
41 | const int rc = mdb_dbi_open(txn, name, MDB_INTEGERKEY, dbi: &dbi); |
42 | if (rc) { |
43 | qCWarning(ENGINE) << "DocumentDB::open" << name << mdb_strerror(err: rc); |
44 | return 0; |
45 | } |
46 | |
47 | return dbi; |
48 | } |
49 | |
50 | void DocumentDB::put(quint64 docId, const QVector<QByteArray>& list) |
51 | { |
52 | Q_ASSERT(docId > 0); |
53 | Q_ASSERT(!list.isEmpty()); |
54 | |
55 | MDB_val key; |
56 | key.mv_size = sizeof(quint64); |
57 | key.mv_data = static_cast<void*>(&docId); |
58 | |
59 | QByteArray arr = DocTermsCodec::encode(terms: list); |
60 | |
61 | MDB_val val; |
62 | val.mv_size = arr.size(); |
63 | val.mv_data = static_cast<void*>(arr.data()); |
64 | |
65 | int rc = mdb_put(txn: m_txn, dbi: m_dbi, key: &key, data: &val, flags: 0); |
66 | if (rc) { |
67 | qCWarning(ENGINE) << "DocumentDB::put" << mdb_strerror(err: rc); |
68 | } |
69 | } |
70 | |
71 | QVector<QByteArray> DocumentDB::get(quint64 docId) |
72 | { |
73 | Q_ASSERT(docId > 0); |
74 | |
75 | MDB_val key; |
76 | key.mv_size = sizeof(quint64); |
77 | key.mv_data = static_cast<void*>(&docId); |
78 | |
79 | MDB_val val{.mv_size: 0, .mv_data: nullptr}; |
80 | int rc = mdb_get(txn: m_txn, dbi: m_dbi, key: &key, data: &val); |
81 | if (rc) { |
82 | qCDebug(ENGINE) << "DocumentDB::get" << docId << mdb_strerror(err: rc); |
83 | return QVector<QByteArray>(); |
84 | } |
85 | |
86 | QByteArray arr = QByteArray::fromRawData(data: static_cast<char*>(val.mv_data), size: val.mv_size); |
87 | |
88 | auto result = DocTermsCodec::decode(arr); |
89 | if (result.isEmpty()) { |
90 | qCDebug(ENGINE) << "Document Terms DB contains corrupt data for " << docId; |
91 | } |
92 | return result; |
93 | } |
94 | |
95 | void DocumentDB::del(quint64 docId) |
96 | { |
97 | Q_ASSERT(docId > 0); |
98 | |
99 | MDB_val key; |
100 | key.mv_size = sizeof(quint64); |
101 | key.mv_data = static_cast<void*>(&docId); |
102 | |
103 | int rc = mdb_del(txn: m_txn, dbi: m_dbi, key: &key, data: nullptr); |
104 | if (rc != 0 && rc != MDB_NOTFOUND) { |
105 | qCDebug(ENGINE) << "DocumentDB::del" << docId << mdb_strerror(err: rc); |
106 | } |
107 | } |
108 | |
109 | bool DocumentDB::contains(quint64 docId) |
110 | { |
111 | Q_ASSERT(docId > 0); |
112 | |
113 | MDB_val key; |
114 | key.mv_size = sizeof(quint64); |
115 | key.mv_data = static_cast<void*>(&docId); |
116 | |
117 | MDB_val val; |
118 | int rc = mdb_get(txn: m_txn, dbi: m_dbi, key: &key, data: &val); |
119 | if (rc) { |
120 | if (rc != MDB_NOTFOUND) { |
121 | qCDebug(ENGINE) << "DocumentDB::contains" << docId << mdb_strerror(err: rc); |
122 | } |
123 | return false; |
124 | } |
125 | |
126 | return true; |
127 | } |
128 | |
129 | uint DocumentDB::size() |
130 | { |
131 | MDB_stat stat; |
132 | int rc = mdb_stat(txn: m_txn, dbi: m_dbi, stat: &stat); |
133 | if (rc) { |
134 | qCDebug(ENGINE) << "DocumentDB::size" << mdb_strerror(err: rc); |
135 | return 0; |
136 | } |
137 | |
138 | return stat.ms_entries; |
139 | } |
140 | |
141 | QMap<quint64, QVector<QByteArray>> DocumentDB::toTestMap() const |
142 | { |
143 | MDB_cursor* cursor; |
144 | mdb_cursor_open(txn: m_txn, dbi: m_dbi, cursor: &cursor); |
145 | |
146 | MDB_val key = {.mv_size: 0, .mv_data: nullptr}; |
147 | MDB_val val; |
148 | |
149 | QMap<quint64, QVector<QByteArray>> map; |
150 | while (1) { |
151 | int rc = mdb_cursor_get(cursor, key: &key, data: &val, op: MDB_NEXT); |
152 | if (rc == MDB_NOTFOUND) { |
153 | break; |
154 | } |
155 | if (rc) { |
156 | qCWarning(ENGINE) << "DocumentDB::toTestMap" << mdb_strerror(err: rc); |
157 | break; |
158 | } |
159 | |
160 | const quint64 id = *(static_cast<quint64*>(key.mv_data)); |
161 | const QVector<QByteArray> vec = DocTermsCodec::decode(arr: QByteArray(static_cast<char*>(val.mv_data), val.mv_size)); |
162 | map.insert(key: id, value: vec); |
163 | } |
164 | |
165 | mdb_cursor_close(cursor); |
166 | return map; |
167 | } |
168 | |