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 &param, 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> &param, 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