• 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     valuesBucket.Put("description", event.description.value_or(""));
111     if (event.timeZone) {
112         valuesBucket.Put("eventTimezone", event.timeZone.value());
113     }
114     if (event.isAllDay) {
115         valuesBucket.Put("allDay", event.isAllDay.value() ? 1 : 0);
116     }
117     valuesBucket.Put("allDay", event.isAllDay ? (event.isAllDay.value() ? 1 : 0) : 0);
118     return valuesBucket;
119 }
120 
BuildAttendeeValue(const Attendee & attendee,int eventId)121 DataShare::DataShareValuesBucket BuildAttendeeValue(const Attendee &attendee, int eventId)
122 {
123     DataShare::DataShareValuesBucket valuesBucket;
124     valuesBucket.Put("event_id", eventId);
125     valuesBucket.Put("attendeeName", attendee.name);
126     LOG_DEBUG("attendeeName %{public}s", attendee.name.c_str());
127     valuesBucket.Put("attendeeEmail", attendee.email);
128     LOG_DEBUG("attendeeEmail %{public}s", attendee.email.c_str());
129     return valuesBucket;
130 }
131 
GetValue(DataShareResultSetPtr & resultSet,string_view fieldName,int & out)132 int GetValue(DataShareResultSetPtr &resultSet, string_view fieldName, int& out)
133 {
134     int index = 0;
135     auto ret = resultSet->GetColumnIndex(string(fieldName), index);
136     if (ret != DataShare::E_OK) {
137         return ret;
138     }
139     return resultSet->GetInt(index, out);
140 }
141 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,std::string & out)142 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, std::string& out)
143 {
144     return resultSet->GetString(index, out);
145 }
146 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,int & out)147 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, int& out)
148 {
149     return resultSet->GetInt(index, out);
150 }
151 
GetIndexValue(const DataShareResultSetPtr & resultSet,int index,int64_t & out)152 int GetIndexValue(const DataShareResultSetPtr &resultSet, int index, int64_t& out)
153 {
154     return resultSet->GetLong(index, out);
155 }
156 
GetValue(DataShareResultSetPtr & resultSet,string_view fieldName,std::string & out)157 int GetValue(DataShareResultSetPtr &resultSet, string_view fieldName, std::string& out)
158 {
159     int index = 0;
160     auto fieldNameStr = string(fieldName);
161     auto ret = resultSet->GetColumnIndex(fieldNameStr, index);
162     if (ret != DataShare::E_OK) {
163         LOG_WARN("GetValue [%{public}s] failed [%{public}d]", fieldNameStr.c_str(), ret);
164         return ret;
165     }
166     return resultSet->GetString(index, out);
167 }
168 
169 
ResultSetToCalendars(DataShareResultSetPtr & resultSet)170 std::vector<std::shared_ptr<Calendar>> ResultSetToCalendars(DataShareResultSetPtr &resultSet)
171 {
172     std::vector<std::shared_ptr<Calendar>> result;
173     int rowCount = 0;
174     resultSet->GetRowCount(rowCount);
175     LOG_INFO("GetRowCount is %{public}d", rowCount);
176     if (rowCount == 0) {
177         return result;
178     }
179     auto err = resultSet->GoToFirstRow();
180     if (err != DataShare::E_OK) {
181         LOG_INFO("Failed GoToFirstRow %{public}d", err);
182         return result;
183     }
184     do {
185         int idValue = -1;
186         if (GetValue(resultSet, "_id", idValue) != DataShare::E_OK) {
187             break;
188         }
189         LOG_DEBUG("id: %{public}d", idValue);
190         std::string nameValue;
191         if (GetValue(resultSet, "account_name", nameValue) != DataShare::E_OK) {
192             break;
193         }
194         LOG_DEBUG("account_name: %{public}s", nameValue.c_str());
195         std::string typeValue;
196         if (GetValue(resultSet, "account_type", typeValue) != DataShare::E_OK) {
197             break;
198         }
199         LOG_DEBUG("account_type: %{public}s", typeValue.c_str());
200 
201         std::string displayNameValue;
202         GetValue(resultSet, "calendar_displayName", displayNameValue);
203         LOG_DEBUG("calendar_displayName: %{public}s", displayNameValue.c_str());
204 
205         int canReminder = -1;
206         GetValue(resultSet, "canReminder", canReminder);
207         LOG_DEBUG("canReminder: %{public}d", canReminder);
208 
209         int colorValue = 0;
210         GetValue(resultSet, "calendar_color", colorValue);
211         LOG_DEBUG("calendar_color: %{public}d", colorValue);
212         CalendarConfig config {canReminder, "todo"};
213         CalendarAccount curAccount {nameValue, typeValue, displayNameValue};
214         result.emplace_back(std::make_shared<Calendar>(curAccount, idValue));
215     } while (resultSet->GoToNextRow() == DataShare::E_OK);
216     return result;
217 }
218 
219 
ResultSetToLocation(DataShareResultSetPtr & resultSet)220 std::optional<Location> ResultSetToLocation(DataShareResultSetPtr &resultSet)
221 {
222     Location out;
223     string value;
224     auto ret = GetValue(resultSet, "eventLocation", value);
225     out.location = std::make_optional<string>(value);
226     ret = GetValue(resultSet, "location_longitude", value);
227     int longitudeValue = -1;
228     std::stringstream str2digit;
229     str2digit << value;
230     str2digit >> longitudeValue;
231     if (longitudeValue != -1) {
232         out.longitude = std::make_optional<int>(longitudeValue);
233     }
234     ret = GetValue(resultSet, "location_latitude", value);
235     int latitudeValue = -1;
236     str2digit.clear();
237     str2digit << value;
238     str2digit >> latitudeValue;
239     if (latitudeValue != -1) {
240         out.latitude = std::make_optional<int>(latitudeValue);
241     }
242 
243     if (ret != DataShare::E_OK) {
244         return std::nullopt;
245     }
246     return std::make_optional<Location>(out);
247 }
248 
ResultSetToEventService(DataShareResultSetPtr & resultSet)249 std::optional<EventService> ResultSetToEventService(DataShareResultSetPtr &resultSet)
250 {
251     EventService out;
252     string value;
253     auto ret = GetValue(resultSet, "service_type", value);
254     if (ret != DataShare::E_OK) {
255         return std::nullopt;
256     }
257     out.type = value;
258     ret = GetValue(resultSet, "service_cp_bz_uri", value);
259     if (ret != DataShare::E_OK) {
260         return std::nullopt;
261     }
262     out.uri = value;
263     ret = GetValue(resultSet, "service_description", value);
264     if (ret == DataShare::E_OK) {
265         out.description = std::make_optional<string>(value);
266     }
267     return std::make_optional<EventService>(out);
268 }
269 
ResultSetToEvent(Event & event,DataShareResultSetPtr & resultSet)270 void ResultSetToEvent(Event &event, DataShareResultSetPtr &resultSet)
271 {
272     GetValueOptional(resultSet, "_id", event.id);
273     int type = 0;
274     GetValue(resultSet, "event_calendar_type", type);
275     event.type = static_cast<EventType>(type);
276     GetValueOptional(resultSet, "title", event.title);
277     GetValue(resultSet, "dtstart", event.startTime);
278     GetValue(resultSet, "dtend", event.endTime);
279     int isAllDay = 0;
280     GetValue(resultSet, "allDay", isAllDay);
281     event.isAllDay = static_cast<bool>(isAllDay);
282     GetValueOptional(resultSet, "description", event.description);
283     GetValueOptional(resultSet, "eventTimezone", event.timeZone);
284     event.location = ResultSetToLocation(resultSet);
285     event.service = ResultSetToEventService(resultSet);
286 }
287 
ResultSetToEvents(std::vector<Event> & events,DataShareResultSetPtr & resultSet,const std::vector<std::string> & columns)288 int ResultSetToEvents(std::vector<Event> &events, DataShareResultSetPtr &resultSet,
289     const std::vector<std::string>& columns)
290 {
291     int rowCount = 0;
292     resultSet->GetRowCount(rowCount);
293     LOG_INFO("GetRowCount is %{public}d", rowCount);
294     if (rowCount <= 0) {
295         return -1;
296     }
297     auto err = resultSet->GoToFirstRow();
298     if (err != DataShare::E_OK) {
299         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
300         return -1;
301     }
302     do {
303         Event event;
304         ResultSetToEvent(event, resultSet);
305         events.emplace_back(event);
306     } while (resultSet->GoToNextRow() == DataShare::E_OK);
307     return 0;
308 }
309 
ResultSetToAttendees(std::vector<Attendee> & attendees,DataShareResultSetPtr & resultSet)310 int ResultSetToAttendees(std::vector<Attendee> &attendees, DataShareResultSetPtr &resultSet)
311 {
312     int rowCount = 0;
313     resultSet->GetRowCount(rowCount);
314     LOG_INFO("GetRowCount is %{public}d", rowCount);
315     if (rowCount <= 0) {
316         return -1;
317     }
318     auto err = resultSet->GoToFirstRow();
319     if (err != DataShare::E_OK) {
320         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
321         return -1;
322     }
323     do {
324         Attendee attendee;
325         GetValue(resultSet, "attendeeName", attendee.name);
326         GetValue(resultSet, "attendeeEmail", attendee.email);
327         attendees.emplace_back(attendee);
328     } while (resultSet->GoToNextRow() == DataShare::E_OK);
329     return 0;
330 }
331 
ResultSetToReminders(std::vector<int> & reminders,DataShareResultSetPtr & resultSet)332 int ResultSetToReminders(std::vector<int> &reminders, DataShareResultSetPtr &resultSet)
333 {
334     int rowCount = 0;
335     resultSet->GetRowCount(rowCount);
336     LOG_INFO("GetRowCount is %{public}d", rowCount);
337     if (rowCount <= 0) {
338         return -1;
339     }
340     auto err = resultSet->GoToFirstRow();
341     if (err != DataShare::E_OK) {
342         LOG_ERROR("Failed GoToFirstRow %{public}d", err);
343         return -1;
344     }
345     do {
346         int minutes;
347         GetValue(resultSet, "minutes", minutes);
348         reminders.emplace_back(minutes);
349     } while (resultSet->GoToNextRow() == DataShare::E_OK);
350     return 0;
351 }
352 
IsValidHexString(const std::string & colorStr)353 bool IsValidHexString(const std::string& colorStr)
354 {
355     if (colorStr.empty()) {
356         return false;
357     }
358     for (char ch : colorStr) {
359         if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
360             continue;
361         }
362         return false;
363     }
364     return true;
365 }
366 
ColorParse(const std::string & colorStr,uint32_t & colorValue)367 bool ColorParse(const std::string& colorStr, uint32_t& colorValue)
368 {
369     if (colorStr.empty()) {
370         LOG_ERROR("color string is empty");
371         return false;
372     }
373 
374     if (colorStr[0] != '#') { // start with '#'
375         LOG_ERROR("color string not start with #");
376         return false;
377     }
378 
379     std::string color = colorStr.substr(1);
380     if (!IsValidHexString(color)) {
381         return false;
382     }
383     char* ptr;
384     colorValue = std::strtoul(color.c_str(), &ptr, 16); // 16 is convert hex string to number
385     if (colorStr.size() == 7) { // 7 #RRGGBB: RRGGBB -> AARRGGBB
386         colorValue |= 0xff000000;
387         return true;
388     }
389     if (colorStr.size() == 9) { // 9 #AARRGGBB
390         return true;
391     }
392     return false;
393 }
394 }