Add user space access control
[platform/core/pim/contacts-service.git] / client / ctsvc_client_db.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Dohyung Jin <dh.jin@samsung.com>
7  *                 Jongwon Lee <gogosing.lee@samsung.com>
8  *                 Donghee Ye <donghee.ye@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <glib.h>
25
26 #include "contacts.h"
27 #include "ctsvc_internal.h"
28 #include "ctsvc_list.h"
29 #include "ctsvc_record.h"
30 #include "ctsvc_query.h"
31 #include "ctsvc_inotify.h"
32
33 #include "ctsvc_internal.h"
34 #include "ctsvc_ipc_define.h"
35 #include "ctsvc_ipc_marshal.h"
36 #include "ctsvc_view.h"
37
38 #include "ctsvc_client_ipc.h"
39 #include <pims-ipc-data.h>
40
41 #include "ctsvc_inotify.h"
42
43 typedef struct {
44         void *callback;
45         void *user_data;
46 }ctsvc_ipc_async_userdata_s;
47
48 static void __ctsvc_ipc_client_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
49 static void __ctsvc_ipc_client_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
50 static void __ctsvc_ipc_client_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
51
52 void __ctsvc_ipc_client_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
53 {
54         ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
55         int ret = CONTACTS_ERROR_NONE;
56         int *ids = NULL;
57         unsigned int count = 0;
58
59         if (data_out)
60         {
61                 // check outdata
62                 unsigned int size = 0;
63                 ret = *(int*) pims_ipc_data_get(data_out,&size);
64
65                 if (ret == CONTACTS_ERROR_NONE) {
66                         int i=0;
67                         unsigned int size = 0;
68                         int transaction_ver = 0;
69                         transaction_ver = *(int*)pims_ipc_data_get(data_out, &size);
70                         ctsvc_client_ipc_set_change_version(transaction_ver);
71
72                         count = *(unsigned int*) pims_ipc_data_get(data_out,&size);
73                         ids = calloc(count, sizeof(int));
74                         for(i=0;i<count;i++)
75                         {
76                                 ids[i] = *(int*) pims_ipc_data_get(data_out,&size);
77                         }
78                 }
79         }
80
81         if (sync_data->callback)
82         {
83                 contacts_db_insert_result_cb callback = sync_data->callback;
84                 callback(ret, ids, count, sync_data->user_data);
85         }
86         free(ids);
87
88         ctsvc_inotify_call_blocked_callback();
89
90         CONTACTS_FREE(sync_data);
91
92         return ;
93 }
94
95 void __ctsvc_ipc_client_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
96 {
97         ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
98         int ret = CONTACTS_ERROR_NONE;
99
100         if (data_out)
101         {
102                 // check outdata
103                 unsigned int size = 0;
104                 ret = *(int*) pims_ipc_data_get(data_out,&size);
105
106                 if (CONTACTS_ERROR_NONE == ret) {
107                         int transaction_ver = 0;
108                         transaction_ver = *(int*)pims_ipc_data_get(data_out, &size);
109                         ctsvc_client_ipc_set_change_version(transaction_ver);
110                 }
111         }
112
113         if (sync_data->callback)
114         {
115                 contacts_db_result_cb callback = sync_data->callback;
116                 callback(ret, sync_data->user_data);
117         }
118
119         ctsvc_inotify_call_blocked_callback();
120
121         CONTACTS_FREE(sync_data);
122
123         return ;
124 }
125 void __ctsvc_ipc_client_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
126 {
127         ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
128         int ret = CONTACTS_ERROR_NONE;
129
130         if (data_out)
131         {
132                 // check outdata
133                 unsigned int size = 0;
134                 ret = *(int*) pims_ipc_data_get(data_out,&size);
135                 if (CONTACTS_ERROR_NONE == ret) {
136                         int transaction_ver = 0;
137                         transaction_ver = *(int*)pims_ipc_data_get(data_out, &size);
138                         ctsvc_client_ipc_set_change_version(transaction_ver);
139                 }
140         }
141
142         if (sync_data->callback)
143         {
144                 contacts_db_result_cb callback = sync_data->callback;
145                 callback(ret, sync_data->user_data);
146         }
147
148         ctsvc_inotify_call_blocked_callback();
149
150         CONTACTS_FREE(sync_data);
151
152         return ;
153 }
154
155 API int contacts_db_insert_record( contacts_record_h record, int *id )
156 {
157         int ret = CONTACTS_ERROR_NONE;
158         pims_ipc_data_h indata = NULL;
159         pims_ipc_data_h outdata = NULL;
160
161         if (id)
162                 *id = 0;
163
164         RETVM_IF(record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
165
166         // make indata
167         indata = pims_ipc_data_create(0);
168         if (indata == NULL)
169         {
170                 CTS_ERR("ipc data created fail!");
171                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
172                 return ret;
173         }
174         ret = ctsvc_ipc_marshal_record(record,indata);
175         if (ret != CONTACTS_ERROR_NONE)
176         {
177                 CTS_ERR("marshal fail");
178                 return ret;
179         }
180
181         // ipc call
182         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORD, indata, &outdata) != 0)
183         {
184                 CTS_ERR("ctsvc_ipc_call failed");
185                 pims_ipc_data_destroy(indata);
186                 return CONTACTS_ERROR_IPC;
187         }
188
189         if (indata)
190         {
191                 pims_ipc_data_destroy(indata);
192         }
193
194         if (outdata)
195         {
196                 // check outdata
197                 unsigned int size = 0;
198                 ret = *(int*) pims_ipc_data_get(outdata,&size);
199
200                 if (ret == CONTACTS_ERROR_NONE) {
201                         int transaction_ver = 0;
202                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
203                         ctsvc_client_ipc_set_change_version(transaction_ver);
204
205                         if (id)
206                                 *id = *(int*)pims_ipc_data_get(outdata,&size);
207                 }
208
209                 pims_ipc_data_destroy(outdata);
210         }
211
212         return ret;
213 }
214
215 API int contacts_db_get_record( const char* view_uri, int id, contacts_record_h* out_record )
216 {
217         int ret = CONTACTS_ERROR_NONE;
218         pims_ipc_data_h indata = NULL;
219         pims_ipc_data_h outdata = NULL;
220
221         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
222         RETVM_IF(id<0,CONTACTS_ERROR_INVALID_PARAMETER,"id<0");
223         RETVM_IF(out_record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
224         *out_record = NULL;
225
226         // make indata
227         indata = pims_ipc_data_create(0);
228         if (indata == NULL)
229         {
230                 CTS_ERR("ipc data created fail!");
231                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
232                 return ret;
233         }
234         ret = ctsvc_ipc_marshal_string(view_uri,indata);
235         if (ret != CONTACTS_ERROR_NONE)
236         {
237                 CTS_ERR("marshal fail");
238                 return ret;
239         }
240         ret = ctsvc_ipc_marshal_int(id,indata);
241         if (ret != CONTACTS_ERROR_NONE)
242         {
243                 CTS_ERR("marshal fail");
244                 return ret;
245         }
246
247         // ipc call
248         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORD, indata, &outdata) != 0)
249         {
250                 CTS_ERR("ctsvc_ipc_call failed");
251                 pims_ipc_data_destroy(indata);
252                 return CONTACTS_ERROR_IPC;
253         }
254
255         if (indata)
256         {
257                 pims_ipc_data_destroy(indata);
258         }
259
260         if (outdata)
261         {
262                 // check outdata
263                 unsigned int size = 0;
264                 ret = *(int*) pims_ipc_data_get(outdata,&size);
265
266                 if (ret == CONTACTS_ERROR_NONE)
267                 {
268                         ret = ctsvc_ipc_unmarshal_record(outdata,out_record);
269                 }
270
271                 pims_ipc_data_destroy(outdata);
272         }
273
274         return ret;
275 }
276
277 API int contacts_db_update_record( contacts_record_h record )
278 {
279         int ret = CONTACTS_ERROR_NONE;
280         pims_ipc_data_h indata = NULL;
281         pims_ipc_data_h outdata = NULL;
282
283         RETVM_IF(record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
284
285
286         // make indata
287         indata = pims_ipc_data_create(0);
288         if (indata == NULL)
289         {
290                 CTS_ERR("ipc data created fail!");
291                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
292                 return ret;
293         }
294         ret = ctsvc_ipc_marshal_record(record,indata);
295         if (ret != CONTACTS_ERROR_NONE)
296         {
297                 CTS_ERR("marshal fail");
298                 return ret;
299         }
300
301         // ipc call
302         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORD, indata, &outdata) != 0)
303         {
304                 CTS_ERR("ctsvc_ipc_call failed");
305                 pims_ipc_data_destroy(indata);
306                 return CONTACTS_ERROR_IPC;
307         }
308
309         if (indata)
310         {
311                 pims_ipc_data_destroy(indata);
312         }
313
314         if (outdata)
315         {
316                 // check outdata
317                 unsigned int size = 0;
318                 ret = *(int*) pims_ipc_data_get(outdata,&size);
319                 if (CONTACTS_ERROR_NONE == ret) {
320                         CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
321                         int transaction_ver = 0;
322                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
323                         ctsvc_client_ipc_set_change_version(transaction_ver);
324                 }
325
326                 pims_ipc_data_destroy(outdata);
327         }
328
329         return ret;
330 }
331
332 API int contacts_db_delete_record( const char* view_uri, int id )
333 {
334         int ret = CONTACTS_ERROR_NONE;
335         pims_ipc_data_h indata = NULL;
336         pims_ipc_data_h outdata = NULL;
337
338         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
339         RETVM_IF(id<=0,CONTACTS_ERROR_INVALID_PARAMETER,"id <= 0");
340
341
342         // make indata
343         indata = pims_ipc_data_create(0);
344         if (indata == NULL)
345         {
346                 CTS_ERR("ipc data created fail!");
347                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
348                 return ret;
349         }
350         ret = ctsvc_ipc_marshal_string(view_uri,indata);
351         if (ret != CONTACTS_ERROR_NONE)
352         {
353                 CTS_ERR("marshal fail");
354                 return ret;
355         }
356         ret = ctsvc_ipc_marshal_int(id,indata);
357         if (ret != CONTACTS_ERROR_NONE)
358         {
359                 CTS_ERR("marshal fail");
360                 return ret;
361         }
362
363         // ipc call
364         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORD, indata, &outdata) != 0)
365         {
366                 CTS_ERR("ctsvc_ipc_call failed");
367                 pims_ipc_data_destroy(indata);
368                 return CONTACTS_ERROR_IPC;
369         }
370
371         if (indata)
372         {
373                 pims_ipc_data_destroy(indata);
374         }
375
376         if (outdata)
377         {
378                 // check outdata
379                 unsigned int size = 0;
380                 ret = *(int*) pims_ipc_data_get(outdata,&size);
381                 if (CONTACTS_ERROR_NONE == ret) {
382                         int transaction_ver = 0;
383                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
384                         ctsvc_client_ipc_set_change_version(transaction_ver);
385                 }
386
387                 pims_ipc_data_destroy(outdata);
388         }
389
390         return ret;
391 }
392
393 API int contacts_db_replace_record( contacts_record_h record, int id )
394 {
395         int ret = CONTACTS_ERROR_NONE;
396         pims_ipc_data_h indata = NULL;
397         pims_ipc_data_h outdata = NULL;
398
399         RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is NULL");
400
401         // make indata
402         indata = pims_ipc_data_create(0);
403         if (indata == NULL) {
404                 CTS_ERR("ipc data created fail!");
405                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
406                 return ret;
407         }
408
409         ret = ctsvc_ipc_marshal_record(record, indata);
410         if (ret != CONTACTS_ERROR_NONE) {
411                 CTS_ERR("marshal fail");
412                 return ret;
413         }
414         ret = ctsvc_ipc_marshal_int(id, indata);
415         if (ret != CONTACTS_ERROR_NONE) {
416                 CTS_ERR("marshal fail");
417                 return ret;
418         }
419
420         // ipc call
421         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE,
422                                 CTSVC_IPC_SERVER_DB_REPLACE_RECORD, indata, &outdata) != 0) {
423                 CTS_ERR("ctsvc_ipc_call failed");
424                 pims_ipc_data_destroy(indata);
425                 return CONTACTS_ERROR_IPC;
426         }
427
428         pims_ipc_data_destroy(indata);
429
430         if (outdata) {
431                 // check outdata
432                 unsigned int size = 0;
433                 ret = *(int*) pims_ipc_data_get(outdata,&size);
434                 if (CONTACTS_ERROR_NONE == ret) {
435                         int transaction_ver = 0;
436                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
437                         ctsvc_client_ipc_set_change_version(transaction_ver);
438                 }
439                 pims_ipc_data_destroy(outdata);
440         }
441
442         return ret;
443 }
444
445 API int contacts_db_get_all_records( const char* view_uri, int offset, int limit, contacts_list_h* out_list )
446 {
447         int ret = CONTACTS_ERROR_NONE;
448         pims_ipc_data_h indata = NULL;
449         pims_ipc_data_h outdata = NULL;
450
451         RETVM_IF(out_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
452         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
453         *out_list = NULL;
454
455         // make indata
456         indata = pims_ipc_data_create(0);
457         if (indata == NULL)
458         {
459                 CTS_ERR("ipc data created fail!");
460                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
461                 return ret;
462         }
463
464         ret = ctsvc_ipc_marshal_string(view_uri,indata);
465         if (ret != CONTACTS_ERROR_NONE)
466         {
467                 CTS_ERR("marshal fail");
468                 return ret;
469         }
470         ret = ctsvc_ipc_marshal_int(offset,indata);
471         if (ret != CONTACTS_ERROR_NONE)
472         {
473                 CTS_ERR("marshal fail");
474                 return ret;
475         }
476         ret = ctsvc_ipc_marshal_int(limit,indata);
477         if (ret != CONTACTS_ERROR_NONE)
478         {
479                 CTS_ERR("marshal fail");
480                 return ret;
481         }
482
483         // ipc call
484         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_ALL_RECORDS, indata, &outdata) != 0)
485         {
486                 CTS_ERR("ctsvc_ipc_call failed");
487                 pims_ipc_data_destroy(indata);
488                 return CONTACTS_ERROR_IPC;
489         }
490
491         if (indata)
492         {
493                 pims_ipc_data_destroy(indata);
494         }
495
496         if (outdata)
497         {
498                 // check outdata
499                 unsigned int size = 0;
500                 ret = *(int*) pims_ipc_data_get(outdata,&size);
501
502                 if (ret == CONTACTS_ERROR_NONE)
503                 {
504                         ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
505                 }
506                 pims_ipc_data_destroy(outdata);
507         }
508
509         return ret;
510 }
511
512 API int contacts_db_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
513 {
514         int ret = CONTACTS_ERROR_NONE;
515         pims_ipc_data_h indata = NULL;
516         pims_ipc_data_h outdata = NULL;
517
518         RETVM_IF(query==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"query is NULL");
519         RETVM_IF(out_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
520         *out_list = NULL;
521
522         // make indata
523         indata = pims_ipc_data_create(0);
524         if (indata == NULL)
525         {
526                 CTS_ERR("ipc data created fail!");
527                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
528                 return ret;
529         }
530         ret = ctsvc_ipc_marshal_query(query,indata);
531         if (ret != CONTACTS_ERROR_NONE)
532         {
533                 CTS_ERR("marshal fail");
534                 return ret;
535         }
536         ret = ctsvc_ipc_marshal_int(offset,indata);
537         if (ret != CONTACTS_ERROR_NONE)
538         {
539                 CTS_ERR("marshal fail");
540                 return ret;
541         }
542         ret = ctsvc_ipc_marshal_int(limit,indata);
543         if (ret != CONTACTS_ERROR_NONE)
544         {
545                 CTS_ERR("marshal fail");
546                 return ret;
547         }
548
549         // ipc call
550         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY, indata, &outdata) != 0)
551         {
552                 CTS_ERR("ctsvc_ipc_call failed");
553                 pims_ipc_data_destroy(indata);
554                 return CONTACTS_ERROR_IPC;
555         }
556
557         if (indata)
558         {
559                 pims_ipc_data_destroy(indata);
560         }
561
562         if (outdata)
563         {
564                 // check outdata
565                 unsigned int size = 0;
566                 ret = *(int*) pims_ipc_data_get(outdata,&size);
567
568                 if (ret == CONTACTS_ERROR_NONE)
569                 {
570                         ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
571                 }
572
573                 pims_ipc_data_destroy(outdata);
574         }
575
576         return ret;
577 }
578
579
580 API int contacts_db_get_count( const char* view_uri, int *out_count )
581 {
582         int ret = CONTACTS_ERROR_NONE;
583         pims_ipc_data_h indata = NULL;
584         pims_ipc_data_h outdata = NULL;
585
586         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
587         RETVM_IF(out_count==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"count pointer is NULL");
588         *out_count = 0;
589
590         // make indata
591         indata = pims_ipc_data_create(0);
592         if (indata == NULL)
593         {
594                 CTS_ERR("ipc data created fail!");
595                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
596                 return ret;
597         }
598         ret = ctsvc_ipc_marshal_string(view_uri,indata);
599         if (ret != CONTACTS_ERROR_NONE)
600         {
601                 CTS_ERR("marshal fail");
602                 return ret;
603         }
604
605         // ipc call
606         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT, indata, &outdata) != 0)
607         {
608                 CTS_ERR("ctsvc_ipc_call failed");
609                 pims_ipc_data_destroy(indata);
610                 return CONTACTS_ERROR_IPC;
611         }
612
613         if (indata)
614         {
615                 pims_ipc_data_destroy(indata);
616         }
617
618         if (outdata)
619         {
620                 // check outdata
621                 unsigned int size = 0;
622                 ret = *(int*) pims_ipc_data_get(outdata,&size);
623
624                 if (ret == CONTACTS_ERROR_NONE)
625                 {
626                         ret = ctsvc_ipc_unmarshal_int(outdata,out_count);
627                 }
628
629                 pims_ipc_data_destroy(outdata);
630         }
631
632         return ret;
633 }
634
635 API int contacts_db_get_count_with_query( contacts_query_h query, int *out_count )
636 {
637         int ret = CONTACTS_ERROR_NONE;
638         pims_ipc_data_h indata = NULL;
639         pims_ipc_data_h outdata = NULL;
640
641         RETVM_IF(query==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
642         RETVM_IF(out_count==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"count pointer is NULL");
643         *out_count = 0;
644
645         // make indata
646         indata = pims_ipc_data_create(0);
647         if (indata == NULL)
648         {
649                 CTS_ERR("ipc data created fail!");
650                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
651                 return ret;
652         }
653         ret = ctsvc_ipc_marshal_query(query,indata);
654         if (ret != CONTACTS_ERROR_NONE)
655         {
656                 CTS_ERR("marshal fail");
657                 return ret;
658         }
659
660         // ipc call
661         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT_WITH_QUERY, indata, &outdata) != 0)
662         {
663                 CTS_ERR("ctsvc_ipc_call failed");
664                 pims_ipc_data_destroy(indata);
665                 return CONTACTS_ERROR_IPC;
666         }
667
668         if (indata)
669         {
670                 pims_ipc_data_destroy(indata);
671         }
672
673         if (outdata)
674         {
675                 // check outdata
676                 unsigned int size = 0;
677                 ret = *(int*) pims_ipc_data_get(outdata,&size);
678
679                 if (ret == CONTACTS_ERROR_NONE)
680                 {
681                         ret = ctsvc_ipc_unmarshal_int(outdata,out_count);
682                 }
683
684                 pims_ipc_data_destroy(outdata);
685         }
686
687         return ret;
688 }
689
690 API int contacts_db_insert_records_async(const contacts_list_h list, contacts_db_insert_result_cb callback, void *user_data)
691 {
692         int ret = CONTACTS_ERROR_NONE;
693         pims_ipc_data_h indata = NULL;
694         ctsvc_ipc_async_userdata_s *async_data = NULL;
695
696         RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
697
698         indata = pims_ipc_data_create(0);
699         if (indata == NULL)
700         {
701                 CTS_ERR("ipc data created fail!");
702                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
703                 return ret;
704         }
705         ret = ctsvc_ipc_marshal_list(list,indata);
706         if (ret != CONTACTS_ERROR_NONE)
707         {
708                 CTS_ERR("marshal fail");
709                 return ret;
710         }
711
712         async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
713         if (async_data == NULL)
714         {
715                 CTS_ERR("malloc fail!");
716                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
717                 pims_ipc_data_destroy(indata);
718                 return ret;
719         }
720         async_data->callback = callback;
721         async_data->user_data = user_data;
722
723         if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_INSERT_RECORDS,
724                                 indata,__ctsvc_ipc_client_insert_records_cb,async_data) != 0)
725         {
726                 CONTACTS_FREE(async_data);
727                 CTS_ERR("ctsvc_ipc_call_async failed");
728                 return CONTACTS_ERROR_IPC;
729         }
730
731         pims_ipc_data_destroy(indata);
732
733         return ret;
734 }
735
736 API int contacts_db_update_records_async(const contacts_list_h list, contacts_db_result_cb callback, void *user_data)
737 {
738         int ret = CONTACTS_ERROR_NONE;
739         pims_ipc_data_h indata = NULL;
740         ctsvc_ipc_async_userdata_s *async_data = NULL;
741
742         RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
743
744         // make indata
745         indata = pims_ipc_data_create(0);
746         if (indata == NULL)
747         {
748                 CTS_ERR("ipc data created fail!");
749                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
750                 return ret;
751         }
752         ret = ctsvc_ipc_marshal_list(list,indata);
753         if (ret != CONTACTS_ERROR_NONE)
754         {
755                 CTS_ERR("marshal fail");
756                 return ret;
757         }
758
759         async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
760         if (async_data == NULL)
761         {
762                 CTS_ERR("malloc fail!");
763                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
764                 pims_ipc_data_destroy(indata);
765                 return ret;
766         }
767         async_data->callback = callback;
768         async_data->user_data = user_data;
769
770         if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_UPDATE_RECORDS,
771                                 indata,__ctsvc_ipc_client_update_records_cb,async_data) != 0)
772         {
773                 CONTACTS_FREE(async_data);
774                 CTS_ERR("ctsvc_ipc_call_async failed");
775                 return CONTACTS_ERROR_IPC;
776         }
777
778         if (indata)
779         {
780                 pims_ipc_data_destroy(indata);
781         }
782
783         return ret;
784 }
785
786 API int contacts_db_delete_records_async(const char* view_uri, int ids[], int count, contacts_db_result_cb callback, void *user_data)
787 {
788         int ret = CONTACTS_ERROR_NONE;
789         pims_ipc_data_h indata = NULL;
790         int i = 0;
791         ctsvc_ipc_async_userdata_s *async_data = NULL;
792
793         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
794         RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
795         RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
796
797         // make indata
798         indata = pims_ipc_data_create(0);
799         if (indata == NULL)
800         {
801                 CTS_ERR("ipc data created fail!");
802                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
803                 return ret;
804         }
805         ret = ctsvc_ipc_marshal_string(view_uri,indata);
806         if (ret != CONTACTS_ERROR_NONE)
807         {
808                 CTS_ERR("marshal fail");
809                 return ret;
810         }
811         ret = ctsvc_ipc_marshal_int(count,indata);
812         if (ret != CONTACTS_ERROR_NONE)
813         {
814                 CTS_ERR("marshal fail");
815                 return ret;
816         }
817         for (i=0;i<count;i++)
818         {
819                 ret = ctsvc_ipc_marshal_int(ids[i],indata);
820                 if (ret != CONTACTS_ERROR_NONE)
821                 {
822                         CTS_ERR("marshal fail");
823                         return ret;
824                 }
825         }
826
827         async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
828         if (async_data == NULL)
829         {
830                 CTS_ERR("malloc fail!");
831                 pims_ipc_data_destroy(indata);
832                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
833                 return ret;
834         }
835         async_data->callback = callback;
836         async_data->user_data = user_data;
837         if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_DELETE_RECORDS,
838                                 indata,__ctsvc_ipc_client_delete_records_cb,async_data) != 0)
839         {
840                 CONTACTS_FREE(async_data);
841                 CTS_ERR("ctsvc_ipc_call_async failed");
842                 return CONTACTS_ERROR_IPC;
843         }
844
845         pims_ipc_data_destroy(indata);
846
847         return ret;
848 }
849
850 void __ctsvc_ipc_client_replace_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
851 {
852         ctsvc_ipc_async_userdata_s *async_data = (ctsvc_ipc_async_userdata_s *)userdata;
853         int ret = CONTACTS_ERROR_NONE;
854
855         if (data_out) {
856                 unsigned int size = 0;
857                 ret = *(int*) pims_ipc_data_get(data_out,&size);
858
859                 if (CONTACTS_ERROR_NONE == ret) {
860                         int transaction_ver = 0;
861                         transaction_ver = *(int*)pims_ipc_data_get(data_out, &size);
862                         ctsvc_client_ipc_set_change_version(transaction_ver);
863                 }
864         }
865
866         if (async_data->callback) {
867                 contacts_db_result_cb callback = async_data->callback;
868                 callback(ret, async_data->user_data);
869         }
870
871         ctsvc_inotify_call_blocked_callback();
872
873         free(async_data);
874
875         return ;
876 }
877
878 API int contacts_db_replace_records_async( contacts_list_h list, int ids[], unsigned int count,
879                 contacts_db_result_cb callback, void *user_data )
880 {
881         int i;
882         int ret = CONTACTS_ERROR_NONE;
883         pims_ipc_data_h indata = NULL;
884         ctsvc_ipc_async_userdata_s *async_data = NULL;
885
886         RETVM_IF(NULL == list,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
887         RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
888         RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
889
890         // make indata
891         indata = pims_ipc_data_create(0);
892         if (indata == NULL) {
893                 CTS_ERR("ipc data created fail!");
894                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
895                 return ret;
896         }
897
898         ret = ctsvc_ipc_marshal_list(list, indata);
899         if (ret != CONTACTS_ERROR_NONE) {
900                 CTS_ERR("marshal fail");
901                 return ret;
902         }
903
904         ret = ctsvc_ipc_marshal_unsigned_int(count, indata);
905         if (ret != CONTACTS_ERROR_NONE) {
906                 CTS_ERR("marshal fail");
907                 return ret;
908         }
909
910         for (i=0;i<count;i++) {
911                 ret = ctsvc_ipc_marshal_int(ids[i],indata);
912                 if (ret != CONTACTS_ERROR_NONE) {
913                         CTS_ERR("marshal fail");
914                         return ret;
915                 }
916         }
917
918         async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
919         async_data->callback = callback;
920         async_data->user_data = user_data;
921
922         if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS,
923                                 indata, __ctsvc_ipc_client_replace_records_cb, async_data) != 0) {
924                 CONTACTS_FREE(async_data);
925                 CTS_ERR("ctsvc_ipc_call_async failed");
926                 return CONTACTS_ERROR_IPC;
927         }
928
929         pims_ipc_data_destroy(indata);
930
931         return ret;
932 }
933
934 API int contacts_db_insert_records( contacts_list_h list, int **ids, unsigned int *count)
935 {
936         int ret = CONTACTS_ERROR_NONE;
937         pims_ipc_data_h indata = NULL;
938         pims_ipc_data_h outdata = NULL;
939
940         if (ids)
941                 *ids = NULL;
942         if (count)
943                 *count = 0;
944
945         RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
946         RETVM_IF(ctsvc_get_ipc_handle()==NULL,CONTACTS_ERROR_IPC, "contacts not connected");
947
948         indata = pims_ipc_data_create(0);
949         if (indata == NULL) {
950                 CTS_ERR("ipc data created fail!");
951                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
952                 return ret;
953         }
954
955         ret = ctsvc_ipc_marshal_list(list,indata);
956         if (ret != CONTACTS_ERROR_NONE) {
957                 CTS_ERR("marshal fail");
958                 pims_ipc_data_destroy(indata);
959                 return ret;
960         }
961
962         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORDS,
963                                 indata, &outdata) != 0) {
964                 CTS_ERR("ctsvc_ipc_call_async failed");
965                 pims_ipc_data_destroy(indata);
966                 return CONTACTS_ERROR_IPC;
967         }
968
969         pims_ipc_data_destroy(indata);
970
971         if (outdata) {
972                 unsigned int size = 0;
973                 ret = *(int*) pims_ipc_data_get(outdata,&size);
974
975                 if (ret == CONTACTS_ERROR_NONE) {
976                         int transaction_ver = 0;
977                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
978                         ctsvc_client_ipc_set_change_version(transaction_ver);
979
980                         if (ids && count) {
981                                 int i = 0;
982                                 int *id = NULL;
983                                 unsigned int c;
984                                 c = *(unsigned int*)pims_ipc_data_get(outdata, &size);
985                                 id = calloc(c, sizeof(int));
986                                 for(i=0;i<c;i++)
987                                         id[i] = *(int*) pims_ipc_data_get(outdata, &size);
988                                 *ids = id;
989                                 *count = c;
990                         }
991                 }
992                 pims_ipc_data_destroy(outdata);
993         }
994
995         return ret;
996 }
997
998 API int contacts_db_update_records( contacts_list_h list)
999 {
1000         int ret = CONTACTS_ERROR_NONE;
1001         pims_ipc_data_h indata = NULL;
1002         pims_ipc_data_h outdata = NULL;
1003
1004         RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "record is NULL");
1005         RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
1006
1007         indata = pims_ipc_data_create(0);
1008         if (indata == NULL) {
1009                 CTS_ERR("ipc data created fail!");
1010                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1011                 return ret;
1012         }
1013
1014         ret = ctsvc_ipc_marshal_list(list,indata);
1015         if (ret != CONTACTS_ERROR_NONE) {
1016                 CTS_ERR("marshal fail");
1017                 pims_ipc_data_destroy(indata);
1018                 return ret;
1019         }
1020
1021         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORDS,
1022                                 indata, &outdata) != 0) {
1023                 CTS_ERR("ctsvc_ipc_call failed");
1024                 pims_ipc_data_destroy(indata);
1025                 return CONTACTS_ERROR_IPC;
1026         }
1027
1028         pims_ipc_data_destroy(indata);
1029
1030         if (outdata) {
1031                 unsigned int size = 0;
1032                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1033                 if (CONTACTS_ERROR_NONE == ret) {
1034                         int transaction_ver = 0;
1035                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
1036                         ctsvc_client_ipc_set_change_version(transaction_ver);
1037                 }
1038
1039                 pims_ipc_data_destroy(outdata);
1040         }
1041
1042         return ret;
1043 }
1044
1045 API int contacts_db_delete_records(const char* view_uri, int ids[], int count)
1046 {
1047         int i;
1048         int ret = CONTACTS_ERROR_NONE;
1049         pims_ipc_data_h indata = NULL;
1050         pims_ipc_data_h outdata = NULL;
1051
1052         RETVM_IF(view_uri == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "view_uri is NULL");
1053         RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
1054
1055         indata = pims_ipc_data_create(0);
1056         if (indata == NULL) {
1057                 CTS_ERR("ipc data created fail!");
1058                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1059                 return ret;
1060         }
1061
1062         ret = ctsvc_ipc_marshal_string(view_uri,indata);
1063         if (ret != CONTACTS_ERROR_NONE) {
1064                 CTS_ERR("marshal fail");
1065                 pims_ipc_data_destroy(indata);
1066                 return ret;
1067         }
1068
1069         ret = ctsvc_ipc_marshal_int(count,indata);
1070         if (ret != CONTACTS_ERROR_NONE) {
1071                 CTS_ERR("marshal fail");
1072                 pims_ipc_data_destroy(indata);
1073                 return ret;
1074         }
1075
1076         for (i=0;i<count;i++) {
1077                 ret = ctsvc_ipc_marshal_int(ids[i],indata);
1078                 if (ret != CONTACTS_ERROR_NONE) {
1079                         CTS_ERR("marshal fail");
1080                         pims_ipc_data_destroy(indata);
1081                         return ret;
1082                 }
1083         }
1084
1085         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORDS,
1086                                 indata, &outdata) != 0) {
1087                 CTS_ERR("ctsvc_ipc_call failed");
1088                 pims_ipc_data_destroy(indata);
1089                 return CONTACTS_ERROR_IPC;
1090         }
1091
1092         pims_ipc_data_destroy(indata);
1093
1094         if (outdata) {
1095                 unsigned int size = 0;
1096                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1097
1098                 if (CONTACTS_ERROR_NONE == ret) {
1099                         int transaction_ver = 0;
1100                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
1101                         ctsvc_client_ipc_set_change_version(transaction_ver);
1102                 }
1103
1104                 pims_ipc_data_destroy(outdata);
1105         }
1106
1107         return ret;
1108 }
1109
1110 API int contacts_db_replace_records( contacts_list_h list, int ids[], unsigned int count )
1111 {
1112         int i;
1113         int ret = CONTACTS_ERROR_NONE;
1114         pims_ipc_data_h indata = NULL;
1115         pims_ipc_data_h outdata = NULL;
1116
1117         RETVM_IF(NULL == list,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
1118         RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
1119         RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
1120
1121         // make indata
1122         indata = pims_ipc_data_create(0);
1123         if (indata == NULL) {
1124                 CTS_ERR("ipc data created fail!");
1125                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1126                 return ret;
1127         }
1128
1129         ret = ctsvc_ipc_marshal_list(list, indata);
1130         if (ret != CONTACTS_ERROR_NONE) {
1131                 CTS_ERR("marshal fail");
1132                 return ret;
1133         }
1134
1135         ret = ctsvc_ipc_marshal_unsigned_int(count, indata);
1136         if (ret != CONTACTS_ERROR_NONE) {
1137                 CTS_ERR("marshal fail");
1138                 return ret;
1139         }
1140
1141         for (i=0;i<count;i++) {
1142                 ret = ctsvc_ipc_marshal_int(ids[i], indata);
1143                 if (ret != CONTACTS_ERROR_NONE) {
1144                         CTS_ERR("marshal fail");
1145                         return ret;
1146                 }
1147         }
1148
1149         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS,
1150                                 indata, &outdata) != 0) {
1151                 CTS_ERR("ctsvc_ipc_call failed");
1152                 pims_ipc_data_destroy(indata);
1153                 return CONTACTS_ERROR_IPC;
1154         }
1155
1156         pims_ipc_data_destroy(indata);
1157
1158         if (outdata) {
1159                 unsigned int size = 0;
1160                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1161                 if (CONTACTS_ERROR_NONE == ret) {
1162                         int transaction_ver = 0;
1163                         transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
1164                         ctsvc_client_ipc_set_change_version(transaction_ver);
1165                 }
1166                 pims_ipc_data_destroy(outdata);
1167         }
1168
1169         return ret;
1170 }
1171
1172 API int contacts_db_get_changes_by_version(const char* view_uri, int addressbook_id, int contacts_db_version, contacts_list_h* record_list, int* current_contacts_db_version )
1173 {
1174         int ret = CONTACTS_ERROR_NONE;
1175         pims_ipc_data_h indata = NULL;
1176         pims_ipc_data_h outdata = NULL;
1177
1178         RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
1179         RETVM_IF(record_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record_list is NULL");
1180         RETVM_IF(current_contacts_db_version==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"current_contacts_db_version is NULL");
1181         *record_list = NULL;
1182
1183         // make indata
1184         indata = pims_ipc_data_create(0);
1185         if (indata == NULL)
1186         {
1187                 CTS_ERR("ipc data created fail!");
1188                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1189                 return ret;
1190         }
1191         ret = ctsvc_ipc_marshal_string(view_uri,indata);
1192         if (ret != CONTACTS_ERROR_NONE)
1193         {
1194                 CTS_ERR("marshal fail");
1195                 return ret;
1196         }
1197         ret = ctsvc_ipc_marshal_int(addressbook_id,indata);
1198         if (ret != CONTACTS_ERROR_NONE)
1199         {
1200                 CTS_ERR("marshal fail");
1201                 return ret;
1202         }
1203         ret = ctsvc_ipc_marshal_int(contacts_db_version,indata);
1204         if (ret != CONTACTS_ERROR_NONE)
1205         {
1206                 CTS_ERR("marshal fail");
1207                 return ret;
1208         }
1209
1210         // ipc call
1211         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_CHANGES_BY_VERSION, indata, &outdata) != 0)
1212         {
1213                 CTS_ERR("ctsvc_ipc_call failed");
1214                 pims_ipc_data_destroy(indata);
1215                 return CONTACTS_ERROR_IPC;
1216         }
1217
1218         if (indata)
1219         {
1220                 pims_ipc_data_destroy(indata);
1221         }
1222
1223         if (outdata)
1224         {
1225                 // check outdata
1226                 unsigned int size = 0;
1227                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1228
1229                 if (ret == CONTACTS_ERROR_NONE)
1230                 {
1231                         ret = ctsvc_ipc_unmarshal_list(outdata,record_list);
1232
1233                         if (ret == CONTACTS_ERROR_NONE)
1234                         {
1235                                 ret = ctsvc_ipc_unmarshal_int(outdata,current_contacts_db_version);
1236                         }
1237                 }
1238
1239                 pims_ipc_data_destroy(outdata);
1240         }
1241
1242         return ret;
1243 }
1244
1245 API int contacts_db_get_current_version(int* contacts_db_version)
1246 {
1247         int ret = CONTACTS_ERROR_NONE;
1248         pims_ipc_data_h outdata = NULL;
1249
1250         RETVM_IF(contacts_db_version==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"contacts_db_version is null");
1251         *contacts_db_version = 0;
1252
1253         // ipc call
1254         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_CURRENT_VERSION, NULL, &outdata) != 0)
1255         {
1256                 CTS_ERR("ctsvc_ipc_call failed");
1257                 return CONTACTS_ERROR_IPC;
1258         }
1259
1260         if (outdata)
1261         {
1262                 // check outdata
1263                 unsigned int size = 0;
1264                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1265                 if (ret == CONTACTS_ERROR_NONE)
1266                 {
1267                         ret = ctsvc_ipc_unmarshal_int(outdata,contacts_db_version);
1268                 }
1269                 pims_ipc_data_destroy(outdata);
1270         }
1271
1272         return ret;
1273 }
1274
1275 API int contacts_db_search_records(const char* view_uri, const char *keyword,
1276                 int offset, int limit, contacts_list_h* out_list)
1277 {
1278         int ret = CONTACTS_ERROR_NONE;
1279         pims_ipc_data_h indata = NULL;
1280         pims_ipc_data_h outdata = NULL;
1281
1282         RETVM_IF(out_list == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
1283         RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
1284         *out_list = NULL;
1285
1286         // make indata
1287         indata = pims_ipc_data_create(0);
1288         if (indata == NULL)
1289         {
1290                 CTS_ERR("ipc data created fail !");
1291                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1292                 return ret;
1293         }
1294         ret = ctsvc_ipc_marshal_string(view_uri,indata);
1295         if (ret != CONTACTS_ERROR_NONE)
1296         {
1297                 CTS_ERR("marshal fail");
1298                 return ret;
1299         }
1300         ret = ctsvc_ipc_marshal_string(keyword,indata);
1301         if (ret != CONTACTS_ERROR_NONE)
1302         {
1303                 CTS_ERR("marshal fail");
1304                 return ret;
1305         }
1306         ret = ctsvc_ipc_marshal_int(offset,indata);
1307         if (ret != CONTACTS_ERROR_NONE)
1308         {
1309                 CTS_ERR("marshal fail");
1310                 return ret;
1311         }
1312         ret = ctsvc_ipc_marshal_int(limit,indata);
1313         if (ret != CONTACTS_ERROR_NONE)
1314         {
1315                 CTS_ERR("marshal fail");
1316                 return ret;
1317         }
1318
1319         // ipc call
1320         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS, indata, &outdata) != 0)
1321         {
1322                 CTS_ERR("ctsvc_ipc_call failed");
1323                 pims_ipc_data_destroy(indata);
1324                 return CONTACTS_ERROR_IPC;
1325         }
1326
1327         if (indata)
1328         {
1329                 pims_ipc_data_destroy(indata);
1330         }
1331
1332         if (outdata)
1333         {
1334                 // check outdata
1335                 unsigned int size = 0;
1336                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1337
1338                 if (ret == CONTACTS_ERROR_NONE)
1339                 {
1340                         ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
1341                 }
1342
1343                 pims_ipc_data_destroy(outdata);
1344         }
1345
1346         return ret;
1347 }
1348
1349 API int contacts_db_search_records_with_range(const char* view_uri, const char *keyword,
1350                 int offset, int limit, int range, contacts_list_h* out_list)
1351 {
1352         int ret = CONTACTS_ERROR_NONE;
1353         pims_ipc_data_h indata = NULL;
1354         pims_ipc_data_h outdata = NULL;
1355
1356         RETVM_IF(out_list == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
1357         *out_list = NULL;
1358         RETVM_IF(range == 0, CONTACTS_ERROR_INVALID_PARAMETER, "range is 0");
1359         RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
1360
1361         indata = pims_ipc_data_create(0);
1362         if (indata == NULL) {
1363                 CTS_ERR("ipc data created fail !");
1364                 return CONTACTS_ERROR_OUT_OF_MEMORY;
1365         }
1366
1367         ret = ctsvc_ipc_marshal_string(view_uri, indata);
1368         if (ret != CONTACTS_ERROR_NONE) {
1369                 CTS_ERR("marshal fail");
1370                 goto DATA_FREE;
1371         }
1372         ret = ctsvc_ipc_marshal_string(keyword, indata);
1373         if (ret != CONTACTS_ERROR_NONE) {
1374                 CTS_ERR("marshal fail");
1375                 goto DATA_FREE;
1376         }
1377         ret = ctsvc_ipc_marshal_int(offset, indata);
1378         if (ret != CONTACTS_ERROR_NONE) {
1379                 CTS_ERR("marshal fail");
1380                 goto DATA_FREE;
1381         }
1382         ret = ctsvc_ipc_marshal_int(limit, indata);
1383         if (ret != CONTACTS_ERROR_NONE) {
1384                 CTS_ERR("marshal fail");
1385                 goto DATA_FREE;
1386         }
1387         ret = ctsvc_ipc_marshal_int(range, indata);
1388         if (ret != CONTACTS_ERROR_NONE) {
1389                 CTS_ERR("marshal fail");
1390                 goto DATA_FREE;
1391         }
1392
1393         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_RANGE, indata, &outdata) != 0) {
1394                 CTS_ERR("ctsvc_ipc_call failed");
1395                 pims_ipc_data_destroy(indata);
1396                 return CONTACTS_ERROR_IPC;
1397         }
1398
1399         pims_ipc_data_destroy(indata);
1400
1401         if (outdata) {
1402                 unsigned int size = 0;
1403                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1404
1405                 if (ret == CONTACTS_ERROR_NONE)
1406                         ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
1407                 pims_ipc_data_destroy(outdata);
1408         }
1409
1410         return ret;
1411
1412 DATA_FREE:
1413         free(indata);
1414         return ret;
1415 }
1416
1417 API int contacts_db_search_records_with_query(contacts_query_h query, const char *keyword,
1418                 int offset, int limit, contacts_list_h* out_list)
1419 {
1420         int ret = CONTACTS_ERROR_NONE;
1421         pims_ipc_data_h indata = NULL;
1422         pims_ipc_data_h outdata = NULL;
1423
1424         RETVM_IF(query==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "query is NULL");
1425         RETVM_IF(out_list==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
1426         RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
1427         *out_list = NULL;
1428
1429         // make indata
1430         indata = pims_ipc_data_create(0);
1431         if (indata == NULL)
1432         {
1433                 CTS_ERR("ipc data created fail !");
1434                 ret = CONTACTS_ERROR_OUT_OF_MEMORY;
1435                 return ret;
1436         }
1437         ret = ctsvc_ipc_marshal_query(query,indata);
1438         if (ret != CONTACTS_ERROR_NONE)
1439         {
1440                 CTS_ERR("marshal fail");
1441                 return ret;
1442         }
1443         ret = ctsvc_ipc_marshal_string(keyword,indata);
1444         if (ret != CONTACTS_ERROR_NONE)
1445         {
1446                 CTS_ERR("marshal fail");
1447                 return ret;
1448         }
1449         ret = ctsvc_ipc_marshal_int(offset,indata);
1450         if (ret != CONTACTS_ERROR_NONE)
1451         {
1452                 CTS_ERR("marshal fail");
1453                 return ret;
1454         }
1455         ret = ctsvc_ipc_marshal_int(limit,indata);
1456         if (ret != CONTACTS_ERROR_NONE)
1457         {
1458                 CTS_ERR("marshal fail");
1459                 return ret;
1460         }
1461
1462         // ipc call
1463         if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_QUERY, indata, &outdata) != 0)
1464         {
1465                 CTS_ERR("ctsvc_ipc_call failed");
1466                 pims_ipc_data_destroy(indata);
1467                 return CONTACTS_ERROR_IPC;
1468         }
1469
1470         if (indata)
1471         {
1472                 pims_ipc_data_destroy(indata);
1473         }
1474
1475         if (outdata)
1476         {
1477                 // check outdata
1478                 unsigned int size = 0;
1479                 ret = *(int*) pims_ipc_data_get(outdata,&size);
1480
1481                 if (ret == CONTACTS_ERROR_NONE)
1482                 {
1483                         ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
1484                 }
1485
1486                 pims_ipc_data_destroy(outdata);
1487         }
1488
1489         return ret;
1490 }
1491
1492 API int contacts_db_get_last_change_version(int* last_version)
1493 {
1494         int ret = CONTACTS_ERROR_NONE;
1495
1496         RETVM_IF(NULL == last_version, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
1497         *last_version = ctsvc_client_ipc_get_change_version();
1498         return ret;
1499 }
1500