[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_sip.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 "contacts.h"
21 #include "ctsvc_internal.h"
22 #include "ctsvc_db_schema.h"
23 #include "ctsvc_db_sqlite.h"
24 #include "ctsvc_db_utils.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_access_control.h"
27 #include "ctsvc_db_plugin_sip_helper.h"
28 #include "ctsvc_db_plugin_contact_helper.h"
29 #include "ctsvc_record.h"
30 #include "ctsvc_db_query.h"
31 #include "ctsvc_list.h"
32 #include "ctsvc_notification.h"
33
34 static int __ctsvc_db_sip_insert_record(contacts_record_h record, int *id);
35 static int __ctsvc_db_sip_get_record(int id, contacts_record_h* out_record);
36 static int __ctsvc_db_sip_update_record(contacts_record_h record);
37 static int __ctsvc_db_sip_delete_record(int id);
38 static int __ctsvc_db_sip_get_all_records(int offset, int limit, contacts_list_h* out_list);
39 static int __ctsvc_db_sip_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h* out_list);
40
41 ctsvc_db_plugin_info_s ctsvc_db_plugin_sip = {
42         .is_query_only = false,
43         .insert_record = __ctsvc_db_sip_insert_record,
44         .get_record = __ctsvc_db_sip_get_record,
45         .update_record = __ctsvc_db_sip_update_record,
46         .delete_record = __ctsvc_db_sip_delete_record,
47         .get_all_records = __ctsvc_db_sip_get_all_records,
48         .get_records_with_query = __ctsvc_db_sip_get_records_with_query,
49         .insert_records = NULL,
50         .update_records = NULL,
51         .delete_records = NULL,
52         .get_count = NULL,
53         .get_count_with_query = NULL,
54         .replace_record = NULL,
55         .replace_records = NULL,
56 };
57
58 static int __ctsvc_db_sip_insert_record(contacts_record_h record, int *id)
59 {
60         int ret;
61         int addressbook_id;
62         char query[CTS_SQL_MAX_LEN] = {0};
63         ctsvc_sip_s *sip = (ctsvc_sip_s *)record;
64
65         ret = ctsvc_begin_trans();
66         if (CONTACTS_ERROR_NONE != ret) {
67                 /* LCOV_EXCL_START */
68                 ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
69                 return ret;
70                 /* LCOV_EXCL_STOP */
71         }
72
73         snprintf(query, sizeof(query),
74                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", sip->contact_id);
75         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
76         if (CONTACTS_ERROR_NONE != ret) {
77                 ctsvc_end_trans(false);
78                 if (CONTACTS_ERROR_NO_DATA == ret) {
79                         /* LCOV_EXCL_START */
80                         ERR("No data : contact_id (%d) is not exist", sip->contact_id);
81                         return CONTACTS_ERROR_INVALID_PARAMETER;
82                         /* LCOV_EXCL_STOP */
83                 } else {
84                         /* LCOV_EXCL_START */
85                         ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
86                         return ret;
87                         /* LCOV_EXCL_STOP */
88                 }
89         }
90
91         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
92                 /* LCOV_EXCL_START */
93                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
94                 ctsvc_end_trans(false);
95                 return CONTACTS_ERROR_PERMISSION_DENIED;
96                 /* LCOV_EXCL_STOP */
97         }
98
99         ret = ctsvc_db_sip_insert(record, sip->contact_id, false, id);
100         if (CONTACTS_ERROR_NONE != ret) {
101                 /* LCOV_EXCL_START */
102                 ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
103                 ctsvc_end_trans(false);
104                 return ret;
105                 /* LCOV_EXCL_STOP */
106         }
107
108         ret = ctsvc_db_contact_update_changed_time(sip->contact_id);
109         if (CONTACTS_ERROR_NONE != ret) {
110                 /* LCOV_EXCL_START */
111                 ERR("DB error : ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
112                 ctsvc_end_trans(false);
113                 return ret;
114                 /* LCOV_EXCL_STOP */
115         }
116         ctsvc_set_person_noti();
117
118         ret = ctsvc_end_trans(true);
119         if (ret < CONTACTS_ERROR_NONE) {
120                 /* LCOV_EXCL_START */
121                 ERR("DB error : ctsvc_end_trans() Fail(%d)", ret);
122                 return ret;
123                 /* LCOV_EXCL_STOP */
124         }
125
126         return CONTACTS_ERROR_NONE;
127 }
128
129 static int __ctsvc_db_sip_get_record(int id, contacts_record_h* out_record)
130 {
131         int ret;
132         cts_stmt stmt = NULL;
133         char query[CTS_SQL_MAX_LEN] = {0};
134
135         RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
136         *out_record = NULL;
137
138         snprintf(query, sizeof(query),
139                         "SELECT id, data.contact_id, is_default, data1, data2, data3 "
140                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
141                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
142                         "WHERE id = %d AND datatype = %d ",
143                         id, CONTACTS_DATA_TYPE_SIP);
144
145         ret = ctsvc_query_prepare(query, &stmt);
146         RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Fail(%d)", ret);
147
148         ret = ctsvc_stmt_step(stmt);
149         if (1 /*CTS_TRUE*/ != ret) {
150                 /* LCOV_EXCL_START */
151                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
152                 ctsvc_stmt_finalize(stmt);
153                 if (CONTACTS_ERROR_NONE == ret)
154                         return CONTACTS_ERROR_NO_DATA;
155                 else
156                         return ret;
157                 /* LCOV_EXCL_STOP */
158         }
159
160         ctsvc_db_sip_get_value_from_stmt(stmt, out_record, 0);
161
162         ctsvc_stmt_finalize(stmt);
163
164         return CONTACTS_ERROR_NONE;
165 }
166
167 static int __ctsvc_db_sip_update_record(contacts_record_h record)
168 {
169         int ret;
170         int addressbook_id;
171         char query[CTS_SQL_MAX_LEN] = {0};
172         ctsvc_sip_s *sip = (ctsvc_sip_s *)record;
173
174         ret = ctsvc_begin_trans();
175         if (CONTACTS_ERROR_NONE != ret) {
176                 /* LCOV_EXCL_START */
177                 ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
178                 return ret;
179                 /* LCOV_EXCL_STOP */
180         }
181
182         snprintf(query, sizeof(query),
183                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", sip->contact_id);
184         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
185         if (CONTACTS_ERROR_NONE != ret) {
186                 /* LCOV_EXCL_START */
187                 ERR("No data : contact_id (%d) is not exist", sip->contact_id);
188                 ctsvc_end_trans(false);
189                 return ret;
190                 /* LCOV_EXCL_STOP */
191         }
192
193         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
194                 /* LCOV_EXCL_START */
195                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
196                 ctsvc_end_trans(false);
197                 return CONTACTS_ERROR_PERMISSION_DENIED;
198                 /* LCOV_EXCL_STOP */
199         }
200
201         ret = ctsvc_db_sip_update(record, false);
202         if (CONTACTS_ERROR_NONE != ret) {
203                 /* LCOV_EXCL_START */
204                 ERR("update record Fail(%d)", ret);
205                 ctsvc_end_trans(false);
206                 return ret;
207                 /* LCOV_EXCL_STOP */
208         }
209
210         /* TODO ; contact display sip update */
211         ret = ctsvc_db_contact_update_changed_time(sip->contact_id);
212         if (CONTACTS_ERROR_NONE != ret) {
213                 /* LCOV_EXCL_START */
214                 ERR("DB error : ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
215                 ctsvc_end_trans(false);
216                 return ret;
217                 /* LCOV_EXCL_STOP */
218         }
219         ctsvc_set_person_noti();
220
221         ret = ctsvc_end_trans(true);
222         if (ret < CONTACTS_ERROR_NONE) {
223                 /* LCOV_EXCL_START */
224                 ERR("DB error : ctsvc_end_trans() Fail(%d)", ret);
225                 return ret;
226                 /* LCOV_EXCL_STOP */
227         }
228
229         return CONTACTS_ERROR_NONE;
230 }
231
232 static int __ctsvc_db_sip_delete_record(int id)
233 {
234         int ret;
235         int contact_id;
236         char query[CTS_SQL_MAX_LEN] = {0};
237         cts_stmt stmt = NULL;
238         int addressbook_id;
239
240         ret = ctsvc_begin_trans();
241         if (CONTACTS_ERROR_NONE != ret) {
242                 /* LCOV_EXCL_START */
243                 ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
244                 return ret;
245                 /* LCOV_EXCL_STOP */
246         }
247
248         snprintf(query, sizeof(query),
249                         "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
250                         "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
251         ret = ctsvc_query_prepare(query, &stmt);
252         if (NULL == stmt) {
253                 /* LCOV_EXCL_START */
254                 ERR("DB error : ctsvc_query_prepare() Fail(%d)", ret);
255                 ctsvc_end_trans(false);
256                 return ret;
257                 /* LCOV_EXCL_STOP */
258         }
259         ret = ctsvc_stmt_step(stmt);
260         if (1 != ret) {
261                 /* LCOV_EXCL_START */
262                 ERR("The id(%d) is Invalid(%d)", id, ret);
263                 ctsvc_stmt_finalize(stmt);
264                 ctsvc_end_trans(false);
265                 if (CONTACTS_ERROR_NONE == ret)
266                         return CONTACTS_ERROR_NO_DATA;
267                 else
268                         return ret;
269                 /* LCOV_EXCL_STOP */
270         }
271
272         contact_id = ctsvc_stmt_get_int(stmt, 0);
273         addressbook_id = ctsvc_stmt_get_int(stmt, 1);
274         ctsvc_stmt_finalize(stmt);
275
276         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
277                 /* LCOV_EXCL_START */
278                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
279                 ctsvc_end_trans(false);
280                 return CONTACTS_ERROR_PERMISSION_DENIED;
281                 /* LCOV_EXCL_STOP */
282         }
283
284         ret = ctsvc_db_sip_delete(id, false);
285         if (CONTACTS_ERROR_NONE != ret) {
286                 /* LCOV_EXCL_START */
287                 ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
288                 ctsvc_end_trans(false);
289                 return ret;
290                 /* LCOV_EXCL_STOP */
291         }
292
293         ret = ctsvc_db_contact_update_changed_time(contact_id);
294         if (CONTACTS_ERROR_NONE != ret) {
295                 /* LCOV_EXCL_START */
296                 ERR("DB error : ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
297                 ctsvc_end_trans(false);
298                 return ret;
299                 /* LCOV_EXCL_STOP */
300         }
301         ctsvc_set_person_noti();
302
303         ret = ctsvc_end_trans(true);
304         if (ret < CONTACTS_ERROR_NONE) {
305                 /* LCOV_EXCL_START */
306                 ERR("DB error : ctsvc_end_trans() Fail(%d)", ret);
307                 return ret;
308                 /* LCOV_EXCL_STOP */
309         }
310
311         return CONTACTS_ERROR_NONE;
312 }
313
314 static int __ctsvc_db_sip_get_all_records(int offset, int limit, contacts_list_h* out_list)
315 {
316         int len;
317         int ret;
318         contacts_list_h list;
319         ctsvc_sip_s *sip;
320         cts_stmt stmt = NULL;
321         char query[CTS_SQL_MAX_LEN] = {0};
322
323         len = snprintf(query, sizeof(query),
324                         "SELECT id, data.contact_id, is_default, data1, data2, data3 "
325                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
326                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
327                         "WHERE datatype = %d AND is_my_profile=0 ",
328                         CONTACTS_DATA_TYPE_SIP);
329
330         if (0 != limit) {
331                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
332                 if (0 < offset)
333                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
334         }
335
336         ret = ctsvc_query_prepare(query, &stmt);
337         RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Fail(%d)", ret);
338
339         contacts_list_create(&list);
340         while ((ret = ctsvc_stmt_step(stmt))) {
341                 if (1 /*CTS_TRUE */ != ret) {
342                         /* LCOV_EXCL_START */
343                         ERR("DB : ctsvc_stmt_step fail(%d)", ret);
344                         ctsvc_stmt_finalize(stmt);
345                         contacts_list_destroy(list, true);
346                         return ret;
347                         /* LCOV_EXCL_STOP */
348                 }
349                 ctsvc_db_sip_get_value_from_stmt(stmt, (contacts_record_h*)&sip, 0);
350                 ctsvc_list_prepend(list, (contacts_record_h)sip);
351         }
352         ctsvc_stmt_finalize(stmt);
353         ctsvc_list_reverse(list);
354
355         *out_list = list;
356         return CONTACTS_ERROR_NONE;
357 }
358
359 static int __ctsvc_db_sip_get_records_with_query(contacts_query_h query, int offset,
360                 int limit, contacts_list_h* out_list)
361 {
362         int ret;
363         int i;
364         int field_count;
365         ctsvc_query_s *s_query;
366         cts_stmt stmt;
367         contacts_list_h list;
368         ctsvc_sip_s *sip;
369
370         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
371         s_query = (ctsvc_query_s *)query;
372
373         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
374         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
375
376         contacts_list_create(&list);
377         while ((ret = ctsvc_stmt_step(stmt))) {
378                 contacts_record_h record;
379                 if (1 /*CTS_TRUE */ != ret) {
380                         /* LCOV_EXCL_START */
381                         ERR("DB error : ctsvc_stmt_step() Fail(%d)", ret);
382                         ctsvc_stmt_finalize(stmt);
383                         contacts_list_destroy(list, true);
384                         return ret;
385                         /* LCOV_EXCL_STOP */
386                 }
387
388                 contacts_record_create(_contacts_sip._uri, &record);
389                 sip = (ctsvc_sip_s*)record;
390                 if (0 == s_query->projection_count)
391                         field_count = s_query->property_count;
392                 else {
393                         field_count = s_query->projection_count;
394                         ret = ctsvc_record_set_projection_flags(record, s_query->projection,
395                                         s_query->projection_count, s_query->property_count);
396
397                         if (CONTACTS_ERROR_NONE != ret)
398                                 ASSERT_NOT_REACHED("To set projection is Fail.\n");
399                 }
400
401                 for (i = 0; i < field_count; i++) {
402                         char *temp;
403                         int property_id;
404                         if (0 == s_query->projection_count)
405                                 property_id = s_query->properties[i].property_id;
406                         else
407                                 property_id = s_query->projection[i];
408
409                         switch (property_id) {
410                         case CTSVC_PROPERTY_SIP_ID:
411                                 sip->id = ctsvc_stmt_get_int(stmt, i);
412                                 break;
413                         case CTSVC_PROPERTY_SIP_CONTACT_ID:
414                                 sip->contact_id = ctsvc_stmt_get_int(stmt, i);
415                                 break;
416                         case CTSVC_PROPERTY_SIP_ADDRESS:
417                                 temp = ctsvc_stmt_get_text(stmt, i);
418                                 free(sip->address);
419                                 sip->address = SAFE_STRDUP(temp);
420                                 break;
421                         case CTSVC_PROPERTY_SIP_TYPE:
422                                 sip->type = ctsvc_stmt_get_int(stmt, i);
423                                 break;
424                         case CTSVC_PROPERTY_SIP_LABEL:
425                                 temp = ctsvc_stmt_get_text(stmt, i);
426                                 free(sip->label);
427                                 sip->label = SAFE_STRDUP(temp);
428                                 break;
429                         default:
430                                 break;
431                         }
432                 }
433                 ctsvc_list_prepend(list, record);
434         }
435         ctsvc_stmt_finalize(stmt);
436         ctsvc_list_reverse(list);
437
438         *out_list = list;
439         return CONTACTS_ERROR_NONE;
440 }