1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define LOG_TAG "RdAdapter"
17
18 #include "rd_adapter.h"
19
20 #include "log_print.h"
21
22 namespace OHOS::CollaborationEdit {
RdAdapter()23 RdAdapter::RdAdapter()
24 {}
25
~RdAdapter()26 RdAdapter::~RdAdapter()
27 {}
28
SetDBStore(std::shared_ptr<DBStore> dbStore)29 void RdAdapter::SetDBStore(std::shared_ptr<DBStore> dbStore)
30 {
31 this->dbStore_ = dbStore;
32 }
33
GetDBStore()34 std::shared_ptr<DBStore> RdAdapter::GetDBStore()
35 {
36 return this->dbStore_;
37 }
38
SetTableName(std::string name)39 void RdAdapter::SetTableName(std::string name)
40 {
41 this->tableName_ = name;
42 }
43
GetTableName()44 std::string RdAdapter::GetTableName()
45 {
46 return this->tableName_;
47 }
48
SetID(std::optional<ID> id)49 void RdAdapter::SetID(std::optional<ID> id)
50 {
51 this->id_ = id;
52 }
53
GetID()54 std::optional<ID> RdAdapter::GetID()
55 {
56 return this->id_;
57 }
58
InsertNode(uint32_t index,std::string nodeName)59 std::pair<int32_t, std::optional<ID>> RdAdapter::InsertNode(uint32_t index, std::string nodeName)
60 {
61 GRD_ElementIdT *elementId = nullptr;
62 GRD_ElementIdT tempId;
63 if (this->id_.has_value()) {
64 tempId.equipId = this->id_.value().deviceId.c_str();
65 tempId.incrClock = this->id_.value().clock;
66 elementId = &tempId;
67 }
68 GRD_XmlOpPositionT position = {
69 .tableName = this->tableName_.c_str(),
70 .elementId = elementId,
71 };
72 GRD_DocNodeInfo nodeInfo = {
73 .type = GRD_XML_ELEMENT_TYPE,
74 .content = nodeName.c_str(),
75 };
76
77 GRD_ElementIdT *outElementId = nullptr;
78 int32_t errCode = RdUtils::RdInsertElements(this->dbStore_->GetDB(), &position, index, &nodeInfo, &outElementId);
79 if (errCode != GRD_OK || outElementId == nullptr) {
80 LOG_ERROR("InsertElements go wrong, errCode = %{public}d", errCode);
81 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), std::nullopt);
82 }
83 ID id(std::string(outElementId->equipId), outElementId->incrClock);
84 RdUtils::RdFreeElementId(outElementId);
85 return std::make_pair(errCode, id);
86 }
87
InsertText(uint32_t index)88 std::pair<int32_t, std::optional<ID>> RdAdapter::InsertText(uint32_t index)
89 {
90 GRD_ElementIdT *elementId = nullptr;
91 GRD_ElementIdT tempId;
92 if (this->id_.has_value()) {
93 tempId.equipId = this->id_.value().deviceId.c_str();
94 tempId.incrClock = this->id_.value().clock;
95 elementId = &tempId;
96 }
97 GRD_XmlOpPositionT position = {
98 .tableName = this->tableName_.c_str(),
99 .elementId = elementId,
100 };
101 GRD_DocNodeInfo nodeInfo = {
102 .type = GRD_XML_TEXT_TYPE,
103 .content = nullptr,
104 };
105
106 GRD_ElementIdT *outElementId = nullptr;
107 int32_t errCode = RdUtils::RdInsertElements(this->dbStore_->GetDB(), &position, index, &nodeInfo, &outElementId);
108 if (errCode != GRD_OK || outElementId == nullptr) {
109 LOG_ERROR("InsertElements go wrong, errCode = %{public}d", errCode);
110 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), std::nullopt);
111 }
112 ID id(std::string(outElementId->equipId), outElementId->incrClock);
113 RdUtils::RdFreeElementId(outElementId);
114 return std::make_pair(errCode, id);
115 }
116
DeleteChildren(uint32_t index,uint32_t length)117 int32_t RdAdapter::DeleteChildren(uint32_t index, uint32_t length)
118 {
119 GRD_ElementIdT *elementId = nullptr;
120 GRD_ElementIdT tempId;
121 if (this->id_.has_value()) {
122 tempId.equipId = this->id_.value().deviceId.c_str();
123 tempId.incrClock = this->id_.value().clock;
124 elementId = &tempId;
125 }
126
127 int32_t errCode = RdUtils::RdDeleteElements(this->dbStore_->GetDB(), this->tableName_.c_str(), elementId, index,
128 length);
129 if (errCode != GRD_OK) {
130 LOG_ERROR("DeleteElements go wrong, errCode = %{public}d", errCode);
131 }
132 return RdUtils::TransferToNapiErrNo(errCode);
133 }
134
GetChildren(uint32_t index,uint32_t length)135 std::pair<int32_t, std::string> RdAdapter::GetChildren(uint32_t index, uint32_t length)
136 {
137 GRD_ElementIdT *elementId = nullptr;
138 GRD_ElementIdT tempId;
139 if (this->id_.has_value()) {
140 tempId.equipId = this->id_.value().deviceId.c_str();
141 tempId.incrClock = this->id_.value().clock;
142 elementId = &tempId;
143 }
144 GRD_XmlOpPositionT position = {
145 .tableName = this->tableName_.c_str(),
146 .elementId = elementId,
147 };
148
149 char *respXml = nullptr;
150 int32_t errCode = RdUtils::RdGetElements(this->dbStore_->GetDB(), &position, index, length, &respXml);
151 if (errCode != GRD_OK) {
152 LOG_ERROR("RdGetElements go wrong, errCode = %{public}d", errCode);
153 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), "");
154 }
155 std::string retString(respXml == nullptr ? "" : respXml);
156 (void)RdUtils::RdFreeValue(respXml);
157 return std::make_pair(errCode, retString);
158 }
159
GetJsonString()160 std::pair<int32_t, std::string> RdAdapter::GetJsonString()
161 {
162 GRD_ElementIdT *elementId = nullptr;
163 GRD_ElementIdT tempId;
164 if (this->id_.has_value()) {
165 tempId.equipId = this->id_.value().deviceId.c_str();
166 tempId.incrClock = this->id_.value().clock;
167 elementId = &tempId;
168 }
169
170 char *replyJson = nullptr;
171 int32_t errCode = RdUtils::RdFragmentToString(this->dbStore_->GetDB(), this->tableName_.c_str(), elementId,
172 &replyJson);
173 if (errCode != GRD_OK) {
174 LOG_ERROR("RdFragmentToString go wrong, errCode = %{public}d", errCode);
175 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), "");
176 }
177 std::string retString(replyJson == nullptr ? "" : replyJson);
178 (void)RdUtils::RdFreeValue(replyJson);
179 return std::make_pair(errCode, retString);
180 }
181
SetAttribute(const std::string & attributeName,const std::string & attributeValue,uint32_t flags)182 int32_t RdAdapter::SetAttribute(const std::string &attributeName, const std::string &attributeValue, uint32_t flags)
183 {
184 GRD_ElementIdT *elementId = nullptr;
185 GRD_ElementIdT tempId;
186 if (this->id_.has_value()) {
187 tempId.equipId = this->id_.value().deviceId.c_str();
188 tempId.incrClock = this->id_.value().clock;
189 elementId = &tempId;
190 }
191 GRD_XmlOpPositionT position = {
192 .tableName = this->tableName_.c_str(),
193 .elementId = elementId,
194 };
195 int32_t errCode = RdUtils::RdElementSetAttribute(this->dbStore_->GetDB(), &position, attributeName.c_str(),
196 attributeValue.c_str(), flags);
197 if (errCode != GRD_OK) {
198 LOG_ERROR("RdElementSetAttribute go wrong, errCode = %{public}d", errCode);
199 }
200 return RdUtils::TransferToNapiErrNo(errCode);
201 }
202
RemoveAttrribute(const std::string & attributeName)203 int32_t RdAdapter::RemoveAttrribute(const std::string &attributeName)
204 {
205 GRD_ElementIdT *elementId = nullptr;
206 GRD_ElementIdT tempId;
207 if (this->id_.has_value()) {
208 tempId.equipId = this->id_.value().deviceId.c_str();
209 tempId.incrClock = this->id_.value().clock;
210 elementId = &tempId;
211 }
212 GRD_XmlOpPositionT position = {
213 .tableName = this->tableName_.c_str(),
214 .elementId = elementId,
215 };
216 int32_t errCode = RdUtils::RdElementRemoveAttribute(this->dbStore_->GetDB(), &position, attributeName.c_str());
217 if (errCode != GRD_OK) {
218 LOG_ERROR("RdElementRemoveAttribute go wrong, errCode = %{public}d", errCode);
219 }
220 return RdUtils::TransferToNapiErrNo(errCode);
221 }
222
GetAttributes()223 std::pair<int32_t, std::string> RdAdapter::GetAttributes()
224 {
225 GRD_ElementIdT *elementId = nullptr;
226 GRD_ElementIdT tempId;
227 if (this->id_.has_value()) {
228 tempId.equipId = this->id_.value().deviceId.c_str();
229 tempId.incrClock = this->id_.value().clock;
230 elementId = &tempId;
231 }
232 GRD_XmlOpPositionT position = {
233 .tableName = this->tableName_.c_str(),
234 .elementId = elementId,
235 };
236
237 char *fullAttributes = nullptr;
238 int32_t errCode = RdUtils::RdElementGetAttributes(this->dbStore_->GetDB(), &position, &fullAttributes);
239 if (errCode != GRD_OK) {
240 LOG_ERROR("RdElementGetAttributes go wrong, errCode = %{public}d", errCode);
241 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), "");
242 }
243 std::string attrsString(fullAttributes == nullptr ? "" : fullAttributes);
244 (void)RdUtils::RdFreeValue(fullAttributes);
245 return std::make_pair(errCode, attrsString);
246 }
247
TextInsert(uint32_t index,const std::string & content,const std::string & formatStr)248 int32_t RdAdapter::TextInsert(uint32_t index, const std::string &content, const std::string &formatStr)
249 {
250 GRD_ElementIdT *elementId = nullptr;
251 GRD_ElementIdT tempId;
252 if (this->id_.has_value()) {
253 tempId.equipId = this->id_.value().deviceId.c_str();
254 tempId.incrClock = this->id_.value().clock;
255 elementId = &tempId;
256 }
257 GRD_XmlOpPositionT position = {
258 .tableName = this->tableName_.c_str(),
259 .elementId = elementId,
260 };
261 int32_t errCode = RdUtils::RdTextInsert(this->dbStore_->GetDB(), &position, index, content.c_str(),
262 formatStr.empty() ? nullptr : formatStr.c_str());
263 if (errCode != GRD_OK) {
264 LOG_ERROR("RdTextInsert go wrong, errCode = %{public}d", errCode);
265 }
266 return RdUtils::TransferToNapiErrNo(errCode);
267 }
268
TextDelete(uint32_t index,uint32_t length)269 int32_t RdAdapter::TextDelete(uint32_t index, uint32_t length)
270 {
271 GRD_ElementIdT *elementId = nullptr;
272 GRD_ElementIdT tempId;
273 if (this->id_.has_value()) {
274 tempId.equipId = this->id_.value().deviceId.c_str();
275 tempId.incrClock = this->id_.value().clock;
276 elementId = &tempId;
277 }
278 GRD_XmlOpPositionT position = {
279 .tableName = this->tableName_.c_str(),
280 .elementId = elementId,
281 };
282 int32_t errCode = RdUtils::RdTextDelete(this->dbStore_->GetDB(), &position, index, length);
283 if (errCode != GRD_OK) {
284 LOG_ERROR("RdTextDelete go wrong, errCode = %{public}d", errCode);
285 }
286 return RdUtils::TransferToNapiErrNo(errCode);
287 }
288
TextFormat(uint32_t index,uint32_t length,const std::string & formatStr)289 int32_t RdAdapter::TextFormat(uint32_t index, uint32_t length, const std::string &formatStr)
290 {
291 GRD_ElementIdT *elementId = nullptr;
292 GRD_ElementIdT tempId;
293 if (this->id_.has_value()) {
294 tempId.equipId = this->id_.value().deviceId.c_str();
295 tempId.incrClock = this->id_.value().clock;
296 elementId = &tempId;
297 }
298 GRD_XmlOpPositionT position = {
299 .tableName = this->tableName_.c_str(),
300 .elementId = elementId,
301 };
302 int32_t errCode = RdUtils::RdTextFormat(this->dbStore_->GetDB(), &position, index, length,
303 formatStr.c_str());
304 if (errCode != GRD_OK) {
305 LOG_ERROR("RdTextFormat go wrong, errCode = %{public}d", errCode);
306 }
307 return RdUtils::TransferToNapiErrNo(errCode);
308 }
309
GetTextLength()310 std::pair<int32_t, uint32_t> RdAdapter::GetTextLength()
311 {
312 GRD_ElementIdT *elementId = nullptr;
313 GRD_ElementIdT tempId;
314 if (this->id_.has_value()) {
315 tempId.equipId = this->id_.value().deviceId.c_str();
316 tempId.incrClock = this->id_.value().clock;
317 elementId = &tempId;
318 }
319 GRD_XmlOpPositionT position = {
320 .tableName = this->tableName_.c_str(),
321 .elementId = elementId,
322 };
323 uint32_t textLength = 0;
324 int32_t errCode = RdUtils::RdTextGetLength(this->dbStore_->GetDB(), &position, &textLength);
325 if (errCode != GRD_OK) {
326 LOG_ERROR("RdTextGetLength go wrong, errCode = %{public}d", errCode);
327 }
328 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), textLength);
329 }
330
ReadDeltaText(const std::string & snapshot,const std::string & snapshotPrev)331 std::pair<int32_t, std::string> RdAdapter::ReadDeltaText(const std::string &snapshot, const std::string &snapshotPrev)
332 {
333 GRD_ElementIdT *elementId = nullptr;
334 GRD_ElementIdT tempId;
335 if (this->id_.has_value()) {
336 tempId.equipId = this->id_.value().deviceId.c_str();
337 tempId.incrClock = this->id_.value().clock;
338 elementId = &tempId;
339 }
340 GRD_XmlOpPositionT position = {
341 .tableName = this->tableName_.c_str(),
342 .elementId = elementId,
343 };
344
345 char *deltaText = nullptr;
346 const char *snapshotPtr = snapshot.empty() ? nullptr : snapshot.c_str();
347 const char *snapshotPrevPtr = snapshotPrev.empty() ? nullptr : snapshotPrev.c_str();
348 int32_t errCode = RdUtils::RdTextReadInDeltaMode(this->dbStore_->GetDB(), &position, snapshotPtr,
349 snapshotPrevPtr, &deltaText);
350 if (errCode != GRD_OK) {
351 LOG_ERROR("RdTextReadInDeltaMode go wrong, errCode = %{public}d", errCode);
352 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), "");
353 }
354 std::string deltaString(deltaText == nullptr ? "" : deltaText);
355 (void)RdUtils::RdFreeValue(deltaText);
356 return std::make_pair(errCode, deltaString);
357 }
358
ReadStringText()359 std::pair<int32_t, std::string> RdAdapter::ReadStringText()
360 {
361 GRD_ElementIdT *elementId = nullptr;
362 GRD_ElementIdT tempId;
363 if (this->id_.has_value()) {
364 tempId.equipId = this->id_.value().deviceId.c_str();
365 tempId.incrClock = this->id_.value().clock;
366 elementId = &tempId;
367 }
368 GRD_XmlOpPositionT position = {
369 .tableName = this->tableName_.c_str(),
370 .elementId = elementId,
371 };
372
373 char *text = nullptr;
374 int32_t errCode = RdUtils::RdTextReadInStrMode(this->dbStore_->GetDB(), &position, &text);
375 if (errCode != GRD_OK) {
376 LOG_ERROR("RdTextReadInStrMode go wrong, errCode = %{public}d", errCode);
377 return std::make_pair(RdUtils::TransferToNapiErrNo(errCode), "");
378 }
379 std::string str(text == nullptr ? "" : text);
380 (void)RdUtils::RdFreeValue(text);
381 return std::make_pair(errCode, str);
382 }
383
CreateUndoManager(uint64_t captureTimeout)384 int32_t RdAdapter::CreateUndoManager(uint64_t captureTimeout)
385 {
386 GRD_XmlOpPositionT position = {
387 .tableName = this->tableName_.c_str(),
388 .elementId = nullptr,
389 };
390
391 GRD_UndoParamT undoParam = {
392 .captureTimeout = captureTimeout,
393 };
394
395 int32_t errCode = RdUtils::RdDocUndoManager(this->dbStore_->GetDB(), &position, &undoParam);
396 if (errCode != GRD_OK) {
397 LOG_ERROR("RdDocUndoManager go wrong, errCode = %{public}d", errCode);
398 }
399 return RdUtils::TransferToNapiErrNo(errCode);
400 }
401
CloseUndoManager()402 int32_t RdAdapter::CloseUndoManager()
403 {
404 GRD_XmlOpPositionT position = {
405 .tableName = this->tableName_.c_str(),
406 .elementId = nullptr,
407 };
408
409 int32_t errCode = RdUtils::RdDocCloseUndoManager(this->dbStore_->GetDB(), &position);
410 if (errCode != GRD_OK) {
411 LOG_ERROR("RdDocCloseUndoManager go wrong, errCode = %{public}d", errCode);
412 }
413 return RdUtils::TransferToNapiErrNo(errCode);
414 }
415
Undo()416 int32_t RdAdapter::Undo()
417 {
418 GRD_XmlOpPositionT position = {
419 .tableName = this->tableName_.c_str(),
420 .elementId = nullptr,
421 };
422
423 char *modify = nullptr;
424 int32_t errCode = RdUtils::RdDocUndo(this->GetDBStore()->GetDB(), &position, &modify);
425 if (errCode != GRD_OK) {
426 LOG_ERROR("RdDocUndo go wrong, errCode = %{public}d", errCode);
427 }
428 (void)RdUtils::RdFreeValue(modify);
429 return RdUtils::TransferToNapiErrNo(errCode);
430 }
431
Redo()432 int32_t RdAdapter::Redo()
433 {
434 GRD_XmlOpPositionT position = {
435 .tableName = this->tableName_.c_str(),
436 .elementId = nullptr,
437 };
438
439 char *modify = nullptr;
440 int32_t errCode = RdUtils::RdDocRedo(this->GetDBStore()->GetDB(), &position, &modify);
441 if (errCode != GRD_OK) {
442 LOG_ERROR("RdDocRedo go wrong, errCode = %{public}d", errCode);
443 }
444 (void)RdUtils::RdFreeValue(modify);
445 return RdUtils::TransferToNapiErrNo(errCode);
446 }
447
448 } // namespace OHOS::CollaborationEdit
449