Beta merge 2
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Calendar / CalendarFilter.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <dpl/log/log.h>
19 #include "CalendarFilter.h"
20 #include "CalendarQuery.h"
21 #include <calendar-svc-provider.h>
22 #include <map>
23 #include <sstream>
24 #include <time.h>
25
26 using namespace TizenApis::Api::Calendar;
27 using namespace WrtDeviceApis::Commons;
28
29 namespace TizenApis {
30 namespace Platform {
31 namespace Calendar {
32
33 // The selected fields for the generic filter support.
34 std::map<std::string, std::string> CalendarFilter::m_attributeMap = {
35     {CALENDAR_FILTER_ATTRIBUTE_ID_UID,                              CAL_VALUE_INT_INDEX},
36     {CALENDAR_FILTER_ATTRIBUTE_LAST_MODIFIED_DATE,              CAL_VALUE_GMT_LAST_MODIFIED_TIME},
37     {CALENDAR_FILTER_ATTRIBUTE_DESCRIPTION,                     CAL_VALUE_TXT_DESCRIPTION},
38     {CALENDAR_FILTER_ATTRIBUTE_SUMMARY,                         CAL_VALUE_TXT_SUMMARY},
39     {CALENDAR_FILTER_ATTRIBUTE_START_DATE,                       CAL_VALUE_GMT_START_DATE_TIME},
40     {CALENDAR_FILTER_ATTRIBUTE_LOCATION,                        CAL_VALUE_TXT_LOCATION},
41     {CALENDAR_FILTER_ATTRIBUTE_LATITUDE,                        CAL_VALUE_DBL_LATITUDE},
42     {CALENDAR_FILTER_ATTRIBUTE_LONGITUDE,                       CAL_VALUE_DBL_LONGITUDE},
43     {CALENDAR_FILTER_ATTRIBUTE_ORGANIZER,                       CAL_VALUE_TXT_ORGANIZER_NAME},
44     {CALENDAR_FILTER_ATTRIBUTE_VISIBILITY,                      CAL_VALUE_INT_SENSITIVITY},
45     {CALENDAR_FILTER_ATTRIBUTE_STATUS,                          CAL_VALUE_INT_TASK_STATUS},
46     //{"alarms",                          CAL_VALUE_INT_ALARMS_TICK}, // object interface
47     //{"alarmsType",                      CAL_VALUE_INT_ALARMS_TYPE}, // dependent on the alarm tick
48     {CALENDAR_FILTER_ATTRIBUTE_CATEGORIES,                      CAL_VALUE_LST_MEETING_CATEGORY}, // string array
49     {CALENDAR_FILTER_ATTRIBUTE_PRIORITY,                        CAL_VALUE_INT_PRIORITY},
50     {CALENDAR_FILTER_ATTRIBUTE_DUE_DATE,                        CAL_VALUE_GMT_END_DATE_TIME},
51     //{"completedDate",                   CAL_VALUE_GMT_COMPLETED_DATE_TIME}, // not yet supported in platform
52     //{"progress",                        CAL_VALUE_INT_PROGRESS}, // not yet supported in platform
53     //{"isDetached",                      CAL_VALUE_INT_PRIORITY}, // needs special manipulation
54     {CALENDAR_FILTER_ATTRIBUTE_IS_ALL_DAY,                      CAL_VALUE_INT_ALL_DAY_EVENT},
55     //{CALENDAR_FILTER_ATTRIBUTE_DURATION,                        CAL_VALUE_GMT_END_DATE_TIME}, // needs end date calculation
56     //{"attendees",                       CAL_VALUE_TXT_ATTENDEE_DETAIL_NAME}, // object array interface
57     {CALENDAR_FILTER_ATTRIBUTE_END_DATE,                       CAL_VALUE_GMT_END_DATE_TIME},
58     {CALENDAR_FILTER_ATTRIBUTE_AVAILABILITY,                    CAL_VALUE_INT_AVAILABILITY},
59     //{"recurrenceRule",                  CAL_VALUE_INT_REPEAT_TERM} // object interface
60 };
61
62 CalendarFilter::CalendarFilter()
63 {
64         LogDebug("entered");
65         m_query.clear();
66         m_query.append(" WHERE");
67 }
68
69 CalendarFilter::~CalendarFilter()
70 {
71 }
72
73 void CalendarFilter::visitPreComposite(TizenApis::Api::Tizen::FilterType& type, int depth)
74 {
75         LogDebug("entered");
76         m_query.append(" (");
77 }
78
79 void CalendarFilter::visitInComposite(TizenApis::Api::Tizen::FilterType& type, int depth)
80 {
81         LogDebug("entered");
82         if(type == TizenApis::Api::Tizen::UNION_FILTER)
83                 m_query.append(" OR ");
84         else if(type == TizenApis::Api::Tizen::INTERSECTION_FILTER)
85                 m_query.append(" AND ");
86 }
87
88 void CalendarFilter::visitPostComposite(TizenApis::Api::Tizen::FilterType& type, int depth)
89 {
90         LogDebug("entered");
91         m_query.append(" )");
92 }
93
94 void CalendarFilter::visitAttribute(std::string& attrName, TizenApis::Api::Tizen::MatchFlag& matchFlag, TizenApis::Api::Tizen::AnyArrayPtr& matchValues, int depth)
95 {
96         LogDebug("attrName: "<<attrName<<", value length: "<<matchValues->size()<<", matchFlag: "<<matchFlag<<", depth:"<<depth);
97
98         std::string conditionQuery;
99         std::string matchString;
100     std::string valueString;
101
102     conditionQuery.append("(");
103     TizenApis::Api::Tizen::AnyArray::iterator iter;
104     for(iter = matchValues->begin(); iter != matchValues->end(); iter++)
105     {
106         TizenApis::Api::Tizen::AnyPtr matchValue = *iter;
107         if(iter != matchValues->begin())
108             conditionQuery.append("OR");
109
110         if(matchValue->getType() == TizenApis::Api::Tizen::PrimitiveType_Time)
111         {
112             tm date = matchValue->getDateTm();
113             std::stringstream time;
114             time << mktime(&date);
115             valueString = time.str();
116         }
117         else
118         {
119             valueString = matchValue->toString();
120         }
121
122         if(attrName=="visibility" || attrName=="status" || attrName=="priority" || attrName=="availability") {
123             valueString = convertStringToValue(attrName, valueString);
124         }
125
126         if( matchFlag==TizenApis::Api::Tizen::MATCH_EXACTLY ) {
127             matchString = " like \'" + valueString + "\'";
128         } else if( matchFlag==TizenApis::Api::Tizen::MATCH_CONTAINS) {
129             matchString = " like \'%" + valueString + "%\'";
130         } else if( matchFlag==TizenApis::Api::Tizen::MATCH_STARTSWITH) {
131             matchString = " like \'%" + valueString + "\'";
132         } else if( matchFlag==TizenApis::Api::Tizen::MATCH_ENDSWITH) {
133             matchString = " like \'" + valueString + "%\'";
134         }else if( matchFlag==TizenApis::Api::Tizen::MATCH_EXISTS) {
135             matchString = " is not null";
136         } else {
137             LogError("Invalid matchFlag!");
138             matchString = " is not null";
139         }
140
141         // If the attrName is not directly mapped, branch here.
142         conditionQuery.append(" (" + m_attributeMap[attrName] + matchString + ") ");
143     }
144     conditionQuery.append(")");
145
146         LogInfo("Generated condition query: [" << conditionQuery << "]");
147
148         m_query.append(conditionQuery);
149 }
150
151 void CalendarFilter::visitAttributeRange(std::string& attrName, TizenApis::Api::Tizen::AnyPtr& initialValue, TizenApis::Api::Tizen::AnyPtr& endValue, int depth)
152 {
153     LogDebug("attrName: " <<attrName<<", initialValue: "<<initialValue->toString()<<", endValue: " <<endValue->toString()<<", depth: "<<depth);
154         std::string conditionQuery;
155     std::string initialValueStr;
156     std::string endValueStr;
157
158         if (initialValue != NULL) {
159         if( TizenApis::Api::Tizen::PrimitiveType_Time==initialValue->getType() ) {
160             tm date = initialValue->getDateTm();
161             std::stringstream time;
162             time << mktime(&date);
163             initialValueStr = time.str();
164         } else {
165             initialValueStr = initialValue->toString();
166         }
167         }
168
169         if (endValue != NULL) {
170         if( TizenApis::Api::Tizen::PrimitiveType_Time==endValue->getType() ) {
171             tm date = endValue->getDateTm();
172             std::stringstream time;
173             time << mktime(&date);
174             endValueStr = time.str();
175         } else {
176             endValueStr = endValue->toString();
177         }
178     }
179
180     if (initialValue!=NULL && endValue==NULL ) {
181         conditionQuery = " " + m_attributeMap[attrName] + ">" + initialValueStr + " ";
182     } else if (initialValue==NULL && endValue!=NULL ) {
183         conditionQuery = " " + m_attributeMap[attrName] + "<" + endValueStr + " ";
184     } else if (initialValue!=NULL && endValue!=NULL ) {
185         conditionQuery = " " + m_attributeMap[attrName] + ">" + initialValueStr + " AND " + m_attributeMap[attrName] + "<" + endValueStr + " ";
186     }
187
188         m_query.append(conditionQuery);
189 }
190
191 std::string CalendarFilter::getResult() const
192 {
193         LogDebug("entered");
194         return m_query;
195 }
196
197 bool CalendarFilter::convertToCalendar(calendar_query_s *queryData, CalendarEventListPtr calendarListPtr)
198 {
199     LogDebug("entered");
200
201     if (queryData == NULL)
202        return false;
203
204     CalendarEventPtr calendarEvent(new CalendarEvent());
205
206     // Convert query results to the event struct.
207     calendarEvent->setId(queryData->id);
208
209     calendarListPtr->push_back(calendarEvent);
210
211     return true;
212 }
213
214 bool CalendarFilter::executeQuery(std::string &query, CalendarEventListPtr calendarListPtr)
215 {    
216         LogDebug("entered");
217
218         calendar_query_s query_data;
219
220         stmt hstmt = NULL;
221         int ret = 0;
222
223         hstmt = _query_prepare((char *)(query.c_str()));
224     if( NULL==hstmt) {
225         ThrowMsg(PlatformException, "Can't prepare query!");
226     }
227
228         do {
229                 ret = _query_step(hstmt);
230                 LogDebug("Query result : [" << ret << "]");
231                 if (ret == SQLITE_ROW) { // 100
232                         query_data.id = _query_column_int(hstmt, 0);
233
234                         convertToCalendar(&query_data, calendarListPtr);
235                 } else if (ret == SQLITE_DONE) { // 101
236                         LogDebug("Query done [" << ret << "]");
237                         break;
238                 } else { //if (ret == SQLITE_DONE || ret == SQLITE_IOERR || ret == SQLITE_BUSY || ret == SQLITE_ERROR || ret == SQLITE_MISUSE)
239                         LogDebug("Query error [" << ret << "]");
240                         break;
241                 }
242         } while (1);
243
244         _query_finalize(hstmt);
245
246         return true;
247 }
248
249 std::string CalendarFilter::makeQuerySortMode(TizenApis::Api::Tizen::SortModeArrayPtr attr)
250 {    
251         LogDebug("entered");
252
253         std::string query("");
254         std::string attriName;
255         int cnt = 0;
256         TizenApis::Api::Tizen::SortModeArray::iterator it = attr->begin();
257
258         for (;it!=attr->end(); ++it) {
259                 attriName = (*it)->getAttributeName();
260                 if (attriName.compare("") != 0) { 
261                         if (cnt == 0) {
262                                 query.append(" ORDER BY ");
263                         } else {
264                                 query.append(", ");
265                         }
266                         query.append(attriName);
267
268                         if ((*it)->getOrder()==TizenApis::Api::Tizen::ASCENDING_SORT_ORDER) {
269                                 query.append(" ASC");
270                         } else {
271                                 query.append(" DESC");
272                         }
273                         cnt++;
274                 }
275         }
276
277         return query;
278 }
279
280 std::string CalendarFilter::convertStringToValue(const std::string attrName, const std::string valueString)
281 {
282         LogDebug("entered");
283
284     std::stringstream ss;
285
286     if(attrName=="visibility")
287     {
288         if(valueString=="PUBLIC") {
289             ss<<PUBLIC_VISIBILITY;
290             return ss.str();
291         } else if(valueString=="PRIVATE") {
292             ss<<PRIVATE_VISIBILITY;
293             return ss.str();
294         } else if(valueString=="CONFIDENTIAL") {
295             ss<<CONFIDENTIAL_VISIBILITY;
296             return ss.str();
297         } else {
298             return valueString;
299         }
300     }
301     else if(attrName=="status")
302     {
303         if(valueString=="TENTATIVE") {
304             ss<<CALS_EVENT_STATUS_TENTATIVE;
305             return ss.str();
306         } else if(valueString=="CONFIRMED") {
307             ss<<CALS_EVENT_STATUS_CONFIRMED;
308             return ss.str();
309         } else if(valueString=="CANCELLED") {
310             ss<<CALS_EVENT_STATUS_CANCELLED;
311             return ss.str();
312         } else if(valueString=="NEEDS_ACTION") {
313             ss<<CALS_TODO_STATUS_NEEDS_ACTION;
314             return ss.str();
315         } else if(valueString=="IN_PROCESS") {
316             ss<<CALS_TODO_STATUS_IN_PROCESS;
317
318         } else if(valueString=="COMPLETED") {
319             ss<<CALS_TODO_STATUS_COMPLETED;
320             return ss.str();
321         } else {
322             return valueString;
323         }
324     }
325     else if(attrName=="priority")
326     {
327         if(valueString=="HIGH") {
328             ss<<EVENT_PRIORITY_HIGH;
329             return ss.str();
330         } else if(valueString=="MEDIUM") {
331             ss<<EVENT_PRIORITY_NORMAL;
332             return ss.str();
333         } else if(valueString=="LOW") {
334             ss<<EVENT_PRIORITY_LOW;
335             return ss.str();
336         } else {
337             return valueString;
338         }
339     }
340     else if(attrName=="availability")
341     {
342         if(valueString=="BUSY") {
343             ss<<EVENT_BUSY_FB;
344             return ss.str();
345         } else if(valueString=="FREE") {
346             ss<<EVENT_FREE_FB;
347             return ss.str();
348         } else {
349             return valueString;
350         }
351     }
352     else
353     {
354         LogWarning("Invalid attrName");
355     }
356
357     return valueString;
358 }
359
360 std::string CalendarFilter::concatenateFilterAttributes()
361 {
362         LogDebug("entered");
363
364     std::string attributes;
365     std::map<std::string, std::string>::iterator iter;
366     unsigned int i = 0;
367     for( iter=m_attributeMap.begin(); iter!=m_attributeMap.end(); iter++) {
368         attributes.append((*iter).second);
369         if( i+1<m_attributeMap.size() ) {
370             attributes.append(", ");
371         }
372         i++;
373     }
374
375     return attributes;
376 }
377
378 }
379 }
380 }