[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_speeddial.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_list.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_query.h"
27 #include "ctsvc_record.h"
28 #include "ctsvc_notification.h"
29 #include "ctsvc_notify.h"
30
31
32 static int __ctsvc_db_speeddial_insert_record(contacts_record_h record, int *id)
33 {
34         int ret;
35         int number_id = 0;
36         char query[CTS_SQL_MAX_LEN] = {0};
37         ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
38
39         ret = ctsvc_begin_trans();
40         RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
41
42         /* check number_id validation */
43         snprintf(query, sizeof(query),
44                         "SELECT data.id FROM "CTS_TABLE_DATA", "CTS_TABLE_CONTACTS" "
45                         "ON "CTS_TABLE_DATA".contact_id = "CTS_TABLE_CONTACTS".contact_id "
46                         "AND contacts.deleted = 0  AND is_my_profile = 0 AND datatype = %d "
47                         "WHERE id = %d ",
48                         CONTACTS_DATA_TYPE_NUMBER, speeddial->number_id);
49         ret = ctsvc_query_get_first_int_result(query, &number_id);
50         if (CONTACTS_ERROR_NONE != ret) {
51                 /* LCOV_EXCL_START */
52                 ERR("ctsvc_query_get_first_int_result() Fail(%d) : number_id is invalid", ret);
53                 ctsvc_end_trans(false);
54                 return CONTACTS_ERROR_INVALID_PARAMETER;
55                 /* LCOV_EXCL_STOP */
56         }
57
58         snprintf(query, sizeof(query),
59                         "INSERT INTO "CTS_TABLE_SPEEDDIALS"(speed_number, number_id) VALUES(%d, %d)",
60                         speeddial->dial_number, speeddial->number_id);
61
62         ret = ctsvc_query_exec(query);
63         if (CONTACTS_ERROR_NONE != ret) {
64                 /* LCOV_EXCL_START */
65                 ERR("ctsvc_query_exec() Fail(%d)", ret);
66                 ctsvc_end_trans(false);
67                 return ret;
68                 /* LCOV_EXCL_STOP */
69         }
70
71         ret = ctsvc_db_change();
72         if (0 < ret) {
73                 if (id)
74                         *id  = speeddial->dial_number;
75                 ctsvc_set_speed_noti();
76         } else {
77                 /* LCOV_EXCL_START */
78                 ERR("already exist");
79                 /* LCOV_EXCL_STOP */
80         }
81
82         ret = ctsvc_end_trans(true);
83         if (ret < CONTACTS_ERROR_NONE)
84                 return ret;
85         else
86                 return CONTACTS_ERROR_NONE;
87 }
88
89 static int __ctsvc_db_speeddial_value_set(cts_stmt stmt, contacts_record_h *record)
90 {
91         int i;
92         int ret;
93         char *temp;
94         ctsvc_speeddial_s *speeddial;
95
96         ret = contacts_record_create(_contacts_speeddial._uri, record);
97         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create Fail(%d)", ret);
98         speeddial = (ctsvc_speeddial_s*)*record;
99
100         i = 0;
101         speeddial->person_id = ctsvc_stmt_get_int(stmt, i++);
102         temp = ctsvc_stmt_get_text(stmt, i++);
103         speeddial->display_name = SAFE_STRDUP(temp);
104         temp = ctsvc_stmt_get_text(stmt, i++);
105         if (temp) {
106                 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
107                 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
108                 speeddial->image_thumbnail_path = strdup(full_path);
109         }
110
111         speeddial->number_id = ctsvc_stmt_get_int(stmt, i++);
112         speeddial->number_type = ctsvc_stmt_get_int(stmt, i++);
113         temp = ctsvc_stmt_get_text(stmt, i++);
114         speeddial->label = SAFE_STRDUP(temp);
115         temp = ctsvc_stmt_get_text(stmt, i++);
116         speeddial->number = SAFE_STRDUP(temp);
117         speeddial->dial_number = ctsvc_stmt_get_int(stmt, i++);
118         speeddial->id = speeddial->dial_number; /* dial_number is an unique key */
119
120         return CONTACTS_ERROR_NONE;
121 }
122
123 static int __ctsvc_db_speeddial_get_record(int id, contacts_record_h *out_record)
124 {
125         int ret;
126         cts_stmt stmt = NULL;
127         contacts_record_h record;
128         char query[CTS_SQL_MAX_LEN] = {0};
129
130         snprintf(query, sizeof(query),
131                         "SELECT person_id, %s, image_thumbnail_path, number_id, "
132                         "type, label, number, speed_number  "
133                         "FROM "CTSVC_DB_VIEW_SPEEDIDAL " "
134                         "WHERE speed_number = %d",
135                         ctsvc_get_display_column(), id);
136
137         ret = ctsvc_query_prepare(query, &stmt);
138         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
139
140         ret = ctsvc_stmt_step(stmt);
141         if (1 /*CTS_TRUE*/ != ret) {
142                 /* LCOV_EXCL_START */
143                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
144                 ctsvc_stmt_finalize(stmt);
145                 if (CONTACTS_ERROR_NONE == ret)
146                         return CONTACTS_ERROR_NO_DATA;
147                 else
148                         return ret;
149                 /* LCOV_EXCL_STOP */
150         }
151
152         ret = __ctsvc_db_speeddial_value_set(stmt, &record);
153
154         ctsvc_stmt_finalize(stmt);
155         if (CONTACTS_ERROR_NONE != ret) {
156                 /* LCOV_EXCL_START */
157                 ERR("__ctsvc_db_speeddial_value_set(ALL) Fail(%d)", ret);
158                 return ret;
159                 /* LCOV_EXCL_STOP */
160         }
161
162         *out_record = record;
163
164         return CONTACTS_ERROR_NONE;
165 }
166
167 static int __ctsvc_db_speeddial_update_record(contacts_record_h record)
168 {
169         int ret;
170         int number_id;
171         int speeddial_id;
172         cts_stmt stmt;
173         char query[CTS_SQL_MIN_LEN] = {0};
174         ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
175
176         RETVM_IF(speeddial->dial_number < 0, CONTACTS_ERROR_INVALID_PARAMETER,
177                         "dial number (%d)", speeddial->dial_number);
178         RETVM_IF(speeddial->number_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
179                         "number id (%d)", speeddial->number_id);
180         ret = ctsvc_begin_trans();
181         RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "ctsvc_begin_trans() Fail(%d)", ret);
182
183         /* check number_id validation */
184         snprintf(query, sizeof(query),
185                         "SELECT data.id FROM "CTS_TABLE_DATA", "CTS_TABLE_CONTACTS" "
186                         "ON "CTS_TABLE_DATA".contact_id = "CTS_TABLE_CONTACTS".contact_id "
187                         "AND contacts.deleted = 0  AND is_my_profile = 0 AND datatype = %d "
188                         "WHERE id = %d ",
189                         CONTACTS_DATA_TYPE_NUMBER, speeddial->number_id);
190         ret = ctsvc_query_get_first_int_result(query, &number_id);
191         if (CONTACTS_ERROR_NONE != ret) {
192                 /* LCOV_EXCL_START */
193                 ERR("ctsvc_query_get_first_int_result() Fail(%d) : number_id is invalid", ret);
194                 ctsvc_end_trans(false);
195                 return CONTACTS_ERROR_INVALID_PARAMETER;
196                 /* LCOV_EXCL_STOP */
197         }
198
199         snprintf(query, sizeof(query),
200                         "SELECT speed_number FROM "CTS_TABLE_SPEEDDIALS" WHERE speed_number = %d", speeddial->dial_number);
201         ret = ctsvc_query_get_first_int_result(query, &speeddial_id);
202         if (CONTACTS_ERROR_NONE != ret) {
203                 /* LCOV_EXCL_START */
204                 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
205                 ctsvc_end_trans(false);
206                 return ret;
207                 /* LCOV_EXCL_STOP */
208         }
209
210         snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_SPEEDDIALS" "
211                         "SET number_id = %d WHERE speed_number = %d",
212                         speeddial->number_id, speeddial->dial_number);
213         ret = ctsvc_query_prepare(query, &stmt);
214         if (NULL == stmt) {
215                 /* LCOV_EXCL_START */
216                 ERR("ctsvc_query_prepare() Fail(%d)", ret);
217                 ctsvc_end_trans(false);
218                 return ret;
219                 /* LCOV_EXCL_STOP */
220         }
221
222         ret = ctsvc_stmt_step(stmt);
223         if (CONTACTS_ERROR_NONE != ret) {
224                 /* LCOV_EXCL_START */
225                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
226                 ctsvc_stmt_finalize(stmt);
227                 ctsvc_end_trans(false);
228                 return ret;
229                 /* LCOV_EXCL_STOP */
230         }
231         ret = ctsvc_db_change();
232         ctsvc_stmt_finalize(stmt);
233
234         if (0 < ret) {
235                 ctsvc_set_speed_noti();
236                 ret = ctsvc_end_trans(true);
237         } else {
238                 ctsvc_end_trans(false);
239                 ret = CONTACTS_ERROR_NO_DATA;
240         }
241
242         if (ret < CONTACTS_ERROR_NONE)
243                 return ret;
244         else
245                 return CONTACTS_ERROR_NONE;
246 }
247
248 static int __ctsvc_db_speeddial_delete_record(int id)
249 {
250         int ret;
251         int speeddial_id;
252         cts_stmt stmt;
253         char query[CTS_SQL_MIN_LEN] = {0};
254
255         ret = ctsvc_begin_trans();
256         RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "ctsvc_begin_trans() Fail(%d)", ret);
257
258         snprintf(query, sizeof(query),
259                         "SELECT speed_number FROM "CTS_TABLE_SPEEDDIALS" WHERE speed_number = %d", id);
260         ret = ctsvc_query_get_first_int_result(query, &speeddial_id);
261         if (CONTACTS_ERROR_NONE != ret) {
262                 /* LCOV_EXCL_START */
263                 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
264                 ctsvc_end_trans(false);
265                 return ret;
266                 /* LCOV_EXCL_STOP */
267         }
268
269         snprintf(query, sizeof(query), "DELETE FROM %s WHERE speed_number = %d",
270                         CTS_TABLE_SPEEDDIALS, id);
271         ret = ctsvc_query_prepare(query, &stmt);
272         if (NULL == stmt) {
273                 /* LCOV_EXCL_START */
274                 ERR("ctsvc_query_prepare() Fail(%d)", ret);
275                 ctsvc_end_trans(false);
276                 return ret;
277                 /* LCOV_EXCL_STOP */
278         }
279
280         ret = ctsvc_stmt_step(stmt);
281         if (CONTACTS_ERROR_NONE != ret) {
282                 /* LCOV_EXCL_START */
283                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
284                 ctsvc_stmt_finalize(stmt);
285                 ctsvc_end_trans(false);
286                 return ret;
287                 /* LCOV_EXCL_STOP */
288         }
289         ret = ctsvc_db_change();
290         ctsvc_stmt_finalize(stmt);
291
292         if (0 < ret) {
293                 ctsvc_set_speed_noti();
294                 ret = ctsvc_end_trans(true);
295         } else {
296                 ctsvc_end_trans(false);
297                 ret = CONTACTS_ERROR_NO_DATA;
298         }
299
300         if (ret < CONTACTS_ERROR_NONE)
301                 return ret;
302         else
303                 return CONTACTS_ERROR_NONE;
304 }
305
306 static int __ctsvc_db_speeddial_get_all_records(int offset, int limit, contacts_list_h *out_list)
307 {
308         int ret;
309         int len;
310         cts_stmt stmt;
311         char query[CTS_SQL_MAX_LEN] = {0};
312         contacts_list_h list;
313
314         len = snprintf(query, sizeof(query),
315                         "SELECT person_id, %s, image_thumbnail_path, number_id, "
316                         "type, label, number, speed_number      "
317                         "FROM "CTSVC_DB_VIEW_SPEEDIDAL " ",     ctsvc_get_display_column());
318
319         if (0 != limit) {
320                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
321                 if (0 < offset)
322                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
323         }
324
325         ret = ctsvc_query_prepare(query, &stmt);
326         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
327
328         contacts_list_create(&list);
329         while ((ret = ctsvc_stmt_step(stmt))) {
330                 contacts_record_h record;
331                 if (1 != ret) {
332                         /* LCOV_EXCL_START */
333                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
334                         ctsvc_stmt_finalize(stmt);
335                         contacts_list_destroy(list, true);
336                         return ret;
337                         /* LCOV_EXCL_STOP */
338                 }
339                 __ctsvc_db_speeddial_value_set(stmt, &record);
340
341                 ctsvc_list_prepend(list, record);
342         }
343         ctsvc_stmt_finalize(stmt);
344         ctsvc_list_reverse(list);
345
346         *out_list = (contacts_list_h)list;
347         return CONTACTS_ERROR_NONE;
348 }
349
350 static int __ctsvc_db_speeddial_get_records_with_query(contacts_query_h query,
351                 int offset, int limit, contacts_list_h *out_list)
352 {
353         int ret;
354         int i;
355         int field_count;
356         ctsvc_query_s *s_query;
357         cts_stmt stmt;
358         contacts_list_h list;
359         ctsvc_speeddial_s *speeddial;
360         char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
361
362         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
363         s_query = (ctsvc_query_s*)query;
364
365         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
366         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt Fail(%d)", ret);
367
368         contacts_list_create(&list);
369         while ((ret = ctsvc_stmt_step(stmt))) {
370                 contacts_record_h record;
371                 if (1 != ret) {
372                         /* LCOV_EXCL_START */
373                         ERR("ctsvc_stmt_step() Fail(%d)", ret);
374                         ctsvc_stmt_finalize(stmt);
375                         contacts_list_destroy(list, true);
376                         return ret;
377                         /* LCOV_EXCL_STOP */
378                 }
379
380                 contacts_record_create(_contacts_speeddial._uri, &record);
381                 speeddial = (ctsvc_speeddial_s*)record;
382                 if (0 == s_query->projection_count) {
383                         field_count = s_query->property_count;
384                 } else {
385                         field_count = s_query->projection_count;
386
387                         int err = ctsvc_record_set_projection_flags(record, s_query->projection,
388                                         s_query->projection_count, s_query->property_count);
389                         if (CONTACTS_ERROR_NONE != err)
390                                 ASSERT_NOT_REACHED("ctsvc_record_set_projection_flags() Fail(%d)", err);
391                 }
392
393                 for (i = 0; i < field_count; i++) {
394                         char *temp;
395                         int property_id;
396                         if (0 == s_query->projection_count)
397                                 property_id = s_query->properties[i].property_id;
398                         else
399                                 property_id = s_query->projection[i];
400
401                         switch (property_id) {
402                         case CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER:
403                                 speeddial->dial_number = ctsvc_stmt_get_int(stmt, i);
404                                 speeddial->id = speeddial->dial_number; /* dial_number is an unique key */
405                                 break;
406                         case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID:
407                                 speeddial->number_id = ctsvc_stmt_get_int(stmt, i);
408                                 break;
409                         case CTSVC_PROPERTY_SPEEDDIAL_NUMBER:
410                                 temp = ctsvc_stmt_get_text(stmt, i);
411                                 free(speeddial->number);
412                                 speeddial->number = SAFE_STRDUP(temp);
413                                 break;
414                         case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL:
415                                 temp = ctsvc_stmt_get_text(stmt, i);
416                                 free(speeddial->label);
417                                 speeddial->label = SAFE_STRDUP(temp);
418                                 break;
419                         case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE:
420                                 speeddial->number_type = ctsvc_stmt_get_int(stmt, i);
421                                 break;
422                         case CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID:
423                                 speeddial->person_id = ctsvc_stmt_get_int(stmt, i);
424                                 break;
425                         case CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME:
426                                 temp = ctsvc_stmt_get_text(stmt, i);
427                                 free(speeddial->display_name);
428                                 speeddial->display_name = SAFE_STRDUP(temp);
429                                 break;
430                         case CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL:
431                                 temp = ctsvc_stmt_get_text(stmt, i);
432                                 if (temp) {
433                                         snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
434                                         free(speeddial->image_thumbnail_path);
435                                         speeddial->image_thumbnail_path = strdup(full_path);
436                                 }
437                                 break;
438                         default:
439                                 break;
440                         }
441                 }
442                 ctsvc_list_prepend(list, record);
443         }
444         ctsvc_stmt_finalize(stmt);
445         ctsvc_list_reverse(list);
446
447         *out_list = (contacts_list_h)list;
448
449         return CONTACTS_ERROR_NONE;
450 }
451
452 ctsvc_db_plugin_info_s ctsvc_db_plugin_speeddial = {
453         .is_query_only = false,
454         .insert_record = __ctsvc_db_speeddial_insert_record,
455         .get_record = __ctsvc_db_speeddial_get_record,
456         .update_record = __ctsvc_db_speeddial_update_record,
457         .delete_record = __ctsvc_db_speeddial_delete_record,
458         .get_all_records = __ctsvc_db_speeddial_get_all_records,
459         .get_records_with_query = __ctsvc_db_speeddial_get_records_with_query,
460         .insert_records = NULL,
461         .update_records = NULL,
462         .delete_records = NULL,
463         .get_count = NULL,
464         .get_count_with_query = NULL,
465         .replace_record = NULL,
466         .replace_records = NULL,
467 };
468