sync with 2.4
[platform/core/pim/contacts-service.git] / native / ctsvc_db_plugin_url.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2012 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
20 #include "contacts.h"
21 #include "ctsvc_internal.h"
22 #include "ctsvc_schema.h"
23 #include "ctsvc_sqlite.h"
24 #include "ctsvc_utils.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_plugin_contact_helper.h"
27 #include "ctsvc_db_plugin_url_helper.h"
28 #include "ctsvc_record.h"
29 #include "ctsvc_db_query.h"
30 #include "ctsvc_list.h"
31 #include "ctsvc_notification.h"
32 #include "ctsvc_db_access_control.h"
33
34 static int __ctsvc_db_url_insert_record( contacts_record_h record, int *id );
35 static int __ctsvc_db_url_get_record( int id, contacts_record_h* out_record );
36 static int __ctsvc_db_url_update_record( contacts_record_h record );
37 static int __ctsvc_db_url_delete_record( int id );
38 static int __ctsvc_db_url_get_all_records( int offset, int limit, contacts_list_h* out_list );
39 static int __ctsvc_db_url_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
40 //static int __ctsvc_db_url_insert_records(const contacts_list_h in_list, int **ids);
41 //static int __ctsvc_db_url_update_records(const contacts_list_h in_list);
42 //static int __ctsvc_db_url_delete_records( int ids[], int count);
43
44 ctsvc_db_plugin_info_s ctsvc_db_plugin_url = {
45         .is_query_only = false,
46         .insert_record = __ctsvc_db_url_insert_record,
47         .get_record = __ctsvc_db_url_get_record,
48         .update_record = __ctsvc_db_url_update_record,
49         .delete_record = __ctsvc_db_url_delete_record,
50         .get_all_records = __ctsvc_db_url_get_all_records,
51         .get_records_with_query = __ctsvc_db_url_get_records_with_query,
52         .insert_records = NULL,//__ctsvc_db_url_insert_records,
53         .update_records = NULL,//__ctsvc_db_url_update_records,
54         .delete_records = NULL,//__ctsvc_db_url_delete_records
55         .get_count = NULL,
56         .get_count_with_query = NULL,
57         .replace_record = NULL,
58         .replace_records = NULL,
59 };
60
61 static int __ctsvc_db_url_insert_record( contacts_record_h record, int *id )
62 {
63         int ret;
64         int addressbook_id;
65         char query[CTS_SQL_MAX_LEN] = {0};
66         ctsvc_url_s *url = (ctsvc_url_s *)record;
67
68         RETVM_IF(NULL == url->url, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : url is NULL");
69
70         ret = ctsvc_begin_trans();
71         if (CONTACTS_ERROR_NONE != ret) {
72                 CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
73                 return ret;
74         }
75
76         snprintf(query, sizeof(query),
77                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id);
78         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
79         if (CONTACTS_ERROR_NONE != ret) {
80                 ctsvc_end_trans(false);
81                 if (CONTACTS_ERROR_NO_DATA == ret) {
82                         CTS_ERR("No data : contact_id (%d) is not exist", url->contact_id);
83                         return CONTACTS_ERROR_INVALID_PARAMETER;
84                 }
85                 else {
86                         CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
87                         return ret;
88                 }
89         }
90
91         if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
92                 CTS_ERR("Does not have permission to update this url record : addressbook_id(%d)", addressbook_id);
93                 ctsvc_end_trans(false);
94                 return CONTACTS_ERROR_PERMISSION_DENIED;
95         }
96
97         ret = ctsvc_db_url_insert(record, url->contact_id, false, id);
98         if (CONTACTS_ERROR_NONE != ret) {
99                 CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
100                 ctsvc_end_trans(false);
101                 return ret;
102         }
103
104         ret = ctsvc_db_contact_update_changed_time(url->contact_id);
105         if (CONTACTS_ERROR_NONE != ret) {
106                 CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
107                 ctsvc_end_trans(false);
108                 return ret;
109         }
110         ctsvc_set_person_noti();
111
112         ret = ctsvc_end_trans(true);
113         if (ret < CONTACTS_ERROR_NONE)
114         {
115                 CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
116                 return ret;
117         }
118         else
119                 return CONTACTS_ERROR_NONE;
120 }
121
122 static int __ctsvc_db_url_get_record( int id, contacts_record_h* out_record )
123 {
124         int ret;
125         cts_stmt stmt = NULL;
126         char query[CTS_SQL_MAX_LEN] = {0};
127
128         RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
129         *out_record = NULL;
130
131         snprintf(query, sizeof(query),
132                         "SELECT id, data.contact_id, is_default, data1, data2, data3 "
133                                 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
134                                 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
135                                 "WHERE id = %d AND datatype = %d ",
136                                 id, CTSVC_DATA_URL);
137
138         ret = ctsvc_query_prepare(query, &stmt);
139         RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
140
141         ret = ctsvc_stmt_step(stmt);
142         if (1 /*CTS_TRUE*/ != ret) {
143                 CTS_ERR("ctsvc_stmt_step() Failed(%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         }
150
151         ctsvc_db_url_get_value_from_stmt(stmt, out_record, 0);
152
153         ctsvc_stmt_finalize(stmt);
154
155         return CONTACTS_ERROR_NONE;
156 }
157
158 static int __ctsvc_db_url_update_record( contacts_record_h record )
159 {
160         int ret;
161         int addressbook_id;
162         char query[CTS_SQL_MAX_LEN] = {0};
163         ctsvc_url_s *url = (ctsvc_url_s *)record;
164         RETVM_IF(NULL == url->url, CONTACTS_ERROR_INVALID_PARAMETER, "url is empty");
165
166         ret = ctsvc_begin_trans();
167         if (CONTACTS_ERROR_NONE != ret) {
168                 CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
169                 return ret;
170         }
171
172         snprintf(query, sizeof(query),
173                         "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id);
174         ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
175         if (CONTACTS_ERROR_NONE != ret) {
176                 CTS_ERR("No data : contact_id (%d) is not exist", url->contact_id);
177                 ctsvc_end_trans(false);
178                 return ret;
179         }
180
181         if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
182                 CTS_ERR("Does not have permission to update this url record : addressbook_id(%d)", addressbook_id);
183                 ctsvc_end_trans(false);
184                 return CONTACTS_ERROR_PERMISSION_DENIED;
185         }
186
187         ret = ctsvc_db_url_update(record, false);
188         if (CONTACTS_ERROR_NONE != ret) {
189                 CTS_ERR("Update record Failed(%d)", ret);
190                 ctsvc_end_trans(false);
191                 return ret;
192         }
193
194         ret = ctsvc_db_contact_update_changed_time(url->contact_id);
195         if (CONTACTS_ERROR_NONE != ret) {
196                 CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
197                 ctsvc_end_trans(false);
198                 return ret;
199         }
200         ctsvc_set_person_noti();
201
202         ret = ctsvc_end_trans(true);
203         if (ret < CONTACTS_ERROR_NONE)
204         {
205                 CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
206                 return ret;
207         }
208         else
209                 return CONTACTS_ERROR_NONE;
210 }
211
212 static int __ctsvc_db_url_delete_record( int id )
213 {
214         int ret;
215         int contact_id;
216         char query[CTS_SQL_MAX_LEN] = {0};
217         cts_stmt stmt = NULL;
218         int addressbook_id;
219
220         ret = ctsvc_begin_trans();
221         if (CONTACTS_ERROR_NONE != ret) {
222                 CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
223                 return ret;
224         }
225
226         snprintf(query, sizeof(query),
227                         "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
228                                 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
229         ret = ctsvc_query_prepare(query, &stmt);
230         if (NULL == stmt) {
231                 CTS_ERR("DB error : ctsvc_query_prepare Fail(%d)", ret);
232                 ctsvc_end_trans(false);
233                 return ret;
234         }
235         ret = ctsvc_stmt_step(stmt);
236         if (1 != ret) {
237                 CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
238                 ctsvc_stmt_finalize(stmt);
239                 ctsvc_end_trans(false);
240                 if (CONTACTS_ERROR_NONE == ret)
241                         return CONTACTS_ERROR_NO_DATA;
242                 else
243                         return ret;
244         }
245
246         contact_id = ctsvc_stmt_get_int(stmt, 0);
247         addressbook_id = ctsvc_stmt_get_int(stmt, 1);
248         ctsvc_stmt_finalize(stmt);
249
250         if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
251                 CTS_ERR("Does not have permission to delete this url record : addressbook_id(%d)", addressbook_id);
252                 ctsvc_end_trans(false);
253                 return CONTACTS_ERROR_PERMISSION_DENIED;
254         }
255
256         ret = ctsvc_db_url_delete(id, false);
257         if (CONTACTS_ERROR_NONE != ret) {
258                 CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
259                 ctsvc_end_trans(false);
260                 return ret;
261         }
262
263         ret = ctsvc_db_contact_update_changed_time(contact_id);
264         if (CONTACTS_ERROR_NONE != ret) {
265                 CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
266                 ctsvc_end_trans(false);
267                 return ret;
268         }
269         ctsvc_set_person_noti();
270
271         ret = ctsvc_end_trans(true);
272         if (ret < CONTACTS_ERROR_NONE)
273         {
274                 CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
275                 return ret;
276         }
277         else
278                 return CONTACTS_ERROR_NONE;
279 }
280
281 static int __ctsvc_db_url_get_all_records( int offset, int limit, contacts_list_h* out_list )
282 {
283         int len;
284         int ret;
285         contacts_list_h list;
286         ctsvc_url_s *url;
287         cts_stmt stmt = NULL;
288         char query[CTS_SQL_MAX_LEN] = {0};
289
290         len = snprintf(query, sizeof(query),
291                         "SELECT id, data.contact_id, is_default, data1, data2, data3 "
292                                 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
293                                 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
294                                 "WHERE datatype = %d AND is_my_profile=0 ",
295                                 CTSVC_DATA_URL);
296
297         if (0 != limit) {
298                 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
299                 if (0 < offset)
300                         len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
301         }
302
303         ret = ctsvc_query_prepare(query, &stmt);
304         RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
305
306         contacts_list_create(&list);
307         while ((ret = ctsvc_stmt_step(stmt))) {
308                 if (1 /*CTS_TRUE */ != ret) {
309                         CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
310                         ctsvc_stmt_finalize(stmt);
311                         contacts_list_destroy(list, true);
312                         return ret;
313                 }
314                 ctsvc_db_url_get_value_from_stmt(stmt, (contacts_record_h*)&url, 0);
315                 ctsvc_list_prepend(list, (contacts_record_h)url);
316         }
317         ctsvc_stmt_finalize(stmt);
318         ctsvc_list_reverse(list);
319
320         *out_list = list;
321         return CONTACTS_ERROR_NONE;
322 }
323
324 static int __ctsvc_db_url_get_records_with_query( contacts_query_h query, int offset,
325                 int limit, contacts_list_h* out_list )
326 {
327         int ret;
328         int i;
329         int field_count;
330         ctsvc_query_s *s_query;
331         cts_stmt stmt;
332         contacts_list_h list;
333         ctsvc_url_s *url;
334
335         RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
336         s_query = (ctsvc_query_s *)query;
337
338         ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
339         RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
340
341         contacts_list_create(&list);
342         while ((ret = ctsvc_stmt_step(stmt))) {
343                 contacts_record_h record;
344                 if (1 /*CTS_TRUE */ != ret) {
345                         CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
346                         ctsvc_stmt_finalize(stmt);
347                         contacts_list_destroy(list, true);
348                         return ret;
349                 }
350
351                 contacts_record_create(_contacts_url._uri, &record);
352                 url = (ctsvc_url_s*)record;
353                 if (0 == s_query->projection_count)
354                         field_count = s_query->property_count;
355                 else {
356                         field_count = s_query->projection_count;
357                         ret = ctsvc_record_set_projection_flags(record, s_query->projection,
358                                         s_query->projection_count, s_query->property_count);
359
360                         if(CONTACTS_ERROR_NONE != ret)
361                                 ASSERT_NOT_REACHED("To set projection is failed.\n");
362                 }
363
364                 for(i=0;i<field_count;i++) {
365                         char *temp;
366                         int property_id;
367                         if (0 == s_query->projection_count)
368                                 property_id = s_query->properties[i].property_id;
369                         else
370                                 property_id = s_query->projection[i];
371
372                         switch(property_id) {
373                         case CTSVC_PROPERTY_URL_ID:
374                                 url->id = ctsvc_stmt_get_int(stmt, i);
375                                 break;
376                         case CTSVC_PROPERTY_URL_CONTACT_ID:
377                                 url->contact_id = ctsvc_stmt_get_int(stmt, i);
378                                 break;
379                         case CTSVC_PROPERTY_URL_TYPE:
380                                 url->type = ctsvc_stmt_get_int(stmt, i);
381                                 break;
382                         case CTSVC_PROPERTY_URL_LABEL:
383                                 temp = ctsvc_stmt_get_text(stmt, i);
384                                 url->label = SAFE_STRDUP(temp);
385                                 break;
386                         case CTSVC_PROPERTY_URL_URL:
387                                 temp = ctsvc_stmt_get_text(stmt, i);
388                                 url->url = SAFE_STRDUP(temp);
389                                 break;
390                         default:
391                                 break;
392                         }
393                 }
394                 ctsvc_list_prepend(list, record);
395         }
396         ctsvc_stmt_finalize(stmt);
397         ctsvc_list_reverse(list);
398
399         *out_list = list;
400         return CONTACTS_ERROR_NONE;
401 }
402
403 //static int __ctsvc_db_url_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
404 //static int __ctsvc_db_url_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
405 //static int __ctsvc_db_url_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }