[SVACE Issue Fixes]
[platform/core/pim/contacts-service.git] / server / db / ctsvc_db_plugin_image_helper.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_init.h"
24 #include "ctsvc_db_query.h"
25 #include "ctsvc_db_plugin_image_helper.h"
26 #include "ctsvc_db_plugin_contact_helper.h"
27 #include "ctsvc_record.h"
28 #include "ctsvc_notification.h"
29 #include "ctsvc_db_access_control.h"
30 #include "ctsvc_notify.h"
31 #include "ctsvc_db_utils.h"
32
33 int ctsvc_db_image_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record,
34                 int start_count)
35 {
36         int ret;
37         char *temp;
38         ctsvc_image_s *image;
39
40         ret = contacts_record_create(_contacts_image._uri, (contacts_record_h*)&image);
41         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create Fail(%d)", ret);
42
43         image->id = ctsvc_stmt_get_int(stmt, start_count++);
44         image->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
45         image->is_default = ctsvc_stmt_get_int(stmt, start_count++);
46         image->type = ctsvc_stmt_get_int(stmt, start_count++);
47         temp = ctsvc_stmt_get_text(stmt, start_count++);
48         image->label = SAFE_STRDUP(temp);
49         temp = ctsvc_stmt_get_text(stmt, start_count++);
50         if (temp) {
51                 char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
52                 snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
53                 image->path = strdup(full_path);
54         }
55
56         *record = (contacts_record_h)image;
57         return CONTACTS_ERROR_NONE;
58 }
59
60 static inline int __ctsvc_image_bind_stmt(cts_stmt stmt, ctsvc_image_s *image, int start_cnt)
61 {
62         if (image->label)
63                 ctsvc_stmt_bind_text(stmt, start_cnt, image->label);
64         if (image->path)
65                 ctsvc_stmt_bind_text(stmt, start_cnt+1, image->path);
66         return CONTACTS_ERROR_NONE;
67 }
68
69 static int __ctsvc_db_image_reset_default(int image_id, int contact_id)
70 {
71         int ret;
72         char query[CTS_SQL_MAX_LEN] = {0};
73
74         snprintf(query, sizeof(query),
75                         "UPDATE "CTS_TABLE_DATA" SET is_default=0, is_primary_default=0 WHERE id != %d AND contact_id = %d AND datatype=%d",
76                         image_id, contact_id, CONTACTS_DATA_TYPE_IMAGE);
77         ret = ctsvc_query_exec(query);
78         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
79         return ret;
80 }
81
82 int ctsvc_db_image_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
83 {
84         int ret;
85         int image_id;
86         cts_stmt stmt = NULL;
87         char query[CTS_SQL_MAX_LEN] = {0};
88         char image_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
89         ctsvc_image_s *image = (ctsvc_image_s*)record;
90
91         /* These check should be done in client side */
92         RETV_IF(NULL == image->path, CONTACTS_ERROR_NONE);
93         RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
94                         "contact_id(%d) is mandatory field to insert image record", image->contact_id);
95         RETVM_IF(0 < image->id, CONTACTS_ERROR_INVALID_PARAMETER,
96                         "id(%d), This record is already inserted", image->id);
97
98         ret = ctsvc_have_file_read_permission(image->path);
99         RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_have_file_read_permission fail(%d)", ret);
100
101         image_id = ctsvc_db_get_next_id(CTS_TABLE_DATA);
102         ret = ctsvc_contact_add_image_file(contact_id, image_id, image->path, image_path, sizeof(image_path));
103         if (CONTACTS_ERROR_NONE != ret) {
104                 /* LCOV_EXCL_START */
105                 ERR("ctsvc_contact_add_image_file() Fail(%d)", ret);
106                 return ret;
107                 /* LCOV_EXCL_STOP */
108         }
109         free(image->path);
110         image->path = strdup(image_path);
111
112         snprintf(query, sizeof(query),
113                         "INSERT INTO "CTS_TABLE_DATA"(id, contact_id, is_my_profile, datatype, is_default, is_primary_default, data1, data2, data3) "
114                         "VALUES(%d, %d, %d, %d, %d, %d, %d, ?, ?)",
115                         image_id, contact_id, is_my_profile, CONTACTS_DATA_TYPE_IMAGE, image->is_default, image->is_default, image->type);
116
117         ret = ctsvc_query_prepare(query, &stmt);
118         RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
119
120         __ctsvc_image_bind_stmt(stmt, image, 1);
121
122         ret = ctsvc_stmt_step(stmt);
123         if (CONTACTS_ERROR_NONE != ret) {
124                 /* LCOV_EXCL_START */
125                 ERR("ctsvc_stmt_step() Fail(%d)", ret);
126                 ctsvc_stmt_finalize(stmt);
127                 return ret;
128                 /* LCOV_EXCL_STOP */
129         }
130
131         /* image->id = ctsvc_db_get_last_insert_id(); */
132         if (id)
133                 *id = image_id;
134         ctsvc_stmt_finalize(stmt);
135
136         if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_image.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
137                 if (image->is_default)
138                         __ctsvc_db_image_reset_default(image_id, contact_id);
139         }
140
141         if (false == is_my_profile)
142                 ctsvc_set_image_noti();
143
144         return CONTACTS_ERROR_NONE;
145 }
146
147 int ctsvc_db_image_update(contacts_record_h record, int contact_id, bool is_my_profile)
148 {
149         int id;
150         int ret = CONTACTS_ERROR_NONE;
151         char *set = NULL;
152         GSList *bind_text = NULL;
153         GSList *cursor = NULL;
154         ctsvc_image_s *image = (ctsvc_image_s*)record;
155         char query[CTS_SQL_MAX_LEN] = {0};
156
157         RETVM_IF(0 == image->id, CONTACTS_ERROR_INVALID_PARAMETER, "image of contact has no ID.");
158         RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (image->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
159
160         snprintf(query, sizeof(query),
161                         "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", image->id);
162         ret = ctsvc_query_get_first_int_result(query, &id);
163         RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
164
165         if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_image.path, CTSVC_PROPERTY_FLAG_DIRTY)) {
166                 char image_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
167                 if (image->path) {
168                         ret = ctsvc_have_file_read_permission(image->path);
169                         if (ret != CONTACTS_ERROR_NONE) {
170                                 /* LCOV_EXCL_START */
171                                 ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
172                                 return ret;
173                                 /* LCOV_EXCL_STOP */
174                         }
175                 }
176
177                 ret = ctsvc_contact_update_image_file(contact_id, image->id, image->path, image_path, sizeof(image_path));
178                 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_contact_update_image_file() Fail(%d)", ret);
179
180                 if (*image_path) {
181                         free(image->path);
182                         image->path = strdup(image_path);
183                 }
184         }
185
186         if (ctsvc_record_check_property_flag((ctsvc_record_s*)record, _contacts_image.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
187                 if (image->is_default)
188                         __ctsvc_db_image_reset_default(image->id, contact_id);
189         }
190
191         do {
192                 if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
193                 if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, image->id))) break;
194                 if (false == is_my_profile)
195                         ctsvc_set_image_noti();
196         } while (0);
197
198         CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s*)record);
199         free(set);
200
201         if (bind_text) {
202                 for (cursor = bind_text; cursor; cursor = cursor->next) {
203                         free(cursor->data);
204                         cursor->data = NULL;
205                 }
206                 g_slist_free(bind_text);
207         }
208         return ret;
209 }
210
211 int ctsvc_db_image_delete(int id, bool is_my_profile)
212 {
213         int ret;
214         char query[CTS_SQL_MIN_LEN] = {0};
215
216         snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
217                         id, CONTACTS_DATA_TYPE_IMAGE);
218
219         ret = ctsvc_query_exec(query);
220         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Fail(%d)", ret);
221
222         if (false == is_my_profile)
223                 ctsvc_set_image_noti();
224
225         return CONTACTS_ERROR_NONE;
226 }
227
228 /*
229  * Whenever deleting image recode in data table, this funcion will be called
230  * in order to delete the image file
231  */
232 void ctsvc_db_image_delete_callback(sqlite3_context *context, int argc, sqlite3_value **argv)
233 {
234         int ret;
235         const unsigned char *image_path;
236
237         if (1 < argc) {
238                 sqlite3_result_null(context);
239                 return;
240         }
241         image_path = sqlite3_value_text(argv[0]);
242
243         ret = ctsvc_contact_delete_image_file_with_path(image_path);
244         WARN_IF(CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret,
245                         "ctsvc_contact_delete_image_file_with_path() Fail(%d)", ret);
246
247         return;
248 }
249
250 int ctsvc_db_image_set_primary_default(int contact_id, const char *image_thumbnail_path,
251                 bool is_primary_default)
252 {
253         int ret;
254         char *image_path = NULL;
255         char query[CTS_SQL_MAX_LEN] = {0};
256
257         RETV_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER);
258         RETV_IF(NULL == image_thumbnail_path, CONTACTS_ERROR_INVALID_PARAMETER);
259
260         image_path = ctsvc_utils_get_image_path(image_thumbnail_path);
261
262         if (NULL == image_path) {
263                 /* LCOV_EXCL_START */
264                 ERR("ctsvc_utils_get_image_path() Fail");
265                 return CONTACTS_ERROR_INTERNAL;
266                 /* LCOV_EXCL_STOP */
267         }
268
269         snprintf(query, sizeof(query),
270                         "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE contact_id = %d AND datatype = %d AND data3 = %s",
271                         is_primary_default, contact_id, CONTACTS_DATA_TYPE_IMAGE, image_path);
272
273         free(image_path);
274         ret = ctsvc_query_exec(query);
275         WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
276         return ret;
277 }
278