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 auto valueEvent = BuildValueEvent(event, m_id, channelId);
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 auto valueEvent = BuildValueEvent(event, m_id, 0);
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
GetAttendeesByEventId(int id)214 std::vector<Attendee> Calendar::GetAttendeesByEventId(int id)
215 {
216 DataShare::DataSharePredicates predicates;
217 predicates.EqualTo("event_id", id);
218 std::vector<std::string> columns = {"attendeeName", "attendeeEmail",
219 "attendeeRelationship", "attendeeStatus", "attendeeType"};
220 DataShare::DatashareBusinessError error;
221 auto result = DataShareHelperManager::GetInstance().Query(*(m_attendeeUri.get()), predicates, columns, &error);
222 std::vector<Attendee> attendees;
223 if (result != nullptr) {
224 ResultSetToAttendees(attendees, result);
225 }
226 LOG_INFO(" query attendee finished");
227 return attendees;
228 }
229
GetRemindersByEventId(int id)230 std::optional<std::vector<int>> Calendar::GetRemindersByEventId(int id)
231 {
232 DataShare::DataSharePredicates predicates;
233 predicates.EqualTo("event_id", id);
234 std::vector<std::string> columns = {"event_id", "minutes"};
235 DataShare::DatashareBusinessError error;
236 auto result = DataShareHelperManager::GetInstance().Query(*(m_reminderUrl.get()), predicates, columns, &error);
237 if (result == nullptr) {
238 return std::nullopt;
239 }
240 std::vector<int> reminders;
241 auto ret = ResultSetToReminders(reminders, result);
242 if (ret != DataShare::E_OK) {
243 return std::nullopt;
244 }
245 LOG_INFO("query reminder finished");
246 return reminders;
247 }
248
GetEvents(std::shared_ptr<EventFilter> filter,const std::vector<string> & eventKey)249 std::vector<Event> Calendar::GetEvents(std::shared_ptr<EventFilter> filter, const std::vector<string>& eventKey)
250 {
251 std::vector<Event> events;
252 std::shared_ptr<DataShare::DataSharePredicates> predicates = nullptr;
253 if (filter) {
254 predicates = filter->GetFilterPrediacates();
255 if (!predicates) {
256 LOG_ERROR("predicates null");
257 return events;
258 }
259 } else {
260 predicates = std::make_shared<DataShare::DataSharePredicates>();
261 }
262 predicates->EqualTo("calendar_id", GetId());
263 std::vector<string> queryField = {};
264 std::set<string> resultSetField;
265 if (eventKey.size() > 0) {
266 queryField.emplace_back("_id");
267 SetField(eventKey, queryField, resultSetField);
268 } else {
269 resultSetField = {"type", "title", "startTime", "endTime", "isAllDay", "description",
270 "timeZone", "location", "service", "attendee", "reminderTime"};
271 }
272 DataShare::DatashareBusinessError error;
273 auto result = DataShareHelperManager::GetInstance().Query(*(m_eventUri.get()),
274 *(predicates.get()), queryField, &error);
275 if (!result) {
276 LOG_ERROR("query failed");
277 return events;
278 }
279 ResultSetToEvents(events, result, resultSetField);
280 for (auto &event : events) {
281 if (!event.id.has_value()) {
282 continue;
283 }
284 const auto eventId = event.id.value();
285 if (resultSetField.count("attendee")) {
286 event.attendees = GetAttendeesByEventId(eventId);
287 }
288 if (resultSetField.count("reminderTime")) {
289 event.reminderTime = GetRemindersByEventId(eventId);
290 }
291 DumpEvent(event);
292 }
293 LOG_INFO("query finished");
294 return events;
295 }
296
FillEventsInfo(std::vector<Event> & events,const std::set<std::string> & resultSetField)297 void Calendar::FillEventsInfo(std::vector<Event> &events, const std::set<std::string>& resultSetField)
298 {
299 std::vector<Attendee> attendees;
300 std::optional<std::vector<int>> reminders;
301 int previousEventId = 0;
302 for (size_t i = 0; i < events.size(); i++) {
303 if (!events[i].id.has_value()) {
304 continue;
305 }
306 const auto eventId = events[i].id.value();
307 if (resultSetField.count("attendee")) {
308 if (eventId != previousEventId) {
309 attendees = GetAttendeesByEventId(eventId);
310 }
311 events[i].attendees = attendees;
312 }
313 if (resultSetField.count("reminderTime")) {
314 if (eventId != previousEventId) {
315 reminders = GetRemindersByEventId(eventId);
316 }
317 events[i].reminderTime = reminders;
318 }
319 previousEventId = eventId;
320 }
321 }
322
QueryEventInstances(int64_t start,int64_t end,const std::vector<int> & ids,const std::vector<string> & eventKey)323 std::vector<Event> Calendar::QueryEventInstances(int64_t start, int64_t end, const std::vector<int> &ids,
324 const std::vector<string>& eventKey)
325 {
326 LOG_INFO("query instance start");
327 std::vector<Event> events;
328 std::shared_ptr<DataShare::DataSharePredicates> predicates = std::make_shared<DataShare::DataSharePredicates>();
329 predicates->EqualTo("calendar_id", GetId());
330 std::vector<string> queryField = {};
331 std::set<string> resultSetField;
332 if (eventKey.size() > 0) {
333 queryField.emplace_back("Events._id");
334 SetField(eventKey, queryField, resultSetField);
335 } else {
336 resultSetField = {"id", "title", "startTime", "endTime", "instanceStartTime", "instanceEndTime",
337 "isAllDay", "description", "timeZone", "location", "service"};
338 queryField = {"Events._id", "title", "dtstart", "dtend", "service_type", "service_cp_bz_uri",
339 "service_description", "allDay", "eventTimezone", "description", "eventLocation",
340 "location_longitude", "location_latitude", "begin", "end"};
341 }
342 auto url = "&begin=" + std::to_string(start) + "&end=" + std::to_string(end) +
343 "&calendarId=" + std::to_string(GetId()) +"&orderByAsc=startDay";
344 std::string idsString = EventIdsToString(ids);
345 if (!idsString.empty()) {
346 url = url + "&eventIds=" + idsString;
347 }
348 m_instanceUrl = std::make_unique<Uri>(m_instanceUrl->ToString() + url);
349 DataShare::DatashareBusinessError error;
350 auto result = DataShareHelperManager::GetInstance().Query(*(m_instanceUrl.get()),
351 *(predicates.get()), queryField, &error);
352 if (!result) {
353 LOG_ERROR("query failed");
354 return events;
355 }
356 ResultSetToEvents(events, result, resultSetField);
357 FillEventsInfo(events, resultSetField);
358 LOG_INFO("query instance finished");
359 return events;
360 }
361
GetConfig()362 CalendarConfig Calendar::GetConfig()
363 {
364 DataShare::DataSharePredicates predicates;
365 predicates.EqualTo("_id", m_id);
366 std::vector<std::string> columns = {"calendar_color", "canReminder"};
367 DataShare::DatashareBusinessError error;
368 auto result = DataShareHelperManager::GetInstance().Query(*(m_calendarUri.get()), predicates, columns, &error);
369 if (result != nullptr) {
370 ResultSetToConfig(m_config, result);
371 };
372 LOG_INFO(" query config finished");
373 return m_config;
374 }
375
SetConfig(const CalendarConfig & config)376 bool Calendar::SetConfig(const CalendarConfig& config)
377 {
378 DataShare::DataSharePredicates m_predicates;
379 m_predicates.EqualTo("_id", m_id);
380 DataShare::DataShareValuesBucket valuesBucket;
381 if (std::get_if<1>(&config.color)) {
382 valuesBucket.Put("calendar_color", std::get<1>(config.color));
383 }
384 if (config.enableReminder) {
385 valuesBucket.Put("canReminder", config.enableReminder.value());
386 }
387 if (valuesBucket.IsEmpty()) {
388 LOG_INFO("no need update");
389 return true;
390 }
391
392 // dataShareHelper 需要提到event_handler基类里面去
393 auto ret = DataShareHelperManager::GetInstance().Update(*(m_calendarUri.get()), m_predicates, valuesBucket) == 1;
394 LOG_INFO("SetConfig %{public}d", ret);
395 if (ret) {
396 m_config = config;
397 }
398 return ret;
399 }
400 }