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 LOG_INFO("bundleName_tokeId: %{public}s", bundleName_tokeId.c_str());
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 LOG_INFO("bundleName_tokeId: %{public}s", bundleName_tokeId.c_str());
49 m_eventUri = std::make_unique<Uri>(eventUrl + bundleName_tokeId);
50 m_attendeeUri = std::make_unique<Uri>(attendeeUrl + bundleName_tokeId);
51 m_calendarUri = std::make_unique<Uri>(calendarUrl + bundleName_tokeId);
52 m_reminderUrl = std::make_unique<Uri>(reminderUrl + bundleName_tokeId);
53 }
54
AddEvent(const Event & event)55 int Calendar::AddEvent(const Event& event)
56 {
57 auto valueEvent = BuildValueEvent(event, m_id);
58 auto eventId = DataShareHelperManager::GetInstance().Insert(*(m_eventUri.get()), valueEvent);
59 LOG_INFO("Insert Event eventId %{public}d", eventId);
60 if (eventId <= 0) {
61 return eventId;
62 }
63 // insert attendee
64 for (const auto &attendee : event.attendees) {
65 auto valueAttendee = BuildAttendeeValue(attendee, eventId);
66 auto index = DataShareHelperManager::GetInstance().Insert(*(m_attendeeUri.get()), valueAttendee);
67 LOG_INFO("Insert attendee index %{public}d", index);
68 }
69 // insert reminder
70 if (event.reminderTime) {
71 for (const auto &reminder : event.reminderTime.value()) {
72 DataShare::DataShareValuesBucket valuesBucket;
73 valuesBucket.Put("event_id", eventId);
74 valuesBucket.Put("minutes", reminder);
75 auto index = DataShareHelperManager::GetInstance().Insert(*(m_reminderUrl.get()), valuesBucket);
76 LOG_INFO("Insert reminder index %{public}d", index);
77 }
78 }
79
80 return eventId;
81 }
82 #define SUPPORT_BATCH_INSERT 0
83
84 #if SUPPORT_BATCH_INSERT
AddEvents(const std::vector<Event> & events)85 int Calendar::AddEvents(const std::vector<Event>& events)
86 {
87 std::vector<DataShare::DataShareValuesBucket> valueEvents;
88 for (const auto &event : events) {
89 valueEvents.emplace_back(BuildValueEvent(event));
90 }
91 auto count = DataShareHelperManager::GetInstance().BatchInsert(*(m_eventUri.get()), valueEvents);
92 LOG_INFO("BatchInsert count %{public}d", count);
93 return count;
94 }
95 #else
AddEvents(const std::vector<Event> & events)96 int Calendar::AddEvents(const std::vector<Event>& events)
97 {
98 int count = 0;
99 for (const auto &event : events) {
100 auto valueEvent = BuildValueEvent(event, m_id);
101 auto index = DataShareHelperManager::GetInstance().Insert(*(m_eventUri.get()), valueEvent);
102 if (index > 0) {
103 ++count;
104 }
105 }
106 LOG_INFO("AddEvents count %{public}d", count);
107 return count;
108 }
109 #endif
110
111
DeleteEvent(int id)112 bool Calendar::DeleteEvent(int id)
113 {
114 DataShare::DataSharePredicates predicates;
115 predicates.EqualTo("_id", id);
116 predicates.EqualTo("calendar_id", GetId());
117 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
118 LOG_INFO("DeleteEvent number %{public}d", ret);
119 {
120 // delete attendee
121 DataShare::DataSharePredicates predicates;
122 predicates.EqualTo("event_id", id);
123 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_attendeeUri.get()), predicates);
124 LOG_INFO("Delete attendee num %{public}d", ret);
125 }
126 {
127 // delete reminder
128 DataShare::DataSharePredicates predicates;
129 predicates.EqualTo("event_id", id);
130 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_reminderUrl.get()), predicates);
131 LOG_INFO("Delete reminder num %{public}d", ret);
132 }
133 return ret == 1;
134 }
135
DeleteAllEvents()136 void Calendar::DeleteAllEvents()
137 {
138 DataShare::DataSharePredicates predicates;
139 predicates.EqualTo("_id", GetId());
140 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_eventUri.get()), predicates);
141 LOG_INFO("DeleteEvent number %{public}d", ret);
142 return;
143 }
144
DeleteEvents(const std::vector<int> & ids)145 int Calendar::DeleteEvents(const std::vector<int>& ids)
146 {
147 int count = 0;
148 for (const auto &id : ids) {
149 if (DeleteEvent(id)) {
150 count +=1;
151 }
152 }
153 LOG_INFO("DeleteEvents %{public}d", count);
154 return count;
155 }
156
UpdateEvent(const Event & event)157 bool Calendar::UpdateEvent(const Event& event)
158 {
159 if (!event.id) {
160 LOG_ERROR("event id not exist");
161 return false;
162 }
163 const auto eventId = event.id.value();
164 DataShare::DataSharePredicates m_predicates;
165 m_predicates.EqualTo("_id", eventId);
166 auto valueEvent = BuildValueEvent(event, m_id);
167 auto ret = DataShareHelperManager::GetInstance().Update(*(m_eventUri.get()), m_predicates, valueEvent);
168 LOG_INFO(" Update code %{public}d", ret);
169 {
170 // delete attendee
171 DataShare::DataSharePredicates predicates;
172 predicates.EqualTo("event_id", eventId);
173 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_attendeeUri.get()), predicates);
174 LOG_INFO("Delete attendee num %{public}d", ret);
175 }
176 for (const auto &attendee : event.attendees) {
177 auto valueAttendee = BuildAttendeeValue(attendee, eventId);
178 auto index = DataShareHelperManager::GetInstance().Insert(*(m_attendeeUri.get()), valueAttendee);
179 LOG_INFO("Update attendee index %{public}d", index);
180 }
181
182 {
183 // delete reminder
184 DataShare::DataSharePredicates predicates;
185 predicates.EqualTo("event_id", eventId);
186 auto ret = DataShareHelperManager::GetInstance().Delete(*(m_reminderUrl.get()), predicates);
187 LOG_INFO("Delete reminder num %{public}d", ret);
188 }
189 if (event.reminderTime) {
190 for (const auto &reminder : event.reminderTime.value()) {
191 DataShare::DataShareValuesBucket valuesBucket;
192 valuesBucket.Put("event_id", eventId);
193 valuesBucket.Put("minutes", reminder);
194 auto index = DataShareHelperManager::GetInstance().Insert(*(m_reminderUrl.get()), valuesBucket);
195 LOG_INFO("Insert reminder index %{public}d", index);
196 }
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 DataShare::DatashareBusinessError error;
220 auto result = DataShareHelperManager::GetInstance().Query(*(m_attendeeUri.get()), predicates, columns, &error);
221 std::vector<Attendee> attendees;
222 ResultSetToAttendees(attendees, result);
223 LOG_INFO(" query attendee finished");
224 return attendees;
225 }
226
GetRemindersByEventId(int id)227 std::optional<std::vector<int>> Calendar::GetRemindersByEventId(int id)
228 {
229 DataShare::DataSharePredicates predicates;
230 predicates.EqualTo("event_id", id);
231 std::vector<std::string> columns = {"event_id", "minutes"};
232 DataShare::DatashareBusinessError error;
233 auto result = DataShareHelperManager::GetInstance().Query(*(m_reminderUrl.get()), predicates, columns, &error);
234 std::vector<int> reminders;
235 auto ret = ResultSetToReminders(reminders, result);
236 if (ret != DataShare::E_OK) {
237 return std::nullopt;
238 }
239 LOG_INFO("query reminder finished");
240 return reminders;
241 }
242
GetEvents(std::shared_ptr<EventFilter> filter,const std::vector<string> & eventKey)243 std::vector<Event> Calendar::GetEvents(std::shared_ptr<EventFilter> filter, const std::vector<string>& eventKey)
244 {
245 std::vector<Event> events;
246 std::shared_ptr<DataShare::DataSharePredicates> predicates = nullptr;
247 if (filter) {
248 predicates = filter->GetFilterPrediacates();
249 if (!predicates) {
250 LOG_ERROR("predicates null");
251 return events;
252 }
253 } else {
254 predicates = std::make_shared<DataShare::DataSharePredicates>();
255 }
256 predicates->EqualTo("calendar_id", GetId());
257 std::vector<std::string> columns = {"_id", "title", "description", "event_calendar_type",
258 "dtstart", "dtend", "allDay", "eventTimezone",
259 "eventLocation", "location_longitude", "location_latitude",
260 "service_type", "service_cp_bz_uri", "service_description"};
261 DataShare::DatashareBusinessError error;
262 auto result = DataShareHelperManager::GetInstance().Query(*(m_eventUri.get()),
263 *(predicates.get()), columns, &error);
264 if (!result) {
265 LOG_ERROR("query failed");
266 return events;
267 }
268 ResultSetToEvents(events, result, columns);
269 for (auto &event : events) {
270 const auto eventId = event.id.value();
271 auto attendees = GetAttendeesByEventId(eventId); // exist bug id must exist
272 event.attendees = std::move(attendees);
273 event.reminderTime = GetRemindersByEventId(eventId);
274 DumpEvent(event);
275 }
276 LOG_INFO("query finished");
277 return events;
278 }
279
GetConfig()280 CalendarConfig Calendar::GetConfig()
281 {
282 return m_config;
283 }
284
SetConfig(const CalendarConfig & config)285 bool Calendar::SetConfig(const CalendarConfig& config)
286 {
287 DataShare::DataSharePredicates m_predicates;
288 m_predicates.EqualTo("_id", m_id);
289 DataShare::DataShareValuesBucket valuesBucket;
290 if (config.color) {
291 uint32_t colorValue = 0;
292 auto ret = ColorParse(config.color.value(), colorValue);
293 if (ret) {
294 valuesBucket.Put("calendar_color", (int64_t)colorValue);
295 } else {
296 return false;
297 }
298 }
299 if (config.enableReminder) {
300 valuesBucket.Put("canReminder", config.enableReminder.value());
301 }
302 if (valuesBucket.IsEmpty()) {
303 LOG_INFO("no need update");
304 return true;
305 }
306
307 // dataShareHelper 需要提到event_handler基类里面去
308 auto ret = DataShareHelperManager::GetInstance().Update(*(m_calendarUri.get()), m_predicates, valuesBucket) == 1;
309 LOG_INFO("SetConfig %{public}d", ret);
310 if (ret) {
311 m_config = config;
312 }
313 return ret;
314 }
315 }