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 
16 #include "native_calendar.h"
17 #include "data_share_helper_manager.h"
18 #include "calendar_log.h"
19 #include "calendar_env.h"
20 #include "data_ability_helper.h"
21 #include "native_util.h"
22 
23 namespace {
24     const string eventUrl = "datashare:///calendardata/Events";
25     const string attendeeUrl = "datashare:///calendardata/Attendees";
26     const string calendarUrl = "datashare:///calendardata/Calendars";
27     const string reminderUrl = "datashare:///calendardata/Reminders";
28 }
29 namespace OHOS::CalendarApi::Native {
Calendar(int id)30 Calendar::Calendar(int id)
31     : m_id(id)
32 {
33     uint64_t tokenId = CalendarEnv::GetInstance().GetTokenId();
34     auto bumdleName = CalendarEnv::GetInstance().GetBundleName();
35     auto bundleName_tokeId = "?bundleName=" + bumdleName + "&tokenId=" + std::to_string(tokenId);
36     m_eventUri = std::make_unique<Uri>(eventUrl + bundleName_tokeId);
37     m_calendarUri = std::make_unique<Uri>(calendarUrl + bundleName_tokeId);
38 }
39 
Calendar(CalendarAccount account, int id)40 Calendar::Calendar(CalendarAccount account, int id)
41     :m_account(std::move(account)), m_id(id)
42 {
43     // todo getallcalendar的时候会重复,需要复用
44     uint64_t tokenId = CalendarEnv::GetInstance().GetTokenId();
45     auto bumdleName = CalendarEnv::GetInstance().GetBundleName();
46     auto bundleName_tokeId = "?bundleName=" + bumdleName + "&tokenId=" + std::to_string(tokenId);
47     m_eventUri = std::make_unique<Uri>(eventUrl + bundleName_tokeId);
48     m_attendeeUri = std::make_unique<Uri>(attendeeUrl + bundleName_tokeId);
49     m_calendarUri = std::make_unique<Uri>(calendarUrl + bundleName_tokeId);
50     m_reminderUrl = std::make_unique<Uri>(reminderUrl + bundleName_tokeId);
51 }
InsertReminders(int eventId, vector<int> reminders)52 void Calendar::InsertReminders(int eventId, vector<int> reminders)
53 {
54     for (const auto &reminder : reminders) {
55             DataShare::DataShareValuesBucket valuesBucket;
56             valuesBucket.Put("event_id", eventId);
57             valuesBucket.Put("minutes", reminder);
58             auto index = DataShareHelperManager::GetInstance().Insert(*(m_reminderUrl.get()), valuesBucket);
59             LOG_INFO("Insert reminder index %{private}d", index);
60         }
61 }
62 
AddEventInfo(const Event& event, int channelId)63 int Calendar::AddEventInfo(const Event& event, int channelId)
64 {
65     auto valueEvent = BuildValueEvent(event, m_id, channelId);
66     auto eventId = DataShareHelperManager::GetInstance().Insert(*(m_eventUri.get()), valueEvent);
67     LOG_INFO("Insert Event eventId %{private}d", eventId);
68     if (eventId <= 0) {
69         return eventId;
70     }
71     // insert attendee
72     auto valueAttendees = std::vector<DataShare::DataShareValuesBucket>();
73     for (const auto &attendee : event.attendees) {
74         auto valueAttendee = BuildAttendeeValue(attendee, eventId);
75         valueAttendees.emplace_back(valueAttendee);
76     }
77     if (valueAttendees.size() > 0) {
78         auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_attendeeUri.get()), valueAttendees);
79         LOG_INFO("batchInsert attendees count %{private}d", count);
80     }
81 
82     // insert reminder
83     if (event.reminderTime.has_value()) {
84         InsertReminders(eventId, event.reminderTime.value());
85     }
86 
87     return eventId;
88 }
89 
AddEvent(const Event& event)90 int Calendar::AddEvent(const Event& event)
91 {
92     return Calendar::AddEventInfo(event, 0);
93 }
94 #define SUPPORT_BATCH_INSERT 0
95 
96 #if SUPPORT_BATCH_INSERT
AddEvents(const std::vector<Event>& events)97 int Calendar::AddEvents(const std::vector<Event>& events)
98 {
99     std::vector<DataShare::DataShareValuesBucket> valueEvents;
100     for (const auto &event : events) {
101         valueEvents.emplace_back(BuildValueEvent(event));
102     }
103     auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_eventUri.get()), valueEvents);
104     LOG_INFO("BatchInsert count %{private}d", count);
105     return count;
106 }
107 #else
AddEvents(const std::vector<Event>& events)108 int Calendar::AddEvents(const std::vector<Event>& events)
109 {
110     int count = 0;
111     int channelId = 0;
112     for (const auto &event : events) {
113         auto index = Calendar::AddEventInfo(event, channelId);
114         if (index > 0) {
115             count++;
116         }
117         channelId++;
118     }
119     LOG_INFO("AddEvents count %{private}d", count);
120     return count;
121 }
122 #endif
123 
124 
DeleteEvent(int id)125 bool Calendar::DeleteEvent(int id)
126 {
127     DataShare::DataSharePredicates predicates;
128     predicates.EqualTo("_id", id);
129     predicates.EqualTo("calendar_id", GetId());
130     auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
131     LOG_INFO("DeleteEvent number %{public}d", ret);
132     {
133         // delete attendee
134         DataShare::DataSharePredicates predicates;
135         predicates.EqualTo("event_id", id);
136         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_attendeeUri.get()), predicates);
137         LOG_INFO("Delete attendee num %{public}d", ret);
138     }
139     {
140         // delete reminder
141         DataShare::DataSharePredicates predicates;
142         predicates.EqualTo("event_id", id);
143         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_reminderUrl.get()), predicates);
144         LOG_INFO("Delete reminder num %{public}d", ret);
145     }
146     return ret == 1;
147 }
148 
DeleteAllEvents()149 void Calendar::DeleteAllEvents()
150 {
151     DataShare::DataSharePredicates predicates;
152     predicates.EqualTo("_id", GetId());
153     auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
154     LOG_INFO("DeleteEvent number %{public}d", ret);
155     return;
156 }
157 
DeleteEvents(const std::vector<int>& ids)158 int Calendar::DeleteEvents(const std::vector<int>& ids)
159 {
160     int count = 0;
161     for (const auto &id : ids) {
162         if (DeleteEvent(id)) {
163             count +=1;
164         }
165     }
166     LOG_INFO("DeleteEvents %{public}d", count);
167     return count;
168 }
169 
UpdateEvent(const Event& event)170 bool Calendar::UpdateEvent(const Event& event)
171 {
172     if (!event.id) {
173         LOG_ERROR("event id not exist");
174         return false;
175     }
176     const auto eventId = event.id.value();
177     DataShare::DataSharePredicates m_predicates;
178     m_predicates.EqualTo("_id", eventId);
179     auto valueEvent = BuildValueEvent(event, m_id, 0);
180     auto ret = DataShareHelperManager::GetInstance().Update(*(m_eventUri.get()), m_predicates, valueEvent);
181     LOG_INFO(" Update code %{public}d", ret);
182     {
183         // delete attendee
184         DataShare::DataSharePredicates predicates;
185         predicates.EqualTo("event_id", eventId);
186         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_attendeeUri.get()), predicates);
187         LOG_INFO("Delete attendee num %{public}d", ret);
188     }
189     auto valueAttendees = std::vector<DataShare::DataShareValuesBucket>();
190     for (const auto &attendee : event.attendees) {
191         auto valueAttendee = BuildAttendeeValue(attendee, eventId);
192         valueAttendees.emplace_back(valueAttendee);
193     }
194     if (valueAttendees.size() > 0) {
195         auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_attendeeUri.get()), valueAttendees);
196         LOG_INFO("batchInsert attendees count %{public}d", count);
197     }
198 
199     {
200         // delete reminder
201         DataShare::DataSharePredicates predicates;
202         predicates.EqualTo("event_id", eventId);
203         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_reminderUrl.get()), predicates);
204         LOG_INFO("Delete reminder num %{public}d", ret);
205     }
206     if (event.reminderTime.has_value()) {
207         InsertReminders(eventId, event.reminderTime.value());
208     }
209 
210     return ret == 1;
211 }
212 
UpdateEvents(const std::vector<Event>& events)213 int Calendar::UpdateEvents(const std::vector<Event>& events)
214 {
215     int count = 0;
216     for (const auto &event : events) {
217         if (UpdateEvent(event)) {
218             count +=1;
219         }
220     }
221     LOG_INFO("UpdateEvents %{public}d", count);
222     return count;
223 }
224 
GetAttendeesByEventId(int id)225 std::vector<Attendee> Calendar::GetAttendeesByEventId(int id)
226 {
227     DataShare::DataSharePredicates predicates;
228     predicates.EqualTo("event_id", id);
229     std::vector<std::string> columns = {"attendeeName", "attendeeEmail", "attendeeRelationship"};
230     DataShare::DatashareBusinessError error;
231     auto result = DataShareHelperManager::GetInstance().Query(*(m_attendeeUri.get()), predicates, columns, &error);
232     std::vector<Attendee> attendees;
233     if (result != nullptr) {
234         ResultSetToAttendees(attendees, result);
235     }
236     LOG_INFO(" query attendee finished");
237     return attendees;
238 }
239 
GetRemindersByEventId(int id)240 std::optional<std::vector<int>> Calendar::GetRemindersByEventId(int id)
241 {
242     DataShare::DataSharePredicates predicates;
243     predicates.EqualTo("event_id", id);
244     std::vector<std::string> columns = {"event_id", "minutes"};
245     DataShare::DatashareBusinessError error;
246     auto result = DataShareHelperManager::GetInstance().Query(*(m_reminderUrl.get()), predicates, columns, &error);
247     if (result == nullptr) {
248         return std::nullopt;
249     }
250     std::vector<int> reminders;
251     auto ret = ResultSetToReminders(reminders, result);
252     if (ret != DataShare::E_OK) {
253         return std::nullopt;
254     }
255     LOG_INFO("query reminder finished");
256     return reminders;
257 }
258 
GetEvents(std::shared_ptr<EventFilter> filter, const std::vector<string>& eventKey)259 std::vector<Event> Calendar::GetEvents(std::shared_ptr<EventFilter> filter, const std::vector<string>& eventKey)
260 {
261     std::vector<Event> events;
262     std::shared_ptr<DataShare::DataSharePredicates> predicates = nullptr;
263     if (filter) {
264         predicates = filter->GetFilterPrediacates();
265         if (!predicates) {
266             LOG_ERROR("predicates null");
267             return events;
268         }
269     } else {
270         predicates = std::make_shared<DataShare::DataSharePredicates>();
271     }
272     predicates->EqualTo("calendar_id", GetId());
273     std::vector<string> queryField = {};
274     std::set<string> resultSetField;
275     if (eventKey.size() > 0) {
276         queryField.emplace_back("_id");
277         SetField(eventKey, queryField, resultSetField);
278     } else {
279         resultSetField = {"type", "title", "startTime", "endTime", "isAllDay", "description",
280         "timeZone", "location", "service", "attendee", "reminderTime"};
281     }
282     DataShare::DatashareBusinessError error;
283     auto result = DataShareHelperManager::GetInstance().Query(*(m_eventUri.get()),
284         *(predicates.get()), queryField, &error);
285     if (!result) {
286         LOG_ERROR("query failed");
287         return events;
288     }
289     ResultSetToEvents(events, result, resultSetField);
290     for (auto &event : events) {
291         if (!event.id.has_value()) {
292             continue;
293         }
294         const auto eventId = event.id.value();
295         if (resultSetField.count("attendee")) {
296             event.attendees = GetAttendeesByEventId(eventId);
297         }
298         if (resultSetField.count("reminderTime")) {
299             event.reminderTime = GetRemindersByEventId(eventId);
300         }
301         DumpEvent(event);
302     }
303     LOG_INFO("query finished");
304     return events;
305 }
306 
GetConfig()307 CalendarConfig Calendar::GetConfig()
308 {
309     return m_config;
310 }
311 
SetConfig(const CalendarConfig& config)312 bool Calendar::SetConfig(const CalendarConfig& config)
313 {
314     DataShare::DataSharePredicates m_predicates;
315     m_predicates.EqualTo("_id", m_id);
316     DataShare::DataShareValuesBucket valuesBucket;
317     if (std::get_if<1>(&config.color)) {
318         valuesBucket.Put("calendar_color", std::get<1>(config.color));
319     }
320     if (config.enableReminder) {
321         valuesBucket.Put("canReminder", config.enableReminder.value());
322     }
323     if (valuesBucket.IsEmpty()) {
324         LOG_INFO("no need update");
325         return true;
326     }
327 
328     // dataShareHelper 需要提到event_handler基类里面去
329     auto ret = DataShareHelperManager::GetInstance().Update(*(m_calendarUri.get()), m_predicates, valuesBucket) == 1;
330     LOG_INFO("SetConfig %{public}d", ret);
331     if (ret) {
332         m_config = config;
333     }
334     return ret;
335 }
336 }