1 /*
2 * Copyright (c) 2021-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 #include "napi_data_ability_operation.h"
16
17 #include <cstring>
18 #include <map>
19
20 #include "data_ability_predicates.h"
21 #include "hilog_tag_wrapper.h"
22 #include "napi_common_want.h"
23 #include "napi_data_ability_helper.h"
24 #include "values_bucket.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
DataAbilityOperationInit(napi_env env,napi_value exports)28 napi_value DataAbilityOperationInit(napi_env env, napi_value exports)
29 {
30 const int INSERT = 1;
31 const int UPDATE = 2;
32 const int DELETE = 3;
33 const int ASSERT = 4;
34 TAG_LOGD(AAFwkTag::FA, "called");
35
36 napi_value dataAbilityOperationType = nullptr;
37 napi_create_object(env, &dataAbilityOperationType);
38 SetNamedProperty(env, dataAbilityOperationType, "TYPE_INSERT", INSERT);
39 SetNamedProperty(env, dataAbilityOperationType, "TYPE_UPDATE", UPDATE);
40 SetNamedProperty(env, dataAbilityOperationType, "TYPE_DELETE", DELETE);
41 SetNamedProperty(env, dataAbilityOperationType, "TYPE_ASSERT", ASSERT);
42
43 napi_property_descriptor properties[] = {
44 DECLARE_NAPI_PROPERTY("DataAbilityOperationType", dataAbilityOperationType),
45 };
46 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
47
48 return exports;
49 }
50
UnwrapDataAbilityOperation(std::shared_ptr<DataAbilityOperation> & dataAbilityOperation,napi_env env,napi_value param)51 napi_value UnwrapDataAbilityOperation(
52 std::shared_ptr<DataAbilityOperation> &dataAbilityOperation, napi_env env, napi_value param)
53 {
54 TAG_LOGI(AAFwkTag::FA, "called");
55 if (!IsTypeForNapiValue(env, param, napi_object)) {
56 TAG_LOGE(AAFwkTag::FA, "invalid params");
57 return nullptr;
58 }
59
60 napi_value result = BuildDataAbilityOperation(dataAbilityOperation, env, param);
61 return result;
62 }
63
ParseUriAndType(napi_env env,napi_value & param,std::shared_ptr<Uri> & uri,int & type)64 bool ParseUriAndType(napi_env env, napi_value ¶m, std::shared_ptr<Uri> &uri, int &type)
65 {
66 // get uri property
67 std::string uriStr("");
68 if (!UnwrapStringByPropertyName(env, param, "uri", uriStr)) {
69 TAG_LOGE(AAFwkTag::FA, "%{public}s, uri is not exist.", __func__);
70 return false;
71 }
72 TAG_LOGI(AAFwkTag::FA, "%{public}s, uri:%{public}s", __func__, uriStr.c_str());
73 uri = std::make_shared<Uri>(uriStr);
74
75 // get type property
76 if (!UnwrapInt32ByPropertyName(env, param, "type", type)) {
77 TAG_LOGE(AAFwkTag::FA, "%{public}s, type:%{public}d is not exist.", __func__, type);
78 return false;
79 }
80 TAG_LOGI(AAFwkTag::FA, "type:%{public}d", type);
81
82 return true;
83 }
84
BuildDataAbilityOperation(std::shared_ptr<DataAbilityOperation> & dataAbilityOperation,napi_env env,napi_value param)85 napi_value BuildDataAbilityOperation(
86 std::shared_ptr<DataAbilityOperation> &dataAbilityOperation, napi_env env, napi_value param)
87 {
88 TAG_LOGI(AAFwkTag::FA, "%{public}s start.", __func__);
89 std::shared_ptr<Uri> uri = nullptr;
90 int type = 0;
91 if (!ParseUriAndType(env, param, uri, type)) {
92 return nullptr;
93 }
94
95 std::shared_ptr<DataAbilityOperationBuilder> builder = nullptr;
96 if (!GetDataAbilityOperationBuilder(builder, type, uri)) {
97 TAG_LOGE(AAFwkTag::FA, "GetDataAbilityOperationBuilder failed");
98 return nullptr;
99 }
100
101 // get valuesBucket property
102 std::shared_ptr<NativeRdb::ValuesBucket> valuesBucket = std::make_shared<NativeRdb::ValuesBucket>();
103 valuesBucket->Clear();
104 napi_value jsValueBucket = GetPropertyValueByPropertyName(env, param, "valuesBucket", napi_object);
105 UnwrapValuesBucket(valuesBucket, env, jsValueBucket);
106 builder->WithValuesBucket(valuesBucket);
107
108 // get dataAbilityPredicates property
109 std::shared_ptr<NativeRdb::DataAbilityPredicates> predicates = std::make_shared<NativeRdb::DataAbilityPredicates>();
110 napi_value jsPredicates = GetPropertyValueByPropertyName(env, param, "predicates", napi_object);
111 UnwrapDataAbilityPredicates(*predicates, env, jsPredicates);
112 builder->WithPredicates(predicates);
113
114 // get expectedCount property
115 int expectedCount = 0;
116 UnwrapInt32ByPropertyName(env, param, "expectedCount", expectedCount);
117 TAG_LOGI(AAFwkTag::FA, "expectedCount:%{public}d", expectedCount);
118 if (expectedCount > 0) {
119 builder->WithExpectedCount(expectedCount);
120 }
121
122 // get PredicatesBackReferences property
123 napi_value jsPredicatesBackReferences =
124 GetPropertyValueByPropertyName(env, param, "PredicatesBackReferences", napi_object);
125 UnwrapDataAbilityPredicatesBackReferences(builder, env, jsPredicatesBackReferences);
126
127 // get interrupted property
128 bool interrupted = false;
129 UnwrapBooleanByPropertyName(env, param, "interrupted", interrupted);
130 builder->WithInterruptionAllowed(interrupted);
131
132 // get backReferences
133 std::shared_ptr<NativeRdb::ValuesBucket> backReferences = std::make_shared<NativeRdb::ValuesBucket>();
134 backReferences->Clear();
135 napi_value jsBackReferences = GetPropertyValueByPropertyName(env, param, "valueBackReferences", napi_object);
136 UnwrapValuesBucket(backReferences, env, jsBackReferences);
137 builder->WithValueBackReferences(backReferences);
138
139 if (builder != nullptr) {
140 TAG_LOGI(AAFwkTag::FA, "builder not nullptr");
141 dataAbilityOperation = builder->Build();
142 }
143 napi_value result;
144 NAPI_CALL(env, napi_create_int32(env, 1, &result));
145
146 return result;
147 }
148
GetDataAbilityOperationBuilder(std::shared_ptr<DataAbilityOperationBuilder> & builder,const int type,const std::shared_ptr<Uri> & uri)149 bool GetDataAbilityOperationBuilder(
150 std::shared_ptr<DataAbilityOperationBuilder> &builder, const int type, const std::shared_ptr<Uri> &uri)
151 {
152 TAG_LOGI(AAFwkTag::FA, "called");
153 switch (type) {
154 case DataAbilityOperation::TYPE_INSERT:
155 builder = DataAbilityOperation::NewInsertBuilder(uri);
156 break;
157 case DataAbilityOperation::TYPE_UPDATE:
158 builder = DataAbilityOperation::NewUpdateBuilder(uri);
159 break;
160 case DataAbilityOperation::TYPE_DELETE:
161 builder = DataAbilityOperation::NewDeleteBuilder(uri);
162 break;
163 case DataAbilityOperation::TYPE_ASSERT:
164 builder = DataAbilityOperation::NewAssertBuilder(uri);
165 break;
166 default:
167 TAG_LOGE(AAFwkTag::FA, "invalid type:%{public}d", type);
168 return false;
169 }
170 return true;
171 }
172
UnwrapValuesBucket(const std::shared_ptr<NativeRdb::ValuesBucket> & param,napi_env env,napi_value valueBucketParam)173 napi_value UnwrapValuesBucket(const std::shared_ptr<NativeRdb::ValuesBucket> ¶m, napi_env env,
174 napi_value valueBucketParam)
175 {
176 TAG_LOGI(AAFwkTag::FA, "called");
177 napi_value result;
178
179 if (param == nullptr) {
180 TAG_LOGI(AAFwkTag::FA, "null param");
181 NAPI_CALL(env, napi_create_int32(env, 0, &result));
182 return result;
183 }
184 AnalysisValuesBucket(*param, env, valueBucketParam);
185
186 NAPI_CALL(env, napi_create_int32(env, 1, &result));
187 return result;
188 }
189
UnwrapDataAbilityPredicatesBackReferences(std::shared_ptr<DataAbilityOperationBuilder> & builder,napi_env env,napi_value predicatesBackReferencesParam)190 napi_value UnwrapDataAbilityPredicatesBackReferences(
191 std::shared_ptr<DataAbilityOperationBuilder> &builder, napi_env env, napi_value predicatesBackReferencesParam)
192 {
193 TAG_LOGI(AAFwkTag::FA, "called");
194
195 if (!IsTypeForNapiValue(env, predicatesBackReferencesParam, napi_object)) {
196 TAG_LOGE(AAFwkTag::FA, "invalid predicatesBackReferencesParam");
197 return nullptr;
198 }
199
200 napi_valuetype jsValueType = napi_undefined;
201 napi_value jsProNameList = nullptr;
202 uint32_t jsProCount = 0;
203
204 NAPI_CALL(env, napi_get_property_names(env, predicatesBackReferencesParam, &jsProNameList));
205 NAPI_CALL(env, napi_get_array_length(env, jsProNameList, &jsProCount));
206 TAG_LOGI(AAFwkTag::FA, "Property size=%{public}d", jsProCount);
207
208 napi_value jsProName = nullptr;
209 napi_value jsProValue = nullptr;
210 for (uint32_t index = 0; index < jsProCount; index++) {
211 NAPI_CALL(env, napi_get_element(env, jsProNameList, index, &jsProName));
212 std::string strProName = UnwrapStringFromJS(env, jsProName);
213 int intProName = std::atoi(strProName.c_str());
214 TAG_LOGI(AAFwkTag::FA, "Property name=%{public}d", intProName);
215 NAPI_CALL(env, napi_get_property(env, predicatesBackReferencesParam, jsProName, &jsProValue));
216 NAPI_CALL(env, napi_typeof(env, jsProValue, &jsValueType));
217 int32_t natValue32 = 0;
218 if (napi_get_value_int32(env, jsProValue, &natValue32) == napi_ok) {
219 TAG_LOGI(AAFwkTag::FA, "Property value=%{public}d", natValue32);
220 builder->WithPredicatesBackReference(intProName, natValue32);
221 }
222 }
223 napi_value result;
224 NAPI_CALL(env, napi_create_int32(env, 1, &result));
225 return result;
226 }
227
SetNamedProperty(napi_env env,napi_value obj,const char * propName,int propValue)228 void SetNamedProperty(napi_env env, napi_value obj, const char *propName, int propValue)
229 {
230 napi_value prop = nullptr;
231 napi_create_int32(env, propValue, &prop);
232 napi_set_named_property(env, obj, propName, prop);
233 }
234 } // namespace AppExecFwk
235 } // namespace OHOS
236