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.
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_profile_helper.h"
29 #include "ctsvc_record.h"
30 #include "ctsvc_db_query.h"
31 #include "ctsvc_list.h"
32 #include "ctsvc_notification.h"
35 static int __ctsvc_db_profile_insert_record(contacts_record_h record, int *id)
39 char query[CTS_SQL_MAX_LEN] = {0};
40 ctsvc_profile_s *profile = (ctsvc_profile_s*)record;
42 RETV_IF(NULL == profile->text, CONTACTS_ERROR_INVALID_PARAMETER);
44 ret = ctsvc_begin_trans();
45 if (CONTACTS_ERROR_NONE != ret) {
47 ERR("ctsvc_begin_trans() Fail(%d)", ret);
52 snprintf(query, sizeof(query),
53 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id);
54 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
55 if (CONTACTS_ERROR_NONE != ret) {
56 ctsvc_end_trans(false);
57 if (CONTACTS_ERROR_NO_DATA == ret) {
59 ERR("No data : contact_id (%d) is not exist", profile->contact_id);
60 return CONTACTS_ERROR_INVALID_PARAMETER;
64 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
70 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
72 ERR("No permission in this addresbook_id(%d)", addressbook_id);
73 ctsvc_end_trans(false);
74 return CONTACTS_ERROR_PERMISSION_DENIED;
78 ret = ctsvc_db_profile_insert(record, profile->contact_id, false, id);
79 if (CONTACTS_ERROR_NONE != ret) {
81 ERR("ctsvc_begin_trans() Fail(%d)", ret);
82 ctsvc_end_trans(false);
87 ret = ctsvc_db_contact_update_changed_time(profile->contact_id);
88 if (CONTACTS_ERROR_NONE != ret) {
90 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
91 ctsvc_end_trans(false);
95 ctsvc_set_person_noti();
97 ret = ctsvc_end_trans(true);
98 if (ret < CONTACTS_ERROR_NONE) {
100 ERR("ctsvc_end_trans() Fail(%d)", ret);
104 return CONTACTS_ERROR_NONE;
108 static int __ctsvc_db_profile_get_record(int id, contacts_record_h *out_record)
111 cts_stmt stmt = NULL;
112 char query[CTS_SQL_MAX_LEN] = {0};
114 RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
117 snprintf(query, sizeof(query),
118 "SELECT id, data.contact_id, is_default, data1, data2, "
119 "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
120 "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
121 "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
122 "WHERE id = %d AND datatype = %d ",
123 id, CONTACTS_DATA_TYPE_PROFILE);
125 ret = ctsvc_query_prepare(query, &stmt);
126 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
128 ret = ctsvc_stmt_step(stmt);
129 if (1 /*CTS_TRUE*/ != ret) {
130 /* LCOV_EXCL_START */
131 ERR("ctsvc_stmt_step() Fail(%d)", ret);
132 ctsvc_stmt_finalize(stmt);
133 if (CONTACTS_ERROR_NONE == ret)
134 return CONTACTS_ERROR_NO_DATA;
140 ctsvc_db_profile_get_value_from_stmt(stmt, out_record, 0);
142 ctsvc_stmt_finalize(stmt);
144 return CONTACTS_ERROR_NONE;
147 static int __ctsvc_db_profile_update_record(contacts_record_h record)
151 char query[CTS_SQL_MAX_LEN] = {0};
152 ctsvc_profile_s *profile = (ctsvc_profile_s*)record;
153 RETVM_IF(NULL == profile->text, CONTACTS_ERROR_INVALID_PARAMETER, "profile text is empty");
155 ret = ctsvc_begin_trans();
156 if (CONTACTS_ERROR_NONE != ret) {
157 /* LCOV_EXCL_START */
158 ERR("ctsvc_begin_trans() Fail(%d)", ret);
163 snprintf(query, sizeof(query),
164 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id);
165 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
166 if (CONTACTS_ERROR_NONE != ret) {
167 /* LCOV_EXCL_START */
168 ERR("No data : contact_id (%d) is not exist", profile->contact_id);
169 ctsvc_end_trans(false);
174 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
175 /* LCOV_EXCL_START */
176 ERR("No permission in this addresbook_id(%d)", addressbook_id);
177 ctsvc_end_trans(false);
178 return CONTACTS_ERROR_PERMISSION_DENIED;
182 ret = ctsvc_db_profile_update(record, false);
183 if (CONTACTS_ERROR_NONE != ret) {
184 /* LCOV_EXCL_START */
185 ERR("Update record Fail(%d)", ret);
186 ctsvc_end_trans(false);
191 ret = ctsvc_db_contact_update_changed_time(profile->contact_id);
192 if (CONTACTS_ERROR_NONE != ret) {
193 /* LCOV_EXCL_START */
194 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
195 ctsvc_end_trans(false);
199 ctsvc_set_person_noti();
201 ret = ctsvc_end_trans(true);
202 if (ret < CONTACTS_ERROR_NONE) {
203 /* LCOV_EXCL_START */
204 ERR("ctsvc_end_trans() Fail(%d)", ret);
208 return CONTACTS_ERROR_NONE;
212 static int __ctsvc_db_profile_delete_record(int id)
216 char query[CTS_SQL_MAX_LEN] = {0};
217 cts_stmt stmt = NULL;
220 ret = ctsvc_begin_trans();
221 if (CONTACTS_ERROR_NONE != ret) {
222 /* LCOV_EXCL_START */
223 ERR("ctsvc_begin_trans() Fail(%d)", ret);
228 snprintf(query, sizeof(query),
229 "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
230 "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
231 ret = ctsvc_query_prepare(query, &stmt);
233 /* LCOV_EXCL_START */
234 ERR("ctsvc_query_prepare Fail(%d", ret);
235 ctsvc_end_trans(false);
239 ret = ctsvc_stmt_step(stmt);
241 /* LCOV_EXCL_START */
242 ERR("The id(%d) is Invalid(%d)", id, ret);
243 ctsvc_stmt_finalize(stmt);
244 ctsvc_end_trans(false);
245 if (CONTACTS_ERROR_NONE == ret)
246 return CONTACTS_ERROR_NO_DATA;
252 contact_id = ctsvc_stmt_get_int(stmt, 0);
253 addressbook_id = ctsvc_stmt_get_int(stmt, 1);
254 ctsvc_stmt_finalize(stmt);
256 if (false == ctsvc_have_ab_write_permission(addressbook_id, false)) {
257 /* LCOV_EXCL_START */
258 ERR("No permission in this addresbook_id(%d)", addressbook_id);
259 ctsvc_end_trans(false);
260 return CONTACTS_ERROR_PERMISSION_DENIED;
264 ret = ctsvc_db_profile_delete(id, false);
265 if (CONTACTS_ERROR_NONE != ret) {
266 /* LCOV_EXCL_START */
267 ERR("ctsvc_begin_trans() Fail(%d)", ret);
268 ctsvc_end_trans(false);
273 ret = ctsvc_db_contact_update_changed_time(contact_id);
274 if (CONTACTS_ERROR_NONE != ret) {
275 /* LCOV_EXCL_START */
276 ERR("ctsvc_db_contact_update_changed_time() Fail(%d)", ret);
277 ctsvc_end_trans(false);
281 ctsvc_set_person_noti();
283 ret = ctsvc_end_trans(true);
284 if (ret < CONTACTS_ERROR_NONE) {
285 /* LCOV_EXCL_START */
286 ERR("ctsvc_end_trans() Fail(%d)", ret);
290 return CONTACTS_ERROR_NONE;
294 static int __ctsvc_db_profile_get_all_records(int offset, int limit, contacts_list_h *out_list)
298 contacts_list_h list;
299 ctsvc_profile_s *profile;
300 cts_stmt stmt = NULL;
301 char query[CTS_SQL_MAX_LEN] = {0};
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 "
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 CONTACTS_DATA_TYPE_PROFILE);
312 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
314 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
317 ret = ctsvc_query_prepare(query, &stmt);
318 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
320 contacts_list_create(&list);
321 while ((ret = ctsvc_stmt_step(stmt))) {
322 if (1 /*CTS_TRUE */ != ret) {
323 /* LCOV_EXCL_START */
324 ERR("DB : ctsvc_stmt_step fail(%d)", ret);
325 ctsvc_stmt_finalize(stmt);
326 contacts_list_destroy(list, true);
330 ctsvc_db_profile_get_value_from_stmt(stmt, (contacts_record_h*)&profile, 0);
331 ctsvc_list_prepend(list, (contacts_record_h)profile);
333 ctsvc_stmt_finalize(stmt);
334 ctsvc_list_reverse(list);
337 return CONTACTS_ERROR_NONE;
340 static int __ctsvc_db_profile_get_records_with_query(contacts_query_h query, int offset,
341 int limit, contacts_list_h *out_list)
346 ctsvc_query_s *s_query;
348 contacts_list_h list;
349 ctsvc_profile_s *profile;
351 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
352 s_query = (ctsvc_query_s*)query;
354 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
355 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
357 contacts_list_create(&list);
358 while ((ret = ctsvc_stmt_step(stmt))) {
359 contacts_record_h record;
360 if (1 /*CTS_TRUE */ != ret) {
361 /* LCOV_EXCL_START */
362 ERR("ctsvc_stmt_step() Fail(%d)", ret);
363 ctsvc_stmt_finalize(stmt);
364 contacts_list_destroy(list, true);
369 contacts_record_create(_contacts_profile._uri, &record);
370 profile = (ctsvc_profile_s*)record;
371 if (0 == s_query->projection_count) {
372 field_count = s_query->property_count;
374 field_count = s_query->projection_count;
375 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
376 s_query->projection_count, s_query->property_count);
378 if (CONTACTS_ERROR_NONE != ret)
379 ASSERT_NOT_REACHED("To set projection is Fail.\n");
382 for (i = 0; i < field_count; i++) {
385 if (0 == s_query->projection_count)
386 property_id = s_query->properties[i].property_id;
388 property_id = s_query->projection[i];
390 switch (property_id) {
391 case CTSVC_PROPERTY_PROFILE_ID:
392 profile->id = ctsvc_stmt_get_int(stmt, i);
394 case CTSVC_PROPERTY_PROFILE_CONTACT_ID:
395 profile->contact_id = ctsvc_stmt_get_int(stmt, i);
397 case CTSVC_PROPERTY_PROFILE_UID:
398 temp = ctsvc_stmt_get_text(stmt, i);
400 profile->uid = SAFE_STRDUP(temp);
402 case CTSVC_PROPERTY_PROFILE_TEXT:
403 temp = ctsvc_stmt_get_text(stmt, i);
405 profile->text = SAFE_STRDUP(temp);
407 case CTSVC_PROPERTY_PROFILE_ORDER:
408 profile->order = ctsvc_stmt_get_int(stmt, i);
410 case CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION:
411 temp = ctsvc_stmt_get_text(stmt, i);
412 free(profile->service_operation);
413 profile->service_operation = SAFE_STRDUP(temp);
415 case CTSVC_PROPERTY_PROFILE_MIME:
416 temp = ctsvc_stmt_get_text(stmt, i);
418 profile->mime = SAFE_STRDUP(temp);
420 case CTSVC_PROPERTY_PROFILE_APP_ID:
421 temp = ctsvc_stmt_get_text(stmt, i);
422 free(profile->app_id);
423 profile->app_id = SAFE_STRDUP(temp);
425 case CTSVC_PROPERTY_PROFILE_URI:
426 temp = ctsvc_stmt_get_text(stmt, i);
428 profile->uri = SAFE_STRDUP(temp);
430 case CTSVC_PROPERTY_PROFILE_CATEGORY:
431 temp = ctsvc_stmt_get_text(stmt, i);
432 free(profile->category);
433 profile->category = SAFE_STRDUP(temp);
435 case CTSVC_PROPERTY_PROFILE_EXTRA_DATA:
436 temp = ctsvc_stmt_get_text(stmt, i);
437 free(profile->extra_data);
438 profile->extra_data = SAFE_STRDUP(temp);
444 ctsvc_list_prepend(list, record);
446 ctsvc_stmt_finalize(stmt);
447 ctsvc_list_reverse(list);
450 return CONTACTS_ERROR_NONE;
453 ctsvc_db_plugin_info_s ctsvc_db_plugin_profile = {
454 .is_query_only = false,
455 .insert_record = __ctsvc_db_profile_insert_record,
456 .get_record = __ctsvc_db_profile_get_record,
457 .update_record = __ctsvc_db_profile_update_record,
458 .delete_record = __ctsvc_db_profile_delete_record,
459 .get_all_records = __ctsvc_db_profile_get_all_records,
460 .get_records_with_query = __ctsvc_db_profile_get_records_with_query,
461 .insert_records = NULL,
462 .update_records = NULL,
463 .delete_records = NULL,
465 .get_count_with_query = NULL,
466 .replace_record = NULL,
467 .replace_records = NULL,