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