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