4 * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include "ctsvc_internal.h"
22 #include "ctsvc_db_schema.h"
23 #include "ctsvc_db_sqlite.h"
24 #include "ctsvc_db_utils.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_access_control.h"
27 #include "ctsvc_db_plugin_contact_helper.h"
28 #include "ctsvc_db_plugin_email_helper.h"
29 #include "ctsvc_record.h"
30 #include "ctsvc_notification.h"
31 #include "ctsvc_db_query.h"
32 #include "ctsvc_list.h"
34 static int __ctsvc_db_email_insert_record(contacts_record_h record, int *id);
35 static int __ctsvc_db_email_get_record(int id, contacts_record_h* out_record);
36 static int __ctsvc_db_email_update_record(contacts_record_h record);
37 static int __ctsvc_db_email_delete_record(int id);
38 static int __ctsvc_db_email_get_all_records(int offset, int limit, contacts_list_h* out_list);
39 static int __ctsvc_db_email_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h* out_list);
40 //static int __ctsvc_db_email_insert_records(const contacts_list_h in_list, int **ids);
41 //static int __ctsvc_db_email_update_records(const contacts_list_h in_list);
42 //static int __ctsvc_db_email_delete_records(int ids[], int count);
44 ctsvc_db_plugin_info_s ctsvc_db_plugin_email = {
45 .is_query_only = false,
46 .insert_record = __ctsvc_db_email_insert_record,
47 .get_record = __ctsvc_db_email_get_record,
48 .update_record = __ctsvc_db_email_update_record,
49 .delete_record = __ctsvc_db_email_delete_record,
50 .get_all_records = __ctsvc_db_email_get_all_records,
51 .get_records_with_query = __ctsvc_db_email_get_records_with_query,
52 .insert_records = NULL,//__ctsvc_db_email_insert_records,
53 .update_records = NULL,//__ctsvc_db_email_update_records,
54 .delete_records = NULL,//__ctsvc_db_email_delete_records
56 .get_count_with_query = NULL,
57 .replace_record = NULL,
58 .replace_records = NULL,
61 static int __ctsvc_db_email_get_person_default_email(int person_id)
65 char query[CTS_SQL_MAX_LEN] = {0};
67 snprintf(query, sizeof(query),
68 "SELECT id FROM "CTSVC_DB_VIEW_CONTACT" c, "CTS_TABLE_DATA" d "
69 "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_default = 1",
70 person_id, CTSVC_DATA_EMAIL);
71 ret = ctsvc_query_get_first_int_result(query, &default_email_id);
72 if (CONTACTS_ERROR_NONE != ret)
74 return default_email_id;
77 static int __ctsvc_db_email_update_person_has_email(int person_id, bool has_email)
80 char query[CTS_SQL_MAX_LEN] = {0};
82 snprintf(query, sizeof(query),
83 "UPDATE "CTS_TABLE_PERSONS" SET has_email = %d WHERE person_id = %d",
84 has_email, person_id);
86 ret = ctsvc_query_exec(query);
87 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
91 static int __ctsvc_db_email_update_default(int email_id, int contact_id, bool is_default, bool is_primary_default)
94 char query[CTS_SQL_MAX_LEN] = {0};
96 snprintf(query, sizeof(query),
97 "UPDATE "CTS_TABLE_DATA" SET is_default = %d, is_primary_default = %d WHERE id = %d",
98 is_default, is_primary_default, email_id);
99 ret = ctsvc_query_exec(query);
101 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
105 static int __ctsvc_db_email_get_default_email_id(int contact_id)
109 char query[CTS_SQL_MAX_LEN] = {0};
110 snprintf(query, sizeof(query),
111 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_default=1",
112 CTSVC_DATA_EMAIL, contact_id);
113 ret = ctsvc_query_get_first_int_result(query, &email_id);
114 if (CONTACTS_ERROR_NONE != ret)
119 static int __ctsvc_db_email_get_primary_default_email_id(int contact_id)
123 char query[CTS_SQL_MAX_LEN] = {0};
124 snprintf(query, sizeof(query),
125 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_primary_default=1",
126 CTSVC_DATA_EMAIL, contact_id);
127 ret = ctsvc_query_get_first_int_result(query, &email_id);
128 if (CONTACTS_ERROR_NONE != ret)
133 static int __ctsvc_db_email_get_primary_default_contact_id(int person_id)
136 int default_contact_id;
137 char query[CTS_SQL_MAX_LEN] = {0};
139 snprintf(query, sizeof(query),
140 "SELECT c.contact_id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
141 "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_primary_default = 1",
142 person_id, CTSVC_DATA_EMAIL);
143 ret = ctsvc_query_get_first_int_result(query, &default_contact_id);
144 if (CONTACTS_ERROR_NONE != ret)
146 return default_contact_id;
149 static int __ctsvc_db_email_set_primary_default(int email_id, bool is_primary_default)
152 char query[CTS_SQL_MAX_LEN] = {0};
154 snprintf(query, sizeof(query),
155 "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE id = %d",
156 is_primary_default, email_id);
157 ret = ctsvc_query_exec(query);
158 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
162 static int __ctsvc_db_email_insert_record(contacts_record_h record, int *id)
165 int addressbook_id = 0;
167 int old_default_email_id = 0;
168 char query[CTS_SQL_MAX_LEN] = {0};
169 cts_stmt stmt = NULL;
170 ctsvc_email_s *email = (ctsvc_email_s *)record;
171 RETVM_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER,
172 "Invalid parameter : email is NULL");
174 ret = ctsvc_begin_trans();
175 if (CONTACTS_ERROR_NONE != ret) {
176 CTS_ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
180 snprintf(query, sizeof(query),
181 "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
182 ret = ctsvc_query_prepare(query, &stmt);
184 CTS_ERR("DB error : ctsvc_query_prepare() Fail(%d)", ret);
185 ctsvc_end_trans(false);
189 ret = ctsvc_stmt_step(stmt);
191 CTS_ERR("DB error : ctsvc_stmt_step() Fail(%d)", ret);
192 ctsvc_stmt_finalize(stmt);
193 ctsvc_end_trans(false);
194 if (CONTACTS_ERROR_NONE == ret)
195 return CONTACTS_ERROR_INVALID_PARAMETER;
199 addressbook_id = ctsvc_stmt_get_int(stmt, 0);
200 person_id = ctsvc_stmt_get_int(stmt, 1);
201 ctsvc_stmt_finalize(stmt);
203 if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
204 CTS_ERR("Does not have permission to update this email record : addresbook_id(%d)", addressbook_id);
205 ctsvc_end_trans(false);
206 return CONTACTS_ERROR_PERMISSION_DENIED;
209 old_default_email_id = __ctsvc_db_email_get_default_email_id(email->contact_id);
210 if (0 == old_default_email_id)
211 email->is_default = true;
213 ret = ctsvc_db_email_insert(record, email->contact_id, false, id);
214 if (CONTACTS_ERROR_NONE != ret) {
215 CTS_ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
216 ctsvc_end_trans(false);
220 snprintf(query, sizeof(query),
221 "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
222 "WHERE contact_id = %d",
223 1, ctsvc_get_next_ver(), (int)time(NULL), email->contact_id);
225 ret = ctsvc_query_exec(query);
226 if (CONTACTS_ERROR_NONE != ret) {
227 CTS_ERR("ctsvc_query_exec() Fail(%d)", ret);
228 ctsvc_end_trans(false);
232 if (email->is_default) {
233 int primary_default_contact_id = 0;
235 __ctsvc_db_email_update_person_has_email(person_id, true);
237 primary_default_contact_id = __ctsvc_db_email_get_primary_default_contact_id(person_id);
238 if (0 == primary_default_contact_id || email->contact_id == primary_default_contact_id)
239 __ctsvc_db_email_set_primary_default(*id, true);
241 ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
244 ctsvc_set_contact_noti();
245 ctsvc_set_person_noti();
247 ret = ctsvc_end_trans(true);
248 if (ret < CONTACTS_ERROR_NONE) {
249 CTS_ERR("DB error : ctsvc_end_trans() Fail(%d)", ret);
253 return CONTACTS_ERROR_NONE;
256 static int __ctsvc_db_email_get_record(int id, contacts_record_h* out_record)
259 cts_stmt stmt = NULL;
260 char query[CTS_SQL_MAX_LEN] = {0};
262 RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
265 snprintf(query, sizeof(query),
266 "SELECT id, data.contact_id, is_default, data1, data2, data3 "
267 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
268 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
269 "WHERE id = %d AND datatype = %d ",
270 id, CTSVC_DATA_EMAIL);
272 ret = ctsvc_query_prepare(query, &stmt);
273 RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Fail(%d)", ret);
275 ret = ctsvc_stmt_step(stmt);
276 if (1 /*CTS_TRUE*/ != ret) {
277 CTS_ERR("ctsvc_stmt_step() Fail(%d)", ret);
278 ctsvc_stmt_finalize(stmt);
279 if (CONTACTS_ERROR_NONE == ret)
280 return CONTACTS_ERROR_NO_DATA;
285 ctsvc_db_email_get_value_from_stmt(stmt, out_record, 0);
287 ctsvc_stmt_finalize(stmt);
289 return CONTACTS_ERROR_NONE;
292 static int __ctsvc_db_email_update_record(contacts_record_h record)
296 char query[CTS_SQL_MAX_LEN] = {0};
297 ctsvc_email_s *email = (ctsvc_email_s *)record;
298 RETVM_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER, "email is empty");
300 ret = ctsvc_begin_trans();
301 if (CONTACTS_ERROR_NONE != ret) {
302 CTS_ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
306 snprintf(query, sizeof(query),
307 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
308 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
309 if (CONTACTS_ERROR_NONE != ret) {
310 CTS_ERR("No data : contact_id (%d) is not exist", email->contact_id);
311 ctsvc_end_trans(false);
315 if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
316 CTS_ERR("Does not have permission to update this email record : addresbook_id(%d)", addressbook_id);
317 ctsvc_end_trans(false);
318 return CONTACTS_ERROR_PERMISSION_DENIED;
321 ret = ctsvc_db_email_update(record, false);
322 if (CONTACTS_ERROR_NONE != ret) {
323 CTS_ERR("update record Fail(%d)", ret);
324 ctsvc_end_trans(false);
328 if (email->is_default) {
329 int old_primary_default_email_id = 0;
330 old_primary_default_email_id = __ctsvc_db_email_get_primary_default_email_id(email->contact_id);
331 if (old_primary_default_email_id)
332 __ctsvc_db_email_set_primary_default(email->id, true);
334 ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
336 ret = ctsvc_db_contact_update_changed_time(email->contact_id);
337 if (CONTACTS_ERROR_NONE != ret) {
338 CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
339 ctsvc_end_trans(false);
342 ctsvc_set_person_noti();
344 ret = ctsvc_end_trans(true);
345 if (ret < CONTACTS_ERROR_NONE)
347 CTS_ERR("DB error : ctsvc_end_trans() Fail(%d)", ret);
351 return CONTACTS_ERROR_NONE;
354 static int __ctsvc_db_email_delete_record(int id)
361 int is_primary_default;
362 char query[CTS_SQL_MAX_LEN] = {0};
363 bool has_email = false;
364 cts_stmt stmt = NULL;
367 ret = ctsvc_begin_trans();
368 if (CONTACTS_ERROR_NONE != ret) {
369 CTS_ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
373 snprintf(query, sizeof(query),
374 "SELECT contact_id, person_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
375 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
377 ret = ctsvc_query_prepare(query, &stmt);
379 CTS_ERR("DB error : ctsvc_query_prepare() Fail(%d)", ret);
380 ctsvc_end_trans(false);
384 ret = ctsvc_stmt_step(stmt);
386 CTS_ERR("DB error : ctsvc_stmt_step() Fail(%d)", ret);
387 ctsvc_stmt_finalize(stmt);
388 ctsvc_end_trans(false);
389 if (CONTACTS_ERROR_NONE == ret)
390 return CONTACTS_ERROR_NO_DATA;
394 contact_id = ctsvc_stmt_get_int(stmt, 0);
395 person_id = ctsvc_stmt_get_int(stmt, 1);
396 addressbook_id = ctsvc_stmt_get_int(stmt, 2);
397 ctsvc_stmt_finalize(stmt);
399 if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
400 CTS_ERR("Does not have permission to delete this email record : addresbook_id(%d)", addressbook_id);
401 ctsvc_end_trans(false);
402 return CONTACTS_ERROR_PERMISSION_DENIED;
405 snprintf(query, sizeof(query),
406 "SELECT is_default, is_primary_default FROM "CTS_TABLE_DATA" WHERE id = %d", id);
408 ret = ctsvc_query_prepare(query, &stmt);
409 RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Fail(%d)", ret);
411 ret = ctsvc_stmt_step(stmt);
413 CTS_ERR("DB error : ctsvc_stmt_step() Fail(%d)", ret);
414 ctsvc_stmt_finalize(stmt);
415 ctsvc_end_trans(false);
416 if (CONTACTS_ERROR_NONE == ret)
417 return CONTACTS_ERROR_NO_DATA;
421 is_default = ctsvc_stmt_get_int(stmt, 0);
422 is_primary_default = ctsvc_stmt_get_int(stmt, 1);
423 ctsvc_stmt_finalize(stmt);
425 ret = ctsvc_db_email_delete(id, false);
426 if (CONTACTS_ERROR_NONE != ret) {
427 CTS_ERR("DB error : ctsvc_begin_trans() Fail(%d)", ret);
428 ctsvc_end_trans(false);
432 snprintf(query, sizeof(query),
433 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype = %d AND contact_id = %d AND is_my_profile = 0 limit 1",
434 CTSVC_DATA_EMAIL, contact_id);
435 ret = ctsvc_query_get_first_int_result(query, &email_id);
439 snprintf(query, sizeof(query),
440 "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
441 "WHERE contact_id = %d",
442 has_email, ctsvc_get_next_ver(), (int)time(NULL), contact_id);
444 ret = ctsvc_query_exec(query);
445 if (CONTACTS_ERROR_NONE != ret) {
446 CTS_ERR("ctsvc_query_exec() Fail(%d)", ret);
447 ctsvc_end_trans(false);
454 __ctsvc_db_email_update_default(email_id, contact_id, is_default, is_primary_default);
456 else if (is_primary_default) {
457 int default_email_id = 0;
458 default_email_id = __ctsvc_db_email_get_person_default_email(person_id);
459 if (default_email_id)
460 __ctsvc_db_email_set_primary_default(default_email_id, true);
462 __ctsvc_db_email_update_person_has_email(person_id, false);
464 ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
467 ctsvc_set_contact_noti();
468 ctsvc_set_person_noti();
470 ret = ctsvc_end_trans(true);
471 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Fail(%d)", ret);
472 return CONTACTS_ERROR_NONE;
475 static int __ctsvc_db_email_get_all_records(int offset, int limit, contacts_list_h* out_list)
479 contacts_list_h list;
480 ctsvc_email_s *email;
481 cts_stmt stmt = NULL;
482 char query[CTS_SQL_MAX_LEN] = {0};
484 len = snprintf(query, sizeof(query),
485 "SELECT id, data.contact_id, is_default, data1, data2, data3 "
486 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
487 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
488 "WHERE datatype = %d AND is_my_profile=0 ",
492 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
494 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
497 ret = ctsvc_query_prepare(query, &stmt);
498 RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Fail(%d)", ret);
500 contacts_list_create(&list);
501 while ((ret = ctsvc_stmt_step(stmt))) {
502 if (1 /*CTS_TRUE */ != ret) {
503 CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
504 ctsvc_stmt_finalize(stmt);
505 contacts_list_destroy(list, true);
508 ctsvc_db_email_get_value_from_stmt(stmt, (contacts_record_h*)&email, 0);
509 ctsvc_list_prepend(list, (contacts_record_h)email);
511 ctsvc_stmt_finalize(stmt);
512 ctsvc_list_reverse(list);
515 return CONTACTS_ERROR_NONE;
518 static int __ctsvc_db_email_get_records_with_query(contacts_query_h query, int offset,
519 int limit, contacts_list_h* out_list)
524 ctsvc_query_s *s_query;
526 contacts_list_h list;
527 ctsvc_email_s *email;
529 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
530 s_query = (ctsvc_query_s *)query;
532 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
533 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
535 contacts_list_create(&list);
536 while ((ret = ctsvc_stmt_step(stmt))) {
537 contacts_record_h record;
538 if (1 /*CTS_TRUE */ != ret) {
539 CTS_ERR("DB error : ctsvc_stmt_step() Fail(%d)", ret);
540 ctsvc_stmt_finalize(stmt);
541 contacts_list_destroy(list, true);
545 contacts_record_create(_contacts_email._uri, &record);
546 email = (ctsvc_email_s*)record;
547 if (0 == s_query->projection_count)
548 field_count = s_query->property_count;
550 field_count = s_query->projection_count;
551 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
552 s_query->projection_count, s_query->property_count);
554 if (CONTACTS_ERROR_NONE != ret)
555 ASSERT_NOT_REACHED("To set projection is Fail.\n");
558 for (i=0;i<field_count;i++) {
561 if (0 == s_query->projection_count)
562 property_id = s_query->properties[i].property_id;
564 property_id = s_query->projection[i];
566 switch(property_id) {
567 case CTSVC_PROPERTY_EMAIL_ID:
568 email->id = ctsvc_stmt_get_int(stmt, i);
570 case CTSVC_PROPERTY_EMAIL_CONTACT_ID:
571 email->contact_id = ctsvc_stmt_get_int(stmt, i);
573 case CTSVC_PROPERTY_EMAIL_TYPE:
574 email->type = ctsvc_stmt_get_int(stmt, i);
576 case CTSVC_PROPERTY_EMAIL_LABEL:
577 temp = ctsvc_stmt_get_text(stmt, i);
579 email->label = SAFE_STRDUP(temp);
581 case CTSVC_PROPERTY_EMAIL_EMAIL:
582 temp = ctsvc_stmt_get_text(stmt, i);
583 free(email->email_addr);
584 email->email_addr = SAFE_STRDUP(temp);
586 case CTSVC_PROPERTY_EMAIL_IS_DEFAULT:
587 email->is_default = ctsvc_stmt_get_int(stmt, i);
593 ctsvc_list_prepend(list, record);
595 ctsvc_stmt_finalize(stmt);
596 ctsvc_list_reverse(list);
599 return CONTACTS_ERROR_NONE;
602 //static int __ctsvc_db_email_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
603 //static int __ctsvc_db_email_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
604 //static int __ctsvc_db_email_delete_records(int ids[], int count) { return CONTACTS_ERROR_NONE; }