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