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_plugin_contact_helper.h"
26 #include "ctsvc_db_plugin_address_helper.h"
27 #include "ctsvc_record.h"
28 #include "ctsvc_db_query.h"
29 #include "ctsvc_list.h"
30 #include "ctsvc_notification.h"
31 #include "ctsvc_db_access_control.h"
34 static int __ctsvc_db_address_insert_record(contacts_record_h record, int *id)
38 char query[CTS_SQL_MAX_LEN] = {0};
39 ctsvc_address_s *address = (ctsvc_address_s*)record;
41 RETVM_IF(NULL == address->pobox && NULL == address->postalcode && NULL == address->region
42 && NULL == address->locality && NULL == address->street && NULL == address->extended
43 && NULL == address->country,
44 CONTACTS_ERROR_INVALID_PARAMETER, "address is NULL");
46 ret = ctsvc_begin_trans();
47 if (CONTACTS_ERROR_NONE != ret) {
49 ERR("ctsvc_begin_trans() Fail(%d)", ret);
54 snprintf(query, sizeof(query),
55 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id);
56 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
57 if (CONTACTS_ERROR_NONE != ret) {
58 ctsvc_end_trans(false);
59 if (CONTACTS_ERROR_NO_DATA == ret) {
61 ERR("No data : contact_id (%d) is not exist", address->contact_id);
62 return CONTACTS_ERROR_INVALID_PARAMETER;
66 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
72 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
74 ERR("No permission in this addresbook_id(%d)", addressbook_id);
75 ctsvc_end_trans(false);
76 return CONTACTS_ERROR_PERMISSION_DENIED;
80 ret = ctsvc_db_address_insert(record, address->contact_id, false, id);
81 if (CONTACTS_ERROR_NONE != ret) {
83 ERR("ctsvc_begin_trans() Fail(%d)", ret);
84 ctsvc_end_trans(false);
89 ret = ctsvc_db_contact_update_changed_time(address->contact_id);
90 if (CONTACTS_ERROR_NONE != ret) {
92 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
93 ctsvc_end_trans(false);
97 ctsvc_set_person_noti();
99 ret = ctsvc_end_trans(true);
100 if (ret < CONTACTS_ERROR_NONE)
103 return CONTACTS_ERROR_NONE;
106 static int __ctsvc_db_address_update_record(contacts_record_h record)
110 char query[CTS_SQL_MAX_LEN] = {0};
111 ctsvc_address_s *address = (ctsvc_address_s*)record;
113 RETVM_IF(NULL == address->pobox && NULL == address->postalcode && NULL == address->region &&
114 NULL == address->locality && NULL == address->street && NULL == address->extended &&
115 NULL == address->country, CONTACTS_ERROR_INVALID_PARAMETER, "address is empty");
117 ret = ctsvc_begin_trans();
118 if (CONTACTS_ERROR_NONE != ret) {
119 /* LCOV_EXCL_START */
120 ERR("ctsvc_begin_trans() Fail(%d)", ret);
125 snprintf(query, sizeof(query),
126 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id);
127 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
128 if (CONTACTS_ERROR_NONE != ret) {
129 /* LCOV_EXCL_START */
130 ERR("No data : contact_id (%d) is not exist", address->contact_id);
131 ctsvc_end_trans(false);
136 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
137 /* LCOV_EXCL_START */
138 ERR("No permission in this addresbook_id(%d)", addressbook_id);
139 ctsvc_end_trans(false);
140 return CONTACTS_ERROR_PERMISSION_DENIED;
144 ret = ctsvc_db_address_update(record, false);
145 if (CONTACTS_ERROR_NONE != ret) {
146 /* LCOV_EXCL_START */
147 ERR("update record Fail(%d)", ret);
148 ctsvc_end_trans(false);
153 ret = ctsvc_db_contact_update_changed_time(address->contact_id);
154 if (CONTACTS_ERROR_NONE != ret) {
155 /* LCOV_EXCL_START */
156 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
157 ctsvc_end_trans(false);
161 ctsvc_set_person_noti();
163 ret = ctsvc_end_trans(true);
164 if (ret < CONTACTS_ERROR_NONE)
167 return CONTACTS_ERROR_NONE;
170 static int __ctsvc_db_address_delete_record(int id)
174 cts_stmt stmt = NULL;
176 char query[CTS_SQL_MIN_LEN] = {0};
178 ret = ctsvc_begin_trans();
179 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
181 snprintf(query, sizeof(query),
182 "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
183 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
184 ret = ctsvc_query_prepare(query, &stmt);
186 /* LCOV_EXCL_START */
187 ERR("DB error :ctsvc_query_prepare Fail(%d)", ret);
188 ctsvc_end_trans(false);
192 ret = ctsvc_stmt_step(stmt);
194 /* LCOV_EXCL_START */
195 ERR("The id(%d) is Invalid(%d)", id, ret);
196 ctsvc_stmt_finalize(stmt);
197 ctsvc_end_trans(false);
198 if (CONTACTS_ERROR_NONE == ret)
199 return CONTACTS_ERROR_NO_DATA;
205 contact_id = ctsvc_stmt_get_int(stmt, 0);
206 addressbook_id = ctsvc_stmt_get_int(stmt, 1);
207 ctsvc_stmt_finalize(stmt);
209 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
210 /* LCOV_EXCL_START */
211 ERR("No permission in this addresbook_id(%d)", addressbook_id);
212 ctsvc_end_trans(false);
213 return CONTACTS_ERROR_PERMISSION_DENIED;
217 ret = ctsvc_db_address_delete(id, false);
218 if (CONTACTS_ERROR_NONE != ret) {
219 /* LCOV_EXCL_START */
220 ERR("ctsvc_db_address_delete() Fail(%d)", ret);
221 ctsvc_end_trans(false);
226 ret = ctsvc_db_contact_update_changed_time(contact_id);
227 if (CONTACTS_ERROR_NONE != ret) {
228 /* LCOV_EXCL_START */
229 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
230 ctsvc_end_trans(false);
234 ctsvc_set_person_noti();
236 ret = ctsvc_end_trans(true);
238 if (ret < CONTACTS_ERROR_NONE)
241 return CONTACTS_ERROR_NONE;
244 static int __ctsvc_db_address_get_record(int id, contacts_record_h *out_record)
246 char query[CTS_SQL_MAX_LEN] = {0};
248 cts_stmt stmt = NULL;
249 ctsvc_address_s *address;
251 snprintf(query, sizeof(query),
252 "SELECT id, data.contact_id, is_default, "
253 "data1, data2, data3, data4, data5, data6, data7, data8, data9 "
254 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
255 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
256 "WHERE datatype=%d AND id = %d ",
257 CONTACTS_DATA_TYPE_POSTAL, id);
259 ret = ctsvc_query_prepare(query, &stmt);
260 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
262 ret = ctsvc_stmt_step(stmt);
263 if (1 /*CTS_TRUE*/ != ret) {
264 /* LCOV_EXCL_START */
265 ERR("ctsvc_stmt_step() Fail(%d)", ret);
266 ctsvc_stmt_finalize(stmt);
267 if (CONTACTS_ERROR_NONE == ret)
268 return CONTACTS_ERROR_NO_DATA;
274 ctsvc_db_address_get_value_from_stmt(stmt, (contacts_record_h*)&address, 0);
275 ctsvc_stmt_finalize(stmt);
277 *out_record = (contacts_record_h)address;
279 return CONTACTS_ERROR_NONE;
282 static int __ctsvc_db_address_get_all_records(int offset, int limit, contacts_list_h *out_list)
286 contacts_list_h list;
287 ctsvc_address_s *address;
288 cts_stmt stmt = NULL;
289 char query[CTS_SQL_MAX_LEN] = {0};
291 len = snprintf(query, sizeof(query),
292 "SELECT data.contact_id, is_default, "
293 "data1, data2, data3, data4, data5, data6, data7, data8, data9 "
294 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
295 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
296 "WHERE datatype=%d AND is_my_profile=0 ",
297 CONTACTS_DATA_TYPE_POSTAL);
300 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
302 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
305 ret = ctsvc_query_prepare(query, &stmt);
306 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
308 contacts_list_create(&list);
309 while ((ret = ctsvc_stmt_step(stmt))) {
311 /* LCOV_EXCL_START */
312 ERR("ctsvc_stmt_step() Fail(%d)", ret);
313 ctsvc_stmt_finalize(stmt);
314 contacts_list_destroy(list, true);
318 ctsvc_db_address_get_value_from_stmt(stmt, (contacts_record_h*)&address, 0);
319 ctsvc_list_prepend(list, (contacts_record_h)address);
321 ctsvc_stmt_finalize(stmt);
322 ctsvc_list_reverse(list);
325 return CONTACTS_ERROR_NONE;
328 static int __ctsvc_db_address_get_records_with_query(contacts_query_h query, int offset,
329 int limit, contacts_list_h *out_list)
334 ctsvc_query_s *s_query;
336 contacts_list_h list;
337 ctsvc_address_s *address;
339 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
340 s_query = (ctsvc_query_s*)query;
342 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
343 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
345 contacts_list_create(&list);
346 while ((ret = ctsvc_stmt_step(stmt))) {
347 contacts_record_h record;
349 /* LCOV_EXCL_START */
350 ERR("ctsvc_stmt_step() Fail(%d)", ret);
351 ctsvc_stmt_finalize(stmt);
352 contacts_list_destroy(list, true);
357 contacts_record_create(_contacts_address._uri, &record);
358 address = (ctsvc_address_s*)record;
359 if (0 == s_query->projection_count) {
360 field_count = s_query->property_count;
362 field_count = s_query->projection_count;
363 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
364 s_query->projection_count, s_query->property_count);
366 if (CONTACTS_ERROR_NONE != ret)
367 ASSERT_NOT_REACHED("To set projection is Fail.\n");
370 for (i = 0; i < field_count; i++) {
373 if (0 == s_query->projection_count)
374 property_id = s_query->properties[i].property_id;
376 property_id = s_query->projection[i];
378 switch (property_id) {
379 case CTSVC_PROPERTY_ADDRESS_ID:
380 address->id = ctsvc_stmt_get_int(stmt, i);
382 case CTSVC_PROPERTY_ADDRESS_CONTACT_ID:
383 address->contact_id = ctsvc_stmt_get_int(stmt, i);
385 case CTSVC_PROPERTY_ADDRESS_TYPE:
386 address->type = ctsvc_stmt_get_int(stmt, i);
388 case CTSVC_PROPERTY_ADDRESS_IS_DEFAULT:
389 address->is_default = ctsvc_stmt_get_int(stmt, i);
391 case CTSVC_PROPERTY_ADDRESS_LABEL:
392 temp = ctsvc_stmt_get_text(stmt, i);
393 free(address->label);
394 address->label = SAFE_STRDUP(temp);
396 case CTSVC_PROPERTY_ADDRESS_POSTBOX:
397 temp = ctsvc_stmt_get_text(stmt, i);
398 free(address->pobox);
399 address->pobox = SAFE_STRDUP(temp);
401 case CTSVC_PROPERTY_ADDRESS_POSTAL_CODE:
402 temp = ctsvc_stmt_get_text(stmt, i);
403 free(address->postalcode);
404 address->postalcode = SAFE_STRDUP(temp);
406 case CTSVC_PROPERTY_ADDRESS_REGION:
407 temp = ctsvc_stmt_get_text(stmt, i);
408 free(address->region);
409 address->region = SAFE_STRDUP(temp);
411 case CTSVC_PROPERTY_ADDRESS_LOCALITY:
412 temp = ctsvc_stmt_get_text(stmt, i);
413 free(address->locality);
414 address->locality = SAFE_STRDUP(temp);
416 case CTSVC_PROPERTY_ADDRESS_STREET:
417 temp = ctsvc_stmt_get_text(stmt, i);
418 free(address->street);
419 address->street = SAFE_STRDUP(temp);
421 case CTSVC_PROPERTY_ADDRESS_COUNTRY:
422 temp = ctsvc_stmt_get_text(stmt, i);
423 free(address->country);
424 address->country = SAFE_STRDUP(temp);
426 case CTSVC_PROPERTY_ADDRESS_EXTENDED:
427 temp = ctsvc_stmt_get_text(stmt, i);
428 free(address->extended);
429 address->extended = SAFE_STRDUP(temp);
435 ctsvc_list_prepend(list, record);
437 ctsvc_stmt_finalize(stmt);
438 ctsvc_list_reverse(list);
441 return CONTACTS_ERROR_NONE;
444 ctsvc_db_plugin_info_s ctsvc_db_plugin_address = {
445 .is_query_only = false,
446 .insert_record = __ctsvc_db_address_insert_record,
447 .get_record = __ctsvc_db_address_get_record,
448 .update_record = __ctsvc_db_address_update_record,
449 .delete_record = __ctsvc_db_address_delete_record,
450 .get_all_records = __ctsvc_db_address_get_all_records,
451 .get_records_with_query = __ctsvc_db_address_get_records_with_query,
452 .insert_records = NULL,
453 .update_records = NULL,
454 .delete_records = NULL,
456 .get_count_with_query = NULL,
457 .replace_record = NULL,
458 .replace_records = NULL,