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