4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include "cal_internal.h"
27 #include "calendar2.h"
29 #include "cal_typedef.h"
30 #include "cal_inotify.h"
32 #include "cal_db_util.h"
34 #include "cal_db_query.h"
36 static struct timeval stv; // check time
37 static struct timeval etv; // check time
39 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id);
41 static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
45 DBG("remove alarm id(%d)", alarm_id);
46 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
47 ret = alarmmgr_remove_alarm(alarm_id);
48 if (ret != ALARMMGR_RESULT_SUCCESS)
50 ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
53 return CALENDAR_ERROR_NONE;
59 long long int alarm_utime;
74 static int __cal_server_alarm_get_next_list_normal_event(long long int from_utime, long long int to_utime, GList **list, int *count)
77 char query[CAL_DB_SQL_MAX_LEN] = {0};
78 sqlite3_stmt *stmt = NULL;
80 DBG("searching normal event (%lld) ~ (%lld)", from_utime, to_utime);
82 snprintf(query, sizeof(query),
83 "SELECT A.event_id, B.alarm_time, "
84 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
85 "FROM %s as A, " // A is normal instance
86 "%s as B ON A.event_id = B.event_id, " // B is alarm
87 "%s as C ON B.event_id = C.id " // c is schedule
88 "WHERE C.has_alarm == 1 AND C.type = %d "
89 "AND B.remind_tick_unit = %d AND B.alarm_time = %lld "
91 "SELECT A.event_id, A.dtstart_utime - (B.remind_tick * B.remind_tick_unit), "
92 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
93 "FROM %s as A, " // A is normal instance
94 "%s as B ON A.event_id = B.event_id, " // B is alarm
95 "%s as C ON B.event_id = C.id " // c is schedule
96 "WHERE C.has_alarm = 1 AND C.type = %d "
97 "AND B.remind_tick_unit > %d "
98 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
99 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
100 "ORDER BY (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit))",
101 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
102 CALENDAR_BOOK_TYPE_EVENT,
103 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
104 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
105 CALENDAR_BOOK_TYPE_EVENT,
106 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
107 from_utime, to_utime);
109 stmt = _cal_db_util_query_prepare(query);
112 DBG("query[%s]", query);
113 ERR("_cal_db_util_query_prepare() Failed");
114 return CALENDAR_ERROR_DB_FAILED;
118 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
120 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
123 nd->id = sqlite3_column_int(stmt, index++);
124 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
125 nd->tick = sqlite3_column_int(stmt, index++);
126 nd->unit = sqlite3_column_int(stmt, index++);
127 nd->alarm_id = sqlite3_column_int(stmt, index++);
129 *list = g_list_append(*list, nd);
132 sqlite3_finalize(stmt);
133 return CALENDAR_ERROR_NONE;
136 static int __cal_server_alarm_get_next_list_normal_todo(long long int from_utime, long long int to_utime, GList **list, int *count)
139 char query[CAL_DB_SQL_MAX_LEN] = {0};
140 sqlite3_stmt *stmt = NULL;
142 DBG("searching normal todo (%lld) ~ (%lld)", from_utime, to_utime);
144 snprintf(query, sizeof(query),
145 "SELECT B.id, A.alarm_time, "
146 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
147 "FROM %s as A, " // A is alarm
148 "%s as B ON A.event_id = B.id " // B is schedule
149 "WHERE B.has_alarm == 1 AND B.type = %d "
150 "AND A.remind_tick_unit = %d AND A.alarm_time = %lld "
152 "SELECT B.id, B.dtend_utime - (A.remind_tick * A.remind_tick_unit), "
153 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
154 "FROM %s as A, " // A is alarm
155 "%s as B ON A.event_id = B.id " // B is schedule
156 "WHERE B.has_alarm = 1 AND B.type = %d "
157 "AND A.remind_tick_unit > %d "
158 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
159 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld "
160 "ORDER BY (B.dtend_utime - (A.remind_tick * A.remind_tick_unit))",
161 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
162 CALENDAR_BOOK_TYPE_TODO,
163 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
164 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
165 CALENDAR_BOOK_TYPE_TODO,
166 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
167 from_utime, to_utime);
169 stmt = _cal_db_util_query_prepare(query);
172 DBG("query[%s]", query);
173 ERR("_cal_db_util_query_prepare() Failed");
174 return CALENDAR_ERROR_DB_FAILED;
178 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
180 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
183 nd->id = sqlite3_column_int(stmt, index++);
184 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
185 nd->tick = sqlite3_column_int(stmt, index++);
186 nd->unit = sqlite3_column_int(stmt, index++);
187 nd->alarm_id = sqlite3_column_int(stmt, index++);
189 *list = g_list_append(*list, nd);
192 sqlite3_finalize(stmt);
193 return CALENDAR_ERROR_NONE;
196 static int __cal_server_alarm_get_next_list_allday_event(int from_datetime, int to_datetime, GList **list, int *count)
199 char query[CAL_DB_SQL_MAX_LEN] = {0};
200 sqlite3_stmt *stmt = NULL;
202 DBG("searching allday (%d) ~ (%d)", from_datetime, to_datetime);
204 snprintf(query, sizeof(query),
205 "SELECT A.event_id, B.alarm_time, "
206 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
207 "FROM %s as A, " // A is allday instance
208 "%s as B ON A.event_id = B.event_id, " // B is alarm
209 "%s as C ON B.event_id = C.id " // C is schedule
210 "WHERE C.has_alarm == 1 AND C.type = %d "
211 "AND B.remind_tick_unit = %d AND B.alarm_time = %d "
213 "SELECT A.event_id, A.dtstart_datetime, "
214 "B.remind_tick, B.remind_tick_unit, B.alarm_id "
215 "FROM %s as A, " // A is allday instance
216 "%s as B ON A.event_id = B.event_id, " // B is alarm
217 "%s as C ON B.event_id = C.id " // C is schedule
218 "WHERE C.has_alarm = 1 AND C.type = %d "
219 "AND B.remind_tick_unit > %d "
220 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 > %d "
221 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 <= %d ",
222 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
223 CALENDAR_BOOK_TYPE_EVENT,
224 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
225 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
226 CALENDAR_BOOK_TYPE_EVENT,
227 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
228 from_datetime, to_datetime);
230 stmt = _cal_db_util_query_prepare(query);
233 DBG("query[%s]", query);
234 ERR("_cal_db_util_query_prepare() Failed");
235 return CALENDAR_ERROR_DB_FAILED;
239 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
241 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
244 ad->id = sqlite3_column_int(stmt, index++);
245 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
246 ad->tick = sqlite3_column_int(stmt, index++);
247 ad->unit = sqlite3_column_int(stmt, index++);
248 ad->alarm_id = sqlite3_column_int(stmt, index++);
250 *list = g_list_append(*list, ad);
253 sqlite3_finalize(stmt);
254 return CALENDAR_ERROR_NONE;
257 static int __cal_server_alarm_get_next_list_allday_todo(int from_datetime, int to_datetime, GList **list, int *count)
260 char query[CAL_DB_SQL_MAX_LEN] = {0};
261 sqlite3_stmt *stmt = NULL;
263 DBG("searching allday todo(%d) ~ (%d)", from_datetime, to_datetime);
265 snprintf(query, sizeof(query),
266 "SELECT A.event_id, A.alarm_time, "
267 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
268 "FROM %s as A, " // A is alarm
269 "%s as B ON A.event_id = B.id " // B is schedule
270 "WHERE B.has_alarm == 1 AND B.type = %d "
271 "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
273 "SELECT A.event_id, B.dtend_datetime, "
274 "A.remind_tick, A.remind_tick_unit, A.alarm_id "
275 "FROM %s as A, " // A is alarm
276 "%s as B ON A.event_id = B.id " // B is schedule
277 "WHERE B.has_alarm = 1 AND B.type = %d "
278 "AND A.remind_tick_unit > %d "
279 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 > %d "
280 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 <= %d ",
281 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
282 CALENDAR_BOOK_TYPE_TODO,
283 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
284 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
285 CALENDAR_BOOK_TYPE_TODO,
286 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
287 from_datetime, to_datetime);
289 stmt = _cal_db_util_query_prepare(query);
292 DBG("query[%s]", query);
293 ERR("_cal_db_util_query_prepare() Failed");
294 return CALENDAR_ERROR_DB_FAILED;
298 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
300 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
303 ad->id = sqlite3_column_int(stmt, index++);
304 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
305 ad->tick = sqlite3_column_int(stmt, index++);
306 ad->unit = sqlite3_column_int(stmt, index++);
307 ad->alarm_id = sqlite3_column_int(stmt, index++);
309 *list = g_list_append(*list, ad);
312 sqlite3_finalize(stmt);
313 return CALENDAR_ERROR_NONE;
316 static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
318 char query[CAL_DB_SQL_MAX_LEN] = {0};
319 cal_db_util_error_e dbret = CAL_DB_OK;
321 DBG("Update alarm_id(%d) in alarm table", alarm_id);
322 snprintf(query, sizeof(query), "UPDATE %s SET "
324 "WHERE event_id = %d AND remind_tick = %d AND remind_tick_unit = %d",
327 event_id, tick, unit);
329 dbret = _cal_db_util_query_exec(query);
330 if (CAL_DB_OK != dbret)
332 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
335 case CAL_DB_ERROR_NO_SPACE:
336 return CALENDAR_ERROR_FILE_NO_SPACE;
338 return CALENDAR_ERROR_DB_FAILED;
342 return CALENDAR_ERROR_NONE;
345 static GFunc __cal_server_alarm_print_list_normal(gpointer data, gpointer user_data)
347 struct _normal_data_s *normal = (struct _normal_data_s *)data;
348 DBG("%02d:%lld", normal->id, normal->alarm_utime);
352 static GFunc __cal_server_alarm_print_list_allday_todo(gpointer data, gpointer user_data)
354 struct _allday_data_s *allday = (struct _allday_data_s *)data;
355 DBG("%02d:%d", allday->id, allday->alarm_datetime);
359 static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **normal_list, GList **allday_list)
362 char query[CAL_DB_SQL_MAX_LEN] = {0};
363 sqlite3_stmt *stmt = NULL;
364 struct _normal_data_s *nd;
365 struct _allday_data_s *ad;
367 snprintf(query, sizeof(query),
368 "SELECT A.type, A.dtstart_type, A.dtend_type, B.remind_tick, B.remind_tick_unit "
369 "FROM %s as A, " // schedule
370 "%s as B ON A.id = B.event_id " // alarm
371 "WHERE B.alarm_id = %d",
376 stmt = _cal_db_util_query_prepare(query);
379 DBG("query[%s]", query);
380 ERR("_cal_db_util_query_prepare() Failed");
381 return CALENDAR_ERROR_DB_FAILED;
385 int dtstart_type = 0;
389 if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
392 type = sqlite3_column_int(stmt, index++);
393 dtstart_type = sqlite3_column_int(stmt, index++);
394 dtend_type = sqlite3_column_int(stmt, index++);
395 tick = sqlite3_column_int(stmt, index++);
396 unit = sqlite3_column_int(stmt, index++);
402 sqlite3_finalize(stmt);
405 if ((type == CALENDAR_BOOK_TYPE_EVENT && dtstart_type == CALENDAR_TIME_UTIME)
406 || (type == CALENDAR_BOOK_TYPE_TODO && dtend_type == CALENDAR_TIME_UTIME))
408 long long int now_utime;
409 now_utime = _cal_time_get_now();
410 now_utime -= now_utime % 60;
412 snprintf(query, sizeof(query),
413 "SELECT A.event_id, A.dtstart_utime, "
414 "B.remind_tick, B.remind_tick_unit "
415 "FROM %s as A, " // A is normal instance
416 "%s as B ON A.event_id = B.event_id, " // B is alarm
417 "%s as C ON B.event_id = C.id " // c is schedule
418 "WHERE C.has_alarm == 1 AND C.type = %d "
419 "AND B.remind_tick_unit = %d "
420 "AND B.alarm_time = %lld "
422 "SELECT A.event_id, A.dtstart_utime, "
423 "B.remind_tick, B.remind_tick_unit "
424 "FROM %s as A, " // A is normal instance
425 "%s as B ON A.event_id = B.event_id, " // B is alarm
426 "%s as C ON B.event_id = C.id " // c is schedule
427 "WHERE C.has_alarm = 1 AND C.type = %d "
428 "AND B.remind_tick_unit > %d "
429 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
430 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
432 "SELECT B.id, B.dtend_utime, "
433 "A.remind_tick, A.remind_tick_unit "
434 "FROM %s as A, " // A is alarm
435 "%s as B ON A.event_id = B.id " // B is schedule
436 "WHERE B.has_alarm == 1 AND B.type = %d "
437 "AND A.remind_tick_unit = %d "
438 "AND A.alarm_time = %lld "
440 "SELECT B.id, B.dtend_utime, "
441 "A.remind_tick, A.remind_tick_unit "
442 "FROM %s as A, " // A is alarm
443 "%s as B ON A.event_id = B.id " // B is schedule
444 "WHERE B.has_alarm = 1 AND B.type = %d "
445 "AND A.remind_tick_unit > %d "
446 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
447 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld ",
448 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
449 CALENDAR_BOOK_TYPE_EVENT,
450 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
452 CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
453 CALENDAR_BOOK_TYPE_EVENT,
454 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
455 now_utime, now_utime + 60,
456 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
457 CALENDAR_BOOK_TYPE_TODO,
458 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
460 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
461 CALENDAR_BOOK_TYPE_TODO,
462 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
463 now_utime, now_utime + 60);
465 stmt = _cal_db_util_query_prepare(query);
468 DBG("query[%s]", query);
469 ERR("_cal_db_util_query_prepare() Failed");
470 return CALENDAR_ERROR_DB_FAILED;
473 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
476 nd = calloc(1, sizeof(struct _normal_data_s));
477 nd->id = sqlite3_column_int(stmt, index++);
478 nd->alarm_utime = sqlite3_column_int64(stmt, index++); // dtstart, dtend
479 nd->tick = sqlite3_column_int(stmt, index++);
480 nd->unit = sqlite3_column_int(stmt, index++);
481 *normal_list = g_list_append(*normal_list, nd);
488 time_t now_timet = time(NULL);
489 struct tm start_tm = {0};
490 now_timet -= now_timet % 60;
491 gmtime_r(&now_timet, &start_tm);
492 now_datetime = (start_tm.tm_year + 1900) * 10000
493 + (start_tm.tm_mon + 1) * 100
494 + (start_tm.tm_mday);
496 snprintf(query, sizeof(query),
497 "SELECT A.event_id, A.dtstart_datetime, "
498 "B.remind_tick, B.remind_tick_unit "
499 "FROM %s as A, " // A is allday instance
500 "%s as B ON A.event_id = B.event_id, " // B is alarm
501 "%s as C ON B.event_id = C.id " // C is schedule
502 "WHERE C.has_alarm == 1 AND C.type = %d "
503 "AND B.remind_tick_unit = %d "
504 "AND B.alarm_time = %d "
506 "SELECT A.event_id, A.dtstart_datetime, "
507 "B.remind_tick, B.remind_tick_unit "
508 "FROM %s as A, " // A is allday instance
509 "%s as B ON A.event_id = B.event_id, " // B is alarm
510 "%s as C ON B.event_id = C.id " // C is schedule
511 "WHERE C.has_alarm = 1 AND C.type = %d "
512 "AND B.remind_tick_unit > %d "
513 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 = %d "
515 "SELECT A.event_id, B.dtend_datetime, "
516 "A.remind_tick, A.remind_tick_unit "
517 "FROM %s as A, " // A is alarm
518 "%s as B ON A.event_id = B.id " // B is schedule
519 "WHERE B.has_alarm == 1 AND B.type = %d "
520 "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
522 "SELECT A.event_id, B.dtend_datetime, "
523 "A.remind_tick, A.remind_tick_unit "
524 "FROM %s as A, " // A is alarm
525 "%s as B ON A.event_id = B.id " // B is schedule
526 "WHERE B.has_alarm = 1 AND B.type = %d "
527 "AND A.remind_tick_unit > %d "
528 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 = %d ",
529 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
530 CALENDAR_BOOK_TYPE_EVENT,
531 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
533 CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
534 CALENDAR_BOOK_TYPE_EVENT,
535 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
537 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
538 CALENDAR_BOOK_TYPE_TODO,
539 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
541 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
542 CALENDAR_BOOK_TYPE_TODO,
543 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
546 stmt = _cal_db_util_query_prepare(query);
549 DBG("query[%s]", query);
550 ERR("_cal_db_util_query_prepare() Failed");
551 return CALENDAR_ERROR_DB_FAILED;
554 const unsigned char *temp;
555 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
558 ad = calloc(1, sizeof(struct _allday_data_s));
559 ad->id = sqlite3_column_int(stmt, index++);
560 temp = sqlite3_column_text(stmt, index++); // dtstart, dtend
561 ad->alarm_datetime = atoi((const char *)temp);
562 ad->tick = sqlite3_column_int(stmt, index++);
563 ad->unit = sqlite3_column_int(stmt, index++);
564 *allday_list = g_list_append(*allday_list, ad);
567 sqlite3_finalize(stmt);
568 return CALENDAR_ERROR_NONE;
571 // this api is necessary for repeat instance.
572 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
574 char query[CAL_DB_SQL_MAX_LEN] = {0};
575 cal_db_util_error_e dbret = CAL_DB_OK;
577 DBG("alarm_id(%d)", alarm_id);
579 snprintf(query, sizeof(query),
580 "UPDATE %s SET alarm_id = 0 WHERE alarm_id = %d ",
581 CAL_TABLE_ALARM, alarm_id);
583 dbret = _cal_db_util_query_exec(query);
584 if (CAL_DB_OK != dbret)
586 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
589 case CAL_DB_ERROR_NO_SPACE:
590 return CALENDAR_ERROR_FILE_NO_SPACE;
592 return CALENDAR_ERROR_DB_FAILED;
596 return CALENDAR_ERROR_NONE;
599 static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit)
601 int ret = CALENDAR_ERROR_NONE;
603 char query[CAL_DB_SQL_MAX_LEN] = {0};
606 sqlite3_stmt *stmt = NULL;
607 cal_db_util_error_e dbret = CAL_DB_OK;
611 ERR("Invalid parameter: pkgname is NULL");
612 return CALENDAR_ERROR_INVALID_PARAMETER;
615 // get user key, value
616 snprintf(query, sizeof(query), "SELECT key, value FROM %s WHERE pkgname = '%s' ",
617 CAL_REMINDER_ALERT, pkgname);
618 stmt = _cal_db_util_query_prepare(query);
621 ERR("_cal_db_util_query_prepare() Failed");
622 return CALENDAR_ERROR_DB_FAILED;
625 while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
628 key = (const char *)sqlite3_column_text(stmt, index++);
629 value = (const char *)sqlite3_column_text(stmt, index++);
633 DBG("[%s][%s][%s][%s]", id, time, tick, unit);
637 appsvc_set_pkgname(b, pkgname);
638 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
639 if (key && value) appsvc_add_data(b, key, value);
640 appsvc_add_data(b, "calendar-service/id", id);
641 appsvc_add_data(b, "calendar-service/time", time);
642 appsvc_add_data(b, "calendar-service/tick", tick);
643 appsvc_add_data(b, "calendar-service/unit", unit);
644 ret = appsvc_run_service(b, 0, NULL, NULL);
647 sqlite3_finalize(stmt);
649 // if no app, delete from the table
650 if (APPSVC_RET_ELAUNCH == ret)
652 DBG("Deleted no responce pkg[%s]", pkgname);
653 snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = '%s' ",
654 CAL_REMINDER_ALERT, pkgname);
655 dbret = _cal_db_util_query_exec(query);
656 if (CAL_DB_OK != dbret)
658 ERR("_cal_db_util_query_exec() failed(ret:%d)", ret);
661 case CAL_DB_ERROR_NO_SPACE:
662 return CALENDAR_ERROR_FILE_NO_SPACE;
664 return CALENDAR_ERROR_DB_FAILED;
669 return CALENDAR_ERROR_NONE;
672 static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit)
675 char query[CAL_DB_SQL_MAX_LEN] = {0};
676 sqlite3_stmt *stmt = NULL;
678 snprintf(query, sizeof(query), "SELECT pkgname FROM %s WHERE onoff = 1 ",
680 stmt = _cal_db_util_query_prepare(query);
683 ERR("_cal_db_util_query_prepare() Failed");
684 return CALENDAR_ERROR_DB_FAILED;
687 while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
690 const char *pkgname = (const char *)sqlite3_column_text(stmt, index++);
691 DBG("pkgname[%s]", pkgname);
692 __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit);
694 sqlite3_finalize(stmt);
696 return CALENDAR_ERROR_NONE;
699 static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list, GList *allday_list)
701 char buf_id[128] = {0};
702 char buf_time[128] = {0};
703 char buf_tick[128] = {0};
704 char buf_unit[128] = {0};
707 l = g_list_first(normal_list);
708 if (NULL == l) DBG("normal list is NULL");
711 struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
712 snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
713 snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
714 snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
715 snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
717 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit);
722 l = g_list_first(allday_list);
723 if (NULL == l) DBG("allday list is NULL");
726 struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
727 snprintf(buf_id, sizeof(buf_id), "%d", ad->id);
728 snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
729 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
730 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
732 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit);
738 static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
742 struct _normal_data_s *nd;
744 GList *l = g_list_first(normal_list);
746 // try to save the first record.
747 // if alarm id exists, it means updated record is not earilier than already registerd one.
748 nd = (struct _normal_data_s *)l->data;
752 return CALENDAR_ERROR_DB_FAILED;
755 if (nd->alarm_id > 0)
757 DBG("Already registered this id");
758 return CALENDAR_ERROR_NONE;
761 DBG("new is earilier than registered.");
763 // clear all alarm which set by mine.
764 ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
765 if (ret != ALARMMGR_RESULT_SUCCESS)
767 ERR("alarmmgr_enum_alarm_ids() failed");
772 long long int mod_alarm_utime; // del seconds
773 mod_alarm_utime = nd->alarm_utime - (nd->alarm_utime % 60);
774 ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE,
775 (time_t)(mod_alarm_utime - now_utime),
779 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
782 DBG("Get normal alarmmgr id (%d)", alarm_id);
783 __cal_server_alarm_update_alarm_id(alarm_id, nd->id, nd->tick, nd->unit);
785 return CALENDAR_ERROR_NONE;
788 static int __cal_server_alarm_register_next_allday(time_t now_timet, GList *allday_list)
792 struct _allday_data_s *ad;
795 GList *l = g_list_first(allday_list);
797 ad = (struct _allday_data_s *)l->data;
801 return CALENDAR_ERROR_DB_FAILED;
804 if (ad->alarm_id > 0)
806 DBG("Already registered this id");
807 return CALENDAR_ERROR_NONE;
810 DBG("new is earilier than registered.");
812 // clear all alarm which set by mine.
813 ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
814 if (ret != ALARMMGR_RESULT_SUCCESS)
816 ERR("alarmmgr_enum_alarm_ids() failed");
821 ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE,
822 (time_t)(alarm_timet - (ad->tick * ad->unit) - now_timet),
826 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
829 DBG("Get allday alarmmgr id (%d)", alarm_id);
830 __cal_server_alarm_update_alarm_id(alarm_id, ad->id, ad->tick, ad->unit);
832 return CALENDAR_ERROR_NONE;
835 static gint __cal_server_alarm_normal_sort_cb(gconstpointer a, gconstpointer b)
837 struct _normal_data_s *p1 = (struct _normal_data_s *)a;
838 struct _normal_data_s *p2 = (struct _normal_data_s *)b;
840 return p1->alarm_utime - p2->alarm_utime > 0 ? 1 : -1;
843 static gint __cal_server_alarm_allday_sort_cb(gconstpointer a, gconstpointer b)
845 struct _allday_data_s *p1 = (struct _allday_data_s *)a;
846 struct _allday_data_s *p2 = (struct _allday_data_s *)b;
848 return p1->alarm_datetime - p2->alarm_datetime > 0 ? 1 : -1;
851 static int __cal_server_alarm_register_with_alarmmgr(void)
853 GList *normal_list = NULL;
854 GList *allday_list = NULL;
859 gettimeofday(&stv, NULL); // check time
862 long long int now_utime;
863 long long int from_utime, to_utime;
864 now_utime = _cal_time_get_now();
868 to_utime = now_utime - (now_utime % 60) + 60;
870 // searching 3months, next 6months, next 12months
871 for (loop_count = 1; loop_count < 4; loop_count++)
873 from_utime = to_utime;
874 to_utime = from_utime + (60 * 60 * 24 * 30 * 3 * loop_count);
875 __cal_server_alarm_get_next_list_normal_event(from_utime, to_utime, &normal_list, &event_count);
876 __cal_server_alarm_get_next_list_normal_todo(from_utime, to_utime, &normal_list, &todo_count);
877 if (event_count + todo_count > 0)
882 DBG("event count(%d) todo count(%d)", event_count, todo_count);
884 if (event_count + todo_count > 0)
886 normal_list = g_list_sort(normal_list, __cal_server_alarm_normal_sort_cb);
887 DBG("after sorting");
888 g_list_foreach(normal_list, (GFunc)__cal_server_alarm_print_list_normal, NULL);
889 __cal_server_alarm_register_next_normal(now_utime, normal_list);
894 g_list_free_full(normal_list, free);
901 time_t from_timet, to_timet;
902 int from_datetime, to_datetime;
903 struct tm datetime_tm;
904 now_timet = time(NULL);
908 to_timet = now_timet;
910 // searching 3months, next 6months, next 12months
911 for (loop_count = 1; loop_count < 4; loop_count++)
913 from_timet = to_timet;
914 gmtime_r(&from_timet, &datetime_tm);
915 from_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
917 to_timet = from_timet + (60 * 60 * 24 * 30 * 3 * loop_count);
918 gmtime_r(&to_timet, &datetime_tm);
919 to_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
921 __cal_server_alarm_get_next_list_allday_event(from_datetime, to_datetime, &allday_list, &event_count);
922 __cal_server_alarm_get_next_list_allday_todo(from_datetime, to_datetime, &allday_list, &todo_count);
924 if (event_count + todo_count > 0)
929 DBG("event count(%d) todo count(%d)", event_count, todo_count);
931 if (event_count + todo_count > 0)
933 allday_list = g_list_sort(allday_list, __cal_server_alarm_allday_sort_cb);
934 DBG("after sorting");
935 g_list_foreach(allday_list, (GFunc)__cal_server_alarm_print_list_allday_todo, NULL);
936 __cal_server_alarm_register_next_allday(now_timet, allday_list);
940 g_list_free_full(allday_list, free);
945 gettimeofday(&etv, NULL);
946 diff = ((int)etv.tv_sec *1000 + (int)etv.tv_usec/1000)
947 -((int)stv.tv_sec *1000 + (int)stv.tv_usec/1000);
948 DBG("registering time diff %ld(%d.%d)",diff, diff/1000, diff%1000); // time check
952 static int _alert_cb(alarm_id_t alarm_id, void *data)
954 GList *normal_list = NULL;
955 GList *allday_list = NULL;
957 __cal_server_alarm_get_list_with_alarmmgr_id(alarm_id, &normal_list, &allday_list);
958 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
959 __cal_server_alarm_noti_with_appsvc(alarm_id, normal_list, allday_list);
962 g_list_free_full(normal_list, free);
967 g_list_free_full(allday_list, free);
971 __cal_server_alarm_register_with_alarmmgr();
975 ////////////////////////////////////////////////////////////////////
976 static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
978 __cal_server_alarm_register_with_alarmmgr();
981 int __cal_server_alarm_set_timechange(void)
985 ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIMECHANGE,
986 __cal_server_alarm_timechange_cb, NULL);
989 ERR("vconf_ignore_key_changed() failed");
992 return CALENDAR_ERROR_NONE;
995 static void __changed_cb(const char* view_uri, void* data)
997 __cal_server_alarm_register_with_alarmmgr();
1000 static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1002 _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
1003 _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
1007 int _cal_server_alarm(void)
1011 __cal_server_alarm_set_timechange();
1012 __cal_server_alarm_set_inotify(__changed_cb);
1014 ret = alarmmgr_init("calendar-service");
1015 retvm_if(ret < 0, ret, "alarmmgr_init() failed");
1017 ret = alarmmgr_set_cb(_alert_cb, NULL);
1018 retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
1020 __cal_server_alarm_register_with_alarmmgr();
1022 return CALENDAR_ERROR_NONE;