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