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