• 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 
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     const string instanceUrl = "datashare:///calendardata/Instances";
29 }
30 namespace OHOS::CalendarApi::Native {
Calendar(int id)31 Calendar::Calendar(int id)
32     : m_id(id)
33 {
34     uint64_t tokenId = CalendarEnv::GetInstance().GetTokenId();
35     auto bumdleName = CalendarEnv::GetInstance().GetBundleName();
36     auto bundleName_tokeId = "?bundleName=" + bumdleName + "&tokenId=" + std::to_string(tokenId);
37     m_eventUri = std::make_unique<Uri>(eventUrl + bundleName_tokeId);
38     m_calendarUri = std::make_unique<Uri>(calendarUrl + bundleName_tokeId);
39 }
40 
Calendar(CalendarAccount account,int id)41 Calendar::Calendar(CalendarAccount account, int id)
42     :m_account(std::move(account)), m_id(id)
43 {
44     // todo getallcalendar的时候会重复,需要复用
45     uint64_t tokenId = CalendarEnv::GetInstance().GetTokenId();
46     auto bumdleName = CalendarEnv::GetInstance().GetBundleName();
47     auto bundleName_tokeId = "?bundleName=" + bumdleName + "&tokenId=" + std::to_string(tokenId);
48     m_eventUri = std::make_unique<Uri>(eventUrl + bundleName_tokeId);
49     m_attendeeUri = std::make_unique<Uri>(attendeeUrl + bundleName_tokeId);
50     m_calendarUri = std::make_unique<Uri>(calendarUrl + bundleName_tokeId);
51     m_reminderUrl = std::make_unique<Uri>(reminderUrl + bundleName_tokeId);
52     m_instanceUrl = std::make_unique<Uri>(instanceUrl + bundleName_tokeId);
53 }
InsertReminders(int eventId,vector<int> reminders)54 void Calendar::InsertReminders(int eventId, vector<int> reminders)
55 {
56     std::sort(reminders.begin(), reminders.end());
57     reminders.erase(std::unique(reminders.begin(), reminders.end()), reminders.end());
58     for (const auto &reminder : reminders) {
59             DataShare::DataShareValuesBucket valuesBucket;
60             valuesBucket.Put("event_id", eventId);
61             valuesBucket.Put("minutes", reminder);
62             auto index = DataShareHelperManager::GetInstance().Insert(*(m_reminderUrl.get()), valuesBucket);
63             LOG_INFO("Insert reminder index %{private}d", index);
64         }
65 }
66 
AddEventInfo(const Event & event,int channelId)67 int Calendar::AddEventInfo(const Event& event, int channelId)
68 {
69     const auto valueEvent = BuildValueEvent(event, m_id, channelId, false);
70     auto eventId = DataShareHelperManager::GetInstance().Insert(*(m_eventUri.get()), valueEvent);
71     LOG_INFO("Insert Event eventId %{private}d", eventId);
72     if (eventId <= 0) {
73         return eventId;
74     }
75     // insert attendee
76     auto valueAttendees = std::vector<DataShare::DataShareValuesBucket>();
77     for (const auto &attendee : event.attendees) {
78         auto valueAttendee = BuildAttendeeValue(attendee, eventId);
79         valueAttendees.emplace_back(valueAttendee);
80     }
81     if (valueAttendees.size() > 0) {
82         auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_attendeeUri.get()), valueAttendees);
83         LOG_INFO("batchInsert attendees count %{private}d", count);
84     }
85 
86     // insert reminder
87     if (event.reminderTime.has_value()) {
88         InsertReminders(eventId, event.reminderTime.value());
89     }
90 
91     return eventId;
92 }
93 
AddEvent(const Event & event)94 int Calendar::AddEvent(const Event& event)
95 {
96     return Calendar::AddEventInfo(event, 0);
97 }
98 #define SUPPORT_BATCH_INSERT 0
99 
100 #if SUPPORT_BATCH_INSERT
AddEvents(const std::vector<Event> & events)101 int Calendar::AddEvents(const std::vector<Event>& events)
102 {
103     std::vector<DataShare::DataShareValuesBucket> valueEvents;
104     for (const auto &event : events) {
105         valueEvents.emplace_back(BuildValueEvent(event));
106     }
107     auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_eventUri.get()), valueEvents);
108     LOG_INFO("BatchInsert count %{private}d", count);
109     return count;
110 }
111 #else
AddEvents(const std::vector<Event> & events)112 int Calendar::AddEvents(const std::vector<Event>& events)
113 {
114     int count = 0;
115     int channelId = 0;
116     for (const auto &event : events) {
117         auto index = Calendar::AddEventInfo(event, channelId);
118         if (index > 0) {
119             count++;
120         }
121         channelId++;
122     }
123     LOG_INFO("AddEvents count %{private}d", count);
124     return count;
125 }
126 #endif
127 
128 
DeleteEvent(int id)129 bool Calendar::DeleteEvent(int id)
130 {
131     DataShare::DataSharePredicates predicates;
132     predicates.EqualTo("_id", id);
133     predicates.EqualTo("calendar_id", GetId());
134     auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
135     return ret == 1;
136 }
137 
DeleteAllEvents()138 void Calendar::DeleteAllEvents()
139 {
140     DataShare::DataSharePredicates predicates;
141     predicates.EqualTo("_id", GetId());
142     auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
143     LOG_INFO("DeleteEvent number %{public}d", ret);
144     return;
145 }
146 
DeleteEvents(const std::vector<int> & ids)147 int Calendar::DeleteEvents(const std::vector<int>& ids)
148 {
149     int count = 0;
150     for (const auto &id : ids) {
151         if (DeleteEvent(id)) {
152             count += 1;
153         }
154     }
155     LOG_INFO("DeleteEvents %{public}d", count);
156     return count;
157 }
158 
UpdateEvent(const Event & event)159 bool Calendar::UpdateEvent(const Event& event)
160 {
161     if (!event.id) {
162         LOG_ERROR("event id not exist");
163         return false;
164     }
165     const auto eventId = event.id.value();
166     DataShare::DataSharePredicates m_predicates;
167     m_predicates.EqualTo("_id", eventId);
168     const auto valueEvent = BuildValueEvent(event, m_id, 0, true);
169     auto ret = DataShareHelperManager::GetInstance().Update(*(m_eventUri.get()), m_predicates, valueEvent);
170     LOG_INFO(" Update code %{public}d", ret);
171     {
172         // delete attendee
173         DataShare::DataSharePredicates predicates;
174         predicates.EqualTo("event_id", eventId);
175         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_attendeeUri.get()), predicates);
176         LOG_INFO("Delete attendee num %{public}d", ret);
177     }
178     auto valueAttendees = std::vector<DataShare::DataShareValuesBucket>();
179     for (const auto &attendee : event.attendees) {
180         auto valueAttendee = BuildAttendeeValue(attendee, eventId);
181         valueAttendees.emplace_back(valueAttendee);
182     }
183     if (valueAttendees.size() > 0) {
184         auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_attendeeUri.get()), valueAttendees);
185         LOG_INFO("batchInsert attendees count %{public}d", count);
186     }
187 
188     {
189         // delete reminder
190         DataShare::DataSharePredicates predicates;
191         predicates.EqualTo("event_id", eventId);
192         auto ret = DataShareHelperManager::GetInstance().Delete(*(m_reminderUrl.get()), predicates);
193         LOG_INFO("Delete reminder num %{public}d", ret);
194     }
195     if (event.reminderTime.has_value()) {
196         InsertReminders(eventId, event.reminderTime.value());
197     }
198 
199     return ret == 1;
200 }
201 
UpdateEvents(const std::vector<Event> & events)202 int Calendar::UpdateEvents(const std::vector<Event>& events)
203 {
204     int count = 0;
205     for (const auto &event : events) {
206         if (UpdateEvent(event)) {
207             count +=1;
208         }
209     }
210     LOG_INFO("UpdateEvents %{public}d", count);
211     return count;
212 }
213 
GetAttendeesByEventIds(const std::vector<std::string> & ids,std::vector<Event> & events)214 void Calendar::GetAttendeesByEventIds(const std::vector<std::string> &ids, std::vector<Event> &events)
215 {
216     DataShare::DataSharePredicates predicates;
217     predicates.In("event_id", ids);
218     std::vector<std::string> columns = {"event_id", "attendeeName", "attendeeEmail",
219     "attendeeRelationship", "attendeeStatus", "attendeeType"};
220     DataShare::DatashareBusinessError error;
221     auto result = DataShareHelperManager::GetInstance().Query(*(m_attendeeUri.get()), predicates, columns, &error);
222     if (result == nullptr) {
223         LOG_ERROR("result is null");
224         return;
225     }
226     auto ret = ResultSetToMultiAttendees(events, result);
227     result->Close();
228     if (ret != DataShare::E_OK) {
229         LOG_ERROR("result set to attendees failed");
230         return;
231     }
232     LOG_INFO(" query attendee finished");
233 }
234 
GetRemindersByEventIds(const std::vector<std::string> & ids,std::vector<Event> & events)235 void Calendar::GetRemindersByEventIds(const std::vector<std::string> &ids, std::vector<Event> &events)
236 {
237     DataShare::DataSharePredicates predicates;
238     predicates.In("event_id", ids);
239     std::vector<std::string> columns = {"event_id", "minutes"};
240     DataShare::DatashareBusinessError error;
241     auto result = DataShareHelperManager::GetInstance().Query(*(m_reminderUrl.get()), predicates, columns, &error);
242     if (result == nullptr) {
243         LOG_ERROR("result is null");
244         return;
245     }
246     auto ret = ResultSetToMultiReminders(events, result);
247     result->Close();
248     if (ret != DataShare::E_OK) {
249         LOG_ERROR("result set to reminders failed");
250         return;
251     }
252     LOG_INFO("query reminder finished");
253 }
254 
GetEvents(std::shared_ptr<EventFilter> filter,const std::vector<string> & eventKey)255 std::vector<Event> Calendar::GetEvents(std::shared_ptr<EventFilter> filter, const std::vector<string>& eventKey)
256 {
257     std::vector<Event> events;
258     std::shared_ptr<DataShare::DataSharePredicates> predicates = nullptr;
259     if (filter) {
260         predicates = filter->GetFilterPrediacates();
261         if (!predicates) {
262             LOG_ERROR("predicates null");
263             return events;
264         }
265     } else {
266         predicates = std::make_shared<DataShare::DataSharePredicates>();
267     }
268     predicates->EqualTo("calendar_id", GetId());
269     std::vector<string> queryField = {};
270     std::set<string> resultSetField;
271     if (eventKey.size() > 0) {
272         queryField.emplace_back("_id");
273         SetField(eventKey, queryField, resultSetField);
274     } else {
275         resultSetField = {"type", "title", "startTime", "endTime", "isAllDay", "description",
276         "timeZone", "location", "service", "attendee", "reminderTime", "identifier"};
277     }
278     DataShare::DatashareBusinessError error;
279     auto result = DataShareHelperManager::GetInstance().Query(*(m_eventUri.get()),
280         *(predicates.get()), queryField, &error);
281     if (!result) {
282         LOG_ERROR("query failed");
283         return events;
284     }
285     std::vector<std::string> eventIds;
286     ResultSetToEvents(eventIds, events, result, resultSetField);
287     result->Close();
288     int segmentSize = 10000;
289     for (size_t i = 0; i < eventIds.size(); i += segmentSize) {
290         size_t start = i;
291         size_t end = std::min(i + segmentSize, eventIds.size());
292         std::vector<std::string> queryIdsVec;
293         for (size_t j = start; j < end; ++j) {
294             queryIdsVec.emplace_back(eventIds[j]);
295         }
296         if (resultSetField.count("attendee")) {
297             GetAttendeesByEventIds(queryIdsVec, events);
298         }
299         if (resultSetField.count("reminderTime")) {
300             GetRemindersByEventIds(queryIdsVec, events);
301         }
302     }
303     LOG_INFO("query finished");
304     return events;
305 }
306 
FillEventsInfo(const std::vector<std::string> & eventIds,std::vector<Event> & events,const std::set<std::string> & resultSetField)307 void Calendar::FillEventsInfo(const std::vector<std::string> &eventIds, std::vector<Event> &events,
308     const std::set<std::string>& resultSetField)
309 {
310     if (resultSetField.count("attendee")) {
311         GetAttendeesByEventIds(eventIds, events);
312     }
313     if (resultSetField.count("reminderTime")) {
314         GetRemindersByEventIds(eventIds, events);
315     }
316 }
317 
QueryEventInstances(int64_t start,int64_t end,const std::vector<int> & ids,const std::vector<string> & eventKey)318 std::vector<Event> Calendar::QueryEventInstances(int64_t start, int64_t end, const std::vector<int> &ids,
319     const std::vector<string>& eventKey)
320 {
321     LOG_INFO("query instance start");
322     std::vector<Event> events;
323     std::shared_ptr<DataShare::DataSharePredicates> predicates = std::make_shared<DataShare::DataSharePredicates>();
324     predicates->EqualTo("calendar_id", GetId());
325     std::vector<string> queryField = {};
326     std::set<string> resultSetField;
327     if (eventKey.size() > 0) {
328         queryField.emplace_back("Events._id");
329         SetField(eventKey, queryField, resultSetField);
330     } else {
331         resultSetField = {"id", "title", "startTime", "endTime", "instanceStartTime", "instanceEndTime",
332         "isAllDay", "description", "timeZone", "location", "service"};
333         queryField = {"Events._id", "title", "dtstart", "dtend", "service_type", "service_cp_bz_uri",
334         "service_description", "allDay", "eventTimezone", "description", "eventLocation",
335          "location_longitude", "location_latitude", "begin", "end"};
336     }
337     auto url = "&begin=" + std::to_string(start) + "&end=" + std::to_string(end) +
338          "&calendarId=" + std::to_string(GetId()) +"&orderByAsc=startDay";
339     std::string idsString = EventIdsToString(ids);
340     if (!idsString.empty()) {
341         url = url + "&eventIds=" + idsString;
342     }
343     m_instanceUrl = std::make_unique<Uri>(m_instanceUrl->ToString() + url);
344     DataShare::DatashareBusinessError error;
345     auto result = DataShareHelperManager::GetInstance().Query(*(m_instanceUrl.get()),
346         *(predicates.get()), queryField, &error);
347     if (!result) {
348         LOG_ERROR("query failed");
349         return events;
350     }
351     std::vector<std::string> eventIds;
352     ResultSetToEvents(eventIds, events, result, resultSetField);
353     result->Close();
354     FillEventsInfo(eventIds, events, resultSetField);
355     LOG_INFO("query instance finished");
356     return events;
357 }
358 
GetConfig()359 CalendarConfig Calendar::GetConfig()
360 {
361     DataShare::DataSharePredicates predicates;
362     predicates.EqualTo("_id", m_id);
363     std::vector<std::string> columns = {"calendar_color", "canReminder"};
364     DataShare::DatashareBusinessError error;
365     auto result = DataShareHelperManager::GetInstance().Query(*(m_calendarUri.get()), predicates, columns, &error);
366     if (result != nullptr) {
367         ResultSetToConfig(m_config, result);
368     };
369     LOG_INFO(" query config finished");
370     return m_config;
371 }
372 
SetConfig(const CalendarConfig & config)373 bool Calendar::SetConfig(const CalendarConfig& config)
374 {
375     DataShare::DataSharePredicates m_predicates;
376     m_predicates.EqualTo("_id", m_id);
377     DataShare::DataShareValuesBucket valuesBucket;
378     if (std::get_if<1>(&config.color)) {
379         valuesBucket.Put("calendar_color", std::get<1>(config.color));
380     }
381     if (config.enableReminder) {
382         valuesBucket.Put("canReminder", config.enableReminder.value());
383     }
384     if (valuesBucket.IsEmpty()) {
385         LOG_INFO("no need update");
386         return true;
387     }
388 
389     // dataShareHelper 需要提到event_handler基类里面去
390     auto ret = DataShareHelperManager::GetInstance().Update(*(m_calendarUri.get()), m_predicates, valuesBucket) == 1;
391     LOG_INFO("SetConfig %{public}d", ret);
392     if (ret) {
393         m_config = config;
394     }
395     return ret;
396 }
397 }