Update change log and spec for wrt-plugins-tizen_0.2.84
[framework/web/wrt-plugins-tizen.git] / src / platform / Tizen / Contact / query-svc / query-svc.c
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  * @file                query-svc.h
19  * @author      JihwaPark (82-32-3016262, jh7979.park@samsung.com)
20  * @version      1.0(2011.10.05)
21  * @brief       This file has filter APIs for supporting advanced query
22  */
23
24 #include "query-service.h"
25 #include "query-type.h"
26 #include "query-utility.h"
27 #include <glib.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <dirent.h>
31 #include <contacts-svc.h>
32
33 typedef struct
34 {
35         int addressbook_id;
36         int account_id;
37 }addressbook_list;
38
39 GList* g_addressbook_list = NULL;
40 int total_addressbook_id = 0;
41
42 static int list_cb(CTSvalue *ab, void *user_data)
43 {
44         addressbook_list* list = NULL;
45
46         list = g_new0(addressbook_list, 1);
47         list->addressbook_id = contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_ID_INT);
48         list->account_id = contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_ACC_ID_INT);
49
50         g_addressbook_list = g_list_append(g_addressbook_list, list);
51         total_addressbook_id++;
52
53         return CTS_SUCCESS;
54 }
55
56 void __free_addressbook_list(gpointer data, gpointer user_data)
57 {
58         ADVANCED_SVC_TRACE("__free_address_list");
59         OBJ_FREE(data);
60 }
61
62 API void refresh_addressbook_list(void *data)
63 {
64         g_list_foreach(g_addressbook_list, __free_addressbook_list, NULL);
65         g_list_free(g_addressbook_list);
66         g_addressbook_list = NULL;
67
68         contacts_svc_list_foreach(CTS_LIST_ALL_ADDRESSBOOK, list_cb, NULL);
69 }
70
71 int _value_to_projection(stmt hstmt, char** projection, int count)
72 {
73         int pos = 0;
74
75         pos = count;
76
77         if((*projection) == NULL)
78                 *projection = (char*)g_strdup(_ct_query_column_text(hstmt, pos++));
79         else
80                 pos++;
81
82         return pos;
83 }
84
85 void __convert_number_type_to_str(int db_value, GString* type_str)
86 {
87         if((db_value & HOME) == HOME)
88                 g_string_append_printf (type_str, "%s", number_type_str[1]);
89
90         if((db_value & WORK) == WORK)
91         {
92                 if(type_str->str[0] == '\0')
93                         g_string_append_printf (type_str, "%s", number_type_str[2]);
94                 else
95                         g_string_append_printf(type_str, ",%s", number_type_str[2]);
96         }
97
98         if((db_value & VOICE) == VOICE)
99         {
100                 if(type_str->str[0] == '\0')
101                         g_string_append_printf (type_str, "%s", number_type_str[3]);
102                 else
103                         g_string_append_printf(type_str, ",%s", number_type_str[3]);
104         }
105
106         if((db_value & FAX) == FAX)
107         {
108                 if(type_str->str[0] == '\0')
109                         g_string_append_printf (type_str, "%s", number_type_str[4]);
110                 else
111                         g_string_append_printf(type_str, ",%s", number_type_str[4]);
112         }
113
114         if((db_value & MSG) == MSG)
115         {
116                 if(type_str->str[0] == '\0')
117                         g_string_append_printf (type_str, "%s", number_type_str[5]);
118                 else
119                         g_string_append_printf(type_str, ",%s", number_type_str[5]);
120         }
121
122         if((db_value & CELL) == CELL)
123         {
124                 if(type_str->str[0] == '\0')
125                         g_string_append_printf (type_str, "%s", number_type_str[6]);
126                 else
127                         g_string_append_printf(type_str, ",%s", number_type_str[6]);
128         }
129
130         if((db_value & PAGER) == PAGER)
131         {
132                 if(type_str->str[0] == '\0')
133                         g_string_append_printf (type_str, "%s", number_type_str[7]);
134                 else
135                         g_string_append_printf(type_str, ",%s", number_type_str[7]);
136         }
137
138         if((db_value & BBS) == BBS)
139         {
140                 if(type_str->str[0] == '\0')
141                         g_string_append_printf (type_str, "%s", number_type_str[8]);
142                 else
143                         g_string_append_printf(type_str, ",%s", number_type_str[8]);
144         }
145
146         if((db_value & MODEM) == MODEM)
147         {
148                 if(type_str->str[0] == '\0')
149                         g_string_append_printf (type_str, "%s", number_type_str[9]);
150                 else
151                         g_string_append_printf(type_str, ",%s", number_type_str[9]);
152         }
153
154         if((db_value & CAR) == CAR)
155         {
156                 if(type_str->str[0] == '\0')
157                         g_string_append_printf (type_str, "%s", number_type_str[10]);
158                 else
159                         g_string_append_printf(type_str, ",%s", number_type_str[10]);
160         }
161
162         if((db_value & ISDN) == ISDN)
163         {
164                 if(type_str->str[0] == '\0')
165                         g_string_append_printf (type_str, "%s", number_type_str[11]);
166                 else
167                         g_string_append_printf(type_str, ",%s", number_type_str[11]);
168         }
169
170         if((db_value & VIDEO) == VIDEO)
171         {
172                 if(type_str->str[0] == '\0')
173                         g_string_append_printf (type_str, "%s", number_type_str[12]);
174                 else
175                         g_string_append_printf(type_str, ",%s", number_type_str[12]);
176         }
177
178         if((db_value & PCS) == PCS)
179         {
180                 if(type_str->str[0] == '\0')
181                         g_string_append_printf (type_str, "%s", number_type_str[13]);
182                 else
183                         g_string_append_printf(type_str, ",%s", number_type_str[13]);
184         }
185
186         if(type_str->str[0] == '\0')
187                 g_string_append_printf (type_str, "%s", number_type_str[3]);
188
189 }
190
191 void __convert_email_type_to_str(int db_value, GString* type_str)
192 {
193         if((db_value & EMAIL_HOME) == EMAIL_HOME)
194         {
195                 if(type_str->str[0] == '\0')
196                         g_string_append_printf (type_str, "%s", email_type_str[1]);
197                 else
198                         g_string_append_printf (type_str, ",%s", email_type_str[1]);
199         }
200         if((db_value & EMAIL_WORK) == EMAIL_WORK)
201         {
202                 if(type_str->str[0] == '\0')
203                         g_string_append_printf (type_str, "%s", email_type_str[2]);
204                 else
205                         g_string_append_printf (type_str, ",%s", email_type_str[2]);
206         }
207
208         if(type_str->str[0] == '\0')
209                 g_string_append_printf (type_str, "%s", email_type_str[1]);
210 }
211
212 void __convert_url_type_to_str(int db_value, GString* type_str)
213 {
214         if(db_value == URL_HOME)
215         {
216                 if(type_str->str[0] == '\0')
217                         g_string_append_printf (type_str, "%s", url_type_str[URL_HOME]);
218                 else
219                         g_string_append_printf (type_str, ",%s", url_type_str[URL_HOME]);
220         }else if(db_value == URL_WORK)
221         {
222                 if(type_str->str[0] == '\0')
223                         g_string_append_printf (type_str, "%s", url_type_str[URL_WORK]);
224                 else
225                         g_string_append_printf (type_str, ",%s", url_type_str[URL_WORK]);
226         }
227
228         if(type_str->str[0] == '\0')
229                 g_string_append_printf (type_str, "%s", url_type_str[URL_HOME]);
230 }
231
232 void __convert_event_type_to_str(int db_value, GString* type_str)
233 {
234         if(db_value == 0)
235                 g_string_append_printf (type_str, "%s", event_type_str[EVENT_BIRTHDAY]);
236         else if(db_value == 1)
237                 g_string_append_printf (type_str, "%s", event_type_str[EVENT_ANNIVERSARY]);
238
239         if(type_str->str[0] == '\0')
240                 g_string_append_printf (type_str, "%s", event_type_str[EVENT_BIRTHDAY]);
241 }
242
243 void __convert_address_type_to_str(int db_value, GString* type_str)
244 {
245         if((db_value & ADDRESS_TYPE_HOME) == ADDRESS_TYPE_HOME)
246         {
247                 if(type_str->str[0] == '\0')
248                         g_string_append_printf (type_str, "%s", addr_type_str[1]);
249                 else
250                         g_string_append_printf (type_str, ",%s", addr_type_str[1]);
251         }
252         if((db_value & ADDRESS_TYPE_WORK) == ADDRESS_TYPE_WORK)
253         {
254                 if(type_str->str[0] == '\0')
255                         g_string_append_printf (type_str, "%s", addr_type_str[2]);
256                 else
257                         g_string_append_printf (type_str, ",%s", addr_type_str[2]);
258         }
259         if((db_value & ADDRESS_TYPE_DOM) == ADDRESS_TYPE_DOM)
260         {
261                 if(type_str->str[0] == '\0')
262                         g_string_append_printf (type_str, "%s", addr_type_str[3]);
263                 else
264                         g_string_append_printf (type_str, ",%s", addr_type_str[3]);
265         }
266         if((db_value & ADDRESS_TYPE_INTL) == ADDRESS_TYPE_INTL)
267         {
268                 if(type_str->str[0] == '\0')
269                         g_string_append_printf (type_str, "%s", addr_type_str[4]);
270                 else
271                         g_string_append_printf (type_str, ",%s", addr_type_str[4]);
272         }
273         if((db_value & ADDRESS_TYPE_POSTAL) == ADDRESS_TYPE_POSTAL)
274         {
275                 if(type_str->str[0] == '\0')
276                         g_string_append_printf (type_str, "%s", addr_type_str[5]);
277                 else
278                         g_string_append_printf (type_str, ",%s", addr_type_str[5]);
279         }
280         if((db_value & ADDRESS_TYPE_PARCEL) == ADDRESS_TYPE_PARCEL)
281         {
282                 if(type_str->str[0] == '\0')
283                         g_string_append_printf (type_str, "%s", addr_type_str[6]);
284                 else
285                         g_string_append_printf (type_str, ",%s", addr_type_str[6]);
286         }
287
288         if(type_str->str[0] == '\0')
289                 g_string_append_printf (type_str, "%s", addr_type_str[1]);
290 }
291
292 void __convert_x_info_to_str(int db_value, GString* type_str)
293 {
294         g_string_append_printf (type_str, "%d", db_value);
295 }
296
297 void __convert_bool_to_str(int db_value, GString* type_str)
298 {
299         if(db_value == 1)
300                 g_string_append_printf (type_str, "%s", bool_str[1]);
301         else
302                 g_string_append_printf (type_str, "%s", bool_str[0]);
303 }
304
305 int _int_value_to_projection(tables_e table, db_datatype datatype, stmt hstmt, char** projection, int count)
306 {
307         int pos = 0;
308         int db_value = 0;
309         GString* type_str = g_string_new ("");
310
311         pos = count;
312
313         if((*projection) == NULL)
314         {
315                 db_value = _ct_query_column_int(hstmt, pos++);
316                 if(table == DATA_TABLE)
317                 {
318                         switch(datatype)
319                         {
320                                 case DB_DATATYPE_NUMBER:
321                                         __convert_number_type_to_str(db_value, type_str);
322                                         break;
323                                 case DB_DATATYPE_EMAIL:
324                                         __convert_email_type_to_str(db_value, type_str);
325                                         break;
326                                 case DB_DATATYPE_URL:
327                                         __convert_url_type_to_str(db_value, type_str);
328                                         break;
329                                 case DB_DATATYPE_EVENT:
330                                         __convert_event_type_to_str(db_value, type_str);
331                                         break;
332                                 case DB_DATATYPE_ADDRESS:
333                                         __convert_address_type_to_str(db_value, type_str);
334                                         break;
335                                 default:
336                                         __convert_x_info_to_str(db_value, type_str);
337                                         break;
338                         }
339                 }else if(table == CONTACT_TABLE)
340                 {
341                         __convert_bool_to_str(db_value, type_str);
342                 }else if(table == PERSON_TABLE)
343                 {
344                         __convert_bool_to_str(db_value, type_str);
345                 }
346
347                 *projection = (char*)g_strdup(type_str->str);
348         }else
349                 pos++;
350
351         g_string_free(type_str, TRUE);
352
353         return pos;
354 }
355
356 int _event_value_to_projection(stmt hstmt, char** projection, int count)
357 {
358         int pos = 0;
359         int db_value = 0;
360         GString* type_str = g_string_new ("");
361
362         pos = count;
363
364         if((*projection) == NULL)
365         {
366                 db_value = _ct_query_column_int(hstmt, pos++);
367                 g_string_append_printf (type_str, "%d", db_value);
368
369                 *projection = (char*)g_strdup(type_str->str);
370         }else
371                 pos++;
372
373         g_string_free(type_str, TRUE);
374
375         return pos;
376 }
377
378 target_table_e _check_join_case(advanced_handle_t* q_handle)
379 {
380         ADVANCED_RETURN_VAL((q_handle->query_table  != INVALID_TABLE), {}, INVALID_TABLE_LIST, ("ERROR"));
381         target_table_e value = INVALID_TABLE_LIST;
382
383         if(strcmp(q_handle->table_list->str, table_key[TABLE_PERSON]) == 0)
384         {
385                 value = ONLY_PERSON;
386         }else if(strcmp(q_handle->table_list->str, table_key[TABLE_CONTACT]) == 0)
387         {
388                 value = ONLY_CONTACT;
389         }else if(strcmp(q_handle->table_list->str, table_key[TABLE_DATA]) == 0)
390         {
391                 if(q_handle->query_type == QUERY_TO_CONTACT)
392                         value = ONLY_DATA;
393                 else if(q_handle->query_type == QUERY_TO_PERSON)
394                         value = ONLY_DATA_FROM_PERSON_QUERY;
395         }
396
397         if(value != INVALID_TABLE_LIST)
398                 return value;
399
400         ADVANCED_SVC_TRACE("!! q_handle->query_table : %d", q_handle->query_table);
401
402         if(((q_handle->query_table & PERSON_TABLE) != 0) && ((q_handle->query_table & CONTACT_TABLE) == 0) && ((q_handle->query_table & DATA_TABLE) != 0))
403         {
404                 value = JOIN_PERSON_DATA;
405         }else if(((q_handle->query_table & PERSON_TABLE) == 0) && ((q_handle->query_table & CONTACT_TABLE) != 0) && ((q_handle->query_table & DATA_TABLE) != 0))
406         {
407                 value = JOIN_CONTACT_DATA;
408         }
409
410         ADVANCED_SVC_TRACE("value is %d", value);
411
412         return value;
413 }
414
415 query_error _make_contact_info(advanced_handle_t* q_handle, projection_type type, target_table_e join_table)
416 {
417         query_error error_code = QUERY_SUCCESS;
418         int contact_id = 0;
419         db_datatype datatype_id = DB_DATATYPE_INVALID;
420         int count = 0;
421         char projection[PROJECTION_FIELD_LEN + 1] = {0, };
422
423         number_t* num_info = NULL;
424         email_t* email_info = NULL;
425         url_t* url_info = NULL;
426         nick_name_t* nick_info = NULL;
427         address_t* address_info = NULL;
428         organization_t* organization_info = NULL;
429         event_info_t* event_info = NULL;
430         x_info_t* x_info = NULL;
431
432         if(type == ONLY_CONTACT_ID_FIELD)
433         {
434                 contact_id = _ct_query_column_int(q_handle->hstmt, count++);
435         }else
436         {
437                 if(join_table == ONLY_PERSON || join_table == ONLY_CONTACT)
438                 {
439                         contact_id = _ct_query_column_int(q_handle->hstmt, count++);
440                 }else
441                 {
442                         datatype_id = _ct_query_column_int(q_handle->hstmt, count++);
443                         contact_id = _ct_query_column_int(q_handle->hstmt, count++);
444                 }
445         }
446
447         if(q_handle->window_size > 0)
448         {
449                 if(q_handle->start_pos >= contact_id)
450                         return QUERY_SUCCESS;
451         }
452
453         if(q_handle->old_contact_id != contact_id)
454         {
455                 q_handle->pos++;
456                 q_handle->result_set[q_handle->pos].contact_info = g_new0(contact_t, 1);
457                 q_handle->result_set[q_handle->pos].contact_info->person_info = g_new0(person_contact_t, 1);
458                 q_handle->result_set[q_handle->pos].contact_info->raw_contact_info = g_new0(raw_contact_t, 1);
459
460                 if(join_table == ONLY_PERSON || join_table == JOIN_PERSON_DATA)
461                 {
462                         q_handle->result_set[q_handle->pos].contact_info->person_info->contact_id = g_new0(char, 64);
463                         snprintf(q_handle->result_set[q_handle->pos].contact_info->person_info->contact_id, 64, "%d", contact_id);
464                 }else
465                 {
466                         q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->contact_id = g_new0(char, 64);
467                         snprintf(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->contact_id, 64, "%d", contact_id);
468                 }
469
470                 q_handle->result_set[q_handle->pos].is_occupied = 1;
471                 q_handle->old_contact_id = contact_id;
472
473                 q_handle->mapping_id_to_result_set[q_handle->pos].contact_id = contact_id;
474                 q_handle->total_result_set_count++;
475         }
476
477         if((q_handle->window_size > 0) && (q_handle->total_result_set_count > q_handle->window_size))
478         {
479                 q_handle->total_result_set_count--;
480                 return QUERY_SET_LIMIT;
481         }
482
483         switch(datatype_id)
484         {
485                 case DB_DATATYPE_NAME :
486                 {
487                         ADVANCED_RETURN_VAL((q_handle->result_set[q_handle->pos].contact_info->name_info == NULL), {}, QUERY_FAIL, ("ONLY ONE NAME IS POSSIBLE"));
488                         q_handle->result_set[q_handle->pos].contact_info->name_info = g_new0(name_t, 1);
489                         ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->pos].contact_info->name_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
490                 }
491                         break;
492                 case DB_DATATYPE_NUMBER:
493                 {
494                         num_info = g_new0(number_t, 1);
495                         ADVANCED_CATCH_SET_ERROR((num_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
496                 }
497                         break;
498                 case DB_DATATYPE_EMAIL:
499                 {
500                         email_info = g_new0(email_t, 1);
501                         ADVANCED_CATCH_SET_ERROR((email_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
502                 }
503                         break;
504                 case DB_DATATYPE_URL:
505                 {
506                         url_info = g_new0(url_t, 1);
507                         ADVANCED_CATCH_SET_ERROR((url_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
508                 }
509                         break;
510                 case DB_DATATYPE_NICK_NAME:
511                 {
512                         nick_info = g_new0(nick_name_t, 1);
513                         ADVANCED_CATCH_SET_ERROR((nick_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
514                 }
515                         break;
516                 case DB_DATATYPE_ADDRESS:
517                 {
518                         address_info = g_new0(address_t, 1);
519                         ADVANCED_CATCH_SET_ERROR((address_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
520                 }
521                         break;
522                 case DB_DATATYPE_ORGANIZATION:
523                 {
524                         organization_info = g_new0(organization_t, 1);
525                         ADVANCED_CATCH_SET_ERROR((organization_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
526                 }
527                         break;
528                 case DB_DATATYPE_EVENT:
529                 {
530                         event_info = g_new0(event_info_t, 1);
531                         ADVANCED_CATCH_SET_ERROR((event_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
532                 }
533                         break;
534                 default:
535                 {
536                         if(datatype_id > DB_DATATYPE_MAX)
537                         {
538                                 x_info = g_new0(x_info_t, 1);
539                                 ADVANCED_CATCH_SET_ERROR((x_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
540                         }
541                 }
542                         break;
543         }
544
545         int old_count = 0;
546         GList* tmp_projection = q_handle->new_projection;
547         while(tmp_projection)
548         {
549                 projection_t* projection_info = (projection_t*)tmp_projection->data;
550                 memset(projection, 0x00, sizeof(projection));
551
552                 g_strlcpy(projection, projection_info->field, sizeof(projection) - 1);
553
554                 tmp_projection = g_list_next(tmp_projection);
555
556                 old_count = count;
557                 switch(datatype_id)
558                 {
559                         case DB_DATATYPE_NAME :
560                         {
561                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[NAME_FIRST] == 1)
562                                 {
563                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->first_name), count);
564                                 }else if(strcmp(field_key[FIELD_DATA4], projection) == 0 && q_handle->attribute_list[NAME_MIDDLE] == 1)
565                                 {
566                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->middle_name), count);
567                                 }else if(strcmp(field_key[FIELD_DATA3], projection) == 0 && q_handle->attribute_list[NAME_LAST] == 1)
568                                 {
569                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->last_name), count);
570                                 }else if(strcmp(field_key[FIELD_DATA6], projection) == 0 && q_handle->attribute_list[NAME_PREFIX] == 1)
571                                 {
572                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->prefix), count);
573                                 }else if(strcmp(field_key[FIELD_DATA7], projection) == 0 && q_handle->attribute_list[NAME_PHONETIC] == 1)
574                                 {
575                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->phonetic_name), count);
576                                 }else if(strcmp(field_key[FIELD_DATA5], projection) == 0 && q_handle->attribute_list[NAME_DISPLAY] == 1)
577                                 {
578                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->name_info->display_name), count);
579                                 }
580
581                         }
582                                 break;
583                         case DB_DATATYPE_NUMBER:
584                         {
585                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[NUMBER_ADDRESS] == 1)
586                                 {
587                                         count = _value_to_projection(q_handle->hstmt, &(num_info->number), count);
588                                 }else if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->attribute_list[NUMBER_TYPES] == 1)
589                                 {
590                                         count = _int_value_to_projection(DATA_TABLE, DB_DATATYPE_NUMBER, q_handle->hstmt, &(num_info->number_type), count);
591                                 }else if(strcmp(field_key[FIELD_DATA_ID], projection) == 0 && q_handle->attribute_list[NUMBER_TYPES] == 1)
592                                 {
593                                         count = _value_to_projection(q_handle->hstmt, &(num_info->number_id), count);
594                                 }
595                         }
596                                 break;
597                         case DB_DATATYPE_EMAIL:
598                         {
599                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[EMAIL_ADDRESS] == 1)
600                                 {
601                                         count = _value_to_projection(q_handle->hstmt, &(email_info->email_addr), count);
602                                 }else if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->attribute_list[EMAIL_TYPES] == 1)
603                                 {
604                                         count = _int_value_to_projection(DATA_TABLE, DB_DATATYPE_EMAIL, q_handle->hstmt, &(email_info->email_type), count);
605                                 }else if(strcmp(field_key[FIELD_DATA_ID], projection) == 0 && q_handle->attribute_list[EMAIL_TYPES] == 1)
606                                 {
607                                         count = _value_to_projection(q_handle->hstmt, &(email_info->email_id), count);
608                                 }
609
610                         }
611                                 break;
612                         case DB_DATATYPE_URL:
613                         {
614                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[URL_ADDRESS] == 1)
615                                 {
616                                         count = _value_to_projection(q_handle->hstmt, &(url_info->url_addr), count);
617                                 }else if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->attribute_list[URL_TYPE] == 1)
618                                 {
619                                         count = _int_value_to_projection(DATA_TABLE, DB_DATATYPE_URL, q_handle->hstmt, &(url_info->url_type), count);
620                                 }
621                         }
622                                 break;
623                         case DB_DATATYPE_NICK_NAME:
624                         {
625                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[NICKNAME_NAME] == 1)
626                                 {
627                                         count = _value_to_projection(q_handle->hstmt, &(nick_info->nick_name), count);
628                                 }
629                         }
630                                 break;
631                         case DB_DATATYPE_ADDRESS:
632                         {
633                                 if(strcmp(field_key[FIELD_DATA8], projection) == 0 && q_handle->attribute_list[ADDRESS_COUNTRY] == 1)
634                                 {
635                                         count = _value_to_projection(q_handle->hstmt, &(address_info->country), count);
636                                 }else if(strcmp(field_key[FIELD_DATA4], projection) == 0 && q_handle->attribute_list[ADDRESS_REGION] == 1)
637                                 {
638                                         count = _value_to_projection(q_handle->hstmt, &(address_info->region), count);
639                                 }else if(strcmp(field_key[FIELD_DATA5], projection) == 0 && q_handle->attribute_list[ADDRESS_CITY] == 1)
640                                 {
641                                         count = _value_to_projection(q_handle->hstmt, &(address_info->city), count);
642                                 }else if(strcmp(field_key[FIELD_DATA6], projection) == 0 && q_handle->attribute_list[ADDRESS_STREET] == 1)
643                                 {
644                                         count = _value_to_projection(q_handle->hstmt, &(address_info->street), count);
645                                 }else if(strcmp(field_key[FIELD_DATA3], projection) == 0 && q_handle->attribute_list[ADDRESS_POSTAL_CODE] == 1)
646                                 {
647                                         count = _value_to_projection(q_handle->hstmt, &(address_info->postal_code), count);
648                                 }else if(strcmp(field_key[FIELD_DATA7], projection) == 0 && q_handle->attribute_list[ADDRESS_ADDITIONAL] == 1)
649                                 {
650                                         count = _value_to_projection(q_handle->hstmt, &(address_info->addtional), count);
651                                 }else if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->attribute_list[ADDRESS_TYPES] == 1)
652                                 {
653                                         count = _int_value_to_projection(DATA_TABLE, DB_DATATYPE_ADDRESS, q_handle->hstmt, &(address_info->type), count);
654                                 }
655                         }
656                                 break;
657                         case DB_DATATYPE_ORGANIZATION:
658                         {
659                                 if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[ORGANIZATION_NAME] == 1)
660                                 {
661                                         count = _value_to_projection(q_handle->hstmt, &(organization_info->organization_name), count);
662                                 }else if(strcmp(field_key[FIELD_DATA3], projection) == 0 && q_handle->attribute_list[ORGANIZATION_DEPARTMENT] == 1)
663                                 {
664                                         count = _value_to_projection(q_handle->hstmt, &(organization_info->department), count);
665                                 }else if(strcmp(field_key[FIELD_DATA4], projection) == 0 && q_handle->attribute_list[ORGANIZATION_TITLE] == 1)
666                                 {
667                                         count = _value_to_projection(q_handle->hstmt, &(organization_info->title), count);
668                                 }else if(strcmp(field_key[FIELD_DATA5], projection) == 0 && q_handle->attribute_list[ORGANIZATION_ROLE] == 1)
669                                 {
670                                         count = _value_to_projection(q_handle->hstmt, &(organization_info->role), count);
671                                 }
672                         }
673                                 break;
674                         case DB_DATATYPE_EVENT:
675                         {
676                                 if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->attribute_list[EVENT_TYPE] == 1)
677                                 {
678                                         count = _int_value_to_projection(DATA_TABLE, DB_DATATYPE_EVENT, q_handle->hstmt, &(event_info->type), count);
679                                 }else if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->attribute_list[EVENT_DATE] == 1)
680                                 {
681                                         count = _event_value_to_projection(q_handle->hstmt, &(event_info->date), count);
682                                 }
683                         }
684                                 break;
685                         default:
686                         {
687                                 if(datatype_id > DB_DATATYPE_MAX)
688                                 {
689                                         if(strcmp(field_key[FIELD_DATA1], projection) == 0 && q_handle->x_attribute_list[X_DATA1] == 1)
690                                         {
691                                                 count = _int_value_to_projection(DATA_TABLE, datatype_id, q_handle->hstmt, &(x_info->data1), count);
692                                         }else if(strcmp(field_key[FIELD_DATA2], projection) == 0 && q_handle->x_attribute_list[X_DATA2] == 1)
693                                         {
694                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data2), count);
695                                         }else if(strcmp(field_key[FIELD_DATA3], projection) == 0 && q_handle->x_attribute_list[X_DATA3] == 1)
696                                         {
697                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data3), count);
698                                         }else if(strcmp(field_key[FIELD_DATA4], projection) == 0 && q_handle->x_attribute_list[X_DATA4] == 1)
699                                         {
700                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data4), count);
701                                         }else if(strcmp(field_key[FIELD_DATA5], projection) == 0 && q_handle->x_attribute_list[X_DATA5] == 1)
702                                         {
703                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data5), count);
704                                         }else if(strcmp(field_key[FIELD_DATA6], projection) == 0 && q_handle->x_attribute_list[X_DATA6] == 1)
705                                         {
706                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data6), count);
707                                         }else if(strcmp(field_key[FIELD_DATA7], projection) == 0 && q_handle->x_attribute_list[X_DATA7] == 1)
708                                         {
709                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data7), count);
710                                         }else if(strcmp(field_key[FIELD_DATA8], projection) == 0 && q_handle->x_attribute_list[X_DATA8] == 1)
711                                         {
712                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data8), count);
713                                         }else if(strcmp(field_key[FIELD_DATA9], projection) == 0 && q_handle->x_attribute_list[X_DATA9] == 1)
714                                         {
715                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data9), count);
716                                         }else if(strcmp(field_key[FIELD_DATA10], projection) == 0 && q_handle->x_attribute_list[X_DATA10] == 1)
717                                         {
718                                                 count = _value_to_projection(q_handle->hstmt, &(x_info->data10), count);
719                                         }
720                                 }
721                         }
722                                 break;
723                 }
724
725                 {
726                         if(join_table == ONLY_PERSON || join_table == JOIN_PERSON_DATA)
727                         {
728                                 if(strcmp(field_key[FIELD_PERSON_IS_SELF], projection) == 0)
729                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->is_self), count);
730                                 else if(strcmp(field_key[FIELD_CONTACT_ID_FOR_NAME], projection) == 0)
731                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->contact_id_for_name), count);
732                                 else if(strcmp(field_key[FIELD_CONTACT_ID_FOR_PHOTO], projection) == 0)
733                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->contact_id_for_photo), count);
734                                 else if(strcmp(field_key[FIELD_CONTACT_ID_FOR_RINGTONE], projection) == 0)
735                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->contactid_for_ringtone), count);
736                                 else if(strcmp(field_key[FIELD_PERSON_PREFIX_NAME], projection) == 0)
737                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->prefix), count);
738                                 else if(strcmp(field_key[FIELD_PERSON_FIRST_NAME], projection) == 0)
739                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->first_name), count);
740                                 else if(strcmp(field_key[FIELD_PERSON_MIDDLE_NAME], projection) == 0)
741                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->middle_name), count);
742                                 else if(strcmp(field_key[FIELD_PERSON_LAST_NAME], projection) == 0)
743                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->last_name), count);
744                                 else if(strcmp(field_key[FIELD_PERSON_PHONETIC_NAME], projection) == 0)
745                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->phonetic_name), count);
746                                 else if(strcmp(field_key[FIELD_PERSON_DISPLAY_NAME], projection) == 0)
747                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->display_name), count);
748                                 else if(strcmp(field_key[FIELD_PERSON_PHOTO_URI], projection) == 0)
749                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->photo_URI), count);
750                                 else if(strcmp(field_key[FIELD_PERSON_LAST_UPDATED_TIME], projection) == 0)
751                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->last_updated_timestamp), count);
752                                 else if(strcmp(field_key[FIELD_PERSON_IS_FAVORITE], projection) == 0)
753                                         count = _int_value_to_projection(PERSON_TABLE, DB_DATATYPE_INVALID, q_handle->hstmt,
754                                                                 &(q_handle->result_set[q_handle->pos].contact_info->person_info->is_favorite), count);
755                                 else if(strcmp(field_key[FIELD_PERSON_SEND_TO_VOICEMAIL], projection) == 0)
756                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->send_to_voicemail), count);
757                                 else if(strcmp(field_key[FIELD_PERSON_RINGTONE], projection) == 0)
758                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->person_info->ringtone), count);
759                         }else
760                         {
761                                 if(strcmp(field_key[FIELD_RINGTONE], projection) == 0)
762                                 {
763                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->ringtone), count);
764                                 }else if(strcmp(field_key[FIELD_NOTE], projection) == 0)
765                                 {
766                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->note), count);
767                                 }else if(strcmp(field_key[FIELD_IS_FAVORITE], projection) == 0)
768                                 {
769                                         count = _int_value_to_projection(CONTACT_TABLE, DB_DATATYPE_INVALID, q_handle->hstmt,
770                                                                 &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->is_favorite), count);
771                                 }else if(strcmp(field_key[FIELD_CONTACT_DEFAULT_NUM], projection) == 0)
772                                 {
773                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->default_num), count);
774                                 }else if(strcmp(field_key[FIELD_CONTACT_DEFAULT_EMAIL], projection) == 0)
775                                 {
776                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->default_email), count);
777                                 }else if(strcmp(field_key[FIELD_CHANGED_TIME], projection) == 0)
778                                 {
779                                         int changed_time = 0;
780                                         char tmp_string[64] = {0, };
781                                         changed_time = _ct_query_column_int(q_handle->hstmt, count++);
782                                         snprintf(tmp_string, 64, "%d", changed_time);
783                                         q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->last_updated_time_stamp = (char*)g_strdup(tmp_string);
784                                 }else if(strcmp(field_key[FIELD_CONTACT_ADDRESSBOOK_ID], projection) == 0)
785                                 {
786                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->addressbook_id), count);
787                                 }else if(strcmp(field_key[FIELD_UID], projection) == 0)
788                                 {
789                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->uid), count);
790                                 }else if(strcmp(field_key[FIELD_PHOTO_URI], projection) == 0)
791                                 {
792                                         count = _value_to_projection(q_handle->hstmt, &(q_handle->result_set[q_handle->pos].contact_info->raw_contact_info->photo_uri), count);
793                                 }
794                         }
795                 }
796                 if(count == old_count)
797                         count++;
798         }
799
800         switch(datatype_id)
801         {
802                 case DB_DATATYPE_NUMBER:
803                         q_handle->result_set[q_handle->pos].contact_info->number_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->number_list, num_info);
804                         break;
805                 case DB_DATATYPE_EMAIL:
806                         q_handle->result_set[q_handle->pos].contact_info->email_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->email_list, email_info);
807                         break;
808                 case DB_DATATYPE_URL:
809                         q_handle->result_set[q_handle->pos].contact_info->url_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->url_list, url_info);
810                         break;
811                 case DB_DATATYPE_NICK_NAME :
812                         q_handle->result_set[q_handle->pos].contact_info->nickname_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->nickname_list, nick_info);
813                         break;
814                 case DB_DATATYPE_ADDRESS :
815                         q_handle->result_set[q_handle->pos].contact_info->address_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->address_list, address_info);
816                         break;
817                 case DB_DATATYPE_ORGANIZATION :
818                         q_handle->result_set[q_handle->pos].contact_info->organization_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->organization_list, organization_info);
819                         break;
820                 case DB_DATATYPE_EVENT :
821                         q_handle->result_set[q_handle->pos].contact_info->event_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->event_list, event_info);
822                         break;
823                 default:
824                 {
825                         if(datatype_id > DB_DATATYPE_MAX)
826                         {
827                                 x_info->datatype_id = datatype_id;
828                                 ADVANCED_SVC_TRACE("x_info->datatype_id : %d", x_info->datatype_id);
829                                 q_handle->result_set[q_handle->pos].contact_info->x_list = g_list_append(q_handle->result_set[q_handle->pos].contact_info->x_list, x_info);
830                         }
831                 }
832                         break;
833         }
834 CATCH:
835         return error_code;
836 }
837
838 query_error _post_process_contact_info(advanced_handle_t* q_handle, projection_type type, target_table_e join_table)
839 {
840         query_error error_code = QUERY_SUCCESS;
841
842         if(join_table != ONLY_PERSON && join_table != JOIN_PERSON_DATA)
843         {
844                 contact_t* contact_info = q_handle->result_set[q_handle->pos].contact_info;
845                 if(contact_info == NULL)
846                         return error_code;
847
848                 raw_contact_t* raw_contact_info = contact_info->raw_contact_info;
849                 if(raw_contact_info == NULL)
850                         return error_code;
851
852                 if(raw_contact_info->default_email)
853                 {
854                         GList* email_list = contact_info->email_list;
855                         while(email_list)
856                         {
857                                 email_t* email_info = (email_t*)email_list->data;
858
859                                 if(email_info->email_id != NULL &&
860                                                 strcmp(raw_contact_info->default_email, email_info->email_id) == 0)
861                                 {
862                                         GString* type_str = g_string_new ("");
863                                         g_string_append_printf(type_str, "%s", "PREF");
864                                         char *old_type_str = email_info->email_type;
865                                         if(old_type_str != NULL && old_type_str[0] != '\0')
866                                         {
867                                                 g_string_append_printf(type_str, ",%s", old_type_str);
868                                         }
869
870                                         OBJ_FREE(old_type_str);
871
872                                         email_info->email_type = (char*)g_strdup(type_str->str);
873
874                                         g_string_free(type_str, TRUE);
875                                 }
876
877                                 email_list = g_list_next(email_list);
878                         }
879                 }
880
881                 if(raw_contact_info->default_num)
882                 {
883                         GList* number_list = contact_info->number_list;
884                         while(number_list)
885                         {
886                                 number_t* number_info = (number_t*)number_list->data;
887
888                                 if(number_info->number_id != NULL &&
889                                                 strcmp(raw_contact_info->default_num, number_info->number_id) == 0)
890                                 {
891                                         GString* type_str = g_string_new ("");
892                                         g_string_append_printf(type_str, "%s", "PREF");
893                                         char *old_type_str = number_info->number_type;
894                                         if(old_type_str != NULL && old_type_str[0] != '\0')
895                                         {
896                                                 g_string_append_printf(type_str, ",%s", old_type_str);
897                                         }
898
899                                         OBJ_FREE(old_type_str);
900
901                                         number_info->number_type = (char*)g_strdup(type_str->str);
902
903                                         g_string_free(type_str, TRUE);
904
905                                         break;
906                                 }
907
908                                 number_list = g_list_next(number_list);
909                         }
910                 }
911         }
912
913         return error_code;
914 }
915
916 API ADVANCED_HANDLE query_init(query_error* error_code, query_type_e query_type)
917 {
918         ADVANCED_RETURN_VAL((query_type >= QUERY_TO_PERSON), {}, NULL, ("INVALID QUERY TYPE"));
919
920         advanced_handle_t* handle = NULL;
921         handle = g_new0(advanced_handle_t, 1);
922         ADVANCED_CATCH_SET_ERROR_POINTER((handle != NULL), {}, QUERY_HANDLE_NONE, ("ALLOCATION FAIL"));
923
924         *error_code = _contact_db_init();
925         ADVANCED_CATCH_SET_ERROR_POINTER((*error_code == QUERY_SUCCESS), {}, QUERY_STATEMENT_FAIL, ("DATABASE INIT FAIL"));
926
927         handle->pos = -1;
928         handle->query_type = query_type;
929
930         handle->condition_text = g_string_new ("");
931         handle->table_list = g_string_new ("");
932         handle->order = g_string_new ("");
933         handle->use_normal_field_key = g_string_new ("");
934         handle->use_contact_table_id = g_string_new ("");
935         handle->optimize_condition = 1;
936         handle->id_list = g_string_new ("");
937
938         ADVANCED_SVC_TRACE("QUERY INIT SUCCESS");
939
940 CATCH:
941         if(*error_code != QUERY_SUCCESS)
942         {
943                 _free_handle_info(handle);
944                 handle = NULL;
945         }
946
947         return (ADVANCED_HANDLE)handle;
948 }
949
950 query_error _check_extra_contact_info(advanced_handle_t* q_handle, extra_info_type type, contact_attribute_e attribute)
951 {
952         query_error error_code = QUERY_FAIL;
953
954         if(type == EXTRA_INFO_TYPE_FIELD)
955         {
956                 if(attribute == CATEGORY_INFO)
957                 {
958                         q_handle->extra_info = q_handle->extra_info | CATEGORIES;
959                         error_code = QUERY_SUCCESS;
960                 }
961         }else if(type == EXTRA_INFO_TYPE_CONDITION)
962         {
963                 if(attribute == CATEGORY_INFO)
964                 {
965                         q_handle->condition_extra_info = q_handle->condition_extra_info | CATEGORIES;
966                         error_code = QUERY_SUCCESS;
967                 }
968         }
969
970         return error_code;
971 }
972
973 API query_error query_set_attribute(ADVANCED_HANDLE handle, contact_attribute_e attribute)
974 {
975         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
976         ADVANCED_RETURN_VAL((attribute < ATTRIBUTE_MAX), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID CONTACT ATTRIBUTE"));
977
978         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
979
980         char* column_name = NULL;
981         char* table_name = NULL;
982         query_error error_code = QUERY_SUCCESS;
983         char* loc = NULL;
984         projection_t* projection_info = NULL;
985
986         ADVANCED_SVC_TRACE("attribute : %d", attribute);
987         q_handle->attribute_list[attribute] = 1;
988
989         error_code = _check_extra_contact_info(q_handle, EXTRA_INFO_TYPE_FIELD, attribute);
990         if(error_code == QUERY_SUCCESS)
991                 attribute = CONTACT_ID;
992         error_code = QUERY_SUCCESS;
993
994         if(q_handle->query_type == QUERY_TO_PERSON)
995         {
996                 column_name = _convert_person_attribute_to_column_name(attribute);
997                 if(column_name != NULL)
998                         q_handle->person_field = attribute;
999         }
1000
1001         if(column_name == NULL)
1002                 column_name = _convert_attribute_to_column_name(attribute);
1003
1004         projection_info = g_new0(projection_t, 1);
1005         projection_info->field = g_strdup(column_name);
1006         q_handle->projection = g_list_append(q_handle->projection, projection_info);
1007
1008         if(attribute == NUMBER_TYPES)
1009         {
1010                 column_name = _convert_attribute_to_column_name(DATA_ID);
1011                 projection_info = g_new0(projection_t, 1);
1012                 projection_info->field = g_strdup(column_name);
1013                 q_handle->projection = g_list_append(q_handle->projection, projection_info);
1014
1015                 column_name = _convert_attribute_to_column_name(CONTACT_DEFAULT_NUM);
1016                 projection_info = g_new0(projection_t, 1);
1017                 projection_info->field = g_strdup(column_name);
1018                 q_handle->projection = g_list_append(q_handle->projection, projection_info);
1019         }
1020
1021         if(attribute == EMAIL_TYPES)
1022         {
1023                 column_name = _convert_attribute_to_column_name(DATA_ID);
1024                 projection_info = g_new0(projection_t, 1);
1025                 projection_info->field = g_strdup(column_name);
1026                 q_handle->projection = g_list_append(q_handle->projection, projection_info);
1027
1028                 column_name = _convert_attribute_to_column_name(CONTACT_DEFAULT_EMAIL);
1029                 projection_info = g_new0(projection_t, 1);
1030                 projection_info->field = g_strdup(column_name);
1031                 q_handle->projection = g_list_append(q_handle->projection, projection_info);
1032         }
1033
1034         if(q_handle->query_type == QUERY_TO_PERSON)
1035                 table_name = _convert_person_attribute_to_table_name(attribute);
1036
1037         if((attribute > CONTACT_LAST_UPDATED_TIME_STAMP) && (table_name == NULL))
1038         {
1039                 error_code = _set_datatype_list(q_handle, attribute);
1040                 ADVANCED_CATCH_SET_ERROR((error_code == QUERY_SUCCESS), {}, QUERY_FAIL, ("DATA_TYPE CONVERTING FAIL"));
1041         }
1042
1043         if(table_name == NULL)
1044                 table_name = _convert_attribute_to_table_name(attribute);
1045
1046         if(q_handle->table_list->str[0] != '\0')
1047         {
1048                 loc = strstr(q_handle->table_list->str, table_name);
1049                 if(loc == NULL)
1050                         g_string_append_printf(q_handle->table_list, ", %s", table_name);
1051         }
1052         else
1053         {
1054                 g_string_append_printf(q_handle->table_list, "%s", table_name);
1055         }
1056
1057         tables_e table_type = _contact_table_name_to_table_type(table_name);
1058         q_handle->query_table = q_handle->query_table | table_type;
1059
1060         ADVANCED_SVC_TRACE("table list : %s", q_handle->table_list->str);
1061
1062 CATCH:
1063         return error_code;
1064 }
1065
1066 query_error _construct_order_query(advanced_handle_t* q_handle, GString* query, target_table_e join_table)
1067 {
1068         predefine_datatype datatype = DATATYPE_INVALID;
1069         db_datatype db_datatype_id = DB_DATATYPE_NAME;
1070         query_error error_code = QUERY_SUCCESS;
1071
1072         datatype = _convert_attribute_to_mimetype_id(q_handle->order_field);
1073         db_datatype_id = _convert_datatype_to_db_type(datatype);
1074
1075         if(q_handle->query_type == QUERY_TO_CONTACT)
1076         {
1077                 switch(join_table)
1078                 {
1079                         case ONLY_CONTACT :
1080                         {
1081                                 g_string_printf (query, "select distinct(%s) from %s order by %s", field_key[FIELD_CONTACT_CONTACT_ID], table_key[TABLE_CONTACT], q_handle->order->str);
1082                         }
1083                                 break;
1084                         case ONLY_DATA :
1085                         case JOIN_CONTACT_DATA :
1086                         {
1087                                 if(db_datatype_id == DB_DATATYPE_INVALID)
1088                                 {
1089                                         g_string_printf (query, "select distinct(%s) from %s order by %s", field_key[FIELD_DATA_CONTACT_ID], table_key[TABLE_DATA], q_handle->order->str);
1090                                 }else
1091                                 {
1092                                         g_string_printf (query, "select distinct(%s) from %s where %s = %d order by %s",
1093                                                 field_key[FIELD_DATA_CONTACT_ID], table_key[TABLE_DATA], field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id, q_handle->order->str);
1094                                 }
1095                         }
1096                                 break;
1097                         default:
1098                                 break;
1099                 }
1100         }else
1101         {
1102                 switch(join_table)
1103                 {
1104                         case ONLY_PERSON :
1105                         {
1106                                 g_string_printf (query, "select distinct(%s) from %s order by %s", field_key[FIELD_PERSON_CONTACT_ID], table_key[TABLE_PERSON], q_handle->order->str);
1107                         }
1108                                 break;
1109                         case ONLY_DATA_FROM_PERSON_QUERY :
1110                         case JOIN_PERSON_DATA :
1111                         {
1112                                 if(db_datatype_id == DB_DATATYPE_INVALID)
1113                                 {
1114                                         g_string_printf (query, "select distinct(%s) from %s order by %s", field_key[FIELD_DATA_PERSON_ID], table_key[TABLE_DATA], q_handle->order->str);
1115                                 }else
1116                                 {
1117                                         g_string_printf (query, "select distinct(%s) from %s where %s = %d order by %s",
1118                                                 field_key[FIELD_DATA_PERSON_ID], table_key[TABLE_DATA], field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id, q_handle->order->str);
1119                                 }
1120                         }
1121                                 break;
1122                         default:
1123                                 break;
1124                 }
1125         }
1126         ADVANCED_CATCH_SET_ERROR(query->str[0] != '\0', {}, QUERY_INVALID_ATTRIBUTE, ("DO NOT SUPPORT CASE"));
1127
1128 CATCH:
1129         return error_code;
1130 }
1131
1132 int _make_order_list(advanced_handle_t* q_handle, int count, target_table_e join_table)
1133 {
1134         ADVANCED_RETURN_VAL((q_handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
1135         ADVANCED_RETURN_VAL((q_handle->order->str[0] != '\0'), {}, QUERY_NULL_PARAMETER, ("NO ORDER STRING"));
1136
1137         GString* query;
1138         int rc = -1;
1139         int order_pos = 0;
1140         int i = 0;
1141         int j = 0;
1142         query_error error_code = QUERY_SUCCESS;
1143
1144         ADVANCED_SVC_TRACE("q_handle->order : %s", q_handle->order->str);
1145         query = g_string_new ("");
1146
1147         if(q_handle->limit_iter == 1)
1148         {
1149                 q_handle->ordering_list = g_new0(ordering_list_t, q_handle->total_result_set_count);
1150                 ADVANCED_CATCH_SET_ERROR((q_handle->ordering_list != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1151
1152                 for(j=0; j<q_handle->total_count; j++)
1153                 {
1154                         if(order_pos >= q_handle->total_result_set_count)
1155                                 break;
1156
1157                         int high, low;
1158
1159                         high = q_handle->total_result_set_count;
1160                         low = 0;
1161
1162                         while(high >= low)
1163                         {
1164                                 i = ( low + high ) / 2;
1165
1166                                 if(q_handle->mapping_id_to_result_set[i].contact_id > q_handle->full_ordered_contact_id[j].contact_id)
1167                                         high = i - 1;
1168                                 else if(q_handle->mapping_id_to_result_set[i].contact_id < q_handle->full_ordered_contact_id[j].contact_id)
1169                                         low = i + 1;
1170                                 else if(q_handle->mapping_id_to_result_set[i].contact_id == q_handle->full_ordered_contact_id[j].contact_id)
1171                                 {
1172                                         q_handle->ordering_list[order_pos].ordered_pos = i;
1173                                         order_pos++;
1174                                         break;
1175                                 }
1176                         }
1177                 }
1178         }else
1179         {
1180                 error_code = _construct_order_query(q_handle, query, join_table);
1181                 ADVANCED_CATCH_SET_ERROR(error_code == QUERY_SUCCESS, {}, error_code, ("QUERY CONSTRUCTION FAIL"));
1182
1183                 q_handle->full_ordered_contact_id = g_new0(mapping_list_t, count);
1184                 ADVANCED_CATCH_SET_ERROR((q_handle->full_ordered_contact_id != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1185
1186                 q_handle->ordering_list = g_new0(ordering_list_t, q_handle->total_result_set_count);
1187                 ADVANCED_CATCH_SET_ERROR((q_handle->ordering_list != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1188
1189             q_handle->hstmt = _contact_query_prepare(query->str);
1190                 ADVANCED_CATCH_SET_ERROR((q_handle->hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
1191
1192                 rc = _contact_query_step(q_handle->hstmt);
1193                 ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_ORDERING_FAIL, ("No record in database"));
1194
1195                 while(rc == SQLITE_ROW)
1196                 {
1197                         if(q_handle->total_count >= count)
1198                                 break;
1199
1200                         q_handle->full_ordered_contact_id[q_handle->total_count].contact_id = _ct_query_column_int(q_handle->hstmt, 0);
1201                         rc = _contact_query_step(q_handle->hstmt);
1202                         q_handle->total_count++;
1203                 }
1204                 q_handle->total_count = count;
1205                 _ct_query_finalize(q_handle->hstmt);
1206
1207                 for(j=0; j<q_handle->total_count; j++)
1208                 {
1209                         if(order_pos >= q_handle->total_result_set_count)
1210                                 break;
1211
1212                         if(q_handle->full_ordered_contact_id[j].contact_id <= q_handle->mapping_id_to_result_set[q_handle->total_result_set_count - 1].contact_id)
1213                         {
1214                                 int high, low;
1215
1216                                 high = q_handle->total_result_set_count;
1217                                 low = 0;
1218
1219                                 while(high >= low)
1220                                 {
1221                                         i = ( low + high ) / 2;
1222
1223                                         if(q_handle->mapping_id_to_result_set[i].contact_id > q_handle->full_ordered_contact_id[j].contact_id)
1224                                                 high = i - 1;
1225                                         else if(q_handle->mapping_id_to_result_set[i].contact_id < q_handle->full_ordered_contact_id[j].contact_id)
1226                                                 low = i + 1;
1227                                         else if(q_handle->mapping_id_to_result_set[i].contact_id == q_handle->full_ordered_contact_id[j].contact_id)
1228                                         {
1229                                                 q_handle->ordering_list[order_pos].ordered_pos = i;
1230                                                 order_pos++;
1231                                                 break;
1232                                         }
1233                                 }
1234                         }
1235                 }
1236         }
1237         q_handle->return_array_pos = q_handle->ordering_list[0].ordered_pos;
1238         q_handle->pos = 0;
1239
1240 CATCH:
1241         g_string_free (query, TRUE);
1242         return error_code;
1243 }
1244
1245 query_error _make_contact_id_list_by_condition_part(advanced_handle_t* q_handle, int count, GString* sub_query)
1246 {
1247         ADVANCED_RETURN_VAL((q_handle->condition_text->str[0] != '\0'), {}, QUERY_SUCCESS, ("NO CONDITION PART"));
1248
1249         query_error error_code = QUERY_SUCCESS;
1250         alias_key_e alias = ALIAS_A;
1251         alias_key_e data_table_alias = ALIAS_INVALID;
1252         char* id_field = NULL;
1253         char* default_id_field = NULL;
1254         alias_key_e default_alias = ALIAS_INVALID;
1255
1256         GString* tmp_query;
1257         tmp_query = g_string_new("");
1258
1259         ADVANCED_SVC_TRACE("CHECK CONDITION PART !! ");
1260
1261         GList* tmp_table = q_handle->condition_table_list;
1262         while(tmp_table)
1263         {
1264                 condition_table_t* table_info = (condition_table_t*)tmp_table->data;
1265
1266                 if(strcmp(table_info->table, table_key[TABLE_PERSON]) == 0)
1267                         id_field = condition_field_key[FIELD_PERSON_CONTACT_ID];
1268                 else if(strcmp(table_info->table, table_key[TABLE_CONTACT]) == 0)
1269                         id_field = condition_field_key[FIELD_CONTACT_CONTACT_ID];
1270                 else if(strcmp(table_info->table, table_key[TABLE_DATA]) == 0)
1271                 {
1272                         if(q_handle->query_type == QUERY_TO_PERSON)
1273                                 id_field = condition_field_key[FIELD_DATA_PERSON_ID];
1274                         else
1275                                 id_field = condition_field_key[FIELD_DATA_CONTACT_ID];
1276
1277                         if(data_table_alias == ALIAS_INVALID)
1278                                 data_table_alias = table_info->alias;
1279                 }
1280
1281                 if(q_handle->optimize_condition == 1)
1282                 {
1283                         if(sub_query->str[0] == '\0')
1284                         {
1285                                 g_string_append_printf (sub_query, "select distinct(%s.%s) from %s %s",
1286                                         alias_key[table_info->alias], id_field, table_info->table, alias_key[table_info->alias]);
1287                                 default_id_field = id_field;
1288                                 default_alias = table_info->alias;
1289                         }
1290                 }else
1291                 {
1292                         if(sub_query->str[0] == '\0')
1293                         {
1294                                 g_string_append_printf (sub_query, "select distinct(%s.%s) from %s %s",
1295                                         alias_key[table_info->alias], id_field, table_info->table, alias_key[table_info->alias]);
1296                                 default_id_field = id_field;
1297                                 default_alias = table_info->alias;
1298                         }else
1299                                 g_string_append_printf (sub_query, ", %s %s", table_info->table, alias_key[table_info->alias]);
1300
1301                         if(alias != table_info->alias)
1302                                 g_string_append_printf (tmp_query, " (%s.%s = %s.%s) and",      alias_key[default_alias], default_id_field, alias_key[table_info->alias], id_field);
1303                 }
1304
1305                 alias = table_info->alias;
1306                 tmp_table = g_list_next(tmp_table);
1307         }
1308
1309         g_string_append_printf (sub_query, " where");
1310
1311         if(tmp_query->str[0] != '\0')
1312                 g_string_append_printf (sub_query, " %s", tmp_query->str);
1313
1314         if((q_handle->optimize_condition == 1) && (q_handle->condition_list && q_handle->current_alias > ALIAS_A))
1315         {
1316                 GList* tmp_condition = q_handle->condition_list;
1317                 int is_first = 1;
1318                 while(tmp_condition)
1319                 {
1320                         condition_list_t* condition_info = (condition_list_t*)tmp_condition->data;
1321
1322                         if(is_first)
1323                         {
1324                                 g_string_append_printf(sub_query, " (%s.id in (select id from %s where %s %s ? and %s = %d",
1325                                         alias_key[data_table_alias], table_key[TABLE_DATA], condition_info->column_name,
1326                                         condition_info->condition, condition_field_key[FIELD_DATA_DATATYPE_ID], condition_info->datatype);
1327                                 is_first = 0;
1328                         }else
1329                         {
1330                                 g_string_append_printf(sub_query, " union select id from %s where %s %s ? and %s = %d",
1331                                         table_key[TABLE_DATA], condition_info->column_name,
1332                                         condition_info->condition, condition_field_key[FIELD_DATA_DATATYPE_ID], condition_info->datatype);
1333                         }
1334
1335                         tmp_condition = g_list_next(tmp_condition);
1336                 }
1337                 g_string_append_printf(sub_query, " ))");
1338
1339         }else
1340                 g_string_append_printf (sub_query, " (%s)", q_handle->condition_text->str);
1341
1342         g_string_free (tmp_query, TRUE);
1343         return error_code;
1344 }
1345
1346 void _construct_query(target_table_e value, advanced_handle_t* q_handle, GString* query, char* condtion_sub_query, projection_type type)
1347 {
1348         GString* condition;
1349         GString* contact_condition;
1350         int is_first = 1;
1351         int use_sub_query = 1;
1352
1353         condition = g_string_new("");
1354         contact_condition = g_string_new("");
1355
1356         if(q_handle->condition_datatype == DATATYPE_INVALID && q_handle->condition_category == NULL)
1357                 use_sub_query = 0;
1358
1359         GList* tmp_datatype_list = q_handle->datatype_list;
1360         while(tmp_datatype_list)
1361         {
1362                 datatype_t* datatype_info = (datatype_t*)tmp_datatype_list->data;
1363
1364                 if(is_first)
1365                         g_string_append_printf(condition, "%s = %d", datatype_info->field, datatype_info->datatype);
1366                 else
1367                         g_string_append_printf(condition, " or %s = %d", datatype_info->field, datatype_info->datatype);
1368
1369                 tmp_datatype_list = g_list_next(tmp_datatype_list);
1370                 is_first = 0;
1371         }
1372
1373         switch(value)
1374         {
1375                 case ONLY_CONTACT:
1376                 {
1377                         g_string_append_printf(query, "select %s from %s", q_handle->query_string, table_key[TABLE_CONTACT]);
1378
1379                         if(strlen(condtion_sub_query) != 0)
1380                         {
1381                                 if(use_sub_query == 0)
1382                                 {
1383                                         g_string_append_printf(query, " where %s", q_handle->use_contact_table_id->str);
1384                                 }else
1385                                         g_string_append_printf(query, " where %s in (%s)", field_key[FIELD_CONTACT_CONTACT_ID], condtion_sub_query);
1386                         }
1387
1388                         if(q_handle->order->str[0] != '\0')
1389                                 g_string_append_printf(query, " order by %s", q_handle->order->str);
1390                         else
1391                                 g_string_append_printf(query, " order by %s", field_key[FIELD_CONTACT_CONTACT_ID]);
1392                 }
1393                         break;
1394                 case ONLY_PERSON:
1395                 {
1396                         g_string_append_printf(query, "select %s from %s", q_handle->query_string, table_key[TABLE_PERSON]);
1397
1398                         if(strlen(condtion_sub_query) != 0)
1399                                 g_string_append_printf(query, " where %s in (%s)", field_key[FIELD_PERSON_CONTACT_ID], condtion_sub_query);
1400
1401                         if(q_handle->order->str[0] != '\0')
1402                                 g_string_append_printf(query, " order by %s", q_handle->order->str);
1403                         else
1404                                 g_string_append_printf(query, " order by %s", field_key[FIELD_PERSON_CONTACT_ID]);
1405                 }
1406                         break;
1407                 case ONLY_DATA:
1408                 {
1409                         if(type == ONLY_CONTACT_ID_FIELD)
1410                                 g_string_append_printf(query, "select %s from %s", q_handle->query_string, table_key[TABLE_DATA]);
1411                         else
1412                                 g_string_append_printf(query, "select %s, %s from %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string, table_key[TABLE_DATA]);
1413
1414                         if(strlen(condtion_sub_query) != 0)
1415                         {
1416                                 if(use_sub_query == 0)
1417                                         g_string_append_printf(query, " where %s", q_handle->use_normal_field_key->str);
1418                                 else
1419                                         g_string_append_printf(query, " where %s in (%s) and (%s)", field_key[FIELD_DATA_CONTACT_ID], condtion_sub_query, condition->str);
1420                         }
1421                         else
1422                                 g_string_append_printf(query, " where (%s)", condition->str);
1423
1424                         g_string_append_printf(query, " order by %s", field_key[FIELD_DATA_CONTACT_ID]);
1425
1426                 }
1427                         break;
1428                 case ONLY_DATA_FROM_PERSON_QUERY:
1429                 {
1430                         if(type == ONLY_CONTACT_ID_FIELD)
1431                                 g_string_append_printf(query, "select %s from %s", q_handle->query_string, table_key[TABLE_DATA]);
1432                         else
1433                                 g_string_append_printf(query, "select %s, %s from %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string, table_key[TABLE_DATA]);
1434
1435                         if(strlen(condtion_sub_query) != 0)
1436                         {
1437                                 if(use_sub_query == 0)
1438                                         g_string_append_printf(query, " where %s = ?", field_key[FIELD_PERSON_CONTACT_ID]);
1439                                 else
1440                                         g_string_append_printf(query, " where %s in (%s)", field_key[FIELD_PERSON_CONTACT_ID], condtion_sub_query);
1441                         }
1442
1443                         if(strlen(condtion_sub_query) != 0)
1444                                 g_string_append_printf(query, " and (%s)", condition->str);
1445                         else
1446                                 g_string_append_printf(query, " where (%s)", condition->str);
1447
1448                         g_string_append_printf(query, " order by %s", field_key[FIELD_PERSON_CONTACT_ID]);
1449
1450                 }
1451                         break;
1452                 case JOIN_CONTACT_DATA:
1453                 {
1454                         g_string_append_printf(query, "select %s, %s from %s, %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string, table_key[TABLE_CONTACT], table_key[TABLE_DATA]);
1455                         g_string_append_printf(query, " where (%s = %s) and", field_key[FIELD_CONTACT_CONTACT_ID], field_key[FIELD_DATA_CONTACT_ID]);
1456
1457                         if(strlen(condtion_sub_query) != 0)
1458                         {
1459                                 if(use_sub_query == 0)
1460                                         g_string_append_printf(query, " %s and", q_handle->use_normal_field_key->str);
1461                                 else
1462                                         g_string_append_printf(query, " %s in (%s) and", field_key[FIELD_CONTACT_CONTACT_ID], condtion_sub_query);
1463                         }
1464                         g_string_append_printf(query, " (%s) order by %s", condition->str, field_key[FIELD_CONTACT_CONTACT_ID]);
1465
1466                 }
1467                         break;
1468                 case JOIN_PERSON_DATA:
1469                 {
1470                         g_string_append_printf(query, "select %s, %s from %s, %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string,  table_key[TABLE_PERSON], table_key[TABLE_DATA]);
1471                         g_string_append_printf(query, " where (%s = %s) and", field_key[FIELD_PERSON_CONTACT_ID], field_key[FIELD_DATA_PERSON_ID]);
1472
1473                         if(strlen(condtion_sub_query) != 0)
1474                         {
1475                                 if(use_sub_query == 0)
1476                                         g_string_append_printf(query, " %s = ? and", field_key[FIELD_PERSON_CONTACT_ID]);
1477                                 else
1478                                         g_string_append_printf(query, " %s in (%s) and", field_key[FIELD_PERSON_CONTACT_ID], condtion_sub_query);
1479                         }
1480                         g_string_append_printf(query, " (%s) order by %s", condition->str, field_key[FIELD_PERSON_CONTACT_ID]);
1481
1482                 }
1483                         break;
1484                 default:
1485                         break;
1486         }
1487
1488         g_string_free(condition, TRUE);
1489         g_string_free(contact_condition, TRUE);
1490 }
1491
1492 query_error _query_result_set(advanced_handle_t* q_handle, int rc, int count, projection_type type, target_table_e join_table)
1493 {
1494         query_error error_code = QUERY_SUCCESS;
1495
1496         ADVANCED_SVC_TRACE("_query_result_set");
1497
1498         q_handle->result_set = g_new0(result_t, count + 1);
1499         ADVANCED_CATCH_SET_ERROR((q_handle->result_set != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1500
1501         q_handle->mapping_id_to_result_set = g_new0(mapping_list_t, count + 1);
1502         while(rc == SQLITE_ROW)
1503         {
1504                 error_code = _make_contact_info(q_handle, type, join_table);
1505                 if(error_code == QUERY_SET_LIMIT)
1506                 {
1507                         error_code = QUERY_SUCCESS;
1508                         break;
1509                 }
1510                 ADVANCED_CATCH_SET_ERROR((error_code == QUERY_SUCCESS), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1511
1512                 rc = _contact_query_step(q_handle->hstmt);
1513         }
1514
1515         _ct_query_finalize(q_handle->hstmt);
1516
1517         _post_process_contact_info(q_handle, type, join_table);
1518
1519 CATCH:
1520         return error_code;
1521 }
1522
1523 int _make_result_contact_list(advanced_handle_t* q_handle, int count, char* condtion_sub_query)
1524 {
1525         ADVANCED_RETURN_VAL((q_handle->projection != NULL), {}, QUERY_NULL_PARAMETER, ("PROJECTION LIST IS NULL"));
1526
1527         int rc = -1;
1528         query_error error_code = QUERY_SUCCESS;
1529         GString* query;
1530         GString* projection;
1531         char* loc = NULL;
1532         projection_type type = NORMAL_CASE;
1533         target_table_e value = ONLY_CONTACT;
1534
1535         query = g_string_new("");
1536         projection = g_string_new("");
1537
1538         value = _check_join_case(q_handle);
1539         ADVANCED_SVC_TRACE("value : %d", value);
1540
1541         int table_contact = 0;
1542         int reorganize = 0;
1543         int data_field_count = 0;
1544
1545         if(q_handle->query_string == NULL)
1546         {
1547                 GList* tmp = q_handle->projection;
1548                 while(tmp)
1549                 {
1550                         projection_t* projection_info = (projection_t*)tmp->data;
1551
1552                         loc = strstr(projection_info->field, "contact.");
1553                         if(loc != NULL)
1554                                 table_contact = 1;
1555
1556                         loc = strstr(projection_info->field, "data.contact_id");
1557                         if(loc != NULL)
1558                                 reorganize = 1;
1559
1560                         loc = strstr(projection_info->field, "data.");
1561                         if(loc != NULL)
1562                                 data_field_count++;
1563
1564                         tmp = g_list_next(tmp);
1565                 }
1566
1567                 if(q_handle->query_type == QUERY_TO_PERSON)
1568                         g_string_append_printf(projection, "%s", field_key[FIELD_PERSON_CONTACT_ID]);
1569
1570                 if((table_contact == 1 && reorganize == 1 && data_field_count == 1) || (q_handle->assigned_datatype == 0))
1571                 {
1572                         g_string_append_printf(projection, "%s", field_key[FIELD_CONTACT_CONTACT_ID]);
1573                         value = ONLY_CONTACT;
1574                 }
1575
1576                 if(projection->str[0] == '\0')
1577                 {
1578                         g_string_append_printf(projection, "%s", field_key[FIELD_DATA_CONTACT_ID]);
1579                 }
1580
1581                 GList* tmp_projection = q_handle->projection;
1582                 int projection_duplicate = 0;
1583                 while(tmp_projection)
1584                 {
1585                         projection_t* projection_info = (projection_t*)tmp_projection->data;
1586
1587                         if(strcmp(projection_info->field, field_key[FIELD_CONTACT_CONTACT_ID]) == 0)
1588                                 projection_duplicate = 1;
1589
1590                         if(strcmp(projection_info->field, field_key[FIELD_DATA_CONTACT_ID]) == 0)
1591                                 projection_duplicate = 1;
1592
1593                         loc = strstr(projection->str, projection_info->field);
1594                         if(loc == NULL && projection_duplicate == 0)
1595                         {
1596                                 g_string_append_printf(projection, ", %s", projection_info->field);
1597
1598                                 projection_t* new_projection_info = NULL;
1599                                 new_projection_info = g_new0(projection_t, 1);
1600                                 ADVANCED_CATCH_SET_ERROR((new_projection_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1601
1602                                 new_projection_info->field = g_strdup(projection_info->field);
1603                                 q_handle->new_projection = g_list_append(q_handle->new_projection, new_projection_info);
1604                         }
1605
1606                         tmp_projection = g_list_next(tmp_projection);
1607                         projection_duplicate = 0;
1608                 }
1609                 g_list_foreach(q_handle->projection, _free_projection_list, NULL);
1610                 g_list_free(q_handle->projection);
1611
1612                 q_handle->query_string  = g_strdup(projection->str);
1613         }
1614         ADVANCED_SVC_TRACE("projection : %s", q_handle->query_string);
1615
1616         if((strcmp(q_handle->query_string, field_key[FIELD_DATA_CONTACT_ID]) == 0) || (strcmp(q_handle->query_string, field_key[FIELD_CONTACT_CONTACT_ID]) == 0))
1617                 type = ONLY_CONTACT_ID_FIELD;
1618
1619         _construct_query(value, q_handle, query, condtion_sub_query, type);
1620
1621     q_handle->hstmt = _contact_query_prepare(query->str);
1622         ADVANCED_CATCH_SET_ERROR((q_handle->hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
1623
1624         if(strlen(condtion_sub_query) != 0)
1625         {
1626                 int i = 1;
1627                 if(q_handle->condition_category != NULL)
1628                 {
1629                         ADVANCED_SVC_TRACE("q_handle->condition_category : %s", q_handle->condition_category);
1630                         _contact_query_bind_text(q_handle->hstmt, i, q_handle->condition_category);
1631                 }else
1632                 {
1633                         GList* tmp_condition_val = q_handle->condition_value;
1634                         while(tmp_condition_val)
1635                         {
1636                                 condition_val_t* tmp_val = (condition_val_t*)tmp_condition_val->data;
1637                                 if(tmp_val->indices_filter == 0)
1638                                 {
1639                                 ADVANCED_SVC_TRACE("condition_val->value : %s", tmp_val->value);
1640
1641                                 primitive_type type = _convert_check_attribute_primitive_type(tmp_val->attribute);
1642                                 if(tmp_val->x_attribute == 1)
1643                                         type = STRING;
1644
1645                                 if(type == INTEGER)
1646                                         _contact_query_bind_int(q_handle->hstmt, i++, tmp_val->int_value);
1647                                 else if(type == STRING)
1648                                         _contact_query_bind_text(q_handle->hstmt, i++, tmp_val->value);
1649                                 else if(type == REAL)
1650                                         _contact_query_bind_double(q_handle->hstmt, i++, tmp_val->real_value);
1651                                 }
1652                                 tmp_condition_val = g_list_next(tmp_condition_val);
1653                         }
1654                 }
1655         }
1656
1657         rc = _contact_query_step(q_handle->hstmt);
1658         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
1659
1660         error_code = _query_result_set(q_handle, rc, count, type, value);
1661
1662 CATCH:
1663         g_string_free(query, TRUE);
1664         g_string_free(projection, TRUE);
1665         return error_code;
1666 }
1667
1668 int _check_optimized_query(advanced_handle_t* q_handle, target_table_e join_table)
1669 {
1670         int is_optimized_query = 0;
1671
1672         if((q_handle->extra_info & CATEGORIES) == 0)
1673         {
1674                 switch(join_table)
1675                 {
1676                         case ONLY_DATA:
1677                         case ONLY_DATA_FROM_PERSON_QUERY:
1678                         {
1679                                 if(q_handle->all_datatype_in_query == DATATYPE_NAME)
1680                                         is_optimized_query = 1;
1681                         }
1682                                 break;
1683                         case ONLY_PERSON:
1684                                 is_optimized_query = 1;
1685                                 break;
1686                         default:
1687                                 break;
1688                 }
1689         }
1690         ADVANCED_SVC_TRACE("is_optimized_query : %d ", is_optimized_query);
1691
1692         return is_optimized_query;
1693 }
1694
1695 query_error _optimized_query_to_person_with_data(advanced_handle_t* q_handle, int count)
1696 {
1697         query_error error_code = QUERY_SUCCESS;
1698         int rc = -1;
1699
1700         GString* query;
1701         GString* projection;
1702         GString* condition;
1703
1704         projection = g_string_new("");
1705         query = g_string_new ("");
1706         condition = g_string_new ("");
1707
1708         if(q_handle->query_string == NULL)
1709         {
1710                 g_string_append_printf(projection, "%s", field_key[FIELD_DATA_DATATYPE_ID]);
1711                 g_string_append_printf(projection, ", %s", field_key[FIELD_DATA_PERSON_ID]);
1712
1713                 GList* tmp_projection = q_handle->projection;
1714                 while(tmp_projection)
1715                 {
1716                         projection_t* projection_info = (projection_t*)tmp_projection->data;
1717
1718                         if(strcmp(projection_info->field, field_key[FIELD_PERSON_CONTACT_ID]) != 0)
1719                         {
1720                                 g_string_append_printf(projection, ", %s", projection_info->field);
1721
1722                                 projection_t* new_projection_info = NULL;
1723                                 new_projection_info = g_new0(projection_t, 1);
1724                                 ADVANCED_CATCH_SET_ERROR((new_projection_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1725
1726                                 new_projection_info->field = g_strdup(projection_info->field);
1727                                 q_handle->new_projection = g_list_append(q_handle->new_projection, new_projection_info);
1728                         }
1729                         tmp_projection = g_list_next(tmp_projection);
1730                 }
1731                 g_list_foreach(q_handle->projection, _free_projection_list, NULL);
1732                 g_list_free(q_handle->projection);
1733
1734                 q_handle->query_string = g_strdup(projection->str);
1735         }
1736
1737         g_string_append_printf(query, "select %s from %s ", q_handle->query_string, table_key[TABLE_DATA]);
1738
1739         GList* tmp_datatype_list = q_handle->datatype_list;
1740         while(tmp_datatype_list)
1741         {
1742                 datatype_t* datatype_info = (datatype_t*)tmp_datatype_list->data;
1743                 g_string_append_printf(condition, "where (%s and %s = %d)", q_handle->use_normal_field_key->str, datatype_info->field, datatype_info->datatype);
1744                 tmp_datatype_list = g_list_next(tmp_datatype_list);
1745         }
1746
1747         if(q_handle->order->str[0] != '\0')
1748                 g_string_append_printf(query, " %s order by %s", condition->str, q_handle->order->str);
1749         else
1750         {
1751                 g_string_append_printf(query, " %s order by %s", condition->str, field_key[FIELD_DATA_PERSON_ID]);
1752         }
1753
1754     q_handle->hstmt = _contact_query_prepare(query->str);
1755         ADVANCED_CATCH_SET_ERROR((q_handle->hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
1756
1757         if(q_handle->use_normal_field_key->str[0] != '\0')
1758         {
1759                 GList* tmp_condition_val = q_handle->condition_value;
1760                 while(tmp_condition_val)
1761                 {
1762                         condition_val_t* tmp_val = (condition_val_t*)tmp_condition_val->data;
1763                         ADVANCED_SVC_TRACE("condition_val->value : %s", tmp_val->value);
1764
1765                         _contact_query_bind_text(q_handle->hstmt, 1, tmp_val->value);
1766                         tmp_condition_val = g_list_next(tmp_condition_val);
1767                 }
1768         }
1769
1770         rc = _contact_query_step(q_handle->hstmt);
1771         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
1772
1773         error_code = _query_result_set(q_handle, rc, count, NORMAL_CASE, JOIN_PERSON_DATA);
1774
1775 CATCH:
1776         g_string_free(query, TRUE);
1777         g_string_free(projection, TRUE);
1778         g_string_free(condition, TRUE);
1779
1780         if(error_code != QUERY_SUCCESS)
1781         {
1782                 _ct_query_finalize(q_handle->hstmt);
1783         }
1784
1785         return error_code;
1786 }
1787
1788 query_error _optimized_query_join_person_data(advanced_handle_t* q_handle, int count)
1789 {
1790         int rc = -1;
1791         query_error error_code = QUERY_SUCCESS;
1792         GString* query;
1793         GString* projection;
1794         GString* condition;
1795
1796         char* loc = NULL;
1797         query = g_string_new("");
1798         projection = g_string_new("");
1799         condition = g_string_new("");
1800
1801         if(q_handle->query_string == NULL)
1802         {
1803                 g_string_append_printf(projection, "%s", field_key[FIELD_PERSON_CONTACT_ID]);
1804
1805                 GList* tmp_projection = q_handle->projection;
1806                 int projection_duplicate = 0;
1807                 while(tmp_projection)
1808                 {
1809                         projection_t* projection_info = (projection_t*)tmp_projection->data;
1810
1811                         loc = strstr(projection->str, projection_info->field);
1812                         if(loc == NULL)
1813                         {
1814                                 g_string_append_printf(projection, ", %s", projection_info->field);
1815
1816                                 projection_t* new_projection_info = NULL;
1817                                 new_projection_info = g_new0(projection_t, 1);
1818                                 ADVANCED_CATCH_SET_ERROR((new_projection_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
1819
1820                                 new_projection_info->field = g_strdup(projection_info->field);
1821                                 q_handle->new_projection = g_list_append(q_handle->new_projection, new_projection_info);
1822                         }
1823
1824                         tmp_projection = g_list_next(tmp_projection);
1825                         projection_duplicate = 0;
1826                 }
1827                 g_list_foreach(q_handle->projection, _free_projection_list, NULL);
1828                 g_list_free(q_handle->projection);
1829
1830                 q_handle->query_string  = g_strdup(projection->str);
1831         }
1832
1833         ADVANCED_SVC_TRACE("projection : %s", q_handle->query_string);
1834
1835         g_string_append_printf(query, "select %s, %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string);
1836         g_string_append_printf(query, " from %s", q_handle->table_list->str);
1837
1838         GList* tmp_datatype_list = q_handle->datatype_list;
1839         while(tmp_datatype_list)
1840         {
1841                 datatype_t* datatype_info = (datatype_t*)tmp_datatype_list->data;
1842                 g_string_append_printf(condition, "where (%s and %s = %d) and ", q_handle->use_normal_field_key->str, datatype_info->field, datatype_info->datatype);
1843                 tmp_datatype_list = g_list_next(tmp_datatype_list);
1844         }
1845
1846         g_string_append_printf(condition, " (%s = %s)", field_key[FIELD_PERSON_CONTACT_ID], field_key[FIELD_DATA_PERSON_ID]);
1847
1848         if(q_handle->order->str[0] != '\0')
1849                 g_string_append_printf(query, " %s order by %s", condition->str, q_handle->order->str);
1850         else
1851                 g_string_append_printf(query, " %s order by %s", condition->str, field_key[FIELD_PERSON_CONTACT_ID]);
1852
1853     q_handle->hstmt = _contact_query_prepare(query->str);
1854         ADVANCED_CATCH_SET_ERROR((q_handle->hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
1855
1856         if(strlen(q_handle->use_normal_field_key->str) != 0)
1857         {
1858                 GList* tmp_condition_val = q_handle->condition_value;
1859                 while(tmp_condition_val)
1860                 {
1861                         condition_val_t* tmp_val = (condition_val_t*)tmp_condition_val->data;
1862                         ADVANCED_SVC_TRACE("condition_val->value : %s", tmp_val->value);
1863
1864                         _contact_query_bind_text(q_handle->hstmt, 1, tmp_val->value);
1865                         tmp_condition_val = g_list_next(tmp_condition_val);
1866                 }
1867         }
1868
1869         rc = _contact_query_step(q_handle->hstmt);
1870         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
1871
1872         error_code = _query_result_set(q_handle, rc, count, NORMAL_CASE, JOIN_PERSON_DATA);
1873
1874 CATCH:
1875         g_string_free(query, TRUE);
1876         g_string_free(projection, TRUE);
1877         g_string_free(condition, TRUE);
1878
1879         if(error_code != QUERY_SUCCESS)
1880         {
1881                 _ct_query_finalize(q_handle->hstmt);
1882         }
1883
1884         return error_code;
1885 }
1886
1887 query_error _get_categories_list(advanced_handle_t* q_handle, int count, char* condition_query)
1888 {
1889         GString* query;
1890         stmt    hstmt;
1891         int rc = -1;
1892         int pos = 0;
1893         query_error error_code = QUERY_SUCCESS;
1894
1895         query = g_string_new ("");
1896
1897         g_string_append_printf(query, "select a.%s, a.%s, b.%s from %s a, %s b where (a.%s = b.%s)",
1898                 relation_field_key[FIELD_GROUP_RELATION_CONTACT_ID], relation_field_key[FIELD_GROUP_RELATION_GROUP_ID], group_field_key[FIELD_GROUP_NAME],
1899                 table_key[TABLE_GROUP_RELATION], table_key[TABLE_GROUP],
1900                 group_field_key[FIELD_GROUP_ID], relation_field_key[FIELD_GROUP_RELATION_GROUP_ID]);
1901
1902         if(strlen(condition_query) != 0)
1903                 g_string_append_printf(query, " and a.%s in (%s)", relation_field_key[FIELD_GROUP_RELATION_CONTACT_ID], condition_query);
1904
1905         g_string_append_printf(query, " order by a.%s", relation_field_key[FIELD_GROUP_RELATION_CONTACT_ID]);
1906
1907     hstmt = _contact_query_prepare(query->str);
1908         ADVANCED_CATCH_SET_ERROR((hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("Database prepare fail"));
1909
1910         if(q_handle->condition_category != NULL)
1911         {
1912                 _contact_query_bind_text(hstmt, 1, q_handle->condition_category);
1913         }else if(strlen(condition_query) != 0)
1914         {
1915                 GList* tmp_condition_val = q_handle->condition_value;
1916                 int i = 1;
1917                 while(tmp_condition_val)
1918                 {
1919                         condition_val_t* tmp_val = (condition_val_t*)tmp_condition_val->data;
1920
1921                         if(tmp_val->indices_filter == 0)
1922                         {
1923                         primitive_type type = _convert_check_attribute_primitive_type(tmp_val->attribute);
1924                         if(tmp_val->x_attribute == 1)
1925                                 type = STRING;
1926
1927                         if(type == INTEGER)
1928                                 _contact_query_bind_int(hstmt, i++, tmp_val->int_value);
1929                         else if(type == STRING)
1930                                 _contact_query_bind_text(hstmt, i++, tmp_val->value);
1931                         else if(type == REAL)
1932                                 _contact_query_bind_double(hstmt, i++, tmp_val->real_value);
1933                         }
1934                         tmp_condition_val = g_list_next(tmp_condition_val);
1935                 }
1936         }
1937         rc = _contact_query_step(hstmt);
1938         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
1939
1940         while(rc == SQLITE_ROW)
1941         {
1942                 if(pos > count)
1943                         break;
1944
1945                 q_handle->category[pos].contact_id = _ct_query_column_int(hstmt, 0);
1946                 q_handle->category[pos].group_id = _ct_query_column_int(hstmt, 1);
1947                 q_handle->category[pos].name = g_strdup(_ct_query_column_text(hstmt, 2));
1948
1949                 ADVANCED_SVC_TRACE("q_handle->category[%d].contact_id : %d", pos, q_handle->category[pos].contact_id);
1950
1951                 if(q_handle->category[pos].contact_id == q_handle->category[pos - 1].contact_id)
1952                         q_handle->category[pos].sibling = 1;
1953
1954                 pos++;
1955
1956                 rc = _contact_query_step(hstmt);
1957         }
1958         q_handle->category_total_count = pos;
1959         _ct_query_finalize(hstmt);
1960
1961 CATCH:
1962         g_string_free(query, TRUE);
1963         return error_code;
1964 }
1965
1966 query_error _construct_optimize_query(advanced_handle_t* q_handle, GString* query, target_table_e join_table, projection_type type, char* sub_query)
1967 {
1968         GString* condition;
1969         int is_first = 1;
1970         query_error error_code = QUERY_SUCCESS;
1971         condition = g_string_new ("");
1972         int is_sub_query = 0;
1973
1974         if(sub_query[0] != '\0')
1975                 is_sub_query = 1;
1976
1977         if(is_sub_query)
1978         {
1979                 switch(join_table)
1980                 {
1981                         case ONLY_DATA:
1982                                 g_string_append_printf(condition, " %s in (%s) and ", field_key[FIELD_DATA_CONTACT_ID], sub_query);
1983                                 break;
1984                         case ONLY_PERSON:
1985                         case ONLY_DATA_FROM_PERSON_QUERY:
1986                                 g_string_append_printf(condition, " %s in (%s) and ", field_key[FIELD_PERSON_CONTACT_ID], sub_query);
1987                                 break;
1988                         default:
1989                                 break;
1990                 }
1991         }
1992
1993         if(join_table == ONLY_DATA || join_table == ONLY_DATA_FROM_PERSON_QUERY)
1994         {
1995                 GList* tmp_datatype_list = q_handle->datatype_list;
1996                 is_first = 1;
1997                 while(tmp_datatype_list)
1998                 {
1999                         datatype_t* datatype_info = (datatype_t*)tmp_datatype_list->data;
2000                         if(is_first)
2001                         {
2002                                 if(q_handle->use_normal_field_key->str[0] != '\0' && is_sub_query == 0)
2003                                 {
2004                                         g_string_append_printf(condition, "%s and %s = %d", q_handle->use_normal_field_key->str, datatype_info->field, datatype_info->datatype);
2005                                 }else
2006                                         g_string_append_printf(condition, "%s = %d", datatype_info->field, datatype_info->datatype);
2007                         }else
2008                         {
2009                                 g_string_append_printf(condition, " or %s = %d", datatype_info->field, datatype_info->datatype);
2010                         }
2011
2012                         tmp_datatype_list = g_list_next(tmp_datatype_list);
2013                         is_first = 0;
2014                 }
2015         }
2016
2017         switch(join_table)
2018         {
2019                 case ONLY_DATA:
2020                 {
2021                         if(type == ONLY_CONTACT_ID_FIELD)
2022                                 g_string_append_printf(query, "select distinct(%s) from %s", q_handle->query_string, table_key[TABLE_DATA]);
2023                         else
2024                                 g_string_append_printf(query, "select %s, %s from %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string, table_key[TABLE_DATA]);
2025
2026                         if(condition->str[0] != '\0')
2027                                 g_string_append_printf(query, " where (%s)", condition->str);
2028
2029                         if(q_handle->order->str[0] != '\0')
2030                                 g_string_append_printf(query, " order by %s", q_handle->order->str);
2031                         else
2032                                 g_string_append_printf(query, " order by %s", field_key[FIELD_DATA_CONTACT_ID]);
2033                 }
2034                         break;
2035                 case ONLY_DATA_FROM_PERSON_QUERY:
2036                 {
2037                         if(type == ONLY_CONTACT_ID_FIELD)
2038                                 g_string_append_printf(query, "select distinct(%s) from %s", q_handle->query_string, table_key[TABLE_DATA]);
2039                         else
2040                                 g_string_append_printf(query, "select %s, %s from %s", field_key[FIELD_DATA_DATATYPE_ID], q_handle->query_string, table_key[TABLE_DATA]);
2041
2042                         if(condition->str[0] != '\0')
2043                                 g_string_append_printf(query, " where (%s)", condition->str);
2044
2045                         if(q_handle->order->str[0] != '\0')
2046                                 g_string_append_printf(query, " order by %s", q_handle->order->str);
2047                         else
2048                                 g_string_append_printf(query, " order by %s", field_key[FIELD_PERSON_CONTACT_ID]);
2049                 }
2050                         break;
2051                 case ONLY_PERSON:
2052                 {
2053                         g_string_append_printf(query, "select %s from %s", q_handle->query_string, table_key[TABLE_PERSON]);
2054
2055                         if(q_handle->use_normal_field_key->str[0] != '\0')
2056                                 g_string_append_printf(query, " where (%s)", q_handle->use_normal_field_key->str);
2057
2058                         if(q_handle->order->str[0] != '\0')
2059                                 g_string_append_printf(query, " order by %s", q_handle->order->str);
2060                         else
2061                                 g_string_append_printf(query, " order by %s", field_key[FIELD_PERSON_CONTACT_ID]);
2062                 }
2063                         break;
2064                 default:
2065                         break;
2066         }
2067
2068         g_string_free(condition, TRUE);
2069         return error_code;
2070 }
2071
2072 API query_error query_get_result_contact(ADVANCED_HANDLE handle)
2073 {
2074         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
2075
2076         int rc = -1;
2077         query_error error_code = QUERY_SUCCESS;
2078         GString* query;
2079         GString* projection;
2080         char* loc = NULL;
2081         int count = 0;
2082         projection_type type = NORMAL_CASE;
2083         int i = 1;
2084         int is_optimized_query = 0;
2085         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
2086
2087         if(q_handle->result_set)
2088         {
2089                 ADVANCED_SVC_TRACE("------------------------------ GET NEXT CONTACT INFO ------------------------------ ");
2090
2091                 if(q_handle->order->str[0] != '\0')
2092                 {
2093                         if(q_handle->is_optimized_query)
2094                         {
2095                                 q_handle->return_array_pos++;
2096                                 ADVANCED_CATCH_SET_ERROR((q_handle->return_array_pos < q_handle->total_result_set_count), {}, QUERY_NO_RECORD, ("no record"));
2097                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].is_occupied == 1), {}, QUERY_NO_RECORD, ("no record"));
2098                         }else
2099                         {
2100                                 q_handle->pos++;
2101                                 ADVANCED_CATCH_SET_ERROR((q_handle->pos < q_handle->total_result_set_count), {}, QUERY_NO_RECORD, ("no record"));
2102                                 q_handle->return_array_pos = q_handle->ordering_list[q_handle->pos].ordered_pos;
2103                         }
2104                 }else
2105                 {
2106                         q_handle->return_array_pos++;
2107                         ADVANCED_CATCH_SET_ERROR((q_handle->return_array_pos < q_handle->total_result_set_count), {}, QUERY_NO_RECORD, ("no record"));
2108                         ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].is_occupied == 1), {}, QUERY_NO_RECORD, ("no record"));
2109                 }
2110         }else
2111         {
2112                 ADVANCED_SVC_TRACE("------------------------------ GENERATE RESULT SET ------------------------------ ");
2113
2114                 if(q_handle->query_type == QUERY_TO_PERSON)
2115                         _query_get_count(table_key[TABLE_PERSON], q_handle->query_type, &count);
2116                 else if(q_handle->query_type == QUERY_TO_CONTACT)
2117                         _query_get_count(table_key[TABLE_CONTACT], q_handle->query_type, &count);
2118                 ADVANCED_RETURN_VAL((count != 0), {}, QUERY_NO_RECORD, ("NO RECORD"));
2119
2120                 query = g_string_new ("");
2121
2122                 target_table_e join_table = _check_join_case(q_handle);
2123                 q_handle->join_table = join_table;
2124
2125                 is_optimized_query = _check_optimized_query(q_handle, join_table);
2126
2127                 if(is_optimized_query == 1)
2128                 {
2129                         ADVANCED_SVC_TRACE("!!!!!! EXECUTE OPTIMIZED QUERY !!!!!!");
2130                         q_handle->is_optimized_query = 1;
2131                         projection = g_string_new("");
2132
2133                         if(q_handle->query_string == NULL)
2134                         {
2135                                 if(join_table == ONLY_DATA || join_table == ONLY_DATA_FROM_PERSON_QUERY)
2136                                         g_string_append_printf(projection, "%s", field_key[FIELD_DATA_CONTACT_ID]);
2137                                 else
2138                                         g_string_append_printf(projection, "%s", field_key[FIELD_PERSON_CONTACT_ID]);
2139
2140                                 GList* tmp_projection = q_handle->projection;
2141                                 while(tmp_projection)
2142                                 {
2143                                         projection_t* projection_info = (projection_t*)tmp_projection->data;
2144
2145                                         loc = strstr(projection->str, projection_info->field);
2146                                         if(loc == NULL)
2147                                         {
2148                                                 g_string_append_printf(projection, ", %s", projection_info->field);
2149
2150                                                 projection_t* new_projection_info = NULL;
2151                                                 new_projection_info = g_new0(projection_t, 1);
2152                                                 ADVANCED_CATCH_SET_ERROR((new_projection_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2153
2154                                                 new_projection_info->field = g_strdup(projection_info->field);
2155                                                 q_handle->new_projection = g_list_append(q_handle->new_projection, new_projection_info);
2156                                         }
2157                                         tmp_projection = g_list_next(tmp_projection);
2158                                 }
2159                                 g_list_foreach(q_handle->projection, _free_projection_list, NULL);
2160                                 g_list_free(q_handle->projection);
2161
2162                                 q_handle->query_string = g_strdup(projection->str);
2163                         }
2164
2165                         if((strcmp(q_handle->query_string, field_key[FIELD_DATA_CONTACT_ID]) == 0) || (strcmp(q_handle->query_string, field_key[FIELD_PERSON_CONTACT_ID]) == 0))
2166                                 type = ONLY_CONTACT_ID_FIELD;
2167
2168                         GString* sub_query;
2169                         sub_query = g_string_new("");
2170
2171                         if(q_handle->condition_datatype != DATATYPE_NAME && q_handle->condition_datatype != DATATYPE_INVALID)
2172                                 _make_contact_id_list_by_condition_part(q_handle, count, sub_query);
2173
2174                         error_code = _construct_optimize_query(q_handle, query, join_table, type, sub_query->str);
2175                         ADVANCED_CATCH_SET_ERROR((error_code == QUERY_SUCCESS), {}, error_code, ("CONSTRUCT QUERY FAIL"));
2176
2177                     q_handle->hstmt = _contact_query_prepare(query->str);
2178                         ADVANCED_CATCH_SET_ERROR((q_handle->hstmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
2179
2180                         if(q_handle->use_normal_field_key->str[0] != '\0')
2181                         {
2182                                 GList* tmp_condition_val = q_handle->condition_value;
2183                                 while(tmp_condition_val)
2184                                 {
2185                                         condition_val_t* tmp_val = (condition_val_t*)tmp_condition_val->data;
2186                                         if(tmp_val->indices_filter == 0)
2187                                         {
2188                                         ADVANCED_SVC_TRACE("condition_val->value : %s", tmp_val->value);
2189                                         primitive_type type = _convert_check_attribute_primitive_type(tmp_val->attribute);
2190                                         if(tmp_val->x_attribute == 1)
2191                                                 type = STRING;
2192
2193                                         if(type == INTEGER)
2194                                                 _contact_query_bind_int(q_handle->hstmt, i++, tmp_val->int_value);
2195                                         else if(type == STRING)
2196                                                 _contact_query_bind_text(q_handle->hstmt, i++, tmp_val->value);
2197                                         else if(type == REAL)
2198                                                 _contact_query_bind_double(q_handle->hstmt, i++, tmp_val->real_value);
2199                                         }
2200
2201                                         tmp_condition_val = g_list_next(tmp_condition_val);
2202                                 }
2203                         }
2204
2205                         rc = _contact_query_step(q_handle->hstmt);
2206                         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
2207
2208                         error_code = _query_result_set(q_handle, rc, count, type, join_table);
2209
2210                         g_string_free(projection, TRUE);
2211                         g_string_free(query, TRUE);
2212                         g_string_free (sub_query, TRUE);
2213
2214                 }else
2215                 {
2216                         ADVANCED_SVC_TRACE("!!!!!! EXECUTE NORMAL QUERY !!!!!!");
2217
2218 // generate contact id list
2219                         GString* sub_query;
2220                         sub_query = g_string_new("");
2221
2222                         if(q_handle->condition_category != NULL)
2223                         {
2224                                 g_string_append_printf(sub_query, "select distinct(a.%s) from %s a, %s b where (a.%s = b.%s) and b.%s %s ?",
2225                                         relation_field_key[FIELD_GROUP_RELATION_CONTACT_ID], table_key[TABLE_GROUP_RELATION],
2226                                         table_key[TABLE_GROUP], group_field_key[FIELD_GROUP_ID], relation_field_key[FIELD_GROUP_RELATION_GROUP_ID],
2227                                         group_field_key[FIELD_GROUP_NAME], q_handle->condition_category_op);
2228                         }else
2229                                 error_code = _make_contact_id_list_by_condition_part(q_handle, count, sub_query);
2230
2231 // generate result set
2232                         error_code = _make_result_contact_list(q_handle, count, sub_query->str);
2233 // ordering
2234                         _make_order_list(q_handle, count, join_table);
2235
2236 // get categories
2237                         int category_count = 0;
2238                         if((q_handle->extra_info & CATEGORIES) != 0)
2239                         {
2240                                 _query_get_count(table_key[TABLE_GROUP_RELATION], q_handle->query_type, &category_count);
2241                                 q_handle->category = g_new0(categories_info, category_count + 1);
2242                                 if(category_count != 0)
2243                                         _get_categories_list(q_handle, category_count, sub_query->str);
2244                         }
2245
2246                         g_string_free (sub_query, TRUE);
2247                 }
2248                 ADVANCED_CATCH_SET_ERROR((q_handle->total_result_set_count != 0), {}, QUERY_NO_RECORD, ("NO RESULT CONTACT LIST"));
2249         }
2250
2251 CATCH:
2252         if(error_code != QUERY_SUCCESS)
2253         {
2254         }
2255
2256         return error_code;
2257 }
2258
2259 API query_error query_finalize(ADVANCED_HANDLE handle)
2260 {
2261         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
2262
2263         query_error error_code = QUERY_SUCCESS;
2264         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
2265
2266         _free_handle_info(q_handle);
2267         q_handle = NULL;
2268
2269         error_code = _contact_db_finish();
2270
2271         return error_code;
2272 }
2273
2274 query_error _set_exists_condition(ADVANCED_HANDLE handle, contact_attribute_e attribute)
2275 {
2276         query_error error_code = QUERY_SUCCESS;
2277         predefine_datatype datatype = DATATYPE_INVALID;
2278         db_datatype db_datatype_id = DB_DATATYPE_INVALID;
2279         //char* condition = NULL;
2280         char* table = NULL;
2281         condition_table_t* table_info = NULL;
2282         alias_key_e tmp_current_alias = ALIAS_INVALID;
2283         char* column_name = NULL;
2284         char* normal_column_name = NULL;
2285
2286         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
2287         ADVANCED_RETURN_VAL((q_handle->condition_category == NULL), {}, QUERY_GROUP_CASE, ("GROUP QUERY CASE"));
2288
2289         error_code = _check_extra_contact_info(q_handle, EXTRA_INFO_TYPE_CONDITION, attribute);
2290         ADVANCED_RETURN_VAL((error_code != QUERY_SUCCESS), {}, QUERY_FAIL, ("NOT SUPPORT"));
2291         error_code = QUERY_SUCCESS;
2292
2293         column_name = _convert_attribute_to_condition_column_name(attribute);
2294         normal_column_name = _convert_attribute_to_column_name(attribute);
2295
2296         datatype = _convert_attribute_to_mimetype_id(attribute);
2297         db_datatype_id = _convert_datatype_to_db_type(datatype);
2298
2299         table = _convert_attribute_to_table_name(attribute);
2300         tables_e table_type = _contact_table_name_to_table_type(table);
2301         q_handle->query_table = q_handle->query_table | table_type;
2302
2303         if(q_handle->current_alias != ALIAS_INVALID)
2304         {
2305                 if((q_handle->condition_datatype & datatype) == 0 )
2306                 {
2307                         q_handle->current_alias++;
2308                         tmp_current_alias = q_handle->current_alias;
2309
2310                         table_info = g_new0(condition_table_t, 1);
2311                         table_info->alias = q_handle->current_alias;
2312                         table_info->table = g_strdup(table);
2313                         q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
2314                 }else
2315                 {
2316                         GList* tmp_condition_list = q_handle->condition_list;
2317                         while(tmp_condition_list)
2318                         {
2319                                 condition_list_t* tmp_info = (condition_list_t*)tmp_condition_list->data;
2320
2321                                 if(tmp_info->datatype == db_datatype_id)
2322                                 {
2323                                         tmp_current_alias = tmp_info->current_alias;
2324                                         break;
2325                                 }
2326                                 tmp_condition_list = g_list_next(tmp_condition_list);
2327                         }
2328                 }
2329         }else
2330         {
2331                 q_handle->current_alias++;
2332                 tmp_current_alias = q_handle->current_alias;
2333
2334                 table_info = g_new0(condition_table_t, 1);
2335                 table_info->alias = q_handle->current_alias;
2336                 table_info->table = g_strdup(table);
2337                 q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
2338         }
2339
2340         if(db_datatype_id != DB_DATATYPE_INVALID)
2341         {
2342                 g_string_append_printf(q_handle->use_normal_field_key, "(%s = %d)", condition_field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id);
2343                 g_string_append_printf(q_handle->condition_text, "(%s.%s = %d)", alias_key[tmp_current_alias], condition_field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id);
2344
2345                 condition_list_t* condition_info = NULL;
2346                 condition_info = g_new0(condition_list_t, 1);
2347                 condition_info->current_alias = tmp_current_alias;
2348                 condition_info->datatype = db_datatype_id;
2349                 q_handle->condition_list = g_list_append(q_handle->condition_list, condition_info);
2350         }else
2351         {
2352                 q_handle->optimize_condition = 0;
2353                 g_string_append_printf(q_handle->use_contact_table_id, "(%s is not null)", field_key[FIELD_CONTACT_CONTACT_ID]);
2354                 g_string_append_printf(q_handle->use_normal_field_key, "(%s is not null)", normal_column_name);
2355                 g_string_append_printf(q_handle->condition_text, "(%s.%s is not null)", alias_key[tmp_current_alias], column_name);
2356         }
2357
2358         q_handle->condition_datatype = q_handle->condition_datatype | datatype;
2359
2360         return error_code;
2361 }
2362
2363 API query_error query_set_condition(ADVANCED_HANDLE handle, contact_attribute_e attribute, condition_e attr, const char* value)
2364 {
2365         query_error error_code = QUERY_SUCCESS;
2366         predefine_datatype datatype = DATATYPE_INVALID;
2367         db_datatype db_datatype_id = DB_DATATYPE_INVALID;
2368         char* column_name = NULL;
2369         char* normal_column_name = NULL;
2370         char* condition = NULL;
2371         char* table = NULL;
2372         int is_person_attr = 0;
2373         condition_table_t* table_info = NULL;
2374         alias_key_e tmp_current_alias = ALIAS_INVALID;
2375
2376         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
2377         ADVANCED_RETURN_VAL((attribute < ATTRIBUTE_MAX), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID CONTACT ATTRIBUTE"));
2378         ADVANCED_RETURN_VAL((attr < CONDITION_MAX), {}, QUERY_INVALID_TYPE, ("INVALID CONTACT CONDITION"));
2379         ADVANCED_RETURN_VAL((attribute != CONTACT_PHOTO_URI), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID CONTACT ATTRIBUTE"));
2380
2381         if(attr == EXISTS)
2382         {
2383                 error_code = _set_exists_condition(handle, attribute);
2384                 return error_code;
2385         }
2386         ADVANCED_RETURN_VAL((value != NULL), {}, QUERY_NULL_PARAMETER, ("INVALID VALUE"));
2387
2388         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
2389         ADVANCED_RETURN_VAL((q_handle->condition_category == NULL), {}, QUERY_GROUP_CASE, ("GROUP QUERY CASE"));
2390
2391         ADVANCED_SVC_TRACE("condition value : %s", value);
2392         if(_is_type_bitwise_int(attribute) && attr == LIKE)
2393                 condition = _convert_condition_to_string(BITWISE_AND);
2394         else
2395                 condition = _convert_condition_to_string(attr);
2396
2397         error_code = _check_extra_contact_info(q_handle, EXTRA_INFO_TYPE_CONDITION, attribute);
2398         if(error_code == QUERY_SUCCESS)
2399         {
2400                 ADVANCED_RETURN_VAL((q_handle->condition_text->str[0] == '\0'), {}, QUERY_GROUP_CASE, ("CAN NOT ASSIGN GROUP CONDITION"));
2401                 q_handle->condition_category =  g_strdup(value);
2402                 q_handle->condition_category_op =  g_strdup(condition);
2403                 return error_code;
2404         }
2405         error_code = QUERY_SUCCESS;
2406
2407         if(q_handle->query_type == QUERY_TO_PERSON)
2408         {
2409                 column_name = _convert_person_attribute_to_condition_column_name(attribute);
2410                 normal_column_name = _convert_person_attribute_to_column_name(attribute);
2411         }
2412
2413         if(column_name == NULL)
2414         {
2415 //              column_name = _convert_attribute_to_condition_normalize_column(attribute);
2416 //              normal_column_name = _convert_attribute_to_normalize_column(attribute);
2417
2418 //              if(column_name == NULL)
2419                 {
2420                         column_name = _convert_attribute_to_condition_column_name(attribute);
2421                         normal_column_name = _convert_attribute_to_column_name(attribute);
2422                 }
2423         }
2424
2425         if(q_handle->query_type == QUERY_TO_PERSON)
2426                 is_person_attr = _convert_person_attribute_to_mimetype_id(attribute);
2427
2428         if(is_person_attr == 0)
2429         {
2430                 datatype = _convert_attribute_to_mimetype_id(attribute);
2431                 db_datatype_id = _convert_datatype_to_db_type(datatype);
2432         }
2433
2434         if(q_handle->query_type == QUERY_TO_PERSON)
2435                 table = _convert_person_attribute_to_table_name(attribute);
2436
2437         if(table == NULL)
2438                 table = _convert_attribute_to_table_name(attribute);
2439         tables_e table_type = _contact_table_name_to_table_type(table);
2440         q_handle->query_table = q_handle->query_table | table_type;
2441
2442         if(q_handle->current_alias != ALIAS_INVALID)
2443         {
2444                 if((q_handle->condition_datatype & datatype) == 0 )
2445                 {
2446                         q_handle->current_alias++;
2447                         tmp_current_alias = q_handle->current_alias;
2448
2449                         table_info = g_new0(condition_table_t, 1);
2450                         table_info->alias = q_handle->current_alias;
2451                         table_info->table = g_strdup(table);
2452                         q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
2453                 }else
2454                 {
2455                         GList* tmp_condition_list = q_handle->condition_list;
2456                         while(tmp_condition_list)
2457                         {
2458                                 condition_list_t* tmp_info = (condition_list_t*)tmp_condition_list->data;
2459
2460                                 if(tmp_info->datatype == db_datatype_id)
2461                                 {
2462                                         tmp_current_alias = tmp_info->current_alias;
2463                                         break;
2464                                 }
2465                                 tmp_condition_list = g_list_next(tmp_condition_list);
2466                         }
2467                 }
2468         }else
2469         {
2470                 q_handle->current_alias++;
2471                 tmp_current_alias = q_handle->current_alias;
2472
2473                 table_info = g_new0(condition_table_t, 1);
2474                 table_info->alias = q_handle->current_alias;
2475                 table_info->table = g_strdup(table);
2476                 q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
2477         }
2478
2479         if(db_datatype_id != DB_DATATYPE_INVALID)
2480         {
2481                 g_string_append_printf(q_handle->use_normal_field_key, "(%s %s ? and %s = %d)",
2482                         normal_column_name, condition, condition_field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id);
2483
2484                 g_string_append_printf(q_handle->condition_text, "(%s.%s %s ? and %s.%s = %d)",
2485                         alias_key[tmp_current_alias], column_name, condition, alias_key[tmp_current_alias], condition_field_key[FIELD_DATA_DATATYPE_ID], db_datatype_id);
2486
2487                 condition_list_t* condition_info = NULL;
2488                 condition_info = g_new0(condition_list_t, 1);
2489                 condition_info->column_name = g_strdup(column_name);
2490                 condition_info->current_alias = tmp_current_alias;
2491                 condition_info->condition = g_strdup(condition);
2492                 condition_info->datatype = db_datatype_id;
2493
2494                 q_handle->condition_list = g_list_append(q_handle->condition_list, condition_info);
2495
2496         }else
2497         {
2498                 q_handle->optimize_condition = 0;
2499                 g_string_append_printf(q_handle->use_contact_table_id, "(%s %s ?)", field_key[FIELD_CONTACT_CONTACT_ID], condition);
2500
2501                 g_string_append_printf(q_handle->use_normal_field_key, "(%s %s ?)", normal_column_name, condition);
2502
2503                 g_string_append_printf(q_handle->condition_text, "(%s.%s %s ?)", alias_key[tmp_current_alias], column_name, condition);
2504         }
2505
2506         primitive_type type = _convert_check_attribute_primitive_type(attribute);
2507         condition_val_t* condition_txt = NULL;
2508         condition_txt = g_new0(condition_val_t, 1);
2509
2510         condition_txt->attribute = attribute;
2511         if(type == INTEGER)
2512         {
2513                 condition_txt->int_value = _convert_type_string_to_int(attribute, value);
2514         }else if(type == STRING)
2515         {
2516                 condition_txt->value = g_strdup(value);
2517         }else if(type == REAL)
2518                 condition_txt->real_value = atof(value);
2519
2520         q_handle->condition_value = g_list_append(q_handle->condition_value, condition_txt);
2521
2522         q_handle->condition_datatype = q_handle->condition_datatype | datatype;
2523
2524         return error_code;
2525 }
2526
2527 API query_error fetch_next_row(ADVANCED_HANDLE handle)
2528 {
2529         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
2530
2531         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
2532         query_error error_code = QUERY_SUCCESS;
2533
2534         ADVANCED_RETURN_VAL((q_handle->result_set[q_handle->return_array_pos].contact_info != NULL), {}, QUERY_NO_RECORD, ("CONTACT INFO IS NULL"));
2535
2536         switch(q_handle->current_datatype)
2537         {
2538                 case DATATYPE_INVALID:
2539                         if(q_handle->query_type == QUERY_TO_CONTACT)
2540                                 q_handle->result_set[q_handle->return_array_pos].contact_info->get_raw_contact_info = 1;
2541                         else
2542                                 q_handle->result_set[q_handle->return_array_pos].contact_info->get_person_info = 1;
2543                         ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_NEXT_ROW, ("NOT MULTIPLE VALUE"));
2544                         break;
2545                 case DATATYPE_NUMBER:
2546                 {
2547                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->number_list;
2548                         if(tmp_list)
2549                         {
2550                                 number_t* num_info = (number_t*)tmp_list->data;
2551
2552                                 _free_num_info(q_handle->result_set[q_handle->return_array_pos].contact_info->num_info);
2553
2554                                 q_handle->result_set[q_handle->return_array_pos].contact_info->num_info = g_new0(number_t, 1);
2555                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->num_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2556
2557                                 q_handle->result_set[q_handle->return_array_pos].contact_info->num_info->number = g_strdup(num_info->number);
2558                                 q_handle->result_set[q_handle->return_array_pos].contact_info->num_info->number_type = g_strdup(num_info->number_type);
2559
2560                                 ADVANCED_SVC_TRACE("number : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->num_info->number);
2561                                 _free_num_info((number_t*)tmp_list->data);
2562                                 q_handle->result_set[q_handle->return_array_pos].contact_info->number_list = g_list_next(tmp_list);
2563                         }
2564                         else
2565                         {
2566                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2567                         }
2568                 }
2569                         break;
2570                 case DATATYPE_EMAIL:
2571                 {
2572                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->email_list;
2573                         if(tmp_list)
2574                         {
2575                                 email_t* email_info = (email_t*)tmp_list->data;
2576
2577                                 _free_email_info(q_handle->result_set[q_handle->return_array_pos].contact_info->email_info);
2578
2579                                 q_handle->result_set[q_handle->return_array_pos].contact_info->email_info = g_new0(email_t, 1);
2580                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->email_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2581
2582                                 q_handle->result_set[q_handle->return_array_pos].contact_info->email_info->email_addr = g_strdup(email_info->email_addr);
2583                                 q_handle->result_set[q_handle->return_array_pos].contact_info->email_info->email_type = g_strdup(email_info->email_type);
2584
2585                                 ADVANCED_SVC_TRACE("email_addr : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->email_info->email_addr);
2586                                 _free_email_info((email_t*)tmp_list->data);
2587                                 q_handle->result_set[q_handle->return_array_pos].contact_info->email_list = g_list_next(tmp_list);
2588                         }
2589                         else
2590                         {
2591                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2592                         }
2593                 }
2594                         break;
2595                 case DATATYPE_URL:
2596                 {
2597                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->url_list;
2598                         if(tmp_list)
2599                         {
2600                                 url_t* url_info = (url_t*)tmp_list->data;
2601
2602                                 _free_url_info(q_handle->result_set[q_handle->return_array_pos].contact_info->url_info);
2603
2604                                 q_handle->result_set[q_handle->return_array_pos].contact_info->url_info = g_new0(url_t, 1);
2605                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->url_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2606
2607                                 q_handle->result_set[q_handle->return_array_pos].contact_info->url_info->url_addr = g_strdup(url_info->url_addr);
2608                                 q_handle->result_set[q_handle->return_array_pos].contact_info->url_info->url_type = g_strdup(url_info->url_type);
2609
2610                                 ADVANCED_SVC_TRACE("url_addr : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->url_info->url_addr);
2611                                 _free_url_info((url_t*)tmp_list->data);
2612                                 q_handle->result_set[q_handle->return_array_pos].contact_info->url_list = g_list_next(tmp_list);
2613                         }
2614                         else
2615                         {
2616                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2617                         }
2618                 }
2619                         break;
2620                 case DATATYPE_NICK_NAME :
2621                 {
2622                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->nickname_list;
2623                         if(tmp_list)
2624                         {
2625                                 nick_name_t* nick_info = (nick_name_t*)tmp_list->data;
2626
2627                                 _free_nick_info(q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info);
2628
2629                                 q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info = g_new0(nick_name_t, 1);
2630                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2631
2632                                 q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info->nick_name = g_strdup(nick_info->nick_name);
2633
2634                                 ADVANCED_SVC_TRACE("nick_name : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info->nick_name);
2635                                 _free_nick_info((nick_name_t*)tmp_list->data);
2636                                 q_handle->result_set[q_handle->return_array_pos].contact_info->nickname_list = g_list_next(tmp_list);
2637                         }
2638                         else
2639                         {
2640                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2641                         }
2642                 }
2643                         break;
2644                 case DATATYPE_ADDRESS :
2645                 {
2646                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->address_list;
2647                         if(tmp_list)
2648                         {
2649                                 address_t* address_info = (address_t*)tmp_list->data;
2650
2651                                 _free_address_info(q_handle->result_set[q_handle->return_array_pos].contact_info->address_info);
2652
2653                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info = g_new0(address_t, 1);
2654                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2655
2656                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->country = g_strdup(address_info->country);
2657                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->region = g_strdup(address_info->region);
2658                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->county= g_strdup(address_info->county);
2659                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->city = g_strdup(address_info->city);
2660                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->street = g_strdup(address_info->street);
2661                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->postal_code = g_strdup(address_info->postal_code);
2662                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->addtional = g_strdup(address_info->addtional);
2663                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->type = g_strdup(address_info->type);
2664
2665                                 ADVANCED_SVC_TRACE("street : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->street);
2666                                 _free_address_info((address_t*)tmp_list->data);
2667                                 q_handle->result_set[q_handle->return_array_pos].contact_info->address_list = g_list_next(tmp_list);
2668                         }
2669                         else
2670                         {
2671                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2672                         }
2673                 }
2674                         break;
2675                 case DATATYPE_ORGANIZATION :
2676                 {
2677                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->organization_list;
2678                         if(tmp_list)
2679                         {
2680                                 organization_t* organization_info = (organization_t*)tmp_list->data;
2681
2682                                 _free_organization_info(q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info);
2683
2684                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info = g_new0(organization_t, 1);
2685                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2686
2687                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->organization_name = g_strdup(organization_info->organization_name);
2688                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->department = g_strdup(organization_info->department);
2689                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->office = g_strdup(organization_info->office);
2690                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->title = g_strdup(organization_info->title);
2691                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->role = g_strdup(organization_info->role);
2692                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->logo_uri = g_strdup(organization_info->logo_uri);
2693
2694                                 ADVANCED_SVC_TRACE("title : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->title);
2695                                 _free_organization_info((organization_t*)tmp_list->data);
2696                                 q_handle->result_set[q_handle->return_array_pos].contact_info->organization_list = g_list_next(tmp_list);
2697                         }
2698                         else
2699                         {
2700                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2701                         }
2702                 }
2703                         break;
2704                 case DATATYPE_ANNIVERSARY :
2705                 {
2706                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->event_list;
2707                         if(tmp_list)
2708                         {
2709                                 event_info_t* event_info = (event_info_t*)tmp_list->data;
2710
2711                                 _free_anniversary_info(q_handle->result_set[q_handle->return_array_pos].contact_info->event_info);
2712
2713                                 q_handle->result_set[q_handle->return_array_pos].contact_info->event_info = g_new0(event_info_t, 1);
2714                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->event_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2715
2716                                 q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->type = g_strdup(event_info->type);
2717                                 q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->date = g_strdup(event_info->date);
2718                                 q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->label = g_strdup(event_info->label);
2719
2720                                 ADVANCED_SVC_TRACE("date : %s", q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->date);
2721                                 _free_anniversary_info((event_info_t*)tmp_list->data);
2722                                 q_handle->result_set[q_handle->return_array_pos].contact_info->event_list = g_list_next(tmp_list);
2723                         }
2724                         else
2725                         {
2726                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2727                         }
2728                 }
2729                         break;
2730                 case DATATYPE_NAME :
2731                         q_handle->result_set[q_handle->return_array_pos].contact_info->get_name = 1;
2732                         ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_NEXT_ROW, ("NOT MULTIPLE VALUE"));
2733                         break;
2734                 case DATATYPE_CATEGORY :
2735                 {
2736                         if((q_handle->extra_info & CATEGORIES) != 0 && q_handle->next_count > -1)
2737                         {
2738                                 char *value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->contact_id;
2739                                 char *end_ptr = value;
2740                                 errno = 0;
2741                                 int     contact_id = (int)strtol(value, &end_ptr, 0);
2742                                 if(errno == ERANGE || end_ptr == value)
2743                                 {
2744                                         return QUERY_INVALID_TYPE;
2745                                 }
2746
2747                                 if(q_handle->next_count != 0)
2748                                 {
2749                                         ADVANCED_CATCH_SET_ERROR(((q_handle->category_pos + 1) < q_handle->category_total_count), {}, QUERY_NO_RECORD, ("no record"));
2750                                         ADVANCED_CATCH_SET_ERROR((q_handle->category[q_handle->category_pos + 1].sibling != 0), {}, QUERY_NO_RECORD, ("no record"));
2751                                         q_handle->category_pos++;
2752                                         q_handle->next_count++;
2753                                         return QUERY_SUCCESS;
2754                                 }else
2755                                 {
2756 #if 1
2757                                         int high, low, j;
2758                                         high = q_handle->category_total_count;
2759                                         low = 0;
2760
2761                                         while(high >= low)
2762                                         {
2763                                                 j = ( low + high ) / 2;
2764
2765                                                 if(q_handle->category[j].contact_id > contact_id)
2766                                                         high = j - 1;
2767                                                 else if(q_handle->category[j].contact_id < contact_id)
2768                                                         low = j + 1;
2769                                                 else if(q_handle->category[j].contact_id == contact_id)
2770                                                 {
2771                                                         while(j > 0 && q_handle->category[j-1].contact_id == contact_id)
2772                                                                 j--;
2773                                                         q_handle->category_pos = j;
2774                                                         q_handle->next_count++;
2775                                                         return QUERY_SUCCESS;
2776                                                 }
2777                                         }
2778 #else
2779                                         for(i = 0; i < q_handle->category_total_count; i++)
2780                                         {
2781                                                 if(q_handle->category[i].contact_id == contact_id)
2782                                                 {
2783                                                         q_handle->category_pos = i;
2784                                                         q_handle->next_count++;
2785                                                         return QUERY_SUCCESS;
2786                                                 }
2787                                         }
2788 #endif
2789                                 }
2790                         }
2791                         q_handle->next_count = -1;
2792                         ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2793                 }
2794                         break;
2795                 case DATATYPE_X_ATTRIBUTE :
2796                 {
2797                         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->x_list;
2798                         if(tmp_list)
2799                         {
2800                                 x_info_t* x_info = (x_info_t*)tmp_list->data;
2801
2802                                 _free_x_info(q_handle->result_set[q_handle->return_array_pos].contact_info->x_info);
2803
2804                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info = g_new0(x_info_t, 1);
2805                                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
2806
2807                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->datatype_id = x_info->datatype_id;
2808                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data1 = g_strdup(x_info->data1);
2809                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data2 = g_strdup(x_info->data2);
2810                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data3 = g_strdup(x_info->data3);
2811                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data4 = g_strdup(x_info->data4);
2812                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data5 = g_strdup(x_info->data5);
2813                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data6 = g_strdup(x_info->data6);
2814                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data7 = g_strdup(x_info->data7);
2815                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data8 = g_strdup(x_info->data8);
2816                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data9 = g_strdup(x_info->data9);
2817                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data10 = g_strdup(x_info->data10);
2818
2819                                 _free_x_info((x_info_t*)tmp_list->data);
2820                                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_list = g_list_next(tmp_list);
2821                         }
2822                         else
2823                         {
2824                                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
2825                         }
2826                 }
2827                         break;
2828                 default:
2829                         break;
2830         }
2831
2832         ADVANCED_SVC_TRACE("error_code : %d", error_code);
2833
2834 CATCH:
2835         return error_code;
2836 }
2837
2838 query_error _invalid_datatype_fetch_next_row(advanced_handle_t* handle, predefine_datatype datatype)
2839 {
2840         query_error error_code = QUERY_SUCCESS;
2841         ADVANCED_RETURN_VAL((handle->result_set[handle->return_array_pos].contact_info != NULL), {}, QUERY_NO_RECORD, ("CONTACT INFO IS NULL"));
2842
2843         if(datatype == DATATYPE_INVALID)
2844         {
2845                 if(handle->query_type == QUERY_TO_CONTACT)
2846                 {
2847                         ADVANCED_RETURN_VAL((handle->result_set[handle->return_array_pos].contact_info->get_raw_contact_info == 0), {}, QUERY_NO_NEXT_ROW, ("NO ROW"));
2848                 }else if(handle->query_type == QUERY_TO_PERSON)
2849                 {
2850                         ADVANCED_RETURN_VAL((handle->result_set[handle->return_array_pos].contact_info->get_person_info == 0), {}, QUERY_NO_NEXT_ROW, ("NO ROW"));
2851                 }
2852         }else if(datatype == DATATYPE_NAME)
2853         {
2854                 ADVANCED_RETURN_VAL((handle->result_set[handle->return_array_pos].contact_info->get_name == 0), {}, QUERY_NO_NEXT_ROW, ("NO ROW"));
2855         }
2856
2857         return error_code;
2858 }
2859
2860 char* _get_person_attribute_value(advanced_handle_t* q_handle, contact_attribute_e attribute, query_error* error_code)
2861 {
2862         char* value = NULL;
2863
2864         switch(attribute)
2865         {
2866                 case CONTACT_ID :
2867                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2868                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->contact_id;
2869                         break;
2870                 case CONTACT_IS_FAVORITE:
2871                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2872                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->is_favorite;
2873                         break;
2874                 case CONTACT_RINGTONE:
2875                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2876                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->ringtone;
2877                         break;
2878                 case CONTACT_PHOTO_URI:
2879                         break;
2880                 case CONTACT_LAST_UPDATED_TIME_STAMP:
2881                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2882                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->last_updated_timestamp;
2883                         break;
2884                 case CONTACT_UID:
2885                         break;
2886                 case NAME_FIRST :
2887                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2888                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->first_name;
2889                         break;
2890                 case NAME_MIDDLE:
2891                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2892                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->middle_name;
2893                         break;
2894                 case NAME_LAST:
2895                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2896                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->last_name;
2897                         break;
2898                 case NAME_PREFIX:
2899                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2900                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->prefix;
2901                         break;
2902                 case NAME_PHONETIC:
2903                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2904                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->phonetic_name;
2905                         break;
2906                 case NAME_DISPLAY :
2907                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->person_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2908                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->person_info->display_name;
2909                         break;
2910                 default:
2911                         break;
2912         }
2913
2914 CATCH:
2915         return value;
2916 }
2917
2918 char* _get_x_attribute_value(advanced_handle_t* q_handle, contact_x_attribute_e attribute, query_error* error_code)
2919 {
2920         char* value = NULL;
2921
2922         switch(attribute)
2923         {
2924                 case X_DATA1:
2925                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2926                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data1;
2927                         break;
2928                 case X_DATA2:
2929                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2930                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data2;
2931                         break;
2932                 case X_DATA3:
2933                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2934                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data3;
2935                         break;
2936                 case X_DATA4:
2937                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2938                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data4;
2939                         break;
2940                 case X_DATA5:
2941                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2942                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data5;
2943                         break;
2944                 case X_DATA6:
2945                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2946                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data6;
2947                         break;
2948                 case X_DATA7:
2949                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2950                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data7;
2951                         break;
2952                 case X_DATA8:
2953                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2954                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data8;
2955                         break;
2956                 case X_DATA9:
2957                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2958                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data9;
2959                         break;
2960                 case X_DATA10:
2961                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2962                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data10;
2963                         break;
2964                 default:
2965                         break;
2966         }
2967 CATCH:
2968         return value;
2969 }
2970
2971 char* _get_attribute_value(advanced_handle_t* q_handle, contact_attribute_e attribute, query_error* error_code)
2972 {
2973         char* value = NULL;
2974
2975         switch(attribute)
2976         {
2977                 case CONTACT_ID :
2978                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2979                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->contact_id;
2980                         break;
2981                 case CONTACT_UID:
2982                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2983                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->uid;
2984                         break;
2985                 case ADDRESSBOOK_ID :
2986                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2987                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->addressbook_id;
2988                         break;
2989                 case CONTACT_IS_FAVORITE:
2990                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2991                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->is_favorite;
2992                         break;
2993                 case CONTACT_RINGTONE:
2994                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2995                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->ringtone;
2996                         break;
2997                 case CONTACT_NOTE:
2998                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
2999                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->note;
3000                         break;
3001                 case CONTACT_PHOTO_URI:
3002                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3003                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->photo_uri;
3004                         break;
3005                 case CONTACT_LAST_UPDATED_TIME_STAMP:
3006                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3007                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->raw_contact_info->last_updated_time_stamp;
3008                         break;
3009                 case NAME_FIRST :
3010                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3011                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->first_name;
3012                         break;
3013                 case NAME_MIDDLE:
3014                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3015                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->middle_name;
3016                         break;
3017                 case NAME_LAST:
3018                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3019                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->last_name;
3020                         break;
3021                 case NAME_PREFIX:
3022                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3023                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->prefix;
3024                         break;
3025                 case NAME_PHONETIC:
3026                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3027                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->phonetic_name;
3028                         break;
3029                 case NAME_DISPLAY :
3030                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->name_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3031                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->name_info->display_name;
3032                         break;
3033                 case NICKNAME_NAME:
3034                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3035                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->nick_info->nick_name;
3036                         break;
3037                 case NUMBER_ADDRESS:
3038                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->num_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3039                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->num_info->number;
3040                         break;
3041                 case NUMBER_TYPES:
3042                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->num_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3043                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->num_info->number_type;
3044                         break;
3045                 case EMAIL_ADDRESS:
3046                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->email_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3047                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->email_info->email_addr;
3048                         break;
3049                 case EMAIL_TYPES:
3050                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->email_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3051                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->email_info->email_type;
3052                         break;
3053                 case URL_ADDRESS:
3054                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->url_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3055                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->url_info->url_addr;
3056                         break;
3057                 case URL_TYPE:
3058                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->url_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3059                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->url_info->url_type;
3060                         break;
3061                 case ADDRESS_COUNTRY:
3062                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3063                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->country;
3064                         break;
3065                 case ADDRESS_REGION:
3066                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3067                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->region;
3068                         break;
3069                 case ADDRESS_CITY:
3070                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3071                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->city;
3072                         break;
3073                 case ADDRESS_STREET:
3074                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3075                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->street;
3076                         break;
3077                 case ADDRESS_POSTAL_CODE:
3078                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3079                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->postal_code;
3080                         break;
3081                 case ADDRESS_ADDITIONAL:
3082                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3083                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->addtional;
3084                         break;
3085                 case ADDRESS_TYPES:
3086                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->address_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3087                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->address_info->type;
3088                         break;
3089                 case CATEGORY_INFO:
3090                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->category[q_handle->category_pos].name != NULL), {}, QUERY_NO_RECORD, ("no data"));
3091                         value = q_handle->category[q_handle->category_pos].name;
3092                         break;
3093                 case EVENT_DATE:
3094                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->event_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3095                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->date;
3096                         break;
3097                 case EVENT_TYPE:
3098                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->event_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3099                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->event_info->type;
3100                         break;
3101                 case ORGANIZATION_NAME:
3102                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3103                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->organization_name;
3104                         break;
3105                 case ORGANIZATION_DEPARTMENT:
3106                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3107                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->department;
3108                         break;
3109                 case ORGANIZATION_TITLE:
3110                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3111                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->title;
3112                         break;
3113                 case ORGANIZATION_ROLE:
3114                         ADVANCED_CATCH_SET_ERROR_POINTER((q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info != NULL), {}, QUERY_NO_RECORD, ("no data"));
3115                         value = q_handle->result_set[q_handle->return_array_pos].contact_info->organization_info->role;
3116                         break;
3117                 default:
3118                         break;
3119         }
3120
3121 CATCH:
3122         return value;
3123 }
3124
3125 API char* query_get_attribute(ADVANCED_HANDLE handle, contact_attribute_e attribute, query_error* error_code)
3126 {
3127         ADVANCED_RETURN_VAL((handle != NULL), {}, NULL, ("HANDLE IS NULL"));
3128         ADVANCED_RETURN_VAL((attribute < ATTRIBUTE_MAX), {}, NULL, ("INVALID ATTRIBUTE"));
3129
3130         char* value = NULL;
3131         predefine_datatype tmp_datatype = DATATYPE_INVALID;
3132         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3133         ADVANCED_SVC_TRACE("q_handle->return_array_pos : %d", q_handle->return_array_pos);
3134         ADVANCED_RETURN_VAL((q_handle->return_array_pos < q_handle->total_result_set_count), {}, NULL, ("RESULT SET IS NULL"));
3135         ADVANCED_RETURN_VAL((q_handle->result_set[q_handle->return_array_pos].contact_info != NULL), {}, NULL, ("CONTACT INFO IS NULL"));
3136
3137         tmp_datatype = _convert_attribute_to_mimetype_id(attribute);
3138         if(q_handle->current_datatype != tmp_datatype || tmp_datatype == DATATYPE_INVALID)
3139         {
3140                 q_handle->current_datatype = tmp_datatype;
3141                 q_handle->next_count = 0;
3142                 q_handle->category_pos = 0;
3143                 *error_code = QUERY_SUCCESS;
3144
3145                 if(tmp_datatype == DATATYPE_INVALID || tmp_datatype == DATATYPE_NAME)
3146                         *error_code = _invalid_datatype_fetch_next_row(q_handle, tmp_datatype);
3147                 else
3148                         *error_code = fetch_next_row(handle);
3149
3150                 ADVANCED_CATCH_SET_ERROR_POINTER((*error_code == QUERY_SUCCESS), {}, *error_code, ("fetch next row ERROR"));
3151         }
3152
3153         if(q_handle->query_type == QUERY_TO_PERSON)
3154                 value = _get_person_attribute_value(q_handle, attribute, error_code);
3155
3156         if(value == NULL)
3157                 value = _get_attribute_value(q_handle, attribute, error_code);
3158
3159         ADVANCED_SVC_TRACE("%d : %s", attribute, value);
3160
3161 CATCH:
3162         return value;
3163 }
3164
3165 API query_error query_set_order_by(ADVANCED_HANDLE handle, contact_attribute_e attribute, order_e ordering)
3166 {
3167         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3168         ADVANCED_RETURN_VAL((attribute < ATTRIBUTE_MAX), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID CONTACT ATTRIBUTE"));
3169         ADVANCED_RETURN_VAL((ordering <= DESC), {}, QUERY_INVALID_TYPE, ("INVALID CONTACT ORDERING"));
3170         ADVANCED_RETURN_VAL((attribute != CONTACT_ID), {}, QUERY_SUCCESS, ("DEFAULT ORDER ATTRIBUTE"));
3171
3172         char* column_name = NULL;
3173         query_error error_code = QUERY_SUCCESS;
3174         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3175
3176         if(q_handle->query_type == QUERY_TO_PERSON)
3177         {
3178                 column_name = _convert_person_attribute_to_column_name(attribute);
3179         }
3180
3181         if(column_name == NULL)
3182         {
3183                 column_name = _convert_attribute_to_column_name(attribute);
3184
3185                 predefine_datatype datatype = DATATYPE_INVALID;
3186                 datatype = _convert_attribute_to_mimetype_id(attribute);
3187                 q_handle->all_datatype_in_query = (q_handle->all_datatype_in_query | datatype);
3188                 q_handle->order_field = attribute;
3189         }
3190
3191         g_string_append_printf(q_handle->order, "%s", column_name);
3192
3193         q_handle->ordering = ordering;
3194
3195         if(ordering == ASC)
3196         {
3197                 g_string_append_printf(q_handle->order, " %s", "ASC");
3198         }else if(ordering == DESC)
3199         {
3200                 g_string_append_printf(q_handle->order, " %s", "DESC");
3201         }
3202
3203         ADVANCED_SVC_TRACE("order : %s", q_handle->order->str);
3204         return error_code;
3205 }
3206
3207 API query_error query_set_condition_append(ADVANCED_HANDLE handle, condition_type_e type)
3208 {
3209         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3210         ADVANCED_RETURN_VAL((type < CONDITION_TYPE_MAX), {}, QUERY_INVALID_TYPE, ("INVALID CONDITION TYPE"));
3211         query_error error_code = QUERY_SUCCESS;
3212         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3213         char* type_string = NULL;
3214
3215         if(type == AND)
3216                 q_handle->optimize_condition = 0;
3217
3218         type_string = _convert_condition_type_to_string(type);
3219         g_string_append_printf (q_handle->condition_text, " %s ", type_string);
3220         g_string_append_printf (q_handle->use_normal_field_key, " %s ", type_string);
3221         g_string_append_printf(q_handle->use_contact_table_id, " %s ", type_string);
3222
3223         return error_code;
3224 }
3225
3226 API query_error query_set_x_attribute(ADVANCED_HANDLE handle, int cts_custom_type_index, contact_x_attribute_e attribute)
3227 {
3228         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3229         ADVANCED_RETURN_VAL((attribute < X_DATA_MAX), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID X-ATTRIBUTE"));
3230
3231         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3232
3233         char* column_name = NULL;
3234         char* table_name = NULL;
3235         query_error error_code = QUERY_SUCCESS;
3236         char* loc = NULL;
3237         projection_t* projection_info = NULL;
3238
3239         ADVANCED_SVC_TRACE("x_attribute : %d", attribute);
3240
3241         q_handle->x_attribute_list[attribute] = 1;
3242
3243         column_name = _convert_x_attribute_to_column_name(attribute);
3244
3245         projection_info = g_new0(projection_t, 1);
3246         projection_info->field = g_strdup(column_name);
3247         q_handle->projection = g_list_append(q_handle->projection, projection_info);
3248
3249         error_code = _set_datatype_list_by_x_attribute(q_handle, cts_custom_type_index, attribute);
3250         ADVANCED_CATCH_SET_ERROR((error_code == QUERY_SUCCESS), {}, QUERY_FAIL, ("X DATA_TYPE CONVERTING FAIL"));
3251
3252         if(table_name == NULL)
3253                 table_name = _convert_x_attribute_to_table_name(attribute);
3254
3255         if(q_handle->table_list->str[0] != '\0')
3256         {
3257                 loc = strstr(q_handle->table_list->str, table_name);
3258                 if(loc == NULL)
3259                         g_string_append_printf(q_handle->table_list, ", %s", table_name);
3260         }
3261         else
3262         {
3263                 g_string_append_printf(q_handle->table_list, "%s", table_name);
3264         }
3265
3266         tables_e table_type = _contact_table_name_to_table_type(table_name);
3267         q_handle->query_table = q_handle->query_table | table_type;
3268
3269         ADVANCED_SVC_TRACE("table list : %s", q_handle->table_list->str);
3270         q_handle->all_datatype_in_query = (q_handle->all_datatype_in_query | DATATYPE_X_ATTRIBUTE);
3271
3272 CATCH:
3273         return error_code;
3274 }
3275
3276 API query_error query_set_x_condition(ADVANCED_HANDLE handle, int cts_custom_type_index, contact_x_attribute_e attribute, condition_e attr, const char* value)
3277 {
3278         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3279         ADVANCED_RETURN_VAL((attribute < X_DATA_MAX), {}, QUERY_INVALID_ATTRIBUTE, ("INVALID X-ATTRIBUTE"));
3280         ADVANCED_RETURN_VAL((attr < CONDITION_MAX), {}, QUERY_INVALID_TYPE, ("INVALID CONTACT CONDITION"));
3281
3282         query_error error_code = QUERY_SUCCESS;
3283         char* column_name = NULL;
3284         char* condition = NULL;
3285         char* table = NULL;
3286         condition_table_t* table_info = NULL;
3287         int new_custom_type = 0;
3288         alias_key_e tmp_current_alias = ALIAS_INVALID;
3289
3290         if(attr == EXISTS)
3291         {
3292                 error_code = _set_exists_condition(handle, attribute);
3293                 return error_code;
3294         }
3295         ADVANCED_RETURN_VAL((value != NULL), {}, QUERY_NULL_PARAMETER, ("INVALID VALUE"));
3296
3297         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3298         ADVANCED_RETURN_VAL((q_handle->condition_category == NULL), {}, QUERY_GROUP_CASE, ("GROUP QUERY CASE"));
3299
3300         ADVANCED_SVC_TRACE("condition value : %s", value);
3301         condition = _convert_condition_to_string(attr);
3302
3303         column_name = _convert_x_attribute_to_condition_column_name(attribute);
3304         table = _convert_x_attribute_to_table_name(attribute);
3305         tables_e table_type = _contact_table_name_to_table_type(table);
3306         q_handle->query_table = q_handle->query_table | table_type;
3307
3308         if(q_handle->current_alias != ALIAS_INVALID)
3309         {
3310                 GList* tmp_condition_list = q_handle->condition_list;
3311                 while(tmp_condition_list)
3312                 {
3313                         condition_list_t* tmp_info = (condition_list_t*)tmp_condition_list->data;
3314
3315                         if(tmp_info->datatype != cts_custom_type_index)
3316                         {
3317                                 new_custom_type = 1;
3318                         }else
3319                         {
3320                                 new_custom_type = 0;
3321                                 tmp_current_alias = tmp_info->current_alias;
3322                                 break;
3323                         }
3324                         tmp_condition_list = g_list_next(tmp_condition_list);
3325                 }
3326                 if(new_custom_type)
3327                 {
3328                         q_handle->current_alias++;
3329                         tmp_current_alias = q_handle->current_alias;
3330
3331                         table_info = g_new0(condition_table_t, 1);
3332                         table_info->alias = q_handle->current_alias;
3333                         table_info->table = g_strdup(table);
3334                         q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
3335                 }
3336         }else
3337         {
3338                 q_handle->current_alias++;
3339                 tmp_current_alias = q_handle->current_alias;
3340
3341                 table_info = g_new0(condition_table_t, 1);
3342                 table_info->alias = q_handle->current_alias;
3343                 table_info->table = g_strdup(table);
3344                 q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
3345         }
3346
3347         g_string_append_printf(q_handle->condition_text, "(%s.%s %s ? and %s.%s = %d)",
3348                 alias_key[tmp_current_alias], column_name, condition, alias_key[tmp_current_alias], condition_field_key[FIELD_DATA_DATATYPE_ID], cts_custom_type_index);
3349
3350         condition_list_t* condition_info = NULL;
3351         condition_info = g_new0(condition_list_t, 1);
3352         condition_info->current_alias = tmp_current_alias;
3353         condition_info->column_name = g_strdup(column_name);
3354         condition_info->condition = g_strdup(condition);
3355         condition_info->datatype = cts_custom_type_index;
3356
3357         q_handle->condition_list = g_list_append(q_handle->condition_list, condition_info);
3358
3359         condition_val_t* condition_txt = NULL;
3360         condition_txt = g_new0(condition_val_t, 1);
3361         condition_txt->value = g_strdup(value);
3362         condition_txt->x_attribute = 1;
3363         q_handle->condition_value = g_list_append(q_handle->condition_value, condition_txt);
3364
3365         q_handle->condition_datatype = q_handle->condition_datatype | DATATYPE_X_ATTRIBUTE;
3366
3367         return error_code;
3368 }
3369
3370 query_error query_set_limit(ADVANCED_HANDLE handle, int window_size)
3371 {
3372         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3373
3374         query_error error_code = QUERY_SUCCESS;
3375         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3376
3377         q_handle->start_pos = 0;
3378         q_handle->window_size = window_size;
3379
3380 return error_code;
3381 }
3382
3383 query_error query_get_next_limit_result_set(ADVANCED_HANDLE handle, int window_size)
3384 {
3385         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3386         ADVANCED_RETURN_VAL((window_size >= 0), {}, QUERY_INVALID_ATTRIBUTE, ("RETURN COUNT SHOULD BE POSITIVE VALUE"));
3387
3388         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3389         query_error error_code = QUERY_SUCCESS;
3390
3391         q_handle->start_pos = _free_for_limit_iter(q_handle);
3392         ADVANCED_SVC_TRACE("q_handle->start_pos : %d", q_handle->start_pos);
3393
3394         q_handle->limit_iter = 1;
3395         q_handle->total_result_set_count = 0;
3396         q_handle->pos = -1;
3397         q_handle->old_contact_id = 0;
3398         q_handle->return_array_pos = 0;
3399         ADVANCED_SVC_TRACE("q_handle->total_result_set_count : %d", q_handle->total_result_set_count);
3400
3401         q_handle->result_set = NULL;
3402         q_handle->window_size = window_size;
3403
3404         error_code = query_get_result_contact(handle);
3405
3406         return error_code;
3407 }
3408
3409 API query_error query_next_custom_type(ADVANCED_HANDLE handle)
3410 {
3411         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3412         query_error error_code = QUERY_SUCCESS;
3413         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3414         ADVANCED_RETURN_VAL((q_handle->result_set[q_handle->return_array_pos].contact_info != NULL), {}, QUERY_NO_RECORD, ("CONTACT INFO IS NULL"));
3415
3416         q_handle->x_fetching = NEXT_ROW_FETCH;
3417
3418         GList* tmp_list = q_handle->result_set[q_handle->return_array_pos].contact_info->x_list;
3419         if(tmp_list)
3420         {
3421                 x_info_t* x_info = (x_info_t*)tmp_list->data;
3422                 _free_x_info(q_handle->result_set[q_handle->return_array_pos].contact_info->x_info);
3423
3424                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info = g_new0(x_info_t, 1);
3425                 ADVANCED_CATCH_SET_ERROR((q_handle->result_set[q_handle->return_array_pos].contact_info->x_info != NULL), {}, QUERY_ALLOCATE_MEMORY_FAIL, ("ALLOCATION FAIL"));
3426
3427                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->datatype_id = x_info->datatype_id;
3428                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data1 = g_strdup(x_info->data1);
3429
3430                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data2 = g_strdup(x_info->data2);
3431                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data3 = g_strdup(x_info->data3);
3432                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data4 = g_strdup(x_info->data4);
3433                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data5 = g_strdup(x_info->data5);
3434                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data6 = g_strdup(x_info->data6);
3435                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data7 = g_strdup(x_info->data7);
3436                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data8 = g_strdup(x_info->data8);
3437                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data9 = g_strdup(x_info->data9);
3438                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->data10 = g_strdup(x_info->data10);
3439
3440                 _free_x_info((x_info_t*)tmp_list->data);
3441                 q_handle->result_set[q_handle->return_array_pos].contact_info->x_list = g_list_next(tmp_list);
3442         }
3443         else
3444         {
3445                 ADVANCED_CATCH_SET_ERROR(0, {}, QUERY_NO_RECORD, ("no record"));
3446         }
3447         ADVANCED_SVC_TRACE("error_code : %d", error_code);
3448
3449 CATCH:
3450         return error_code;
3451 }
3452
3453 API char* query_get_x_attribute(ADVANCED_HANDLE handle, contact_x_attribute_e attribute, int* cts_custom_type_index, query_error* error_code)
3454 {
3455         ADVANCED_RETURN_VAL((handle != NULL), {}, NULL, ("HANDLE IS NULL"));
3456         ADVANCED_RETURN_VAL((attribute < X_DATA_MAX), {}, NULL, ("INVALID ATTRIBUTE"));
3457
3458         char* value = NULL;
3459         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3460         ADVANCED_SVC_TRACE("q_handle->return_array_pos : %d", q_handle->return_array_pos);
3461         ADVANCED_RETURN_VAL((q_handle->return_array_pos < q_handle->total_result_set_count), {}, NULL, ("RESULT SET IS NULL"));
3462         ADVANCED_RETURN_VAL((q_handle->result_set[q_handle->return_array_pos].contact_info != NULL), {}, NULL, ("CONTACT INFO IS NULL"));
3463
3464         if(q_handle->x_fetching != NEXT_ROW_FETCH)
3465                 q_handle->x_fetching = INIT_FETCH;
3466
3467         if(q_handle->x_fetching == INIT_FETCH)
3468         {
3469                 *error_code = query_next_custom_type(handle);
3470                 ADVANCED_CATCH_SET_ERROR_POINTER((*error_code == QUERY_SUCCESS), {}, *error_code, ("query_next_custom_type ERROR "));
3471         }
3472
3473         value = _get_x_attribute_value(q_handle, attribute, error_code);
3474         ADVANCED_CATCH_SET_ERROR_POINTER((*error_code == QUERY_SUCCESS), {}, *error_code, ("ERROR "));
3475
3476         *cts_custom_type_index = q_handle->result_set[q_handle->return_array_pos].contact_info->x_info->datatype_id;
3477
3478         ADVANCED_SVC_TRACE("*cts_custom_type_index : %d", *cts_custom_type_index);
3479         ADVANCED_SVC_TRACE("value : %s", value);
3480
3481 CATCH:
3482         return value;
3483 }
3484
3485 API query_error query_set_condition_with_indices_begin(ADVANCED_HANDLE handle)
3486 {
3487         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3488         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3489         query_error error_code = QUERY_SUCCESS;
3490
3491         ADVANCED_RETURN_VAL((q_handle->condition_category == NULL), {}, QUERY_GROUP_CASE, ("GROUP QUERY CASE"));
3492
3493         g_string_append_printf(q_handle->id_list, "(");
3494
3495         return error_code;
3496 }
3497
3498 API query_error query_set_condition_with_indices_end(ADVANCED_HANDLE handle)
3499 {
3500         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3501
3502         query_error error_code = QUERY_SUCCESS;
3503         //predefine_datatype datatype = DATATYPE_INVALID;
3504         //db_datatype db_datatype_id = DB_DATATYPE_INVALID;
3505         char* column_name = NULL;
3506         char* normal_column_name = NULL;
3507         //char* condition = NULL;
3508         char* table = NULL;
3509         condition_table_t* table_info = NULL;
3510         alias_key_e tmp_current_alias = ALIAS_INVALID;
3511
3512         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3513         ADVANCED_RETURN_VAL((q_handle->condition_category == NULL), {}, QUERY_GROUP_CASE, ("GROUP QUERY CASE"));
3514
3515         g_string_append_printf(q_handle->id_list, ")");
3516
3517         column_name = _convert_attribute_to_condition_column_name(CONTACT_ID);
3518         normal_column_name = _convert_attribute_to_column_name(CONTACT_ID);
3519
3520         table = _convert_attribute_to_table_name(CONTACT_ID);
3521
3522         q_handle->current_alias++;
3523         tmp_current_alias = q_handle->current_alias;
3524
3525         table_info = g_new0(condition_table_t, 1);
3526         table_info->alias = q_handle->current_alias;
3527         table_info->table = g_strdup(table);
3528         q_handle->condition_table_list = g_list_append(q_handle->condition_table_list, table_info);
3529
3530         q_handle->optimize_condition = 0;
3531         g_string_append_printf(q_handle->use_contact_table_id, "(%s in %s)", field_key[FIELD_CONTACT_CONTACT_ID], q_handle->id_list->str);
3532         g_string_append_printf(q_handle->use_normal_field_key, "(%s in %s)", normal_column_name, q_handle->id_list->str);
3533
3534         g_string_append_printf(q_handle->condition_text, "(%s.%s in %s)", alias_key[tmp_current_alias], column_name, q_handle->id_list->str);
3535
3536         condition_val_t* condition_txt = NULL;
3537         condition_txt = g_new0(condition_val_t, 1);
3538
3539         condition_txt->attribute = CONTACT_ID;
3540         condition_txt->indices_filter = 1;
3541
3542         q_handle->condition_value = g_list_append(q_handle->condition_value, condition_txt);
3543
3544         return error_code;
3545 }
3546
3547 API query_error query_set_condition_with_indices(ADVANCED_HANDLE handle, const char* contact_index)
3548 {
3549         ADVANCED_RETURN_VAL((handle != NULL), {}, QUERY_HANDLE_NONE, ("HANDLE IS NULL"));
3550         advanced_handle_t* q_handle = (advanced_handle_t*)handle;
3551         query_error error_code = QUERY_SUCCESS;
3552
3553         if(q_handle->is_first_id_in_list == 0)
3554         {
3555                 q_handle->is_first_id_in_list = 1;
3556                 g_string_append_printf(q_handle->id_list, "%s", contact_index);
3557         }else
3558         {
3559                 g_string_append_printf(q_handle->id_list, ", %s", contact_index);
3560         }
3561
3562         return error_code;
3563 }
3564
3565 API int get_contact_version()
3566 {
3567         char query[128] = {0, };
3568         int rc = -1;
3569         stmt pStmt = NULL;
3570         int ver = 0;
3571         query_error error_code = QUERY_SUCCESS;
3572
3573         error_code = _contact_db_init();
3574         ADVANCED_CATCH_SET_ERROR((error_code == QUERY_SUCCESS), {}, QUERY_STATEMENT_FAIL, ("DATABASE INIT FAIL"));
3575
3576         snprintf(query, 128, "%s", "select max(ver) from cts_version");
3577
3578         pStmt = _contact_query_prepare(query);
3579         ADVANCED_CATCH_SET_ERROR((pStmt != NULL), {}, QUERY_STATEMENT_FAIL, ("database prepare fail"));
3580
3581         rc = _contact_query_step(pStmt);
3582         ADVANCED_CATCH_SET_ERROR((rc == SQLITE_ROW), {}, QUERY_NO_RECORD, ("No record in database"));
3583
3584         ver = _ct_query_column_int(pStmt, 0);
3585         ADVANCED_SVC_TRACE("get_contact_version :: ver : %d ", ver);
3586
3587         CATCH:
3588         _ct_query_finalize(pStmt);
3589         _contact_db_finish();
3590
3591         return ver;
3592 }
3593