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_list.h"
24 #include "ctsvc_db_plugin_activity_photo_helper.h"
25 #include "ctsvc_db_plugin_contact_helper.h"
26 #include "ctsvc_db_init.h"
27 #include "ctsvc_db_utils.h"
28 #include "ctsvc_record.h"
29 #include "ctsvc_db_query.h"
30 #include "ctsvc_notification.h"
31 #include "ctsvc_db_access_control.h"
34 static int __ctsvc_db_activity_insert_record(contacts_record_h record, int *id)
41 char query[CTS_SQL_MAX_LEN] = {0};
42 ctsvc_activity_s *activity = (ctsvc_activity_s*)record;
44 RETV_IF(NULL == activity, CONTACTS_ERROR_INVALID_PARAMETER);
45 RETVM_IF(activity->id, CONTACTS_ERROR_INVALID_PARAMETER,
46 "The activity has ID(%d)", activity->id);
48 RETVM_IF(activity->contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
49 "The contact_id(%d) does not exist", activity->contact_id);
51 ret = ctsvc_begin_trans();
52 RETVM_IF(ret, ret, "contacts_svc_begin_trans() Fail(%d)", ret);
54 snprintf(query, sizeof(query),
55 "SELECT addressbook_id from %s WHERE contact_id = %d",
56 CTSVC_DB_VIEW_CONTACT, activity->contact_id);
58 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
59 if (CONTACTS_ERROR_NONE != ret) {
60 ctsvc_end_trans(false);
61 if (CONTACTS_ERROR_NO_DATA == ret) {
63 ERR("No data : contact id (%d)", activity->contact_id);
64 return CONTACTS_ERROR_INVALID_PARAMETER;
68 ERR("ctsvc_query_get_first_int_result() Fail(%d)", ret);
74 ret = ctsvc_is_owner(addressbook_id);
75 if (CONTACTS_ERROR_NONE != ret) {
76 if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
78 ERR("Does not have permission of address_book (%d)", addressbook_id);
80 ERR("ctsvc_is_owner() Fail(%d)", ret);
81 ctsvc_end_trans(false);
86 snprintf(query, sizeof(query), "INSERT INTO "CTS_TABLE_ACTIVITIES"("
87 "contact_id, source_name, status, timestamp, "
88 "service_operation, uri) "
89 "VALUES(%d, ?, ?, %d, ?, ?)",
90 activity->contact_id, activity->timestamp);
92 ret = ctsvc_query_prepare(query, &stmt);
95 ERR("ctsvc_query_prepare() Fail(%d)", ret);
96 ctsvc_end_trans(false);
101 if (activity->source_name)
102 ctsvc_stmt_bind_text(stmt, 1, activity->source_name);
103 if (activity->status)
104 ctsvc_stmt_bind_text(stmt, 2, activity->status);
105 if (activity->service_operation)
106 ctsvc_stmt_bind_text(stmt, 3, activity->service_operation);
108 ctsvc_stmt_bind_text(stmt, 4, activity->uri);
110 ret = ctsvc_stmt_step(stmt);
111 if (CONTACTS_ERROR_NONE != ret) {
112 /* LCOV_EXCL_START */
113 ERR("ctsvc_stmt_step() Fail(%d)", ret);
114 ctsvc_stmt_finalize(stmt);
115 ctsvc_end_trans(false);
120 activity_id = ctsvc_db_get_last_insert_id();
122 ctsvc_stmt_finalize(stmt);
124 if (activity->photos) {
125 ret = contacts_list_get_count((contacts_list_h)activity->photos, &count);
126 if (CONTACTS_ERROR_NONE == ret && 0 < count) {
127 ctsvc_activity_photo_s *photo = NULL;
128 contacts_record_h record = NULL;
130 contacts_list_first((contacts_list_h)activity->photos);
132 contacts_list_get_current_record_p((contacts_list_h)activity->photos, &record);
133 photo = (ctsvc_activity_photo_s*)record;
134 ret = ctsvc_db_activity_photo_insert((contacts_record_h)photo, activity_id, NULL);
135 if (CONTACTS_ERROR_DB == ret) {
136 /* LCOV_EXCL_START */
137 ERR("return (%d)", ret);
141 } while (CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)activity->photos));
145 ctsvc_set_activity_noti();
146 ctsvc_set_person_noti();
151 ret = ctsvc_end_trans(true);
152 if (ret < CONTACTS_ERROR_NONE)
155 return CONTACTS_ERROR_NONE;
158 static int __ctsvc_db_activity_value_set(cts_stmt stmt, contacts_record_h *record)
162 ctsvc_activity_s *activity;
164 contacts_record_create(_contacts_activity._uri, record);
165 activity = (ctsvc_activity_s*)*record;
167 activity->id = ctsvc_stmt_get_int(stmt, i++);
168 activity->contact_id = ctsvc_stmt_get_int(stmt, i++);
169 temp = ctsvc_stmt_get_text(stmt, i++);
170 activity->source_name = SAFE_STRDUP(temp);
171 temp = ctsvc_stmt_get_text(stmt, i++);
172 activity->status = SAFE_STRDUP(temp);
173 activity->timestamp = ctsvc_stmt_get_int(stmt, i++);
174 temp = ctsvc_stmt_get_text(stmt, i++);
175 activity->service_operation = SAFE_STRDUP(temp);
176 temp = ctsvc_stmt_get_text(stmt, i++);
177 activity->uri = SAFE_STRDUP(temp);
179 return CONTACTS_ERROR_NONE;
183 static int __ctsvc_db_activity_get_record(int id, contacts_record_h *out_record)
185 char query[CTS_SQL_MAX_LEN] = {0};
187 cts_stmt stmt = NULL;
188 contacts_record_h record;
190 snprintf(query, sizeof(query), "SELECT id, contact_id, source_name, status, "
191 "timestamp, service_operation, uri "
192 "FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d", id);
194 ret = ctsvc_query_prepare(query, &stmt);
195 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
197 ret = ctsvc_stmt_step(stmt);
198 if (1 /*CTS_TRUE*/ != ret) {
199 /* LCOV_EXCL_START */
200 ERR("ctsvc_stmt_step() Fail(%d)", ret);
201 ctsvc_stmt_finalize(stmt);
202 if (CONTACTS_ERROR_NONE == ret)
203 return CONTACTS_ERROR_NO_DATA;
209 __ctsvc_db_activity_value_set(stmt, &record);
210 ctsvc_stmt_finalize(stmt);
212 ctsvc_db_activity_photo_get_records(id, record);
214 *out_record = (contacts_record_h)record;
216 return CONTACTS_ERROR_NONE;
219 static int __ctsvc_db_activity_update_record(contacts_record_h record)
221 /* LCOV_EXCL_START */
222 ERR("Invalid operation : activity can not update, only insert/delete");
223 return CONTACTS_ERROR_INVALID_PARAMETER;
227 static int __ctsvc_db_activity_delete_record(int id)
231 char query[CTS_SQL_MAX_LEN] = {0};
233 ret = ctsvc_begin_trans();
234 RETVM_IF(ret, ret, "ctsvc_begin_trans() Fail(%d)", ret);
236 snprintf(query, sizeof(query),
237 "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
238 "WHERE contact_id = (SELECT contact_id FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d)", id);
239 ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
240 if (CONTACTS_ERROR_NONE != ret) {
241 /* LCOV_EXCL_START */
242 ERR("No data : id (%d)", id);
243 ctsvc_end_trans(false);
248 ret = ctsvc_is_owner(addressbook_id);
249 if (CONTACTS_ERROR_NONE != ret) {
250 if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
251 /* LCOV_EXCL_START */
252 ERR("Does not have permission of address_book (%d)", addressbook_id);
254 ERR("ctsvc_is_owner Fail(%d)", ret);
255 ctsvc_end_trans(false);
260 snprintf(query, sizeof(query),
261 "DELETE FROM "CTS_TABLE_ACTIVITIES" WHERE id = %d", id);
262 ret = ctsvc_query_exec(query);
263 if (CONTACTS_ERROR_NONE != ret) {
264 /* LCOV_EXCL_START */
265 ERR("ctsvc_query_exec() Fail(%d)", ret);
266 ctsvc_end_trans(false);
271 ctsvc_set_activity_noti();
272 ctsvc_set_person_noti();
274 ret = ctsvc_end_trans(true);
275 if (ret < CONTACTS_ERROR_NONE)
278 return CONTACTS_ERROR_NONE;
281 static int __ctsvc_db_activity_get_all_records(int offset, int limit,
282 contacts_list_h *out_list)
288 char query[CTS_SQL_MAX_LEN] = {0};
289 contacts_list_h list;
291 len = snprintf(query, sizeof(query),
292 "SELECT id FROM "CTSVC_DB_VIEW_ACTIVITY);
295 len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
297 len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
300 ret = ctsvc_query_prepare(query, &stmt);
301 RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare() Fail(%d)", ret);
303 contacts_list_create(&list);
304 while ((ret = ctsvc_stmt_step(stmt))) {
305 contacts_record_h record;
307 /* LCOV_EXCL_START */
308 ERR("ctsvc_stmt_step() Fail(%d)", ret);
309 ctsvc_stmt_finalize(stmt);
310 contacts_list_destroy(list, true);
314 activity_id = ctsvc_stmt_get_int(stmt, 0);
315 ret = ctsvc_db_get_record(_contacts_activity._uri, activity_id, &record);
316 if (CONTACTS_ERROR_NONE != ret) {
317 /* LCOV_EXCL_START */
318 ERR("contacts_db_get_record() Fail(%d)", ret);
319 ctsvc_stmt_finalize(stmt);
320 contacts_list_destroy(list, true);
324 ctsvc_list_prepend(list, record);
326 ctsvc_stmt_finalize(stmt);
327 ctsvc_list_reverse(list);
329 *out_list = (contacts_list_h)list;
330 return CONTACTS_ERROR_NONE;
333 static int __ctsvc_db_activity_get_records_with_query(contacts_query_h query, int offset, int limit, contacts_list_h *out_list)
339 ctsvc_query_s *s_query;
341 contacts_list_h list;
342 ctsvc_activity_s *activity;
343 bool had_activity_id = false;
345 RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
346 s_query = (ctsvc_query_s*)query;
348 if (s_query->projection) {
349 for (i = 0; i < s_query->projection_count; i++) {
350 if (s_query->projection[i] == CTSVC_PROPERTY_ACTIVITY_ID) {
351 had_activity_id = true;
356 s_query->projection_count = 0;
357 had_activity_id = true;
360 if (false == had_activity_id) {
361 s_query->projection = realloc(s_query->projection, s_query->projection_count+1);
362 if (NULL == s_query->projection) {
363 /* LCOV_EXCL_START */
364 ERR("realloc() Fail");
365 return CONTACTS_ERROR_OUT_OF_MEMORY;
368 s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_ACTIVITY_ID;
369 s_query->projection_count++;
372 ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
373 RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
375 contacts_list_create(&list);
376 while ((ret = ctsvc_stmt_step(stmt))) {
377 contacts_record_h record;
378 if (1 /*CTS_TRUE */ != ret) {
379 /* LCOV_EXCL_START */
380 ERR("ctsvc_stmt_step() Fail(%d)", ret);
381 ctsvc_stmt_finalize(stmt);
382 contacts_list_destroy(list, true);
387 contacts_record_create(_contacts_activity._uri, &record);
388 activity = (ctsvc_activity_s*)record;
389 if (0 == s_query->projection_count) {
390 field_count = s_query->property_count;
392 field_count = s_query->projection_count;
393 ret = ctsvc_record_set_projection_flags(record, s_query->projection,
394 s_query->projection_count, s_query->property_count);
396 if (CONTACTS_ERROR_NONE != ret)
397 ASSERT_NOT_REACHED("To set projection is Fail\n");
400 for (i = 0; i < field_count; i++) {
403 if (0 == s_query->projection_count)
404 property_id = s_query->properties[i].property_id;
406 property_id = s_query->projection[i];
409 switch (property_id) {
410 case CTSVC_PROPERTY_ACTIVITY_ID:
411 activity_id = ctsvc_stmt_get_int(stmt, i);
413 activity->id = activity_id;
415 case CTSVC_PROPERTY_ACTIVITY_CONTACT_ID:
416 activity->contact_id = ctsvc_stmt_get_int(stmt, i);
418 case CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME:
419 temp = ctsvc_stmt_get_text(stmt, i);
420 free(activity->source_name);
421 activity->source_name = SAFE_STRDUP(temp);
423 case CTSVC_PROPERTY_ACTIVITY_STATUS:
424 temp = ctsvc_stmt_get_text(stmt, i);
425 free(activity->status);
426 activity->status = SAFE_STRDUP(temp);
428 case CTSVC_PROPERTY_ACTIVITY_TIMESTAMP:
429 activity->timestamp = ctsvc_stmt_get_int(stmt, i);
431 case CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION:
432 temp = ctsvc_stmt_get_text(stmt, i);
433 free(activity->service_operation);
434 activity->service_operation = SAFE_STRDUP(temp);
436 case CTSVC_PROPERTY_ACTIVITY_URI:
437 temp = ctsvc_stmt_get_text(stmt, i);
439 activity->uri = SAFE_STRDUP(temp);
445 ctsvc_db_activity_photo_get_records(activity_id, record);
447 ctsvc_list_prepend(list, record);
449 ctsvc_stmt_finalize(stmt);
450 ctsvc_list_reverse(list);
453 return CONTACTS_ERROR_NONE;
456 ctsvc_db_plugin_info_s ctsvc_db_plugin_activity = {
457 .is_query_only = false,
458 .insert_record = __ctsvc_db_activity_insert_record,
459 .get_record = __ctsvc_db_activity_get_record,
460 .update_record = __ctsvc_db_activity_update_record,
461 .delete_record = __ctsvc_db_activity_delete_record,
462 .get_all_records = __ctsvc_db_activity_get_all_records,
463 .get_records_with_query = __ctsvc_db_activity_get_records_with_query,
464 .insert_records = NULL,
465 .update_records = NULL,
466 .delete_records = NULL,
468 .get_count_with_query = NULL,
469 .replace_record = NULL,
470 .replace_records = NULL,