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_normalize.h"
25 #include "ctsvc_db_init.h"
26 #include "ctsvc_db_query.h"
27 #include "ctsvc_db_access_control.h"
28 #include "ctsvc_db_plugin_contact_helper.h"
29 #include "ctsvc_db_plugin_name_helper.h"
30 #include "ctsvc_record.h"
31 #include "ctsvc_list.h"
32 #include "ctsvc_notification.h"
35 static int __ctsvc_db_name_insert_record(contacts_record_h record, int *id)
40 char query[CTS_SQL_MAX_LEN] = {0};
41 ctsvc_name_s *name = (ctsvc_name_s*)record;
43 ret = ctsvc_begin_trans();
44 if (CONTACTS_ERROR_NONE != ret) {
46 ERR("ctsvc_begin_trans() Fail(%d)", ret);
51 snprintf(query, sizeof(query),
52 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
53 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
54 if (CONTACTS_ERROR_NONE != ret) {
55 ctsvc_end_trans(false);
56 if (CONTACTS_ERROR_NO_DATA == ret) {
58 ERR("No data : contact_id (%d) is not exist", name->contact_id);
59 return CONTACTS_ERROR_INVALID_PARAMETER;
63 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
69 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
71 ERR("No permission in this addresbook_id(%d)", addressbook_id);
72 ctsvc_end_trans(false);
73 return CONTACTS_ERROR_PERMISSION_DENIED;
77 snprintf(query, sizeof(query),
78 "SELECT id FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND datatype=%d", name->contact_id, CONTACTS_DATA_TYPE_NAME);
79 ret = ctsvc_query_get_first_int_result(query, &name_id);
82 ERR("name_id (%d) is exist", name_id);
83 ctsvc_end_trans(false);
84 return CONTACTS_ERROR_INVALID_PARAMETER;
88 ret = ctsvc_db_name_insert(record, name->contact_id, false, id);
89 if (CONTACTS_ERROR_NONE != ret) {
91 ERR("ctsvc_begin_trans() Fail(%d)", ret);
92 ctsvc_end_trans(false);
97 ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
99 ret = ctsvc_db_contact_update_changed_time(name->contact_id);
100 if (CONTACTS_ERROR_NONE != ret) {
101 /* LCOV_EXCL_START */
102 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
103 ctsvc_end_trans(false);
107 ctsvc_set_person_noti();
109 ret = ctsvc_end_trans(true);
110 if (ret < CONTACTS_ERROR_NONE) {
111 /* LCOV_EXCL_START */
112 ERR("ctsvc_end_trans() Fail(%d)", ret);
116 return CONTACTS_ERROR_NONE;
120 static int __ctsvc_db_name_get_record(int id, contacts_record_h *out_record)
123 cts_stmt stmt = NULL;
124 char query[CTS_SQL_MAX_LEN] = {0};
126 RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
129 snprintf(query, sizeof(query),
130 "SELECT id, data.contact_id, is_default, data1, data2, "
131 "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
132 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
133 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
134 "WHERE id = %d AND datatype = %d ",
135 id, CONTACTS_DATA_TYPE_NAME);
137 ret = ctsvc_query_prepare(query, &stmt);
138 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
140 ret = ctsvc_stmt_step(stmt);
141 if (1 /*CTS_TRUE*/ != ret) {
142 /* LCOV_EXCL_START */
143 ERR("ctsvc_stmt_step() Fail(%d)", ret);
144 ctsvc_stmt_finalize(stmt);
145 if (CONTACTS_ERROR_NONE == ret)
146 return CONTACTS_ERROR_NO_DATA;
152 ctsvc_db_name_get_value_from_stmt(stmt, out_record, 0);
153 ctsvc_stmt_finalize(stmt);
155 return CONTACTS_ERROR_NONE;
158 static int __ctsvc_db_name_update_record(contacts_record_h record)
162 char query[CTS_SQL_MAX_LEN] = {0};
163 ctsvc_name_s *name = (ctsvc_name_s*)record;
165 RETVM_IF(NULL == name->first && NULL == name->last && NULL == name->addition &&
166 NULL == name->prefix && NULL == name->suffix && NULL == name->phonetic_first &&
167 NULL == name->phonetic_middle && NULL == name->phonetic_last, CONTACTS_ERROR_INVALID_PARAMETER, "name is empty");
169 ret = ctsvc_begin_trans();
170 if (CONTACTS_ERROR_NONE != ret) {
171 /* LCOV_EXCL_START */
172 ERR("ctsvc_begin_trans() Fail(%d)", ret);
177 snprintf(query, sizeof(query),
178 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
179 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
180 if (CONTACTS_ERROR_NONE != ret) {
181 /* LCOV_EXCL_START */
182 ERR("No data : contact_id (%d) is not exist", name->contact_id);
183 ctsvc_end_trans(false);
188 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
189 /* LCOV_EXCL_START */
190 ERR("No permission in this addresbook_id(%d)", addressbook_id);
191 ctsvc_end_trans(false);
192 return CONTACTS_ERROR_PERMISSION_DENIED;
196 ret = ctsvc_db_name_update(record, false);
197 if (CONTACTS_ERROR_NONE != ret) {
198 /* LCOV_EXCL_START */
199 ERR("ctsvc_begin_trans() Fail(%d)", ret);
200 ctsvc_end_trans(false);
205 ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
207 ret = ctsvc_db_contact_update_changed_time(name->contact_id);
208 if (CONTACTS_ERROR_NONE != ret) {
209 /* LCOV_EXCL_START */
210 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
211 ctsvc_end_trans(false);
215 ctsvc_set_person_noti();
217 ret = ctsvc_end_trans(true);
218 if (ret < CONTACTS_ERROR_NONE) {
219 /* LCOV_EXCL_START */
220 ERR("ctsvc_end_trans() Fail(%d)", ret);
224 return CONTACTS_ERROR_NONE;
229 static int __ctsvc_db_name_delete_record(int id)
234 cts_stmt stmt = NULL;
235 char query[CTS_SQL_MAX_LEN] = {0};
237 ret = ctsvc_begin_trans();
238 if (CONTACTS_ERROR_NONE != ret) {
239 /* LCOV_EXCL_START */
240 ERR("ctsvc_begin_trans() Fail(%d)", ret);
245 snprintf(query, sizeof(query),
246 "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
247 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
248 ret = ctsvc_query_prepare(query, &stmt);
250 /* LCOV_EXCL_START */
251 ERR("ctsvc_query_prepare Fail(%d)", ret);
252 ctsvc_end_trans(false);
256 ret = ctsvc_stmt_step(stmt);
258 /* LCOV_EXCL_START */
259 ERR("The id(%d) is Invalid(%d)", id, ret);
260 ctsvc_stmt_finalize(stmt);
261 ctsvc_end_trans(false);
262 if (CONTACTS_ERROR_NONE == ret)
263 return CONTACTS_ERROR_NO_DATA;
269 contact_id = ctsvc_stmt_get_int(stmt, 0);
270 addressbook_id = ctsvc_stmt_get_int(stmt, 1);
271 ctsvc_stmt_finalize(stmt);
273 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
274 /* LCOV_EXCL_START */
275 ERR("No permission in this addresbook_id(%d)", addressbook_id);
276 ctsvc_end_trans(false);
277 return CONTACTS_ERROR_PERMISSION_DENIED;
281 ret = ctsvc_db_name_delete(id, false);
282 if (CONTACTS_ERROR_NONE != ret) {
283 /* LCOV_EXCL_START */
284 ERR("ctsvc_begin_trans() Fail(%d)", ret);
285 ctsvc_end_trans(false);
290 ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
292 ret = ctsvc_db_contact_update_changed_time(contact_id);
293 if (CONTACTS_ERROR_NONE != ret) {
294 /* LCOV_EXCL_START */
295 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
296 ctsvc_end_trans(false);
300 ctsvc_set_person_noti();
302 ret = ctsvc_end_trans(true);
303 if (ret < CONTACTS_ERROR_NONE) {
304 /* LCOV_EXCL_START */
305 ERR("ctsvc_end_trans() Fail(%d)", ret);
309 return CONTACTS_ERROR_NONE;
313 static int __ctsvc_db_name_get_all_records(int offset, int limit, contacts_list_h *out_list)
317 contacts_list_h list;
319 cts_stmt stmt = NULL;
320 char query[CTS_SQL_MAX_LEN] = {0};
322 len = snprintf(query, sizeof(query),
323 "SELECT id, data.contact_id, is_default, data1, data2, "
324 "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
325 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
326 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
327 "WHERE datatype = %d AND is_my_profile=0 ",
328 CONTACTS_DATA_TYPE_NAME);
331 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
333 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
336 ret = ctsvc_query_prepare(query, &stmt);
337 RETVM_IF(NULL == stmt, ret, " ctsvc_query_prepare() Fail(%d)", ret);
339 contacts_list_create(&list);
340 while ((ret = ctsvc_stmt_step(stmt))) {
342 /* LCOV_EXCL_START */
343 ERR("ctsvc_stmt_step() Fail(%d)", ret);
344 ctsvc_stmt_finalize(stmt);
345 contacts_list_destroy(list, true);
349 ctsvc_db_name_get_value_from_stmt(stmt, (contacts_record_h*)&name, 0);
350 ctsvc_list_prepend(list, (contacts_record_h)name);
353 ctsvc_stmt_finalize(stmt);
354 ctsvc_list_reverse(list);
357 return CONTACTS_ERROR_NONE;
360 static int __ctsvc_db_name_get_records_with_query(contacts_query_h query, int offset,
361 int limit, contacts_list_h *out_list)
366 ctsvc_query_s *s_query;
368 contacts_list_h list;
371 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
372 s_query = (ctsvc_query_s*)query;
374 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
375 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
377 contacts_list_create(&list);
378 while ((ret = ctsvc_stmt_step(stmt))) {
379 contacts_record_h record;
381 /* LCOV_EXCL_START */
382 ERR("ctsvc_stmt_step() Fail(%d)", ret);
383 ctsvc_stmt_finalize(stmt);
384 contacts_list_destroy(list, true);
389 contacts_record_create(_contacts_name._uri, &record);
390 name = (ctsvc_name_s*)record;
391 if (0 == s_query->projection_count) {
392 field_count = s_query->property_count;
394 field_count = s_query->projection_count;
395 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
396 s_query->projection_count, s_query->property_count);
398 if (CONTACTS_ERROR_NONE != ret)
399 ASSERT_NOT_REACHED("To set projection is Fail.\n");
402 for (i = 0; i < field_count; i++) {
405 if (0 == s_query->projection_count)
406 property_id = s_query->properties[i].property_id;
408 property_id = s_query->projection[i];
410 switch (property_id) {
411 case CTSVC_PROPERTY_NAME_ID:
412 name->id = ctsvc_stmt_get_int(stmt, i);
414 case CTSVC_PROPERTY_NAME_CONTACT_ID:
415 name->contact_id = ctsvc_stmt_get_int(stmt, i);
417 case CTSVC_PROPERTY_NAME_FIRST:
418 temp = ctsvc_stmt_get_text(stmt, i);
420 name->first = SAFE_STRDUP(temp);
422 case CTSVC_PROPERTY_NAME_LAST:
423 temp = ctsvc_stmt_get_text(stmt, i);
425 name->last = SAFE_STRDUP(temp);
427 case CTSVC_PROPERTY_NAME_ADDITION:
428 temp = ctsvc_stmt_get_text(stmt, i);
429 free(name->addition);
430 name->addition = SAFE_STRDUP(temp);
432 case CTSVC_PROPERTY_NAME_SUFFIX:
433 temp = ctsvc_stmt_get_text(stmt, i);
435 name->suffix = SAFE_STRDUP(temp);
437 case CTSVC_PROPERTY_NAME_PREFIX:
438 temp = ctsvc_stmt_get_text(stmt, i);
440 name->prefix = SAFE_STRDUP(temp);
442 case CTSVC_PROPERTY_NAME_PHONETIC_FIRST:
443 temp = ctsvc_stmt_get_text(stmt, i);
444 free(name->phonetic_first);
445 name->phonetic_first = SAFE_STRDUP(temp);
447 case CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE:
448 temp = ctsvc_stmt_get_text(stmt, i);
449 free(name->phonetic_middle);
450 name->phonetic_middle = SAFE_STRDUP(temp);
452 case CTSVC_PROPERTY_NAME_PHONETIC_LAST:
453 temp = ctsvc_stmt_get_text(stmt, i);
454 free(name->phonetic_last);
455 name->phonetic_last = SAFE_STRDUP(temp);
461 ctsvc_list_prepend(list, record);
463 ctsvc_stmt_finalize(stmt);
464 ctsvc_list_reverse(list);
467 return CONTACTS_ERROR_NONE;
470 ctsvc_db_plugin_info_s ctsvc_db_plugin_name = {
471 .is_query_only = false,
472 .insert_record = __ctsvc_db_name_insert_record,
473 .get_record = __ctsvc_db_name_get_record,
474 .update_record = __ctsvc_db_name_update_record,
475 .delete_record = __ctsvc_db_name_delete_record,
476 .get_all_records = __ctsvc_db_name_get_all_records,
477 .get_records_with_query = __ctsvc_db_name_get_records_with_query,
478 .insert_records = NULL,
479 .update_records = NULL,
480 .delete_records = NULL,
482 .get_count_with_query = NULL,
483 .replace_record = NULL,
484 .replace_records = NULL,