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 }