[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_extension.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_contact_helper.h"
27 #include "ctsvc_db_plugin_extension_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_extension_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_extension_s *extension = (ctsvc_extension_s*)record;
40
41         RETVM_IF(NULL == extension->data2 && NULL == extension->data3 && NULL == extension->data4
42                         && NULL == extension->data5 && NULL == extension->data6 && NULL == extension->data7
43                         && NULL == extension->data8 && NULL == extension->data9 && NULL == extension->data10
44                         && NULL == extension->data11 && NULL == extension->data12,
45                         CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
46
47         ret = ctsvc_begin_trans();
48         if (CONTACTS_ERROR_NONE != ret) {
49                 /* LCOV_EXCL_START */
50                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
51                 return ret;
52                 /* LCOV_EXCL_STOP */
53         }
54
55         snprintf(query, sizeof(query),
56                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id);
57         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
58         if (CONTACTS_ERROR_NONE != ret) {
59                 ctsvc_end_trans(false);
60                 if (CONTACTS_ERROR_NO_DATA == ret) {
61                         /* LCOV_EXCL_START */
62                         ERR("No data : contact_id (%d) is not exist", extension->contact_id);
63                         return CONTACTS_ERROR_INVALID_PARAMETER;
64                         /* LCOV_EXCL_STOP */
65                 } else {
66                         /* LCOV_EXCL_START */
67                         ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
68                         return ret;
69                         /* LCOV_EXCL_STOP */
70                 }
71         }
72
73         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
74                 /* LCOV_EXCL_START */
75                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
76                 ctsvc_end_trans(false);
77                 return CONTACTS_ERROR_PERMISSION_DENIED;
78                 /* LCOV_EXCL_STOP */
79         }
80
81         ret = ctsvc_db_extension_insert(record, extension->contact_id, false, id);
82         if (CONTACTS_ERROR_NONE != ret) {
83                 /* LCOV_EXCL_START */
84                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
85                 ctsvc_end_trans(false);
86                 return ret;
87                 /* LCOV_EXCL_STOP */
88         }
89
90         ret = ctsvc_db_contact_update_changed_time(extension->contact_id);
91         if (CONTACTS_ERROR_NONE != ret) {
92                 /* LCOV_EXCL_START */
93                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
94                 ctsvc_end_trans(false);
95                 return ret;
96                 /* LCOV_EXCL_STOP */
97         }
98         ctsvc_set_person_noti();
99
100         ret = ctsvc_end_trans(true);
101         if (ret < CONTACTS_ERROR_NONE) {
102                 /* LCOV_EXCL_START */
103                 ERR("ctsvc_end_trans() Fail(%d)", ret);
104                 return ret;
105                 /* LCOV_EXCL_STOP */
106         } else {
107                 return CONTACTS_ERROR_NONE;
108         }
109 }
110
111 static int __ctsvc_db_extension_get_record(int id, contacts_record_h *out_record)
112 {
113         int ret;
114         cts_stmt stmt = NULL;
115         char query[CTS_SQL_MAX_LEN] = {0};
116
117         RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
118         *out_record = NULL;
119
120         snprintf(query, sizeof(query),
121                         "SELECT id, data.contact_id, is_default, data1, data2, "
122                         "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
123                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
124                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
125                         "WHERE id = %d AND datatype = %d ",
126                         id, CONTACTS_DATA_TYPE_EXTENSION);
127
128         ret = ctsvc_query_prepare(query, &stmt);
129         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
130
131         ret = ctsvc_stmt_step(stmt);
132         if (1 /*CTS_TRUE*/ != ret) {
133                 /* LCOV_EXCL_START */
134                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
135                 ctsvc_stmt_finalize(stmt);
136                 if (CONTACTS_ERROR_NONE == ret)
137                         return CONTACTS_ERROR_NO_DATA;
138                 else
139                         return ret;
140                 /* LCOV_EXCL_STOP */
141         }
142
143         ctsvc_db_extension_get_value_from_stmt(stmt, out_record, 0);
144
145         ctsvc_stmt_finalize(stmt);
146
147         return CONTACTS_ERROR_NONE;
148 }
149
150 static int __ctsvc_db_extension_update_record(contacts_record_h record)
151 {
152         int ret;
153         int addressbook_id;
154         char query[CTS_SQL_MAX_LEN] = {0};
155         ctsvc_extension_s *extension = (ctsvc_extension_s*)record;
156
157         RETVM_IF(NULL == extension->data2 && NULL == extension->data3 && NULL == extension->data4 &&
158                         NULL == extension->data5 && NULL == extension->data6 && NULL == extension->data7 &&
159                         NULL == extension->data8 && NULL == extension->data9 && NULL == extension->data10 &&
160                         NULL == extension->data11 && NULL == extension->data12, CONTACTS_ERROR_INVALID_PARAMETER, "extension is empty");
161
162         ret = ctsvc_begin_trans();
163         if (CONTACTS_ERROR_NONE != ret) {
164                 /* LCOV_EXCL_START */
165                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
166                 return ret;
167                 /* LCOV_EXCL_STOP */
168         }
169
170         snprintf(query, sizeof(query),
171                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id);
172         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
173         if (CONTACTS_ERROR_NONE != ret) {
174                 /* LCOV_EXCL_START */
175                 ERR("No data : contact_id (%d) is not exist", extension->contact_id);
176                 ctsvc_end_trans(false);
177                 return ret;
178                 /* LCOV_EXCL_STOP */
179         }
180
181         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
182                 /* LCOV_EXCL_START */
183                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
184                 ctsvc_end_trans(false);
185                 return CONTACTS_ERROR_PERMISSION_DENIED;
186                 /* LCOV_EXCL_STOP */
187         }
188
189         ret = ctsvc_db_extension_update(record);
190         if (CONTACTS_ERROR_NONE != ret) {
191                 /* LCOV_EXCL_START */
192                 ERR("update record Fail(%d)", ret);
193                 ctsvc_end_trans(false);
194                 return ret;
195                 /* LCOV_EXCL_STOP */
196         }
197
198         ret = ctsvc_db_contact_update_changed_time(extension->contact_id);
199         if (CONTACTS_ERROR_NONE != ret) {
200                 /* LCOV_EXCL_START */
201                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
202                 ctsvc_end_trans(false);
203                 return ret;
204                 /* LCOV_EXCL_STOP */
205         }
206         ctsvc_set_person_noti();
207
208         ret = ctsvc_end_trans(true);
209         if (ret < CONTACTS_ERROR_NONE) {
210                 /* LCOV_EXCL_START */
211                 ERR("ctsvc_end_trans() Fail(%d)", ret);
212                 return ret;
213                 /* LCOV_EXCL_STOP */
214         } else {
215                 return CONTACTS_ERROR_NONE;
216         }
217 }
218
219 static int __ctsvc_db_extension_delete_record(int id)
220 {
221         int ret;
222         int contact_id;
223         char query[CTS_SQL_MAX_LEN] = {0};
224         cts_stmt stmt = NULL;
225         int addressbook_id;
226
227         ret = ctsvc_begin_trans();
228         if (CONTACTS_ERROR_NONE != ret) {
229                 /* LCOV_EXCL_START */
230                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
231                 return ret;
232                 /* LCOV_EXCL_STOP */
233         }
234
235         snprintf(query, sizeof(query),
236                         "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
237                         "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
238         ret = ctsvc_query_prepare(query, &stmt);
239         if (NULL == stmt) {
240                 /* LCOV_EXCL_START */
241                 ERR("ctsvc_query_prepare Fail(%d)", ret);
242                 ctsvc_end_trans(false);
243                 return ret;
244                 /* LCOV_EXCL_STOP */
245         }
246         ret = ctsvc_stmt_step(stmt);
247         if (1 != ret) {
248                 /* LCOV_EXCL_START */
249                 ERR("The id(%d) is Invalid(%d)", id, ret);
250                 ctsvc_stmt_finalize(stmt);
251                 ctsvc_end_trans(false);
252                 if (CONTACTS_ERROR_NONE == ret)
253                         return CONTACTS_ERROR_NO_DATA;
254                 else
255                         return ret;
256                 /* LCOV_EXCL_STOP */
257         }
258
259         contact_id = ctsvc_stmt_get_int(stmt, 0);
260         addressbook_id = ctsvc_stmt_get_int(stmt, 1);
261         ctsvc_stmt_finalize(stmt);
262
263         if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
264                 /* LCOV_EXCL_START */
265                 ERR("No permission in this addresbook_id(%d)", addressbook_id);
266                 ctsvc_end_trans(false);
267                 return CONTACTS_ERROR_PERMISSION_DENIED;
268                 /* LCOV_EXCL_STOP */
269         }
270
271         ret = ctsvc_db_extension_delete(id, false);
272         if (CONTACTS_ERROR_NONE != ret) {
273                 /* LCOV_EXCL_START */
274                 ERR("ctsvc_begin_trans() Fail(%d)", ret);
275                 ctsvc_end_trans(false);
276                 return ret;
277                 /* LCOV_EXCL_STOP */
278         }
279
280         ret = ctsvc_db_contact_update_changed_time(contact_id);
281         if (CONTACTS_ERROR_NONE != ret) {
282                 /* LCOV_EXCL_START */
283                 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
284                 ctsvc_end_trans(false);
285                 return ret;
286                 /* LCOV_EXCL_STOP */
287         }
288         ctsvc_set_person_noti();
289
290         ret = ctsvc_end_trans(true);
291         if (ret < CONTACTS_ERROR_NONE) {
292                 /* LCOV_EXCL_START */
293                 ERR("ctsvc_end_trans() Fail(%d)", ret);
294                 return ret;
295                 /* LCOV_EXCL_STOP */
296         } else {
297                 return CONTACTS_ERROR_NONE;
298         }
299 }
300
301 static int __ctsvc_db_extension_get_all_records(int offset, int limit, contacts_list_h *out_list)
302 {
303         int len;
304         int ret;
305         contacts_list_h list;
306         ctsvc_extension_s *extension;
307         cts_stmt stmt = NULL;
308         char query[CTS_SQL_MAX_LEN] = {0};
309
310         len = snprintf(query, sizeof(query),
311                         "SELECT id, data.contact_id, is_default, data1, data2, "
312                         "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
313                         "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
314                         "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
315                         "WHERE datatype = %d AND is_my_profile=0 ",
316                         CONTACTS_DATA_TYPE_EXTENSION);
317
318         if (0 != limit) {
319                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
320                 if (0 < offset)
321                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
322         }
323
324         ret = ctsvc_query_prepare(query, &stmt);
325         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
326
327         contacts_list_create(&list);
328         while ((ret = ctsvc_stmt_step(stmt))) {
329                 if (1 /*CTS_TRUE */ != ret) {
330                         /* LCOV_EXCL_START */
331                         ERR("DB : ctsvc_stmt_step fail(%d)", ret);
332                         ctsvc_stmt_finalize(stmt);
333                         contacts_list_destroy(list, true);
334                         return ret;
335                         /* LCOV_EXCL_STOP */
336                 }
337                 ctsvc_db_extension_get_value_from_stmt(stmt, (contacts_record_h*)&extension, 0);
338                 ctsvc_list_prepend(list, (contacts_record_h)extension);
339         }
340         ctsvc_stmt_finalize(stmt);
341         ctsvc_list_reverse(list);
342
343         *out_list = list;
344         return CONTACTS_ERROR_NONE;
345 }
346
347 static int __ctsvc_db_extension_get_records_with_query(contacts_query_h query, int offset,
348                 int limit, contacts_list_h *out_list)
349 {
350         int ret;
351         int i;
352         int field_count;
353         ctsvc_query_s *s_query;
354         cts_stmt stmt;
355         contacts_list_h list;
356         ctsvc_extension_s *extension;
357
358         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
359         s_query = (ctsvc_query_s*)query;
360
361         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
362         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
363
364         contacts_list_create(&list);
365         while ((ret = ctsvc_stmt_step(stmt))) {
366                 contacts_record_h record;
367                 if (1 /*CTS_TRUE */ != ret) {
368                         /* LCOV_EXCL_START */
369                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
370                         ctsvc_stmt_finalize(stmt);
371                         contacts_list_destroy(list, true);
372                         return ret;
373                         /* LCOV_EXCL_STOP */
374                 }
375
376                 contacts_record_create(_contacts_extension._uri, &record);
377                 extension = (ctsvc_extension_s*)record;
378                 if (0 == s_query->projection_count) {
379                         field_count = s_query->property_count;
380                 } else {
381                         field_count = s_query->projection_count;
382                         ret = ctsvc_record_set_projection_flags(record, s_query->projection,
383                                         s_query->projection_count, s_query->property_count);
384
385                         if (CONTACTS_ERROR_NONE != ret)
386                                 ASSERT_NOT_REACHED("To set projection is Fail.\n");
387                 }
388
389                 for (i = 0; i < field_count; i++) {
390                         char *temp;
391                         int property_id;
392                         if (0 == s_query->projection_count)
393                                 property_id = s_query->properties[i].property_id;
394                         else
395                                 property_id = s_query->projection[i];
396
397                         switch (property_id) {
398                         case CTSVC_PROPERTY_EXTENSION_ID:
399                                 extension->id = ctsvc_stmt_get_int(stmt, i);
400                                 break;
401                         case CTSVC_PROPERTY_EXTENSION_CONTACT_ID:
402                                 extension->contact_id = ctsvc_stmt_get_int(stmt, i);
403                                 break;
404                         case CTSVC_PROPERTY_EXTENSION_DATA1:
405                                 extension->data1 = ctsvc_stmt_get_int(stmt, i);
406                                 break;
407                         case CTSVC_PROPERTY_EXTENSION_DATA2:
408                                 temp = ctsvc_stmt_get_text(stmt, i);
409                                 free(extension->data2);
410                                 extension->data2 = SAFE_STRDUP(temp);
411                                 break;
412                         case CTSVC_PROPERTY_EXTENSION_DATA3:
413                                 temp = ctsvc_stmt_get_text(stmt, i);
414                                 free(extension->data3);
415                                 extension->data3 = SAFE_STRDUP(temp);
416                                 break;
417                         case CTSVC_PROPERTY_EXTENSION_DATA4:
418                                 temp = ctsvc_stmt_get_text(stmt, i);
419                                 free(extension->data4);
420                                 extension->data4 = SAFE_STRDUP(temp);
421                                 break;
422                         case CTSVC_PROPERTY_EXTENSION_DATA5:
423                                 temp = ctsvc_stmt_get_text(stmt, i);
424                                 free(extension->data5);
425                                 extension->data5 = SAFE_STRDUP(temp);
426                                 break;
427                         case CTSVC_PROPERTY_EXTENSION_DATA6:
428                                 temp = ctsvc_stmt_get_text(stmt, i);
429                                 free(extension->data6);
430                                 extension->data6 = SAFE_STRDUP(temp);
431                                 break;
432                         case CTSVC_PROPERTY_EXTENSION_DATA7:
433                                 temp = ctsvc_stmt_get_text(stmt, i);
434                                 free(extension->data7);
435                                 extension->data7 = SAFE_STRDUP(temp);
436                                 break;
437                         case CTSVC_PROPERTY_EXTENSION_DATA8:
438                                 temp = ctsvc_stmt_get_text(stmt, i);
439                                 free(extension->data8);
440                                 extension->data8 = SAFE_STRDUP(temp);
441                                 break;
442                         case CTSVC_PROPERTY_EXTENSION_DATA9:
443                                 temp = ctsvc_stmt_get_text(stmt, i);
444                                 free(extension->data9);
445                                 extension->data9 = SAFE_STRDUP(temp);
446                                 break;
447                         case CTSVC_PROPERTY_EXTENSION_DATA10:
448                                 temp = ctsvc_stmt_get_text(stmt, i);
449                                 free(extension->data10);
450                                 extension->data10 = SAFE_STRDUP(temp);
451                                 break;
452                         case CTSVC_PROPERTY_EXTENSION_DATA11:
453                                 temp = ctsvc_stmt_get_text(stmt, i);
454                                 free(extension->data11);
455                                 extension->data11 = SAFE_STRDUP(temp);
456                                 break;
457                         case CTSVC_PROPERTY_EXTENSION_DATA12:
458                                 temp = ctsvc_stmt_get_text(stmt, i);
459                                 free(extension->data12);
460                                 extension->data12 = SAFE_STRDUP(temp);
461                                 break;
462                         default:
463                                 break;
464                         }
465                 }
466                 ctsvc_list_prepend(list, record);
467         }
468         ctsvc_stmt_finalize(stmt);
469         ctsvc_list_reverse(list);
470
471         *out_list = list;
472         return CONTACTS_ERROR_NONE;
473 }
474
475 ctsvc_db_plugin_info_s ctsvc_db_plugin_extension = {
476         .is_query_only = false,
477         .insert_record = __ctsvc_db_extension_insert_record,
478         .get_record = __ctsvc_db_extension_get_record,
479         .update_record = __ctsvc_db_extension_update_record,
480         .delete_record = __ctsvc_db_extension_delete_record,
481         .get_all_records = __ctsvc_db_extension_get_all_records,
482         .get_records_with_query = __ctsvc_db_extension_get_records_with_query,
483         .insert_records = NULL,
484         .update_records = NULL,
485         .delete_records = NULL,
486         .get_count = NULL,
487         .get_count_with_query = NULL,
488         .replace_record = NULL,
489         .replace_records = NULL,
490 };
491