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