• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <sstream>
16 #include "calendar_log.h"
17 #include "native_util.h"
18 
19 namespace OHOS::CalendarApi::Native {
DumpCalendarAccount(const CalendarAccount & account)20 void DumpCalendarAccount(const CalendarAccount &account)
21 {
22     LOG_DEBUG("account.name:%{public}s", account.name.c_str());
23     LOG_DEBUG("account.type:%{public}s", account.type.c_str());
24     LOG_DEBUG("account.displayName:%{public}s", account.displayName.value_or("").c_str());
25 }
26 
DumpEvent(const Event & event)27 void DumpEvent(const Event &event)
28 {
29     LOG_DEBUG("id       :%{public}d", event.id.value_or(-1));
30     LOG_DEBUG("type     :%{public}d", event.type);
31     LOG_DEBUG("title    :%{public}s", event.title.value_or("[null]").c_str());
32     if (event.location) {
33         auto location = event.location.value();
34         LOG_DEBUG("location.location  :%{public}s", location.location.value_or("[null]").c_str());
35         LOG_DEBUG("location.longitude :%{public}d", location.longitude.value_or(-1));
36         LOG_DEBUG("location.latitude  :%{public}d", location.latitude.value_or(-1));
37     } else {
38         LOG_DEBUG("location [null]");
39     }
40     if (event.service) {
41         auto service = event.service.value();
42         LOG_DEBUG("service.type  :%{public}s", service.type.c_str());
43         LOG_DEBUG("service.description :%{public}s", service.description.value_or("[null]").c_str());
44         LOG_DEBUG("service.uri  :%{public}s", service.uri.c_str());
45     } else {
46         LOG_DEBUG("service [null]");
47     }
48     LOG_DEBUG("title    :%{public}s", event.title.value_or("").c_str());
49     LOG_DEBUG("startTime    :%{public}s", std::to_string(event.startTime).c_str());
50     LOG_DEBUG("endTime      :%{public}s", std::to_string(event.endTime).c_str());
51     LOG_DEBUG("isAllDay :%{public}d", event.isAllDay.value_or(0));
52 
53     for (const auto &attendee : event.attendees) {
54         LOG_DEBUG("attendee.name   :%{public}s", attendee.name.c_str());
55         LOG_DEBUG("attendee.email  :%{public}s", attendee.email.c_str());
56     }
57 
58     LOG_DEBUG("timeZone     :%{public}s", event.timeZone.value_or("[null]").c_str());
59     LOG_DEBUG("description  :%{public}s", event.description.value_or("[null]").c_str());
60 }
61 
BuildEventLocation(DataShare::DataShareValuesBucket & valuesBucket,const Event & event)62 void BuildEventLocation(DataShare::DataShareValuesBucket &valuesBucket, const Event &event)
63 {
64     if (!event.location) {
65         return;
66     }
67     auto location = event.location.value();
68     if (location.location) {
69         valuesBucket.Put("eventLocation", location.location.value());
70     }
71     if (location.longitude) {
72         // longitude is string in db
73         valuesBucket.Put("location_longitude", std::to_string(location.longitude.value()));
74     }
75     if (location.latitude) {
76         // latitude is string in db
77         valuesBucket.Put("location_latitude", std::to_string(location.latitude.value()));
78     }
79 }
80 
BuildEventService(DataShare::DataShareValuesBucket & valuesBucket,const Event & event)81 void BuildEventService(DataShare::DataShareValuesBucket &valuesBucket, const Event &event)
82 {
83     if (!event.service) {
84         return;
85     }
86     const auto service = event.service.value();
87     if (service.description) {
88         valuesBucket.Put("service_description", service.description.value());
89     }
90     valuesBucket.Put("service_type", service.type);
91     valuesBucket.Put("service_cp_bz_uri", service.uri);
92 }
93 
BuildValueEvent(const Event & event,int calendarId)94 DataShare::DataShareValuesBucket BuildValueEvent(const Event &event, int calendarId)
95 {
96     DataShare::DataShareValuesBucket valuesBucket;
97     valuesBucket.Put("calendar_id", calendarId);
98 
99     LOG_DEBUG("title %{public}s", event.title.value_or("").c_str());
100     valuesBucket.Put("title", event.title.value_or(""));
101     valuesBucket.Put("event_calendar_type", event.type);
102     valuesBucket.Put("dtstart", event.startTime);
103     valuesBucket.Put("dtend", event.endTime);
104 
105     BuildEventLocation(valuesBucket, event);
106     BuildEventService(valuesBucket, event);
107 
108     LOG_DEBUG("description %{public}s", event.description.value_or("").c_str());
109 
110     if (event.description.has_value()) {
111         valuesBucket.Put("description", event.description.value());
112     }
113     if (event.timeZone.has_value()) {
114         valuesBucket.Put("eventTimezone", event.timeZone.value());
115     }
116     if (event.isAllDay.has_value()) {
117         valuesBucket.Put("allDay", event.isAllDay.value());
118     }
119     return valuesBucket;
120 }
121 
BuildAttendeeValue(const Attendee & attendee,int eventId)122 DataShare::DataShareValuesBucket BuildAttendeeValue(const Attendee &attendee, int eventId)
123 {
124     DataShare::DataShareValuesBucket valuesBucket;
125     valuesBucket.Put("event_id", eventId);
126     valuesBucket.Put("attendeeName", attendee.name);
127     LOG_DEBUG("attendeeName %{public}s", attendee.name.c_str());
128     valuesBucket.Put("attendeeEmail", attendee.email);
129     LOG_DEBUG("attendeeEmail %{public}s", attendee.email.c_str());
130     return valuesBucket;
131 }
132 
GetValue(DataShareResultSetPtr & resultSet,string_view fieldName,int & out)133 int GetValue(DataShareResultSetPtr &resultSet, string_view fieldName, int& out)
134 {
135     int index = 0;
136     auto ret = resultSet->GetColumnIndex(string(fieldName), index);
137     if (ret != DataShare::E_OK) {
138         return ret;
139     }
140     return resultSet->GetInt(index, out);
141 }
142 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,std::string & out)143 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, std::string& out)
144 {
145     return resultSet->GetString(index, out);
146 }
147 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,int & out)148 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, int& out)
149 {
150     return resultSet->GetInt(index, out);
151 }
152 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,int64_t & out)153 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, int64_t& out)
154 {
155     return resultSet->GetLong(index, out);
156 }
157 
GetValue(DataShareResultSetPtr & resultSet,string_view fieldName,std::string & out)158 int GetValue(DataShareResultSetPtr &resultSet, string_view fieldName, std::string& out)
159 {
160     int index = 0;
161     auto fieldNameStr = string(fieldName);
162     auto ret = resultSet->GetColumnIndex(fieldNameStr, index);
163     if (ret != DataShare::E_OK) {
164         LOG_WARN("GetValue [%{public}s] failed [%{public}d]", fieldNameStr.c_str(), ret);
165         return ret;
166     }
167     return resultSet->GetString(index, out);
168 }
169 
170 
ResultSetToCalendars(DataShareResultSetPtr & resultSet)171 std::vector<std::shared_ptr<Calendar>> ResultSetToCalendars(DataShareResultSetPtr &resultSet)
172 {
173     std::vector<std::shared_ptr<Calendar>> result;
174     int rowCount = 0;
175     resultSet->GetRowCount(rowCount);
176     LOG_INFO("GetRowCount is %{public}d", rowCount);
177     if (rowCount == 0) {
178         return result;
179     }
180     auto err = resultSet->GoToFirstRow();
181     if (err != DataShare::E_OK) {
182         LOG_INFO("Failed GoToFirstRow %{public}d", err);
183         return result;
184     }
185     do {
186         int idValue = -1;
187         if (GetValue(resultSet, "_id", idValue) != DataShare::E_OK) {
188             break;
189         }
190         LOG_DEBUG("id: %{public}d", idValue);
191         std::string nameValue;
192         if (GetValue(resultSet, "account_name", nameValue) != DataShare::E_OK) {
193             break;
194         }
195         LOG_DEBUG("account_name: %{public}s", nameValue.c_str());
196         std::string typeValue;
197         if (GetValue(resultSet, "account_type", typeValue) != DataShare::E_OK) {
198             break;
199         }
200         LOG_DEBUG("account_type: %{public}s", typeValue.c_str());
201 
202         std::string displayNameValue;
203         GetValue(resultSet, "calendar_displayName", displayNameValue);
204         LOG_DEBUG("calendar_displayName: %{public}s", displayNameValue.c_str());
205 
206         int canReminder = -1;
207         GetValue(resultSet, "canReminder", canReminder);
208         LOG_DEBUG("canReminder: %{public}d", canReminder);
209 
210         int colorValue = 0;
211         GetValue(resultSet, "calendar_color", colorValue);
212         CalendarAccount curAccount {nameValue, typeValue, displayNameValue};
213         result.emplace_back(std::make_shared<Calendar>(curAccount, idValue));
214     } while (resultSet->GoToNextRow() == DataShare::E_OK);
215     return result;
216 }
217 
218 
ResultSetToLocation(DataShareResultSetPtr & resultSet)219 std::optional<Location> ResultSetToLocation(DataShareResultSetPtr &resultSet)
220 {
221     Location out;
222     string value;
223     auto ret = GetValue(resultSet, "eventLocation", value);
224     out.location = std::make_optional<string>(value);
225     ret = GetValue(resultSet, "location_longitude", value);
226     int longitudeValue = -1;
227     std::stringstream str2digit;
228     str2digit << value;
229     str2digit >> longitudeValue;
230     if (longitudeValue != -1) {
231         out.longitude = std::make_optional<int>(longitudeValue);
232     }
233     ret = GetValue(resultSet, "location_latitude", value);
234     int latitudeValue = -1;
235     str2digit.clear();
236     str2digit << value;
237     str2digit >> latitudeValue;
238     if (latitudeValue != -1) {
239         out.latitude = std::make_optional<int>(latitudeValue);
240     }
241 
242     if (ret != DataShare::E_OK) {
243         return std::nullopt;
244     }
245     return std::make_optional<Location>(out);
246 }
247 
ResultSetToEventService(DataShareResultSetPtr & resultSet)248 std::optional<EventService> ResultSetToEventService(DataShareResultSetPtr &resultSet)
249 {
250     EventService out;
251     string value;
252     auto ret = GetValue(resultSet, "service_type", value);
253     if (ret != DataShare::E_OK) {
254         return std::nullopt;
255     }
256     const std::set<std::string> serviceType = {"Meeting", "Watching", "Repayment", "Live", "Shopping",
257                                                "Trip", "Class", "SportsEvents", "SportsExercise"};
258     if (serviceType.count(value)) {
259         out.type = value;
260     } else {
261         return std::nullopt;
262     }
263     ret = GetValue(resultSet, "service_cp_bz_uri", value);
264     if (ret != DataShare::E_OK) {
265         return std::nullopt;
266     }
267     out.uri = value;
268     ret = GetValue(resultSet, "service_description", value);
269     if (ret == DataShare::E_OK) {
270         out.description = std::make_optional<string>(value);
271     }
272     return std::make_optional<EventService>(out);
273 }
274 
ResultSetToEvent(Event & event,DataShareResultSetPtr & resultSet,const std::set<std::string> & columns)275 void ResultSetToEvent(Event &event, DataShareResultSetPtr &resultSet, const std::set<std::string>& columns)
276 {
277     GetValueOptional(resultSet, "_id", event.id);
278     if (columns.count("type")) {
279         int type = 0;
280         GetValue(resultSet, "event_calendar_type", type);
281         event.type = static_cast<EventType>(type);
282     }
283     if (columns.count("title")) {
284         GetValueOptional(resultSet, "title", event.title);
285     }
286     if (columns.count("startTime")) {
287         LOG_DEBUG("TLQ get startTime");
288         GetValue(resultSet, "dtstart", event.startTime);
289     }
290     if (columns.count("endTime")) {
291         LOG_DEBUG("TLQ get endTime");
292         GetValue(resultSet, "dtend", event.endTime);
293     }
294     if (columns.count("isAllDay")) {
295         int isAllDay = 0;
296         GetValue(resultSet, "allDay", isAllDay);
297         event.isAllDay = static_cast<bool>(isAllDay);
298     }
299     if (columns.count("description")) {
300         GetValueOptional(resultSet, "description", event.description);
301     }
302     if (columns.count("timeZone")) {
303         GetValueOptional(resultSet, "eventTimezone", event.timeZone);
304     }
305     if (columns.count("location")) {
306         event.location = ResultSetToLocation(resultSet);
307     }
308     if (columns.count("service")) {
309         event.service = ResultSetToEventService(resultSet);
310     }
311 }
312 
ResultSetToEvents(std::vector<Event> & events,DataShareResultSetPtr & resultSet,const std::set<std::string> & columns)313 int ResultSetToEvents(std::vector<Event> &events, DataShareResultSetPtr &resultSet,
314     const std::set<std::string>& columns)
315 {
316     int rowCount = 0;
317     resultSet->GetRowCount(rowCount);
318     LOG_INFO("GetRowCount is %{public}d", rowCount);
319     if (rowCount <= 0) {
320         return -1;
321     }
322     auto err = resultSet->GoToFirstRow();
323     if (err != DataShare::E_OK) {
324         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
325         return -1;
326     }
327     do {
328         Event event;
329         ResultSetToEvent(event, resultSet, columns);
330         events.emplace_back(event);
331     } while (resultSet->GoToNextRow() == DataShare::E_OK);
332     return 0;
333 }
334 
ResultSetToAttendees(std::vector<Attendee> & attendees,DataShareResultSetPtr & resultSet)335 int ResultSetToAttendees(std::vector<Attendee> &attendees, DataShareResultSetPtr &resultSet)
336 {
337     int rowCount = 0;
338     resultSet->GetRowCount(rowCount);
339     LOG_INFO("GetRowCount is %{public}d", rowCount);
340     if (rowCount <= 0) {
341         return -1;
342     }
343     auto err = resultSet->GoToFirstRow();
344     if (err != DataShare::E_OK) {
345         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
346         return -1;
347     }
348     do {
349         Attendee attendee;
350         GetValue(resultSet, "attendeeName", attendee.name);
351         GetValue(resultSet, "attendeeEmail", attendee.email);
352         attendees.emplace_back(attendee);
353     } while (resultSet->GoToNextRow() == DataShare::E_OK);
354     return 0;
355 }
356 
ResultSetToReminders(std::vector<int> & reminders,DataShareResultSetPtr & resultSet)357 int ResultSetToReminders(std::vector<int> &reminders, DataShareResultSetPtr &resultSet)
358 {
359     int rowCount = 0;
360     resultSet->GetRowCount(rowCount);
361     LOG_INFO("GetRowCount is %{public}d", rowCount);
362     if (rowCount <= 0) {
363         return -1;
364     }
365     auto err = resultSet->GoToFirstRow();
366     if (err != DataShare::E_OK) {
367         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
368         return -1;
369     }
370     do {
371         int minutes;
372         GetValue(resultSet, "minutes", minutes);
373         reminders.emplace_back(minutes);
374     } while (resultSet->GoToNextRow() == DataShare::E_OK);
375     return 0;
376 }
377 
IsValidHexString(const std::string & colorStr)378 bool IsValidHexString(const std::string& colorStr)
379 {
380     if (colorStr.empty()) {
381         return false;
382     }
383     for (char ch : colorStr) {
384         if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
385             continue;
386         }
387         return false;
388     }
389     return true;
390 }
391 
ColorParse(const std::string & colorStr,variant<string,int64_t> & colorValue)392 bool ColorParse(const std::string& colorStr, variant<string, int64_t>& colorValue)
393 {
394     if (colorStr.empty()) {
395         LOG_ERROR("color string is empty");
396         return false;
397     }
398 
399     if (colorStr[0] != '#') { // start with '#'
400         LOG_ERROR("color string not start with #");
401         return false;
402     }
403 
404     const int rgbLen = 7;
405     const int argbLen = 9;
406     if (colorStr.size() != rgbLen && colorStr.size() != argbLen) {
407         LOG_ERROR("color string length is not 7 or 9");
408         return false;
409     }
410 
411     std::string colorStrSub = colorStr.substr(1);
412     if (!IsValidHexString(colorStrSub)) {
413         LOG_DEBUG("color string is not valid hex string");
414         return false;
415     }
416 
417     LOG_DEBUG("color string size is 7 or 9");
418     colorValue.emplace<1>(std::stoll(colorStrSub, NULL, 16)); // 16 is convert hex string to number
419     if (std::get_if<1>(&colorValue)) {
420         LOG_DEBUG("colorStrSub -> colorValue colorValue:%{public}s", std::to_string(std::get<1>(colorValue)).c_str());
421         return true;
422     }
423     LOG_DEBUG("color is null");
424     return false;
425 }
426 
setField(const std::vector<string> & eventKey,std::vector<string> & queryField,std::set<string> & resultSetField)427 void setField(const std::vector<string>& eventKey, std::vector<string>& queryField, std::set<string>& resultSetField)
428 {
429     const std::map<string, string> eventField = { { "id", "_id" },
430                                                   { "type", "event_calendar_type" },
431                                                   { "title", "title" },
432                                                   { "startTime", "dtstart" },
433                                                   { "endTime", "dtend" },
434                                                   { "isAllDay", "allDay" },
435                                                   { "timeZone", "eventTimezone" },
436                                                   { "description", "description" } };
437     for (const auto& field : eventKey) {
438         if (field == "location") {
439             queryField.emplace_back("eventLocation");
440             queryField.emplace_back("location_longitude");
441             queryField.emplace_back("location_latitude");
442             resultSetField.insert(field);
443             continue;
444         }
445         if (field == "service") {
446             queryField.emplace_back("service_type");
447             queryField.emplace_back("service_cp_bz_uri");
448             queryField.emplace_back("service_description");
449             resultSetField.insert(field);
450             continue;
451         }
452         if (field == "attendee") {
453             resultSetField.insert(field);
454             continue;
455         }
456         if (field == "reminderTime") {
457             resultSetField.insert(field);
458             continue;
459         }
460         if (field == "id") {
461             continue;
462         }
463         queryField.emplace_back(eventField.at(field));
464         resultSetField.insert(field);
465     }
466 }
467 }