[Calendar] Native filters and sorting
authorWojciech Kosowicz <w.kosowicz@samsung.com>
Fri, 23 Jan 2015 09:14:16 +0000 (10:14 +0100)
committerRafal Galka <r.galka@samsung.com>
Wed, 28 Jan 2015 12:45:55 +0000 (21:45 +0900)
[Verification] TCT without changes
Change-Id: Iefe184b0defca75d759d93c628674002f8e2d636
Signed-off-by: Wojciech Kosowicz <w.kosowicz@samsung.com>
src/calendar/calendar.cc
src/calendar/calendar.h
src/calendar/calendar_item.cc
src/calendar/calendar_item.h
src/calendar/js/calendar.js
src/calendar/js/common.js

index 5720b7665e95537f1384245fd5e014cfb2e7ea97..2a8ecec39a82629436783221ddab8a6219d71d6f 100644 (file)
@@ -20,6 +20,7 @@
 #include "common/logger.h"
 #include "common/converter.h"
 #include "common/task-queue.h"
+#include "common/filter-utils.h"
 #include "calendar/calendar_manager.h"
 #include "calendar/calendar_privilege.h"
 #include "calendar/calendar_item.h"
 namespace extension {
 namespace calendar {
 
+typedef std::unique_ptr<std::remove_pointer<calendar_filter_h>::type,
+                        void (*)(calendar_filter_h)> CalendarFilterPtr;
+
+void CalendarFilterDeleter(calendar_filter_h calendar_filter) {
+  if (CALENDAR_ERROR_NONE != calendar_filter_destroy(calendar_filter)) {
+    LoggerE("failed to destroy contacts_filter_h");
+  }
+}
+
 using namespace common;
 
 int Calendar::current_db_version_ = 0;
@@ -61,8 +71,6 @@ Calendar::~Calendar() {
 void Calendar::Get(const picojson::object& args, picojson::object& out) {
   LoggerD("enter");
 
-//  NativePlugin::CheckAccess(Privilege::kCalendarRead);
-
   if (!CalendarManager::GetInstance().IsConnected()) {
     throw UnknownException("DB Connection failed.");
   }
@@ -84,12 +92,10 @@ void Calendar::Get(const picojson::object& args, picojson::object& out) {
       CalendarRecord::GetById(id, CalendarRecord::TypeToUri(type));
   picojson::value record_obj = picojson::value(picojson::object());
   CalendarItem::ToJson(type, record_ptr.get(), &out);
-
 }
 
 void Calendar::Add(const picojson::object& args, picojson::object& out) {
   LoggerD("enter");
-
   if (!CalendarManager::GetInstance().IsConnected()) {
     throw UnknownException("DB Connection failed.");
   }
@@ -100,7 +106,6 @@ void Calendar::Add(const picojson::object& args, picojson::object& out) {
   CalendarRecordPtr item_ptr = CalendarItem::Create(type);
   CalendarItem::FromJson(type, item_ptr.get(), item);
   int record_id = CalendarRecord::Insert(item_ptr.get());
-
   out.insert(std::make_pair("uid", std::to_string(record_id)));
 
   if (type == CALENDAR_BOOK_TYPE_EVENT) {
@@ -112,11 +117,9 @@ void Calendar::Add(const picojson::object& args, picojson::object& out) {
       out["rid"] = picojson::value();
     }
   }
-
 }
 
-void Calendar::AddBatch(const picojson::object& args,
-                        picojson::array& array) {
+void Calendar::AddBatch(const picojson::object& args, picojson::array& array) {
   LoggerD("enter");
 
   if (!CalendarManager::GetInstance().IsConnected()) {
@@ -135,8 +138,7 @@ void Calendar::AddBatch(const picojson::object& args,
     LoggerE("Could not create list for batch operation");
     throw UnknownException("Could not create list for batch operation");
   }
-  CalendarListPtr list_ptr =
-      CalendarListPtr(list, CalendarRecord::ListDeleter);
+  CalendarListPtr list_ptr = CalendarListPtr(list, CalendarRecord::ListDeleter);
 
   int ret;
   calendar_record_h record;
@@ -148,7 +150,6 @@ void Calendar::AddBatch(const picojson::object& args,
       throw UnknownException("Can't create platform record");
     }
     CalendarItem::FromJson(type, record, item.get<picojson::object>());
-
     if (CALENDAR_ERROR_NONE != calendar_list_add(list_ptr.get(), record)) {
       LoggerE("Could not add record to list events");
       throw InvalidValuesException("Could not add record to list");
@@ -184,8 +185,7 @@ void Calendar::AddBatch(const picojson::object& args,
   free(ids);
 }
 
-void Calendar::Update(const picojson::object& args,
-                      picojson::object& /*out*/) {
+void Calendar::Update(const picojson::object& args, picojson::object& /*out*/) {
   LoggerD("enter");
 
   if (!CalendarManager::GetInstance().IsConnected()) {
@@ -219,9 +219,11 @@ void Calendar::Update(const picojson::object& args,
     }
   } else {
     // first update the parent event
-    std::string exdate = CalendarItem::ExceptionsFromJson(
-        common::FromJson<picojson::array>(item, "recurrenceRule", "exceptions"));
-    if (!common::IsNull(common::FromJson<picojson::object>(item, "id"), "rid")) {
+    std::string exdate =
+        CalendarItem::ExceptionsFromJson(common::FromJson<picojson::array>(
+            item, "recurrenceRule", "exceptions"));
+    if (!common::IsNull(common::FromJson<picojson::object>(item, "id"),
+                        "rid")) {
       exdate.append(common::FromJson<std::string>(item, "id", "rid"));
     }
     CalendarRecord::SetString(record_ptr.get(), _calendar_event.exdate, exdate);
@@ -267,8 +269,7 @@ void Calendar::UpdateBatch(const picojson::object& args,
     LoggerE("Could not create list for batch operation");
     throw UnknownException("Could not create list for batch operation");
   }
-  CalendarListPtr list_ptr =
-      CalendarListPtr(list, CalendarRecord::ListDeleter);
+  CalendarListPtr list_ptr = CalendarListPtr(list, CalendarRecord::ListDeleter);
 
   int ret, id;
   calendar_record_h record;
@@ -305,8 +306,7 @@ void Calendar::UpdateBatch(const picojson::object& args,
   }
 }
 
-void Calendar::Remove(const picojson::object& args,
-                      picojson::object& out) {
+void Calendar::Remove(const picojson::object& args, picojson::object& out) {
   LoggerD("enter");
 
   if (!CalendarManager::GetInstance().IsConnected()) {
@@ -331,8 +331,6 @@ void Calendar::Find(const picojson::object& args, picojson::array& array) {
   if (!CalendarManager::GetInstance().IsConnected()) {
     throw UnknownException("DB Connection failed.");
   }
-
-  // TODO implement calendar filter and sorting in native code.
   int calendar_id = common::stol(FromJson<std::string>(args, "calendarId"));
   int error_code = 0;
   CalendarRecordPtr calendar_ptr =
@@ -341,22 +339,368 @@ void Calendar::Find(const picojson::object& args, picojson::array& array) {
       CalendarRecord::GetInt(calendar_ptr.get(), _calendar_book.store_type);
   calendar_query_h calendar_query = nullptr;
   if (type == CALENDAR_BOOK_TYPE_EVENT) {
-    error_code =
-        calendar_query_create(_calendar_event._uri, &calendar_query);
+    error_code = calendar_query_create(_calendar_event._uri, &calendar_query);
+    ErrorChecker(error_code);
   } else {
-    error_code =
-        calendar_query_create(_calendar_todo._uri, &calendar_query);
+    error_code = calendar_query_create(_calendar_todo._uri, &calendar_query);
+    ErrorChecker(error_code);
   }
   if (CALENDAR_ERROR_NONE != error_code) {
     throw UnknownException("calendar_query_create failed");
   }
+  std::vector<std::vector<CalendarFilterPtr>> intermediate_filters(1);
+  if (!IsNull(args, "filter")) {
+    FilterVisitor visitor;
+    visitor.SetOnAttributeFilter([&](const std::string& name,
+                                     AttributeMatchFlag match_flag,
+                                     const picojson::value& match_value) {
+      int value = 0;
+      calendar_filter_h calendar_filter = nullptr;
+      if (type == CALENDAR_BOOK_TYPE_EVENT) {
+        error_code =
+            calendar_filter_create(_calendar_event._uri, &calendar_filter);
+        ErrorChecker(error_code);
+      } else {
+        error_code =
+            calendar_filter_create(_calendar_todo._uri, &calendar_filter);
+        ErrorChecker(error_code);
+      }
+      CalendarFilterPtr calendar_filter_ptr(calendar_filter,
+                                            CalendarFilterDeleter);
+      unsigned int propertyId = 0;
+      if (name == "startDate" || name == "endDate" || name == "dueDate")
+        propertyId = CalendarItem::GetPlatformProperty(type, name + "_time");
+      else
+        propertyId = CalendarItem::GetPlatformProperty(type, name);
+      if (name == "id" || name == "id.uid") {
+        if (type == CALENDAR_BOOK_TYPE_EVENT && name == "id") {
+          value = common::stol(
+              FromJson<std::string>(JsonCast<JsonObject>(match_value), "uid"));
+        } else {
+          value = common::stol(JsonCast<std::string>(match_value));
+        }
+        if (value < 0) {
+          throw InvalidValuesException("Match value cannot be less than 0");
+        }
+        calendar_match_int_flag_e flag;
+        if (AttributeMatchFlag::kExists == match_flag) {
+          flag = CALENDAR_MATCH_GREATER_THAN_OR_EQUAL;
+          value = 0;
+        } else if (AttributeMatchFlag::kStartsWith == match_flag ||
+                   AttributeMatchFlag::kContains == match_flag) {
+          flag = CALENDAR_MATCH_GREATER_THAN_OR_EQUAL;
+        } else if (AttributeMatchFlag::kEndsWith == match_flag) {
+          flag = CALENDAR_MATCH_LESS_THAN_OR_EQUAL;
+        } else {
+          flag = CALENDAR_MATCH_EQUAL;
+        }
+        error_code =
+            calendar_filter_add_int(calendar_filter, propertyId, flag, value);
+        ErrorChecker(error_code);
+      } else if (name == "startDate" || name == "endDate" ||
+                 name == "dueDate") {
+        calendar_match_int_flag_e flag;
+        Date dateTofilter =
+            CalendarItem::DateFromJson(JsonCast<picojson::object>(match_value));
+        if (AttributeMatchFlag::kExists == match_flag) {
+          flag = CALENDAR_MATCH_GREATER_THAN_OR_EQUAL;
+          value = 0;
+        } else if (AttributeMatchFlag::kStartsWith == match_flag ||
+                   AttributeMatchFlag::kContains == match_flag) {
+          flag = CALENDAR_MATCH_GREATER_THAN_OR_EQUAL;
+        } else if (AttributeMatchFlag::kEndsWith == match_flag) {
+          flag = CALENDAR_MATCH_LESS_THAN_OR_EQUAL;
+        } else {
+          flag = CALENDAR_MATCH_EQUAL;
+        }
+
+        error_code = calendar_filter_add_caltime(
+            calendar_filter, propertyId, flag,
+            CalendarItem::DateToPlatform(dateTofilter, false));
+        ErrorChecker(error_code);
+      } else {
+        std::string value = JsonCast<std::string>(match_value);
+        calendar_match_str_flag_e flag = CALENDAR_MATCH_EXISTS;
+        if (AttributeMatchFlag::kExactly == match_flag) {
+          flag = CALENDAR_MATCH_EXACTLY;
+        } else if (AttributeMatchFlag::kFullString == match_flag) {
+          flag = CALENDAR_MATCH_FULLSTRING;
+        } else if (AttributeMatchFlag::kContains == match_flag) {
+          flag = CALENDAR_MATCH_CONTAINS;
+        } else if (AttributeMatchFlag::kStartsWith == match_flag) {
+          flag = CALENDAR_MATCH_STARTSWITH;
+        } else if (AttributeMatchFlag::kEndsWith == match_flag) {
+          flag = CALENDAR_MATCH_ENDSWITH;
+        } else if (AttributeMatchFlag::kExists == match_flag) {
+          flag = CALENDAR_MATCH_EXISTS;
+          value = "";
+        }
+        calendar_filter_add_str(calendar_filter, propertyId, flag,
+                                value.c_str());
+      }
+      intermediate_filters[intermediate_filters.size() - 1].push_back(
+          std::move(calendar_filter_ptr));
+    });
+    visitor.SetOnCompositeFilterBegin([&](CompositeFilterType type) {
+      intermediate_filters.push_back(std::vector<CalendarFilterPtr>());
+    });
+
+    visitor.SetOnCompositeFilterEnd([&](CompositeFilterType calType) {
+      if (intermediate_filters.size() == 0) {
+        throw UnknownException("Reached stack size equal to 0!");
+      }
+      calendar_filter_h merged_filter = nullptr;
+
+      if (type == CALENDAR_BOOK_TYPE_EVENT) {
+        error_code =
+            calendar_filter_create(_calendar_event._uri, &merged_filter);
+        ErrorChecker(error_code);
+      } else {
+        error_code =
+            calendar_filter_create(_calendar_todo._uri, &merged_filter);
+        ErrorChecker(error_code);
+      }
+      CalendarFilterPtr merged_filter_ptr(merged_filter, CalendarFilterDeleter);
+      for (std::size_t i = 0; i < intermediate_filters.back().size(); ++i) {
+        error_code = calendar_filter_add_filter(
+            merged_filter, intermediate_filters.back().at(i).get());
+        ErrorChecker(error_code);
+        if (CompositeFilterType::kIntersection == calType) {
+          error_code = calendar_filter_add_operator(
+              merged_filter, CALENDAR_FILTER_OPERATOR_AND);
+          ErrorChecker(error_code);
+        } else if (CompositeFilterType::kUnion == calType) {
+          error_code = calendar_filter_add_operator(
+              merged_filter, CALENDAR_FILTER_OPERATOR_OR);
+          ErrorChecker(error_code);
+        } else {
+          throw InvalidValuesException("Invalid union type!");
+        }
+      }
+      intermediate_filters.pop_back();
+      intermediate_filters.back().push_back(std::move(merged_filter_ptr));
+    });
+
+    visitor.SetOnAttributeRangeFilter([&](const std::string& name,
+                                          const JsonValue& initial_value,
+                                          const JsonValue& end_value) {
+      unsigned int propertyId = 0;
+      if (name == "startDate" || name == "endDate" || name == "dueDate") {
+        propertyId = CalendarItem::GetPlatformProperty(type, name + "_time");
+
+      } else {
+        propertyId = CalendarItem::GetPlatformProperty(type, name);
+      }
+      calendar_filter_h calendar_filter = nullptr;
+      int error_code = 0;
+      if (type == CALENDAR_BOOK_TYPE_EVENT) {
+        error_code =
+            calendar_filter_create(_calendar_event._uri, &calendar_filter);
+        ErrorChecker(error_code);
+      } else {
+        error_code =
+            calendar_filter_create(_calendar_todo._uri, &calendar_filter);
+        ErrorChecker(error_code);
+      }
+      CalendarFilterPtr calendar_filter_ptr(calendar_filter,
+                                            CalendarFilterDeleter);
+
+      bool initial_value_exists = (!IsNull(initial_value));
+      bool end_value_exists = (!IsNull(end_value));
+      if (name == "id") {
+        int initial_value_date = 0;
+        int end_value_date = 0;
+
+        if (initial_value_exists)
+          initial_value_date =
+              common::stol(JsonCast<std::string>(initial_value));
+        if (end_value_exists)
+          end_value_date = common::stol(JsonCast<std::string>(end_value));
+
+        if (initial_value_exists && end_value_exists) {
+          calendar_filter_h sub_filter = NULL;
+
+          if (type == CALENDAR_BOOK_TYPE_EVENT) {
+            error_code =
+                calendar_filter_create(_calendar_event._uri, &sub_filter);
+            ErrorChecker(error_code);
+          } else {
+            error_code =
+                calendar_filter_create(_calendar_todo._uri, &sub_filter);
+            ErrorChecker(error_code);
+          }
+          CalendarFilterPtr sub_filter_ptr(sub_filter, CalendarFilterDeleter);
+
+          error_code = calendar_filter_add_int(
+              sub_filter, propertyId, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL,
+              initial_value_date);
+
+          error_code = calendar_filter_add_operator(
+              sub_filter, CALENDAR_FILTER_OPERATOR_AND);
+
+          error_code = calendar_filter_add_int(
+              sub_filter, propertyId, CALENDAR_MATCH_LESS_THAN_OR_EQUAL,
+              end_value_date);
+
+          error_code = calendar_filter_add_filter(calendar_filter, sub_filter);
+          ErrorChecker(error_code);
+        } else if (initial_value_exists) {
+          error_code = calendar_filter_add_int(
+              calendar_filter, propertyId, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL,
+              initial_value_date);
+          ErrorChecker(error_code);
+        } else if (end_value_exists) {
+          error_code = calendar_filter_add_int(
+              calendar_filter, propertyId, CALENDAR_MATCH_LESS_THAN_OR_EQUAL,
+              end_value_date);
+          ErrorChecker(error_code);
+        }
+      } else if (name == "startDate" || name == "dueDate" ||
+                 name == "endDate") {
+        Date initial_value_date;
+        Date end_value_date;
+
+        if (initial_value_exists)
+          initial_value_date = CalendarItem::DateFromJson(
+              JsonCast<picojson::object>(initial_value));
+        if (end_value_exists)
+          end_value_date =
+              CalendarItem::DateFromJson(JsonCast<picojson::object>(end_value));
+
+        if (initial_value_exists && end_value_exists) {
+          calendar_filter_h sub_filter = NULL;
+
+          if (type == CALENDAR_BOOK_TYPE_EVENT) {
+            error_code =
+                calendar_filter_create(_calendar_event._uri, &sub_filter);
+            ErrorChecker(error_code);
+          } else {
+            error_code =
+                calendar_filter_create(_calendar_todo._uri, &sub_filter);
+            ErrorChecker(error_code);
+          }
+          CalendarFilterPtr sub_filter_ptr(sub_filter, CalendarFilterDeleter);
+
+          error_code = calendar_filter_add_caltime(
+              sub_filter, propertyId, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL,
+              CalendarItem::DateToPlatform(initial_value_date, false));
+          ErrorChecker(error_code);
+
+          error_code = calendar_filter_add_operator(
+              sub_filter, CALENDAR_FILTER_OPERATOR_AND);
+          ErrorChecker(error_code);
+
+          error_code = calendar_filter_add_caltime(
+              sub_filter, propertyId, CALENDAR_MATCH_LESS_THAN_OR_EQUAL,
+              CalendarItem::DateToPlatform(end_value_date, false));
+          ErrorChecker(error_code);
+
+          error_code = calendar_filter_add_filter(calendar_filter, sub_filter);
+          ErrorChecker(error_code);
+        } else if (initial_value_exists) {
+          error_code = calendar_filter_add_caltime(
+              calendar_filter, propertyId, CALENDAR_MATCH_GREATER_THAN_OR_EQUAL,
+              CalendarItem::DateToPlatform(initial_value_date, false));
+          ErrorChecker(error_code);
+        } else if (end_value_exists) {
+          error_code = calendar_filter_add_caltime(
+              calendar_filter, propertyId, CALENDAR_MATCH_LESS_THAN_OR_EQUAL,
+              CalendarItem::DateToPlatform(end_value_date, false));
+          ErrorChecker(error_code);
+        }
+      } else {
+        std::string initial_value_str;
+        std::string end_value_str;
+
+        if (initial_value_exists) {
+          initial_value_str = JsonCast<std::string>(initial_value);
+        }
+
+        if (end_value_exists) {
+          end_value_str = JsonCast<std::string>(end_value);
+        }
+
+        if (initial_value_exists && end_value_exists) {
+          calendar_filter_h sub_filter = NULL;
+
+          if (type == CALENDAR_BOOK_TYPE_EVENT) {
+            error_code =
+                calendar_filter_create(_calendar_event._uri, &sub_filter);
+            ErrorChecker(error_code);
+          } else {
+            error_code =
+                calendar_filter_create(_calendar_todo._uri, &sub_filter);
+            ErrorChecker(error_code);
+          }
+          CalendarFilterPtr sub_filter_ptr(sub_filter, CalendarFilterDeleter);
+
+          error_code = calendar_filter_add_str(sub_filter, propertyId,
+                                               CALENDAR_MATCH_STARTSWITH,
+                                               initial_value_str.c_str());
+          ErrorChecker(error_code);
+          error_code = calendar_filter_add_operator(
+              sub_filter, CALENDAR_FILTER_OPERATOR_AND);
+          ErrorChecker(error_code);
+          error_code = calendar_filter_add_str(sub_filter, propertyId,
+                                               CALENDAR_MATCH_ENDSWITH,
+                                               end_value_str.c_str());
+          ErrorChecker(error_code);
+          error_code = calendar_filter_add_filter(calendar_filter, sub_filter);
+          ErrorChecker(error_code);
+        } else if (initial_value_exists) {
+          error_code = calendar_filter_add_str(calendar_filter, propertyId,
+                                               CALENDAR_MATCH_STARTSWITH,
+                                               initial_value_str.c_str());
+          ErrorChecker(error_code);
+        } else if (end_value_exists) {
+          error_code = calendar_filter_add_str(calendar_filter, propertyId,
+                                               CALENDAR_MATCH_ENDSWITH,
+                                               end_value_str.c_str());
+          ErrorChecker(error_code);
+        }
+      }
+      intermediate_filters[intermediate_filters.size() - 1].push_back(
+          std::move(calendar_filter_ptr));
+    });
+    visitor.Visit(FromJson<JsonObject>(args, "filter"));
+    if ((intermediate_filters.size() != 1) ||
+        (intermediate_filters[0].size() != 1)) {
+      LoggerE("Bad filter evaluation!");
+      throw UnknownException("Bad filter evaluation!");
+    }
+    error_code = calendar_query_set_filter(calendar_query,
+                                           intermediate_filters[0][0].get());
+    ErrorChecker(error_code);
+  }
+
+  if (!IsNull(args, "sortMode")) {
+    picojson::object sortModeObject =
+        FromJson<picojson::object>(args, "sortMode");
+    unsigned int propertyId = 0;
+    std::string attributeName =
+        FromJson<std::string>(sortModeObject, "attributeName");
+    std::string order = FromJson<std::string>(sortModeObject, "order");
+    if (attributeName == "startDate" || attributeName == "dueDate" ||
+        attributeName == "endDate")
+      propertyId =
+          CalendarItem::GetPlatformProperty(type, attributeName + "_time");
+    else
+      propertyId = CalendarItem::GetPlatformProperty(type, attributeName);
+    if (order.empty() || order == "ASC") {
+      error_code = calendar_query_set_sort(calendar_query, propertyId, true);
+      ErrorChecker(error_code);
+    } else if (order == "DESC") {
+      error_code = calendar_query_set_sort(calendar_query, propertyId, false);
+      ErrorChecker(error_code);
+    }
+  }
 
   CalendarQueryPtr calendar_query_ptr(calendar_query,
                                       CalendarRecord::QueryDeleter);
 
   calendar_list_h record_list = nullptr;
-  error_code = calendar_db_get_records_with_query(calendar_query, 0, 0,
-                                                  &record_list);
+  error_code =
+      calendar_db_get_records_with_query(calendar_query, 0, 0, &record_list);
   if (CALENDAR_ERROR_NONE != error_code) {
     throw UnknownException("calendar_db_get_records_with_query failed");
   }
@@ -452,7 +796,8 @@ void Calendar::RemoveBatch(const picojson::object& args,
   }
 }
 
-void Calendar::AddChangeListener(const picojson::object& args, picojson::object& out) {
+void Calendar::AddChangeListener(const picojson::object& args,
+                                 picojson::object& out) {
   LoggerD("enter");
 
   if (!CalendarManager::GetInstance().IsConnected()) {
@@ -503,7 +848,6 @@ void Calendar::RemoveChangeListener(const picojson::object& args,
     }
     listeners_registered_.erase(type);
   }
-
 }
 
 void Calendar::ChangeCallback(const char* view_uri, void*) {
@@ -539,9 +883,11 @@ void Calendar::ChangeCallback(const char* view_uri, void*) {
   picojson::value response = picojson::value(picojson::object());
   picojson::object& response_obj = response.get<picojson::object>();
   if (listeners_registered_.find("EVENT") != listeners_registered_.end())
-    response_obj.insert(std::make_pair("listenerId", listeners_registered_["EVENT"]));
+    response_obj.insert(
+        std::make_pair("listenerId", listeners_registered_["EVENT"]));
   else
-    response_obj.insert(std::make_pair("listenerId", listeners_registered_["TASK"]));
+    response_obj.insert(
+        std::make_pair("listenerId", listeners_registered_["TASK"]));
 
   picojson::array& added =
       response_obj.insert(std::make_pair("added", picojson::array()))
@@ -570,7 +916,8 @@ void Calendar::ChangeCallback(const char* view_uri, void*) {
 
       picojson::value removed_row = picojson::value(picojson::object());
       picojson::object& removed_obj = removed_row.get<picojson::object>();
-      removed_obj.insert(std::make_pair("id", picojson::value(std::to_string(id))));
+      removed_obj.insert(
+          std::make_pair("id", picojson::value(std::to_string(id))));
       removed_obj.insert(std::make_pair(
           "calendarId", picojson::value(std::to_string(calendar_id))));
 
@@ -590,9 +937,8 @@ void Calendar::ChangeCallback(const char* view_uri, void*) {
       } else {
         updated.push_back(record_obj);
       }
-    }
-    catch(PlatformException& ex) {
-        LoggerE("error occured");
+    } catch (PlatformException& ex) {
+      LoggerE("error occured");
     }
 
     calendar_list_next(list);
@@ -617,5 +963,10 @@ void Calendar::ChangeCallback(const char* view_uri, void*) {
   CalendarInstance::GetInstance().PostMessage(response.serialize().c_str());
 }
 
+void Calendar::ErrorChecker(int errorCode) {
+  if (errorCode != CALENDAR_ERROR_NONE)
+    throw UnknownException("exception occured");
+}
+
 }  // namespace calendar
 }  // namespace webapi
index 6b911e6af0c7397112c7036074faca6da795bb68..8191c826e1a6654f055074bbd4918a557d92fb12 100644 (file)
@@ -180,6 +180,7 @@ class Calendar {
   static std::map<std::string, std::string> listeners_registered_;
   static int current_db_version_;
   static void ChangeCallback(const char* view_uri, void* user_data);
+  void ErrorChecker(int errorCode);
 };
 
 }  // namespace calendar
index a2e9e91ef54de6ffb2a67343dffa8b3a6c640f2f..e4fddf1bf1ed0fdb049d84bf30804e2ab04029ea 100644 (file)
@@ -51,6 +51,9 @@ const PlatformPropertyMap CalendarItem::platform_property_map_ = {
     {"id", {
         {CALENDAR_BOOK_TYPE_EVENT, _calendar_event.id},
         {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.id}}},
+    {"id.uid", {
+        {CALENDAR_BOOK_TYPE_EVENT, _calendar_event.id},
+        {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.uid}}},
     {"calendar_id", {
         {CALENDAR_BOOK_TYPE_EVENT, _calendar_event.calendar_book_id},
         {CALENDAR_BOOK_TYPE_TODO, _calendar_todo.calendar_book_id}}},
index 42b71fd9fe88d9af3e2e285d3bf79e3ff6777319..a271af539c6b2796df85d44709d8d86dc3c1c9a0 100644 (file)
@@ -113,12 +113,14 @@ class CalendarItem : public CalendarRecord {
                       picojson::object* out_ptr);
 
   static std::string ExceptionsFromJson(const picojson::array& exceptions);
-
- private:
-  // from JSON to platform
   static Date DateFromJson(const  picojson::object& in);
   static Date DateFromJson(const  picojson::object& in,
                            const char* obj_name);
+   static calendar_time_s DateToPlatform(const Date& date, bool is_all_day);
+
+ private:
+  // from JSON to platform
+
   static void CategoriesFromJson(int type, calendar_record_h rec,
                                  const picojson::array& value);
   static void AttendeesFromJson(int type, calendar_record_h rec,
@@ -128,8 +130,6 @@ class CalendarItem : public CalendarRecord {
   static void RecurrenceRuleFromJson(calendar_record_h rec,
                                      const  picojson::object& rrule);
 
-  static calendar_time_s DateToPlatform(const Date& date, bool is_all_day);
-
   // from platform to JSON
   static picojson::value DateToJson(Date date);
   static picojson::array CategoriesToJson(int type, calendar_record_h rec);
index 284f06cb3cb6f94300f25d28359423cc6593b49d..97590727f64b1ff1681884efb0564bd8f9053522 100644 (file)
@@ -454,47 +454,7 @@ Calendar.prototype.find = function(successCallback, errorCallback, filter, sortM
       nullable: true
     }
   ]);
-  //TODO: Move sorting and filtering to native code
-  var C = {};
-  C.sort = function (arr, sortMode) {
-    var _getSortProperty = function (obj, props) {
-      for (var i = 0; i < props.length; ++i) {
-        if (!obj.hasOwnProperty(props[i])) {
-          return null;
-        }
-        obj = obj[props[i]];
-      }
-      return obj;
-    };
-
-    if (sortMode instanceof tizen.SortMode) {
-      var props = sortMode.attributeName.split('.');
-      arr.sort(function (a, b) {
-        var aValue = _getSortProperty(a, props);
-        var bValue = _getSortProperty(b, props);
-
-        if (sortMode.order === 'DESC') {
-          return aValue < bValue;
-        }
-        return bValue < aValue;
-      });
-    }
-    return arr;
-  };
-
-  C.filter = function (arr, filter) {
-    if (type_.isNullOrUndefined(arr))
-      return arr;
-    if (filter instanceof tizen.AttributeFilter ||
-            filter instanceof tizen.AttributeRangeFilter ||
-            filter instanceof tizen.CompositeFilter) {
-      arr = arr.filter(function (element) {
-          return filter._filter(element);
-      });
-    }
-    return arr;
-  };
-
+  args.filter = C.repackFilter(args.filter);
   var calendarType = this.type;
 
   var callback = function(result) {
@@ -512,9 +472,6 @@ Calendar.prototype.find = function(successCallback, errorCallback, filter, sortM
         }
       });
       _edit.disallow();
-      //TODO: Move sorting and filtering to native code
-      c = C.filter(c, args.filter); // NYA: due to commit dependency
-      c = C.sort(c, args.sortMode);
       args.successCallback(c);
 
     }
@@ -522,7 +479,7 @@ Calendar.prototype.find = function(successCallback, errorCallback, filter, sortM
   native_.call('Calendar_find', {
     calendarId: this.id,
     filter: args.filter,
-    sortMode: args.sortMode
+    sortMode: args.sortMode || null
   }, callback);
 
 };
index b65781d04a92a63e07a2ef8443e6a74a5ba1b2f0..9892e8aed8ecddb5c1d5152d927146834133e7a8 100644 (file)
@@ -291,3 +291,43 @@ RecurrenceManager.prototype.get = function(event, startDate, endDate) {
 };
 
 var _recurrenceManager = new RecurrenceManager();
+
+//TODO: Can be moved to utils
+var Common = function() {};
+
+Common.prototype.repackFilter = function(filter) {
+  if (filter instanceof tizen.AttributeFilter) {
+    return {
+      filterType: 'AttributeFilter',
+      attributeName: filter.attributeName,
+      matchFlag: filter.matchFlag,
+      matchValue: _dateConverter.fromTZDate(filter.matchValue)
+    };
+  }
+  if (filter instanceof tizen.AttributeRangeFilter) {
+    return {
+      filterType: 'AttributeRangeFilter',
+      attributeName: filter.attributeName,
+      initialValue: _dateConverter.fromTZDate(filter.initialValue),
+      endValue: _dateConverter.fromTZDate(filter.endValue)
+    };
+  }
+  if (filter instanceof tizen.CompositeFilter) {
+    var _f = [];
+    var filters = filter.filters;
+
+    for (var i = 0; i < filters.length; ++i) {
+      _f.push(this.repackFilter(filters[i]));
+    }
+
+    return {
+      filterType: 'CompositeFilter',
+      type: filter.type,
+      filters: _f
+    };
+  }
+
+  return null;
+};
+
+var C = new Common();