• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "EditUnit"
17 
18 #include "napi_edit_unit.h"
19 
20 #include <nlohmann/json.hpp>
21 
22 #include "napi_collaboration_edit_object.h"
23 #include "napi_error_utils.h"
24 #include "napi_parser.h"
25 
26 namespace OHOS::CollaborationEdit {
27 using json = nlohmann::json;
EditUnit(std::string name)28 EditUnit::EditUnit(std::string name) : AbstractType(),  name_(name)
29 {}
30 
~EditUnit()31 EditUnit::~EditUnit()
32 {}
33 
Initialize(napi_env env,napi_callback_info info)34 napi_value EditUnit::Initialize(napi_env env, napi_callback_info info)
35 {
36     size_t argc = 1;
37     napi_value argv[1] = {nullptr};
38     napi_value self = nullptr;
39     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
40     std::string name;
41     napi_status status = NapiUtils::GetValue(env, argv[0], name);
42     ASSERT_THROW_BASE(env, status == napi_ok, Status::INVALID_ARGUMENT, "read name param go wrong", self);
43     ASSERT_THROW_BASE(env, !name.empty(), Status::INVALID_ARGUMENT, "Param Error: invalid name", self);
44     name = std::to_string(LABEL_FRAGMENT) + "_" + name;
45     EditUnit *editUnit = new (std::nothrow) EditUnit(name);
46     ASSERT_THROW_BASE(env, editUnit != nullptr, Status::INTERNAL_ERROR, "Initialize: new editunit go wrong", self);
47     editUnit->SetTableName(name);
48     auto finalize = [](napi_env env, void *data, void *hint) {
49         EditUnit *editUnit = reinterpret_cast<EditUnit *>(data);
50         delete editUnit;
51     };
52     status = napi_wrap(env, self, editUnit, finalize, nullptr, nullptr);
53     if (status != napi_ok) {
54         LOG_ERROR("napi_wrap failed. code:%{public}d", status);
55         delete editUnit;
56         return nullptr;
57     }
58     return self;
59 }
60 
Constructor(napi_env env)61 napi_value EditUnit::Constructor(napi_env env)
62 {
63     auto lambda = []() -> std::vector<napi_property_descriptor> {
64         std::vector<napi_property_descriptor> properties = {
65             DECLARE_NAPI_FUNCTION("insertNodes", InsertNodes),
66             DECLARE_NAPI_FUNCTION("delete", Delete),
67             DECLARE_NAPI_FUNCTION("getChildren", GetChildren),
68             DECLARE_NAPI_FUNCTION("getJsonResult", GetJsonResult),
69             DECLARE_NAPI_FUNCTION("getName", GetName),
70             DECLARE_NAPI_FUNCTION("getRelativePos", GetRelativePos),
71             DECLARE_NAPI_FUNCTION("getAbsolutePos", GetAbsolutePos),
72         };
73         return properties;
74     };
75     return NapiUtils::DefineClass(
76         env, "ohos.data.collaborationEditObject", "EditUnit", lambda, Initialize);
77 }
78 
NewInstance(napi_env env,napi_callback_info info,napi_value parent)79 napi_value EditUnit::NewInstance(napi_env env, napi_callback_info info, napi_value parent)
80 {
81     size_t argc = 1;
82     napi_value argv[1] = {nullptr};
83     napi_value editUnit = nullptr;
84     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
85     napi_status status = napi_new_instance(env, Constructor(env), argc, argv, &editUnit);
86     if (editUnit == nullptr || status != napi_ok) {
87         LOG_ERROR("new instance go wrong");
88     }
89     return editUnit;
90 }
91 
GetName(napi_env env,napi_callback_info info)92 napi_value EditUnit::GetName(napi_env env, napi_callback_info info)
93 {
94     napi_value self = nullptr;
95     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
96     EditUnit *editUnit = nullptr;
97     napi_status status = napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit));
98     if (status != napi_ok || editUnit == nullptr) {
99         LOG_ERROR("unwrap editUnit go wrong, status = %{public}d", status);
100         return nullptr;
101     }
102     std::string name = editUnit->name_;
103     if (name.compare(0, NUMBER_OF_CHARS_IN_LABEL_PREFIX, std::to_string(LABEL_FRAGMENT) + "_") == 0) {
104         name = name.substr(NUMBER_OF_CHARS_IN_LABEL_PREFIX);
105     }
106     napi_value result;
107     NapiUtils::SetValue(env, name, result);
108     return result;
109 }
110 
InsertNodes(napi_env env,napi_callback_info info)111 napi_value EditUnit::InsertNodes(napi_env env, napi_callback_info info)
112 {
113     size_t argc = 2;
114     napi_value argv[2] = {nullptr};
115     napi_value self = nullptr;
116     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
117     EditUnit *editUnit = nullptr;
118     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
119     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
120     int64_t index = 0;
121     napi_status status = NapiUtils::GetValue(env, argv[0], index);
122     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: Read index go wrong.");
123     ASSERT_THROW(env, index >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid index.");
124     bool isArray = false;
125     NAPI_CALL(env, napi_is_array(env, argv[1], &isArray));
126     ASSERT_THROW(env, isArray, Status::INVALID_ARGUMENT, "Param Error: The nodes must be an array.");
127     uint32_t length = 0;
128     NAPI_CALL(env, napi_get_array_length(env, argv[1], &length));
129     for (uint32_t i = 0; i < length; i++) {
130         napi_value jsNode = nullptr;
131         NAPI_CALL(env, napi_get_element(env, argv[1], i, &jsNode));
132         Node *tempNode = nullptr;
133         NAPI_CALL(env, napi_unwrap(env, jsNode, reinterpret_cast<void **>(&tempNode)));
134         auto [retCode, id] = editUnit->GetAdapter()->InsertNode(index + i, tempNode->InnerGetName());
135         if (retCode != SUCCESS || !id.has_value()) {
136             ThrowNapiError(env, retCode, "InsertNodes go wrong.");
137             return nullptr;
138         }
139         tempNode->SetID(id);
140         tempNode->SetTableName(editUnit->GetTableName());
141         tempNode->SetDBStore(editUnit->GetDBStore());
142     }
143     LOG_INFO("insert nodes successfully.");
144     return nullptr;
145 }
146 
Delete(napi_env env,napi_callback_info info)147 napi_value EditUnit::Delete(napi_env env, napi_callback_info info)
148 {
149     size_t argc = 2;
150     napi_value argv[2] = {nullptr};
151     napi_value self = nullptr;
152     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
153     EditUnit *editUnit = nullptr;
154     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
155     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
156     int64_t index = 0;
157     napi_status status = NapiUtils::GetValue(env, argv[0], index);
158     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: Read index go wrong.");
159     ASSERT_THROW(env, index >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid index.");
160     int64_t length = 0;
161     status = NapiUtils::GetValue(env, argv[1], length);
162     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: Read length go wrong.");
163     ASSERT_THROW(env, length > 0, Status::INVALID_ARGUMENT, "Param Error: Invalid length.");
164 
165     int32_t retCode = editUnit->GetAdapter()->DeleteChildren(index, length);
166     if (retCode != SUCCESS) {
167         ThrowNapiError(env, retCode, "Delete Nodes go wrong.");
168     }
169     return nullptr;
170 }
171 
GetChildren(napi_env env,napi_callback_info info)172 napi_value EditUnit::GetChildren(napi_env env, napi_callback_info info)
173 {
174     size_t argc = 2;
175     napi_value argv[2] = {nullptr};
176     napi_value self = nullptr;
177     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
178     EditUnit *editUnit = nullptr;
179     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
180     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
181     int64_t start = 0;
182     napi_status status = NapiUtils::GetValue(env, argv[0], start);
183     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: Read start index go wrong.");
184     ASSERT_THROW(env, start >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid start.");
185     int64_t end = 0;
186     status = NapiUtils::GetValue(env, argv[1], end);
187     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "Param Error: Read end index go wrong.");
188     ASSERT_THROW(env, end >= 0, Status::INVALID_ARGUMENT, "Param Error: Invalid end.");
189     ASSERT_THROW(env, end > start, Status::INVALID_ARGUMENT, "Param Error: end should be greater than start.");
190 
191     auto [retCode, result] = editUnit->GetAdapter()->GetChildren(start, end - start);
192     if (retCode != SUCCESS) {
193         ThrowNapiError(env, retCode, "Get Children go wrong.");
194         return nullptr;
195     }
196     // transfer string to node array
197     napi_value output = nullptr;
198     int ret = Parser::ParseJsonStrToJsChildren(env, result, editUnit, output);
199     if (ret != OK) {
200         ThrowNapiError(env, Status::INTERNAL_ERROR, "convert result go wrong.");
201         return nullptr;
202     }
203     return output;
204 }
205 
GetJsonResult(napi_env env,napi_callback_info info)206 napi_value EditUnit::GetJsonResult(napi_env env, napi_callback_info info)
207 {
208     napi_value self = nullptr;
209     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
210     EditUnit *editUnit = nullptr;
211     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
212     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
213     auto [retCode, result] = editUnit->GetAdapter()->GetJsonString();
214     if (retCode != SUCCESS) {
215         ThrowNapiError(env, retCode, "toString go wrong.");
216         return nullptr;
217     }
218     napi_value output = nullptr;
219     napi_status status = NapiUtils::SetValue(env, result, output);
220     if (status != napi_ok || output == nullptr) {
221         ThrowNapiError(env, Status::INTERNAL_ERROR, "create output string go wrong.");
222         return nullptr;
223     }
224     return output;
225 }
226 
GetRelativePos(napi_env env,napi_callback_info info)227 napi_value EditUnit::GetRelativePos(napi_env env, napi_callback_info info)
228 {
229     size_t argc = 1;
230     napi_value argv[1] = {nullptr};
231     napi_value self = nullptr;
232     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
233 
234     uint32_t pos;
235     napi_status status = NapiUtils::GetValue(env, argv[0], pos);
236     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "read pos param go wrong");
237 
238     EditUnit *editUnit = nullptr;
239     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
240     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
241 
242     auto dbStore = editUnit->GetDBStore();
243     std::string relPos;
244     int32_t ret = (*dbStore).GetRelativePos(editUnit->name_.c_str(), "{}", pos, relPos);
245     ASSERT_THROW(env, ret == OK, Status::INTERNAL_ERROR, "GetRelativePos go wrong");
246 
247     return Parser::GetRelativePosFromJsonStr(env, relPos);
248 }
249 
GetAbsolutePos(napi_env env,napi_callback_info info)250 napi_value EditUnit::GetAbsolutePos(napi_env env, napi_callback_info info)
251 {
252     size_t argc = 1;
253     napi_value argv[1] = {nullptr};
254     napi_value self = nullptr;
255     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
256     EditUnit *editUnit = nullptr;
257     NAPI_CALL(env, napi_unwrap(env, self, reinterpret_cast<void **>(&editUnit)));
258     ASSERT(editUnit != nullptr, "unwrap self go wrong.", nullptr);
259 
260     json root;
261     napi_value type;
262     napi_status status = NapiUtils::GetNamedProperty(env, argv[0], "parentId", type);
263     json typeJson;
264     if (status == napi_ok && !NapiUtils::IsNull(env, type)) {
265         Parser::GetUniqueIdFromNapiValueToJsonStr(env, type, typeJson);
266     } else {
267         typeJson = nullptr;
268     }
269     root["type"] = typeJson;
270 
271     std::string typeName;
272     NapiUtils::GetNamedProperty(env, argv[0], "parentName", typeName);
273     if (!typeName.empty()) {
274         root["tname"] = typeName;
275     } else {
276         root["tname"] = nullptr;
277     }
278 
279     napi_value item;
280     status = NapiUtils::GetNamedProperty(env, argv[0], "id", item);
281     json itemJson;
282     if (status == napi_ok && !NapiUtils::IsNull(env, item)) {
283         Parser::GetUniqueIdFromNapiValueToJsonStr(env, item, itemJson);
284     } else {
285         itemJson = nullptr;
286     }
287     root["item"] = itemJson;
288 
289     int64_t assoc;
290     status = NapiUtils::GetNamedProperty(env, argv[0], "pos", assoc);
291     ASSERT_THROW(env, status == napi_ok, Status::INVALID_ARGUMENT, "read pos param go wrong");
292     root["assoc"] = assoc;
293 
294     std::string relPos_str = root.dump();
295     auto dbStore = editUnit->GetDBStore();
296     uint32_t pos;
297     int32_t ret = (*dbStore).GetAbsolutePos(editUnit->name_.c_str(), relPos_str.c_str(), "{}", &pos);
298     ASSERT_THROW(env, ret == SUCCESS, ret, "GetAbsolutePos go wrong");
299 
300     napi_value output = nullptr;
301     status = NapiUtils::SetValue(env, static_cast<int64_t>(pos), output);
302     return output;
303 }
304 }  // namespace OHOS::CollaborationEdit
305