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