4 * Copyright (c) 2010 - 2015 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.
20 #include "ctsvc_internal.h"
21 #include "ctsvc_db_schema.h"
22 #include "ctsvc_db_sqlite.h"
23 #include "ctsvc_db_utils.h"
24 #include "ctsvc_db_init.h"
25 #include "ctsvc_db_access_control.h"
26 #include "ctsvc_db_plugin_contact_helper.h"
27 #include "ctsvc_db_plugin_email_helper.h"
28 #include "ctsvc_record.h"
29 #include "ctsvc_notification.h"
30 #include "ctsvc_db_query.h"
31 #include "ctsvc_list.h"
34 static int __ctsvc_db_email_get_person_default_email(int person_id)
38 char query[CTS_SQL_MAX_LEN] = {0};
40 snprintf(query, sizeof(query),
41 "SELECT id FROM "CTSVC_DB_VIEW_CONTACT" c, "CTS_TABLE_DATA" d "
42 "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_default = 1",
43 person_id, CONTACTS_DATA_TYPE_EMAIL);
44 ret = ctsvc_query_get_first_int_result(query, &default_email_id);
45 if (CONTACTS_ERROR_NONE != ret)
47 return default_email_id;
50 static int __ctsvc_db_email_update_person_has_email(int person_id, bool has_email)
53 char query[CTS_SQL_MAX_LEN] = {0};
55 snprintf(query, sizeof(query),
56 "UPDATE "CTS_TABLE_PERSONS" SET has_email = %d WHERE person_id = %d",
57 has_email, person_id);
59 ret = ctsvc_query_exec(query);
60 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
64 static int __ctsvc_db_email_update_default(int email_id, int contact_id, bool is_default, bool is_primary_default)
67 char query[CTS_SQL_MAX_LEN] = {0};
69 snprintf(query, sizeof(query),
70 "UPDATE "CTS_TABLE_DATA" SET is_default = %d, is_primary_default = %d WHERE id = %d",
71 is_default, is_primary_default, email_id);
72 ret = ctsvc_query_exec(query);
74 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
78 static int __ctsvc_db_email_get_default_email_id(int contact_id)
82 char query[CTS_SQL_MAX_LEN] = {0};
83 snprintf(query, sizeof(query),
84 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_default=1",
85 CONTACTS_DATA_TYPE_EMAIL, contact_id);
86 ret = ctsvc_query_get_first_int_result(query, &email_id);
87 if (CONTACTS_ERROR_NONE != ret)
92 static int __ctsvc_db_email_get_primary_default_email_id(int contact_id)
96 char query[CTS_SQL_MAX_LEN] = {0};
97 snprintf(query, sizeof(query),
98 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_primary_default=1",
99 CONTACTS_DATA_TYPE_EMAIL, contact_id);
100 ret = ctsvc_query_get_first_int_result(query, &email_id);
101 if (CONTACTS_ERROR_NONE != ret)
106 static int __ctsvc_db_email_get_primary_default_contact_id(int person_id)
109 int default_contact_id;
110 char query[CTS_SQL_MAX_LEN] = {0};
112 snprintf(query, sizeof(query),
113 "SELECT c.contact_id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
114 "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_primary_default = 1",
115 person_id, CONTACTS_DATA_TYPE_EMAIL);
116 ret = ctsvc_query_get_first_int_result(query, &default_contact_id);
117 if (CONTACTS_ERROR_NONE != ret)
119 return default_contact_id;
122 static int __ctsvc_db_email_set_primary_default(int email_id, bool is_primary_default)
125 char query[CTS_SQL_MAX_LEN] = {0};
127 snprintf(query, sizeof(query),
128 "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE id = %d",
129 is_primary_default, email_id);
130 ret = ctsvc_query_exec(query);
131 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Fail(%d)", ret);
135 static int __ctsvc_db_email_insert_record(contacts_record_h record, int *id)
138 int addressbook_id = 0;
140 int old_default_email_id = 0;
141 char query[CTS_SQL_MAX_LEN] = {0};
142 cts_stmt stmt = NULL;
143 ctsvc_email_s *email = (ctsvc_email_s*)record;
144 RETV_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER);
146 ret = ctsvc_begin_trans();
147 if (CONTACTS_ERROR_NONE != ret) {
148 /* LCOV_EXCL_START */
149 ERR("ctsvc_begin_trans() Fail(%d)", ret);
154 snprintf(query, sizeof(query),
155 "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
156 ret = ctsvc_query_prepare(query, &stmt);
158 /* LCOV_EXCL_START */
159 ERR("ctsvc_query_prepare() Fail(%d)", ret);
160 ctsvc_end_trans(false);
165 ret = ctsvc_stmt_step(stmt);
167 /* LCOV_EXCL_START */
168 ERR("ctsvc_stmt_step() Fail(%d)", ret);
169 ctsvc_stmt_finalize(stmt);
170 ctsvc_end_trans(false);
171 if (CONTACTS_ERROR_NONE == ret)
172 return CONTACTS_ERROR_INVALID_PARAMETER;
177 addressbook_id = ctsvc_stmt_get_int(stmt, 0);
178 person_id = ctsvc_stmt_get_int(stmt, 1);
179 ctsvc_stmt_finalize(stmt);
181 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
182 /* LCOV_EXCL_START */
183 ERR("No permission in this addresbook_id(%d)", addressbook_id);
184 ctsvc_end_trans(false);
185 return CONTACTS_ERROR_PERMISSION_DENIED;
189 old_default_email_id = __ctsvc_db_email_get_default_email_id(email->contact_id);
190 if (0 == old_default_email_id)
191 email->is_default = true;
193 ret = ctsvc_db_email_insert(record, email->contact_id, false, id);
194 if (CONTACTS_ERROR_NONE != ret) {
195 /* LCOV_EXCL_START */
196 ERR("ctsvc_begin_trans() Fail(%d)", ret);
197 ctsvc_end_trans(false);
202 snprintf(query, sizeof(query),
203 "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
204 "WHERE contact_id = %d",
205 1, ctsvc_get_next_ver(), (int)time(NULL), email->contact_id);
207 ret = ctsvc_query_exec(query);
208 if (CONTACTS_ERROR_NONE != ret) {
209 /* LCOV_EXCL_START */
210 ERR("ctsvc_query_exec() Fail(%d)", ret);
211 ctsvc_end_trans(false);
216 if (email->is_default) {
217 int primary_default_contact_id = 0;
219 __ctsvc_db_email_update_person_has_email(person_id, true);
221 primary_default_contact_id = __ctsvc_db_email_get_primary_default_contact_id(person_id);
222 if (0 == primary_default_contact_id || email->contact_id == primary_default_contact_id)
223 __ctsvc_db_email_set_primary_default(*id, true);
225 ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
228 ctsvc_set_contact_noti();
229 ctsvc_set_person_noti();
231 ret = ctsvc_end_trans(true);
232 if (ret < CONTACTS_ERROR_NONE) {
233 /* LCOV_EXCL_START */
234 ERR("ctsvc_end_trans() Fail(%d)", ret);
238 return CONTACTS_ERROR_NONE;
242 static int __ctsvc_db_email_get_record(int id, contacts_record_h *out_record)
245 cts_stmt stmt = NULL;
246 char query[CTS_SQL_MAX_LEN] = {0};
248 RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
251 snprintf(query, sizeof(query),
252 "SELECT id, data.contact_id, is_default, data1, data2, data3 "
253 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
254 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
255 "WHERE id = %d AND datatype = %d ",
256 id, CONTACTS_DATA_TYPE_EMAIL);
258 ret = ctsvc_query_prepare(query, &stmt);
259 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
261 ret = ctsvc_stmt_step(stmt);
262 if (1 /*CTS_TRUE*/ != ret) {
263 /* LCOV_EXCL_START */
264 ERR("ctsvc_stmt_step() Fail(%d)", ret);
265 ctsvc_stmt_finalize(stmt);
266 if (CONTACTS_ERROR_NONE == ret)
267 return CONTACTS_ERROR_NO_DATA;
273 ctsvc_db_email_get_value_from_stmt(stmt, out_record, 0);
275 ctsvc_stmt_finalize(stmt);
277 return CONTACTS_ERROR_NONE;
280 static int __ctsvc_db_email_update_record(contacts_record_h record)
284 char query[CTS_SQL_MAX_LEN] = {0};
285 ctsvc_email_s *email = (ctsvc_email_s*)record;
286 RETVM_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER, "email is empty");
288 ret = ctsvc_begin_trans();
289 if (CONTACTS_ERROR_NONE != ret) {
290 /* LCOV_EXCL_START */
291 ERR("ctsvc_begin_trans() Fail(%d)", ret);
296 snprintf(query, sizeof(query),
297 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
298 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
299 if (CONTACTS_ERROR_NONE != ret) {
300 /* LCOV_EXCL_START */
301 ERR("No data : contact_id (%d) is not exist", email->contact_id);
302 ctsvc_end_trans(false);
307 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
308 /* LCOV_EXCL_START */
309 ERR("No permission in this addresbook_id(%d)", addressbook_id);
310 ctsvc_end_trans(false);
311 return CONTACTS_ERROR_PERMISSION_DENIED;
315 ret = ctsvc_db_email_update(record, false);
316 if (CONTACTS_ERROR_NONE != ret) {
317 /* LCOV_EXCL_START */
318 ERR("update record Fail(%d)", ret);
319 ctsvc_end_trans(false);
324 if (email->is_default) {
325 int old_primary_default_email_id = 0;
326 old_primary_default_email_id = __ctsvc_db_email_get_primary_default_email_id(email->contact_id);
327 if (old_primary_default_email_id)
328 __ctsvc_db_email_set_primary_default(email->id, true);
330 ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
332 ret = ctsvc_db_contact_update_changed_time(email->contact_id);
333 if (CONTACTS_ERROR_NONE != ret) {
334 /* LCOV_EXCL_START */
335 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
336 ctsvc_end_trans(false);
340 ctsvc_set_person_noti();
342 ret = ctsvc_end_trans(true);
343 if (ret < CONTACTS_ERROR_NONE) {
344 /* LCOV_EXCL_START */
345 ERR("ctsvc_end_trans() Fail(%d)", ret);
349 return CONTACTS_ERROR_NONE;
353 static int __ctsvc_db_email_delete_record(int id)
360 int is_primary_default;
361 char query[CTS_SQL_MAX_LEN] = {0};
362 bool has_email = false;
363 cts_stmt stmt = NULL;
366 ret = ctsvc_begin_trans();
367 if (CONTACTS_ERROR_NONE != ret) {
368 /* LCOV_EXCL_START */
369 ERR("ctsvc_begin_trans() Fail(%d)", ret);
374 snprintf(query, sizeof(query),
375 "SELECT contact_id, person_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
376 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
378 ret = ctsvc_query_prepare(query, &stmt);
380 /* LCOV_EXCL_START */
381 ERR("ctsvc_query_prepare() Fail(%d)", ret);
382 ctsvc_end_trans(false);
387 ret = ctsvc_stmt_step(stmt);
389 /* LCOV_EXCL_START */
390 ERR("ctsvc_stmt_step() Fail(%d)", ret);
391 ctsvc_stmt_finalize(stmt);
392 ctsvc_end_trans(false);
393 if (CONTACTS_ERROR_NONE == ret)
394 return CONTACTS_ERROR_NO_DATA;
399 contact_id = ctsvc_stmt_get_int(stmt, 0);
400 person_id = ctsvc_stmt_get_int(stmt, 1);
401 addressbook_id = ctsvc_stmt_get_int(stmt, 2);
402 ctsvc_stmt_finalize(stmt);
404 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
405 /* LCOV_EXCL_START */
406 ERR("No permission in this addresbook_id(%d)", addressbook_id);
407 ctsvc_end_trans(false);
408 return CONTACTS_ERROR_PERMISSION_DENIED;
412 snprintf(query, sizeof(query),
413 "SELECT is_default, is_primary_default FROM "CTS_TABLE_DATA" WHERE id = %d", id);
415 ret = ctsvc_query_prepare(query, &stmt);
416 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
418 ret = ctsvc_stmt_step(stmt);
420 /* LCOV_EXCL_START */
421 ERR("ctsvc_stmt_step() Fail(%d)", ret);
422 ctsvc_stmt_finalize(stmt);
423 ctsvc_end_trans(false);
424 if (CONTACTS_ERROR_NONE == ret)
425 return CONTACTS_ERROR_NO_DATA;
430 is_default = ctsvc_stmt_get_int(stmt, 0);
431 is_primary_default = ctsvc_stmt_get_int(stmt, 1);
432 ctsvc_stmt_finalize(stmt);
434 ret = ctsvc_db_email_delete(id, false);
435 if (CONTACTS_ERROR_NONE != ret) {
436 /* LCOV_EXCL_START */
437 ERR("ctsvc_begin_trans() Fail(%d)", ret);
438 ctsvc_end_trans(false);
443 snprintf(query, sizeof(query),
444 "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype = %d AND contact_id = %d AND is_my_profile = 0 limit 1",
445 CONTACTS_DATA_TYPE_EMAIL, contact_id);
446 ret = ctsvc_query_get_first_int_result(query, &email_id);
450 snprintf(query, sizeof(query),
451 "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
452 "WHERE contact_id = %d",
453 has_email, ctsvc_get_next_ver(), (int)time(NULL), contact_id);
455 ret = ctsvc_query_exec(query);
456 if (CONTACTS_ERROR_NONE != ret) {
457 /* LCOV_EXCL_START */
458 ERR("ctsvc_query_exec() Fail(%d)", ret);
459 ctsvc_end_trans(false);
467 __ctsvc_db_email_update_default(email_id, contact_id, is_default, is_primary_default);
468 } else if (is_primary_default) {
469 int default_email_id = 0;
470 default_email_id = __ctsvc_db_email_get_person_default_email(person_id);
471 if (default_email_id)
472 __ctsvc_db_email_set_primary_default(default_email_id, true);
474 __ctsvc_db_email_update_person_has_email(person_id, false);
476 ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
479 ctsvc_set_contact_noti();
480 ctsvc_set_person_noti();
482 ret = ctsvc_end_trans(true);
483 RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Fail(%d)", ret);
484 return CONTACTS_ERROR_NONE;
487 static int __ctsvc_db_email_get_all_records(int offset, int limit, contacts_list_h *out_list)
491 contacts_list_h list;
492 ctsvc_email_s *email;
493 cts_stmt stmt = NULL;
494 char query[CTS_SQL_MAX_LEN] = {0};
496 len = snprintf(query, sizeof(query),
497 "SELECT id, data.contact_id, is_default, data1, data2, data3 "
498 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
499 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
500 "WHERE datatype = %d AND is_my_profile=0 ",
501 CONTACTS_DATA_TYPE_EMAIL);
504 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
506 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
509 ret = ctsvc_query_prepare(query, &stmt);
510 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
512 contacts_list_create(&list);
513 while ((ret = ctsvc_stmt_step(stmt))) {
514 if (1 /*CTS_TRUE */ != ret) {
515 /* LCOV_EXCL_START */
516 ERR("DB : ctsvc_stmt_step() Fail(%d)", ret);
517 ctsvc_stmt_finalize(stmt);
518 contacts_list_destroy(list, true);
522 ctsvc_db_email_get_value_from_stmt(stmt, (contacts_record_h*)&email, 0);
523 ctsvc_list_prepend(list, (contacts_record_h)email);
525 ctsvc_stmt_finalize(stmt);
526 ctsvc_list_reverse(list);
529 return CONTACTS_ERROR_NONE;
532 static int __ctsvc_db_email_get_records_with_query(contacts_query_h query, int offset,
533 int limit, contacts_list_h *out_list)
538 ctsvc_query_s *s_query;
540 contacts_list_h list;
541 ctsvc_email_s *email;
543 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
544 s_query = (ctsvc_query_s*)query;
546 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
547 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
549 contacts_list_create(&list);
550 while ((ret = ctsvc_stmt_step(stmt))) {
551 contacts_record_h record;
552 if (1 /*CTS_TRUE */ != ret) {
553 /* LCOV_EXCL_START */
554 ERR("ctsvc_stmt_step() Fail(%d)", ret);
555 ctsvc_stmt_finalize(stmt);
556 contacts_list_destroy(list, true);
561 contacts_record_create(_contacts_email._uri, &record);
562 email = (ctsvc_email_s*)record;
563 if (0 == s_query->projection_count) {
564 field_count = s_query->property_count;
566 field_count = s_query->projection_count;
567 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
568 s_query->projection_count, s_query->property_count);
570 if (CONTACTS_ERROR_NONE != ret)
571 ASSERT_NOT_REACHED("To set projection is Fail.\n");
574 for (i = 0; i < field_count; i++) {
577 if (0 == s_query->projection_count)
578 property_id = s_query->properties[i].property_id;
580 property_id = s_query->projection[i];
582 switch (property_id) {
583 case CTSVC_PROPERTY_EMAIL_ID:
584 email->id = ctsvc_stmt_get_int(stmt, i);
586 case CTSVC_PROPERTY_EMAIL_CONTACT_ID:
587 email->contact_id = ctsvc_stmt_get_int(stmt, i);
589 case CTSVC_PROPERTY_EMAIL_TYPE:
590 email->type = ctsvc_stmt_get_int(stmt, i);
592 case CTSVC_PROPERTY_EMAIL_LABEL:
593 temp = ctsvc_stmt_get_text(stmt, i);
595 email->label = SAFE_STRDUP(temp);
597 case CTSVC_PROPERTY_EMAIL_EMAIL:
598 temp = ctsvc_stmt_get_text(stmt, i);
599 free(email->email_addr);
600 email->email_addr = SAFE_STRDUP(temp);
602 case CTSVC_PROPERTY_EMAIL_IS_DEFAULT:
603 email->is_default = ctsvc_stmt_get_int(stmt, i);
609 ctsvc_list_prepend(list, record);
611 ctsvc_stmt_finalize(stmt);
612 ctsvc_list_reverse(list);
615 return CONTACTS_ERROR_NONE;
618 ctsvc_db_plugin_info_s ctsvc_db_plugin_email = {
619 .is_query_only = false,
620 .insert_record = __ctsvc_db_email_insert_record,
621 .get_record = __ctsvc_db_email_get_record,
622 .update_record = __ctsvc_db_email_update_record,
623 .delete_record = __ctsvc_db_email_delete_record,
624 .get_all_records = __ctsvc_db_email_get_all_records,
625 .get_records_with_query = __ctsvc_db_email_get_records_with_query,
626 .insert_records = NULL,
627 .update_records = NULL,
628 .delete_records = NULL,
630 .get_count_with_query = NULL,
631 .replace_record = NULL,
632 .replace_records = NULL,