Tizen 2.0 Release
[platform/framework/native/social.git] / src / FScl_AddressbookImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FScl_AddressbookImpl.cpp
19  * @brief               This is the implementation for _AddressbookImpl class.
20  *
21  * This file contains definitions of @e _AddressbookImpl class.
22  */
23 #include <contacts.h>
24 #include <FBaseColIListT.h>
25 #include <FBaseColArrayListT.h>
26 #include <FBaseResult.h>
27 #include <FBaseLongLong.h>
28 #include <FBaseInteger.h>
29 #include <FSclContact.h>
30 #include <FSclCategory.h>
31 #include <FSclContactChangeInfo.h>
32 #include <FSclCategoryChangeInfo.h>
33 #include <FSclAddressbook.h>
34 #include <FSclIAddressbookEventListener.h>
35 #include <FSclIRecordEventListener.h>
36 #include <FApp_AppInfo.h>
37 #include <FBaseSysLog.h>
38 #include <FBase_StringConverter.h>
39 #include "FScl_AddressbookImpl.h"
40 #include "FScl_AddressbookUtil.h"
41 #include "FScl_CategoryChangeInfoImpl.h"
42 #include "FScl_CategoryImpl.h"
43 #include "FScl_ContactChangeInfoImpl.h"
44 #include "FScl_ContactDbMonitor.h"
45 #include "FScl_ContactImpl.h"
46 #include "FScl_RecordImpl.h"
47 #include "FScl_ContactDbConnector.h"
48
49 using namespace Tizen::App;
50 using namespace Tizen::Base;
51 using namespace Tizen::Base::Collection;
52 using namespace Tizen::Graphics;
53
54 namespace Tizen { namespace Social
55 {
56
57 _AddressbookImpl::_AddressbookImpl(void)
58         : __pIRecordEventListener(null)
59         , __pIAddressbookEventListener(null)
60         , __dbVersionForContact(0)
61         , __dbVersionForGroup(0)
62         , __dbVersionForRelation(0)
63         , __addressbookId(INVALID_ADDRESSBOOK_ID)
64         , __accountId(-1)
65 {
66         // empty body.
67 }
68
69 _AddressbookImpl::~_AddressbookImpl(void)
70 {
71         if (__pIAddressbookEventListener != null || __pIRecordEventListener != null)
72         {
73                 _ContactDbMonitor* pDbMonitor = _ContactDbMonitor::GetInstance();
74                 if (pDbMonitor != null)
75                 {
76                         pDbMonitor->RemoveListener(*this);
77                 }
78         }
79 }
80
81 result
82 _AddressbookImpl::Construct(void)
83 {
84         static AccountId accountId = 0;
85         static String name;
86
87         if (name.IsEmpty())
88         {
89                 SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
90
91                 char* pName = null;
92                 contacts_record_h recordHandle = null;
93                 int ret = contacts_db_get_record(_contacts_address_book._uri, DEFAULT_ADDRESSBOOK_ID, &recordHandle);
94                 SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
95                 SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, null, E_SYSTEM, "[%s] A system error has been occurred. Addressbook Id(%d)", GetErrorMessage(E_SYSTEM), DEFAULT_ADDRESSBOOK_ID);
96
97                 contacts_record_get_str_p(recordHandle, _contacts_address_book.name, &pName);
98                 contacts_record_get_int(recordHandle, _contacts_address_book.account_id, &accountId);
99
100                 name = pName;
101
102                 contacts_record_destroy(recordHandle, true);
103         }
104
105         __addressbookId = DEFAULT_ADDRESSBOOK_ID;
106         __accountId = accountId;
107         __name = name;
108
109         return E_SUCCESS;
110 }
111
112 result
113 _AddressbookImpl::SetRecordEventListener(IRecordEventListener* pListener)
114 {
115         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
116
117         result r = E_SUCCESS;
118
119         if (pListener != null)
120         {
121                 if (__pIAddressbookEventListener == null && __pIRecordEventListener == null)
122                 {
123                         __dbVersionForContact = GetLatestVersion();
124                         SysTryReturn(NID_SCL, __dbVersionForContact != -1, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
125
126                         __dbVersionForGroup = __dbVersionForContact;
127                         __dbVersionForRelation = __dbVersionForContact;
128
129                         _ContactDbMonitor* pContactDbMonitor = _ContactDbMonitor::GetInstance();
130                         SysTryReturn(NID_SCL, pContactDbMonitor != null, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
131
132                         r = pContactDbMonitor->AddListener(*this);
133                         SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
134                 }
135
136                 __pIAddressbookEventListener = null;
137                 __pIRecordEventListener = const_cast<IRecordEventListener*>(pListener);
138         }
139         else
140         {
141                 if (__pIAddressbookEventListener != null || __pIRecordEventListener != null)
142                 {
143                         _ContactDbMonitor* pContactDbMonitor = _ContactDbMonitor::GetInstance();
144                         SysTryReturn(NID_SCL, pContactDbMonitor != null, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()))
145                         pContactDbMonitor->RemoveListener(*this);
146                 }
147
148                 __pIAddressbookEventListener = null;
149                 __pIRecordEventListener = null;
150         }
151
152         return E_SUCCESS;
153 }
154
155 result
156 _AddressbookImpl::SetAddressbookEventListener(IAddressbookEventListener* pListener)
157 {
158         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
159
160         result r = E_SUCCESS;
161
162         if (pListener != null)
163         {
164                 if (__pIAddressbookEventListener == null && __pIRecordEventListener == null)
165                 {
166                         __dbVersionForContact = GetLatestVersion();
167                         SysTryReturn(NID_SCL, __dbVersionForContact != -1, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
168
169                         __dbVersionForGroup = __dbVersionForContact;
170                         __dbVersionForRelation = __dbVersionForContact;
171
172                         _ContactDbMonitor* pContactDbMonitor = _ContactDbMonitor::GetInstance();
173                         SysTryReturn(NID_SCL, pContactDbMonitor != null, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
174
175                         r = pContactDbMonitor->AddListener(*this);
176                         SysTryReturn(NID_SCL, !IsFailed(r), r, r, "[%s] Propagating.", GetErrorMessage(r));
177                 }
178
179                 __pIRecordEventListener = null;
180                 __pIAddressbookEventListener = pListener;
181         }
182         else
183         {
184                 if (__pIAddressbookEventListener != null || __pIRecordEventListener != null)
185                 {
186                         _ContactDbMonitor* pContactDbMonitor = _ContactDbMonitor::GetInstance();
187                         SysTryReturn(NID_SCL, pContactDbMonitor != null, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
188
189                         pContactDbMonitor->RemoveListener(*this);
190                 }
191
192                 __pIAddressbookEventListener = null;
193                 __pIRecordEventListener = null;
194         }
195
196         return E_SUCCESS;
197 }
198
199 void
200 _AddressbookImpl::SetId(AddressbookId addressbookId)
201 {
202         __addressbookId = addressbookId;
203 }
204
205 void
206 _AddressbookImpl::SetAccountId(AccountId accountId)
207 {
208         __accountId = accountId;
209 }
210
211 void
212 _AddressbookImpl::SetName(const String& name)
213 {
214         __name = name;
215 }
216
217 AddressbookId
218 _AddressbookImpl::GetId(void) const
219 {
220         return __addressbookId;
221 }
222
223 AccountId
224 _AddressbookImpl::GetAccountId(void) const
225 {
226         return __accountId;
227 }
228
229 String
230 _AddressbookImpl::GetName(void) const
231 {
232         return __name;
233 }
234
235 result
236 _AddressbookImpl::AddContact(Contact& contact)
237 {
238         if (_ContactImpl::GetInstance(contact)->IsRemoved())
239         {
240                 result r = _ContactImpl::GetInstance(contact)->Invalidate();
241                 SysTryReturn(NID_SCL, r == E_SUCCESS, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
242         }
243
244         SysTryReturn(NID_SCL, contact.GetRecordId() == INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The ID of specified contact is not INVALID_RECORD_ID.", GetErrorMessage(E_INVALID_ARG));
245         SysTryReturn(NID_SCL, !_ContactImpl::GetInstance(contact)->IsEmpty(), E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified contact does not have any property.", GetErrorMessage(E_INVALID_ARG));
246         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
247
248         int recordId = 0;
249         contacts_record_h recordHandle = null;
250         
251         recordHandle = _ContactImpl::GetInstance(contact)->GetContactRecordHandle();
252
253         contacts_record_set_int(recordHandle, _contacts_contact.address_book_id, __addressbookId);
254
255         int ret = contacts_db_insert_record(recordHandle, &recordId);
256         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
257         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
258
259         ret = contacts_db_get_record(_contacts_contact._uri, recordId, &recordHandle);
260         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The contact is not found.");
261         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OBJ_NOT_FOUND, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
262         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
263
264         _ContactImpl::GetInstance(contact)->SetContactRecordHandle(recordHandle);
265         _RecordImpl::GetInstance(contact)->SetRecordId(recordId);
266
267         return E_SUCCESS;
268 }
269
270 result
271 _AddressbookImpl::AddCategory(Category& category)
272 {
273         SysTryReturn(NID_SCL, category.GetRecordId() == INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified categoryId is not INVALID_RECORD_ID.", GetErrorMessage(E_INVALID_ARG));
274         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
275
276         int recordId = 0;
277         contacts_record_h recordHandle = null;
278         std::unique_ptr<IListT<int> > pList(null);
279
280         recordHandle = _CategoryImpl::GetInstance(category)->GetRecordHandle();
281
282         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
283         {
284                 // It is not allowed to have a same name with other.
285                 int count = 0;
286                 char* pCharValue = null;
287                 contacts_record_get_str_p(recordHandle, _contacts_group.name, &pCharValue);
288
289                 __Filter<__ContactsGroup> filter;
290                 filter.Construct();
291                 filter.AddInt(_contacts_group.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
292                 filter.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
293                 filter.AddString(_contacts_group.name, CONTACTS_MATCH_EXACTLY, pCharValue);
294
295                 __Query<__ContactsGroup> query;
296                 query.Construct();
297                 query.SetFilter(filter);
298
299                 count = _AddressbookUtil::GetCountWithQuery(query);
300                 SysTryReturn(NID_SCL, count >= 0, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
301                 SysTryReturn(NID_SCL, count == 0, E_OBJ_ALREADY_EXIST, E_OBJ_ALREADY_EXIST, "[%s] The category name is already being used by other category.", GetErrorMessage(E_OBJ_ALREADY_EXIST));
302         }
303
304         recordHandle = _CategoryImpl::GetInstance(category)->GetRecordHandle();
305
306         contacts_record_set_int(recordHandle, _contacts_group.address_book_id, __addressbookId);
307
308         int ret = contacts_db_insert_record(recordHandle, &recordId);
309         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
310         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
311
312         ret = contacts_db_get_record(_contacts_group._uri, recordId, &recordHandle);
313         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
314         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
315         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%d] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
316
317         _CategoryImpl::GetInstance(category)->SetRecordHandle(recordHandle);
318         _RecordImpl::GetInstance(category)->SetRecordId(recordId);
319
320         pList.reset(_CategoryImpl::GetInstance(category)->GetAddedMembersN());
321         if (pList != null && pList->GetCount() > 0)
322         {
323                 std::unique_ptr<IEnumeratorT<int> > pEnum(pList->GetEnumeratorN());
324
325                 while (pEnum->MoveNext() == E_SUCCESS)
326                 {
327                         int tableId = -1;
328                         pEnum->GetCurrent(tableId);
329
330                         AddMemberToCategory(category.GetRecordId(), tableId);
331                 }
332
333                 _CategoryImpl::GetInstance(category)->ClearAddedMemberList();
334         }
335
336         return E_SUCCESS;
337 }
338
339 result
340 _AddressbookImpl::RemoveContact(RecordId contactId)
341 {
342         SysTryReturn(NID_SCL, contactId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. contactId = %d.", GetErrorMessage(E_INVALID_ARG), contactId);
343         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
344
345         int intValue = 0;
346         int ret = CONTACTS_ERROR_NONE;
347         contacts_record_h recordHandle = null;
348
349         ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &recordHandle);
350         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
351         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
352         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
353
354         contacts_record_get_int(recordHandle, _contacts_simple_contact.id, &intValue);
355
356         contacts_record_destroy(recordHandle, true);
357
358         SysTryReturn(NID_SCL, intValue == contactId, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
359
360         ret = contacts_db_delete_record(_contacts_contact._uri, contactId);
361         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
362         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
363         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
364
365         return E_SUCCESS;
366 }
367
368 result
369 _AddressbookImpl::RemoveContact(Contact& contact)
370 {
371         SysTryReturn(NID_SCL, contact.GetRecordId() != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The ID of specified contact is not INVALID_RECORD_ID", GetErrorMessage(E_INVALID_ARG));
372         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
373
374         result r = RemoveContact(contact.GetRecordId());
375         SysTryReturn(NID_SCL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
376
377         _ContactImpl::GetInstance(contact)->SetAsRemoved();
378         _RecordImpl::GetInstance(contact)->SetRecordId(INVALID_RECORD_ID);
379
380         return E_SUCCESS;
381 }
382
383 result
384 _AddressbookImpl::RemoveCategory(RecordId categoryId)
385 {
386         SysTryReturn(NID_SCL, categoryId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. categoryId = %d.", GetErrorMessage(E_INVALID_ARG), categoryId);
387         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
388
389         int intValue = 0;
390         int ret = CONTACTS_ERROR_NONE;
391         contacts_record_h recordHandle = null;
392
393         ret = contacts_db_get_record(_contacts_group._uri, categoryId, &recordHandle);
394         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The category is not found.");
395         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
396         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
397
398         __ContactsRecordHandle categoryHandle(recordHandle);
399
400         contacts_record_get_int(recordHandle, _contacts_group.id, &intValue);
401         SysTryReturn(NID_SCL, intValue == categoryId, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
402
403         bool isReadOnly = false;
404         contacts_record_get_bool(recordHandle, _contacts_group.is_read_only, &isReadOnly);
405         SysTryReturn(NID_SCL, !isReadOnly, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified category is a default category.", GetErrorMessage(E_INVALID_ARG));
406
407         ret = contacts_db_delete_record(_contacts_group._uri, categoryId);
408         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
409         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
410         //SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed remove a category.");
411
412         return E_SUCCESS;
413 }
414
415 result
416 _AddressbookImpl::UpdateContact(const Contact& contact)
417 {
418         RecordId contactId = contact.GetRecordId();
419         SysTryReturn(NID_SCL, contactId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used.", GetErrorMessage(E_INVALID_ARG));
420         SysTryReturn(NID_SCL, !_ContactImpl::GetInstance(contact)->IsEmpty(), E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified contact does not have any property.", GetErrorMessage(E_INVALID_ARG));
421         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
422
423         contacts_record_h recordHandle = null;
424
425         int intValue = 0;
426         int ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &recordHandle);
427         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
428         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
429         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
430
431         contacts_record_get_int(recordHandle, _contacts_simple_contact.id, &intValue);
432
433         contacts_record_destroy(recordHandle, true);
434         SysTryReturn(NID_SCL, intValue == contactId, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
435
436         recordHandle = _ContactImpl::GetInstance(contact)->GetContactRecordHandle();
437
438         ret = contacts_db_update_record(recordHandle);
439         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
440         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
441         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
442
443         ret = contacts_db_get_record(_contacts_contact._uri, contact.GetRecordId(), &recordHandle);
444         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
445         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
446         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
447
448         _ContactImpl::GetInstance(*const_cast<Contact*>(&contact))->SetContactRecordHandle(recordHandle);
449
450         return E_SUCCESS;
451 }
452
453 result
454 _AddressbookImpl::UpdateCategory(const Category& category)
455 {
456         RecordId categoryId = category.GetRecordId();
457         SysTryReturn(NID_SCL, categoryId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified category is invalid.", GetErrorMessage(E_INVALID_ARG));
458         SysTryReturn(NID_SCL, !category.GetName().IsEmpty(), E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The specified category does not have name.", GetErrorMessage(E_INVALID_ARG));
459         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
460
461         contacts_record_h recordHandle = null;
462         int intValue = 0;
463         int ret = CONTACTS_ERROR_NONE;
464
465         ret = contacts_db_get_record(_contacts_group._uri, category.GetRecordId(), &recordHandle);
466         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
467         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
468         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
469
470         contacts_record_get_int(recordHandle, _contacts_group.id, &intValue);
471
472         contacts_record_destroy(recordHandle, true);
473
474         SysTryReturn(NID_SCL, intValue == categoryId, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
475
476         recordHandle = _CategoryImpl::GetInstance(category)->GetRecordHandle();
477
478         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
479         {
480                 int count = 0;
481                 char* pCharValue = null;
482
483                 contacts_record_get_str_p(recordHandle, _contacts_group.name, &pCharValue);
484                 contacts_record_get_int(recordHandle, _contacts_group.id, &intValue);
485
486                 __Filter<__ContactsGroup> filter1;
487                 filter1.Construct();
488                 filter1.AddInt(_contacts_group.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
489                 filter1.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
490                 filter1.AddString(_contacts_group.name, CONTACTS_MATCH_EXACTLY, pCharValue);
491
492                 __Filter<__ContactsGroup> filter2;
493                 filter2.Construct();
494                 filter2.AddInt(_contacts_group.id, CONTACTS_MATCH_LESS_THAN, intValue);
495                 filter2.AddOperator(CONTACTS_FILTER_OPERATOR_OR);
496                 filter2.AddInt(_contacts_group.id, CONTACTS_MATCH_GREATER_THAN, intValue);
497
498                 filter1.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
499                 filter1.AddFilter(filter2);
500
501                 __Query<__ContactsGroup> query;
502                 query.Construct();
503                 query.SetFilter(filter1);
504
505                 count = _AddressbookUtil::GetCountWithQuery(query);
506                 SysTryReturn(NID_SCL, count >= 0, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
507                 SysTryReturn(NID_SCL, count == 0, E_OBJ_ALREADY_EXIST, E_OBJ_ALREADY_EXIST, "[%s] The category name is alread being used by other category.", GetErrorMessage(E_OBJ_ALREADY_EXIST));
508         }
509
510         ret = contacts_db_update_record(recordHandle);
511         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
512         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
513         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
514
515         ret = contacts_db_get_record(_contacts_group._uri, category.GetRecordId(), &recordHandle);
516         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
517         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
518         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
519
520         _CategoryImpl::GetInstance(*const_cast<Category*>(&category))->SetRecordHandle(recordHandle);
521
522         std::unique_ptr<IListT<int> > pList(_CategoryImpl::GetInstance(category)->GetAddedMembersN());
523         if (pList != null && pList->GetCount() > 0)
524         {
525                 int tableId = -1;
526                 std::unique_ptr<IEnumeratorT<int> > pEnum(pList->GetEnumeratorN());
527                 while (pEnum->MoveNext() == E_SUCCESS)
528                 {
529                         pEnum->GetCurrent(tableId);
530
531                         AddMemberToCategory(category.GetRecordId(), tableId);
532                 }
533
534                 const_cast<_CategoryImpl*>(_CategoryImpl::GetInstance(category))->ClearAddedMemberList();
535         }
536
537         pList.reset(_CategoryImpl::GetInstance(category)->GetRemovedMembersN());
538         if (pList != null && pList->GetCount() > 0)
539         {
540                 int tableId = -1;
541                 std::unique_ptr<IEnumeratorT<int> > pEnum(pList->GetEnumeratorN());
542                 while (pEnum->MoveNext() == E_SUCCESS)
543                 {
544                         pEnum->GetCurrent(tableId);
545
546                         RemoveMemberFromCategory(category.GetRecordId(), tableId);
547                 }
548
549                 const_cast<_CategoryImpl*>(_CategoryImpl::GetInstance(category))->ClearRemovedMemberList();
550         }
551
552         return E_SUCCESS;
553 }
554
555 result
556 _AddressbookImpl::AddMemberToCategory(RecordId categoryId, RecordId contactId)
557 {
558         SysTryReturn(NID_SCL, categoryId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. categoryId = %d.", GetErrorMessage(E_INVALID_ARG), categoryId);
559         SysTryReturn(NID_SCL, contactId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. contactId = %d.", GetErrorMessage(E_INVALID_ARG), contactId);
560         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
561
562         contacts_record_h recordHandle = null;
563         int addressbookId = 0;
564         int ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &recordHandle);
565         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The contact does not exist.", GetErrorMessage(E_INVALID_ARG));
566         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
567         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
568         contacts_record_get_int(recordHandle, _contacts_simple_contact.address_book_id, &addressbookId);
569         contacts_record_destroy(recordHandle, true);
570
571         SysTryReturn(NID_SCL, addressbookId == __addressbookId, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The contact does not exist in this addresbook.", GetErrorMessage(E_INVALID_ARG));
572
573         ret = contacts_group_add_contact(categoryId, contactId);
574         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_INVALID_PARAMETER, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used.", GetErrorMessage(E_INVALID_ARG));
575         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
576         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
577
578         return E_SUCCESS;
579 }
580
581 result
582 _AddressbookImpl::RemoveMemberFromCategory(RecordId categoryId, RecordId contactId)
583 {
584         SysTryReturn(NID_SCL, categoryId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. categoryId = %d.", GetErrorMessage(E_INVALID_ARG), categoryId);
585         SysTryReturn(NID_SCL, contactId != INVALID_RECORD_ID, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. contactId = %d.", GetErrorMessage(E_INVALID_ARG), contactId);
586         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
587
588         contacts_record_h recordHandle = null;
589         int addressbookId = 0;
590         int ret = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &recordHandle);
591         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The contact does not exist.", GetErrorMessage(E_INVALID_ARG));
592         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
593         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
594         contacts_record_get_int(recordHandle, _contacts_simple_contact.address_book_id, &addressbookId);
595         contacts_record_destroy(recordHandle, true);
596
597         SysTryReturn(NID_SCL, addressbookId == __addressbookId, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The contact does not exist in this addresbook.", GetErrorMessage(E_INVALID_ARG));
598
599         ret = contacts_db_get_record(_contacts_group._uri, categoryId, &recordHandle);
600         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The category does not exist.", GetErrorMessage(E_INVALID_ARG));
601         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
602         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
603
604         contacts_record_get_int(recordHandle, _contacts_group.address_book_id, &addressbookId);
605         contacts_record_destroy(recordHandle, true);
606
607         SysTryReturn(NID_SCL, addressbookId == __addressbookId, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used. The category does not exist in this addresbook.", GetErrorMessage(E_INVALID_ARG));
608
609
610         ret = contacts_group_remove_contact(categoryId, contactId);
611         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_INVALID_PARAMETER, E_INVALID_ARG, E_INVALID_ARG, "[%s] Invalid argument is used.", GetErrorMessage(E_INVALID_ARG));
612         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
613         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, E_SYSTEM, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
614
615         return E_SUCCESS;
616 }
617
618 IList*
619 _AddressbookImpl::GetAllCategoriesN(void) const
620 {
621         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
622
623         ClearLastResult();
624
625         __Filter<__ContactsGroup> filter;
626         filter.Construct();
627         filter.AddInt(_contacts_group.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
628         
629         __Query<__ContactsGroup> query;
630         query.Construct();
631         query.SetFilter(filter);
632         query.SetSort(_contacts_group.name, true);
633
634
635         IList* pCategories = _AddressbookUtil::SearchWithQueryN<__ContactsGroup, Category>(query);
636         SysTryReturn(NID_SCL, pCategories != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
637
638         return pCategories;
639 }
640
641 IList*
642 _AddressbookImpl::GetCategoriesByContactN(RecordId contactId) const
643 {
644         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
645
646         ClearLastResult();
647
648         __Filter<__ContactsGroupRelation> filter;
649         filter.Construct();
650         filter.AddInt(_contacts_group_relation.contact_id, CONTACTS_MATCH_EQUAL, contactId);
651
652         __Query<__ContactsGroupRelation> query;
653         query.Construct();
654         query.SetFilter(filter);
655         query.SetSort(_contacts_group_relation.name, true);
656
657         IList* pCategories = _AddressbookUtil::SearchWithQueryN<__ContactsGroupRelation, Category>(query);
658         SysTryReturn(NID_SCL, pCategories != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
659
660         return pCategories;
661 }
662
663 IList*
664 _AddressbookImpl::GetAllContactsN(void) const
665 {
666         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
667
668         ClearLastResult();
669
670         __Filter<__ContactsContact> filter;
671         filter.Construct();
672         filter.AddInt(_contacts_contact.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
673
674         __Query<__ContactsContact> query;
675         query.Construct();
676         query.SetFilter(filter);
677         query.SetSort(_contacts_contact.display_name, true);
678
679         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContact, Contact>(query);
680         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
681
682         return pContacts;
683 }
684
685 IList*
686 _AddressbookImpl::GetContactsByCategoryN(RecordId categoryId) const
687 {
688         SysTryReturn(NID_SCL, categoryId >= INVALID_RECORD_ID, null, E_INVALID_ARG, "[%s] Invalid argument is used. The category ID must be greater than or equal to INVALID_RECORD_ID.", GetErrorMessage(E_INVALID_ARG));
689         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
690
691         ClearLastResult();
692
693         __Filter<__ContactsContactGroupRel> filter;
694         filter.Construct();
695         if (categoryId != INVALID_RECORD_ID)
696         {
697                 filter.AddInt(_contacts_contact_grouprel.group_id, CONTACTS_MATCH_EQUAL, categoryId);
698         }
699         else
700         {
701                 filter.AddInt(_contacts_contact_grouprel.group_id, CONTACTS_MATCH_NONE, 0);
702         }
703
704         __Query<__ContactsContactGroupRel> query;
705         query.Construct();
706         query.SetFilter(filter);
707         query.SetSort(_contacts_contact_grouprel.display_name, true);
708
709         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContactGroupRel, Contact>(query);
710         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
711
712         return pContacts;
713 }
714
715 IList*
716 _AddressbookImpl::GetContactsN(int pageNo, int countPerPage) const
717 {
718         SysTryReturn(NID_SCL, pageNo > 0 && countPerPage > 0, null, E_OUT_OF_RANGE, "[%s] pageNo(%d) or countPerPage(%d) is less than 1.", GetErrorMessage(E_OUT_OF_RANGE), pageNo, countPerPage);
719         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
720
721         int offset = (pageNo - 1)*countPerPage;
722         int limit = countPerPage;
723
724         ClearLastResult();
725
726         __Filter<__ContactsContact> filter;
727         filter.Construct();
728         filter.AddInt(_contacts_contact.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
729
730         __Query<__ContactsContact> query;
731         query.Construct();
732         query.SetFilter(filter);
733         query.SetSort(_contacts_contact.display_name, true);
734
735         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContact, Contact>(query, offset, limit);
736         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
737
738         return pContacts;
739 }
740
741 IList*
742 _AddressbookImpl::GetContactsInN(const Category& category, int pageNo, int countPerPage) const
743 {
744         SysTryReturn(NID_SCL, category.GetRecordId() != INVALID_RECORD_ID, null, E_INVALID_ARG, "[%s] Invalid argument is used. The specified category is invalid.", GetErrorMessage(E_INVALID_ARG));
745         SysTryReturn(NID_SCL, pageNo > 0 && countPerPage > 0, null, E_OUT_OF_RANGE, "[%s] pageNo(%d) or countPerPage(%d) is less than 1.", GetErrorMessage(E_OUT_OF_RANGE), pageNo, countPerPage);
746         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
747
748         int offset = (pageNo - 1)*countPerPage;
749         int limit = countPerPage;
750
751         ClearLastResult();
752
753         __Filter<__ContactsContactGroupRel> filter;
754         filter.Construct();
755         filter.AddInt(_contacts_contact_grouprel.group_id, CONTACTS_MATCH_EQUAL, category.GetRecordId());
756
757         __Query<__ContactsContactGroupRel> query;
758         query.Construct();
759         query.SetFilter(filter);
760         query.SetSort(_contacts_contact_grouprel.display_name, true);
761
762         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContactGroupRel, Contact>(query, offset, limit);
763         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
764
765         return pContacts;
766 }
767
768 IList*
769 _AddressbookImpl::SearchContactsByEmailN(const String& email) const
770 {
771         SysTryReturn(NID_SCL, !email.IsEmpty(), null, E_INVALID_ARG, "[%s] Invalid argument is used. The specified email is an empty string.", GetErrorMessage(E_INVALID_ARG));
772         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
773
774         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
775         {
776                 SysTryReturn(NID_SCL, email.GetLength() <= MAX_EMAIL_LENGTH, null, E_INVALID_ARG, "[%s] Invalid argument is used. The length of email is greater than MAX_EMAIL_LENGTH.", GetErrorMessage(E_INVALID_ARG));
777         }
778
779         ClearLastResult();
780
781         std::unique_ptr<char[]> pCharArray(_StringConverter::CopyToCharArrayN(email));
782         SysTryReturn(NID_SCL, pCharArray != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
783
784         __Filter<__ContactsContactEmail> filter;
785         filter.Construct();
786         filter.AddInt(_contacts_contact_email.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
787         filter.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
788         filter.AddString(_contacts_contact_email.email, CONTACTS_MATCH_CONTAINS, pCharArray.get());
789
790         unsigned int projectionIds[1];
791         projectionIds[0] = _contacts_contact_email.contact_id;
792
793         __Query<__ContactsContactEmail> query;
794         query.Construct();
795         query.SetProjection(projectionIds, 1);
796         query.SetFilter(filter);
797         query.SetDistinct(true);
798         query.SetSort(_contacts_contact_email.display_name, true);
799
800         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContactEmail, Contact>(query);
801         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
802
803         return pContacts;
804 }
805
806 IList*
807 _AddressbookImpl::SearchContactsByNameN(const String& name) const
808 {
809         SysTryReturn(NID_SCL, !name.IsEmpty(), null, E_INVALID_ARG, "[%s] Invalid argument is used. The specified email is an empty string.", GetErrorMessage(E_INVALID_ARG));
810         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
811
812         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
813         {
814                 SysTryReturn(NID_SCL, name.GetLength() <= MAX_CONTACT_NAME_LENGTH, null, E_INVALID_ARG, "[%s] Invalid argument is used. The length of name is greater than MAX_CONTACT_NAME_LENGTH.", GetErrorMessage(E_INVALID_ARG));
815         }
816
817
818         ClearLastResult();
819
820         std::unique_ptr<char[]> pCharArray(_StringConverter::CopyToCharArrayN(name));
821         SysTryReturn(NID_SCL, pCharArray != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
822
823         __Filter<__ContactsContact> filter;
824         filter.Construct();
825         filter.AddInt(_contacts_contact.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
826         filter.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
827         filter.AddString(_contacts_contact.display_name, CONTACTS_MATCH_CONTAINS, pCharArray.get());
828
829         __Query<__ContactsContact> query;
830         query.Construct();
831         query.SetFilter(filter);
832         query.SetSort(_contacts_contact.display_name, true);
833         query.SetDistinct(true);
834
835         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContact, Contact>(query);
836         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
837
838         return pContacts;
839 }
840
841
842 IList*
843 _AddressbookImpl::SearchContactsByPhoneNumberN(const String& phoneNumber) const
844 {
845         SysTryReturn(NID_SCL, !phoneNumber.IsEmpty(), null, E_INVALID_ARG, "[%s] Invalid argument is used. The specified phoneNumber is an empty string.", GetErrorMessage(E_INVALID_ARG));
846         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
847
848
849         if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
850         {
851                 int count = phoneNumber.GetLength();
852                 SysTryReturn(NID_SCL, count >= MIN_PHONENUMBER_QUERY_LENGTH && count <= MAX_PHONE_NUMBER_LENGTH, null, E_INVALID_ARG, "[%s] Invalid argument is used. The length of phoneNumber is shorter than MIN_PHONENUMBER_QUERY_LENGTH or greater than MAX_PHONE_NUMBER_LENGTH.", GetErrorMessage(E_INVALID_ARG));
853         }
854
855         ClearLastResult();
856
857         std::unique_ptr<char[]> pCharArray(_StringConverter::CopyToCharArrayN(phoneNumber));
858         SysTryReturn(NID_SCL, pCharArray != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
859
860         __Filter<__ContactsContactNumber> filter;
861         filter.Construct();
862         filter.AddInt(_contacts_contact_number.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
863         filter.AddOperator(CONTACTS_FILTER_OPERATOR_AND);
864         filter.AddString(_contacts_contact_number.number, CONTACTS_MATCH_CONTAINS, pCharArray.get());
865
866         unsigned int projectionIds[1];
867         projectionIds[0] = _contacts_contact_number.contact_id;
868
869         __Query<__ContactsContactNumber> query;
870         query.Construct();
871         query.SetProjection(projectionIds, 1);
872         query.SetFilter(filter);
873         query.SetDistinct(true);
874         query.SetSort(_contacts_contact_number.display_name, true);
875
876         IList* pContacts = _AddressbookUtil::SearchWithQueryN<__ContactsContactNumber, Contact>(query);
877         SysTryReturn(NID_SCL, pContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
878
879         return pContacts;
880 }
881
882 int
883 _AddressbookImpl::GetCategoryCount(void) const
884 {
885         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, -1, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
886
887         int count = -1;
888
889         ClearLastResult();
890
891         __Filter<__ContactsGroup> filter;
892         filter.Construct();
893         filter.AddInt(_contacts_group.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
894
895         __Query<__ContactsGroup> query;
896         query.Construct();
897         query.SetFilter(filter);
898
899         count = _AddressbookUtil::GetCountWithQuery(query);
900         SysTryReturn(NID_SCL, count >= 0, -1, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
901
902         return count;
903 }
904
905 int
906 _AddressbookImpl::GetContactCount(void) const
907 {
908         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, -1, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
909
910         int count = -1;
911
912         ClearLastResult();
913
914         __Filter<__ContactsContact> filter;
915         filter.Construct();
916         filter.AddInt(_contacts_contact.address_book_id, CONTACTS_MATCH_EQUAL, __addressbookId);
917
918         __Query<__ContactsContact> query;
919         query.Construct();
920         query.SetFilter(filter);
921
922         count = _AddressbookUtil::GetCountWithQuery(query);
923         SysTryReturn(NID_SCL, count >= 0, -1, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
924
925         return count;
926 }
927
928 Contact*
929 _AddressbookImpl::GetContactN(RecordId contactId) const
930 {
931         SysTryReturn(NID_SCL, contactId != INVALID_RECORD_ID, null, E_INVALID_ARG, "[%s] Invalid argument is used. contactId = %d.", GetErrorMessage(E_INVALID_ARG), contactId);
932         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
933
934         int intValue = 0;
935         contacts_record_h contactHandle = null;
936
937         ClearLastResult();
938
939         std::unique_ptr<Contact> pContact(new (std::nothrow) Contact());
940         SysTryReturn(NID_SCL, pContact, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
941
942         int ret = contacts_db_get_record(_contacts_contact._uri, contactId, &contactHandle);
943         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, null, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
944         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
945         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, null, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM)); 
946
947         _ContactImpl::GetInstance(*pContact)->SetContactRecordHandle(contactHandle);
948
949         contacts_record_get_int(contactHandle, _contacts_contact.id, &intValue);
950         SysTryReturn(NID_SCL, intValue == contactId, null, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
951
952         _RecordImpl::GetInstance(*pContact)->SetRecordId(intValue);
953
954         return pContact.release();
955 }
956
957 Category*
958 _AddressbookImpl::GetCategoryN(RecordId categoryId) const
959 {
960         SysTryReturn(NID_SCL, categoryId != INVALID_RECORD_ID, null, E_INVALID_ARG, "[%s] Invalid argument is used. categoryId = %d.", GetErrorMessage(E_INVALID_ARG), categoryId);
961         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
962
963         contacts_record_h recordHandle = null;
964
965         ClearLastResult();
966
967         int intValue = 0;
968         int ret = contacts_db_get_record(_contacts_group._uri, categoryId, &recordHandle);
969         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_NO_DATA, null, E_OBJ_NOT_FOUND, "[%s] The category is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
970         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
971         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, null, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
972
973         std::unique_ptr<Category> pCategory(new (std::nothrow) Category());
974         SysTryReturn(NID_SCL, pCategory != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
975
976         contacts_record_get_int(recordHandle, _contacts_group.id, &intValue);
977         SysTryReturn(NID_SCL, intValue == categoryId, null, E_OBJ_NOT_FOUND, "[%s] The contact is not found.", GetErrorMessage(E_OBJ_NOT_FOUND));
978
979         __Filter<__ContactsGroupRelation> filter;
980         filter.Construct();
981         filter.AddInt(_contacts_group_relation.group_id, CONTACTS_MATCH_EQUAL, categoryId);
982
983         __Query<__ContactsGroupRelation> query;
984         query.Construct();
985         query.SetFilter(filter);
986
987         int count = _AddressbookUtil::GetCountWithQuery(query);
988         SysTryReturn(NID_SCL, count >= 0, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
989
990         _CategoryImpl::GetInstance(*pCategory)->SetRecordHandle(recordHandle);
991         _CategoryImpl::GetInstance(*pCategory)->SetMemberCount(count);
992         _RecordImpl::GetInstance(*pCategory)->SetRecordId(categoryId);
993
994         return pCategory.release();
995 }
996
997 int
998 _AddressbookImpl::GetLatestVersion(void) const
999 {
1000         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, -1, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1001
1002         int latestVersion = -1;
1003
1004         ClearLastResult();
1005
1006         int ret = contacts_db_get_current_version(&latestVersion);
1007         SysTryReturn(NID_SCL, ret != CONTACTS_ERROR_OUT_OF_MEMORY, -1, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1008         SysTryReturn(NID_SCL, ret == CONTACTS_ERROR_NONE, -1, E_SYSTEM, "[%s] A system error has been occurred.", GetErrorMessage(E_SYSTEM));
1009
1010         return latestVersion;
1011 }
1012
1013 IList*
1014 _AddressbookImpl::GetChangedContactsAfterN(int version, int& latestVersion) const
1015 {
1016         SysTryReturn(NID_SCL, version >= 0, null, E_INVALID_ARG, "[%s] Invalid argument is used. version %d must be greater that or equal 0.", GetErrorMessage(E_INVALID_ARG), version);
1017         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1018
1019         IList* pChangedContacts = _AddressbookUtil::SearchWithVersionN<__ContactsContactUpdatedInfo, ContactChangeInfo>(__addressbookId, version, latestVersion);
1020         SysTryReturn(NID_SCL, pChangedContacts != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1021
1022         return pChangedContacts;
1023 }
1024
1025 IList*
1026 _AddressbookImpl::GetChangedCategoriesAfterN(int version, int& latestVersion) const
1027 {
1028         SysTryReturn(NID_SCL, version >= 0, null, E_INVALID_ARG, "[%s] Invalid argument is used. version %d must be greater that or equal 0.", GetErrorMessage(E_INVALID_ARG), version);
1029         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1030
1031         int latestVersion1 = 0;
1032         int latestVersion2 = 0;
1033
1034         std::unique_ptr<IList, AllElementsDeleter> pChangedGroups(_AddressbookUtil::SearchWithVersionN<__ContactsGroupUpdatedInfo, CategoryChangeInfo>(__addressbookId, version, latestVersion1));
1035         SysTryReturn(NID_SCL, pChangedGroups != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1036
1037         std::unique_ptr<IList, AllElementsDeleter> pChangedRelations(_AddressbookUtil::SearchWithVersionN<__ContactsGroupRelUpdatedInfo, CategoryChangeInfo>(__addressbookId, version, latestVersion2));
1038         SysTryReturn(NID_SCL, pChangedRelations != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1039
1040         std::unique_ptr<ArrayList, AllElementsDeleter> pChangeList(new (std::nothrow) Tizen::Base::Collection::ArrayList());
1041         SysTryReturn(NID_SCL, pChangeList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1042
1043         result r = pChangeList->AddItems(*pChangedGroups);
1044         SysTryReturn(NID_SCL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1045
1046         r = pChangeList->AddItems(*pChangedRelations);
1047         SysTryReturn(NID_SCL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1048
1049         pChangedGroups->RemoveAll(false);
1050         pChangedRelations->RemoveAll(false);
1051
1052         latestVersion = latestVersion2 > latestVersion1 ? latestVersion2 : latestVersion1;
1053         
1054         return pChangeList.release();
1055 }
1056
1057 IList*
1058 _AddressbookImpl::GetChangedGroupsAfterN(int version, int& latestVersion) const
1059 {
1060         SysTryReturn(NID_SCL, version >= 0, null, E_INVALID_ARG, "[%s] Invalid argument is used. version %d must be greater that or equal 0.", GetErrorMessage(E_INVALID_ARG), version);
1061         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1062
1063         IList* pChangedRelations = _AddressbookUtil::SearchWithVersionN<__ContactsGroupUpdatedInfo, CategoryChangeInfo>(__addressbookId, version, latestVersion);
1064         SysTryReturn(NID_SCL, pChangedRelations != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1065
1066         return pChangedRelations;
1067 }
1068
1069 IList*
1070 _AddressbookImpl::GetChangedRelationsAfterN(int version, int& latestVersion) const
1071 {
1072         SysTryReturn(NID_SCL, version >= 0, null, E_INVALID_ARG, "[%s] Invalid argument is used. version %d must be greater that or equal 0.", GetErrorMessage(E_INVALID_ARG), version);
1073         SysTryReturn(NID_SCL, _ContactDbConnector::EnsureDbConnection() == E_SUCCESS, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1074
1075         ClearLastResult();
1076
1077         IList* pChangedRelations = _AddressbookUtil::SearchWithVersionN<__ContactsGroupRelUpdatedInfo, CategoryChangeInfo>(__addressbookId, version, latestVersion);
1078         SysTryReturn(NID_SCL, pChangedRelations != null, null, GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
1079
1080         return pChangedRelations;
1081 }
1082
1083 void
1084 _AddressbookImpl::OnContactChanged(void)
1085 {
1086         if (__pIAddressbookEventListener == null && __pIRecordEventListener == null)
1087         {
1088                 return;
1089         }
1090
1091         std::unique_ptr<IList, AllElementsDeleter> pChangedContactList(GetChangedContactsAfterN(__dbVersionForContact, __dbVersionForContact));
1092         SysTryReturnVoidResult(NID_SCL, pChangedContactList != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1093
1094         if (pChangedContactList->GetCount() > 0)
1095         {
1096                 if (__pIAddressbookEventListener != null)
1097                 {
1098                         __pIAddressbookEventListener->OnContactsChanged(*pChangedContactList);
1099                 }
1100                 else
1101                 {
1102                         RecordEventType recordEventType = RECORD_ADDED;
1103                         std::unique_ptr<IEnumerator> pEnum(pChangedContactList->GetEnumeratorN());
1104                         std::unique_ptr<Contact> pContact(null);
1105
1106                         while (pEnum->MoveNext() == E_SUCCESS)
1107                         {
1108                                 ContactChangeInfo* pContactChagneInfo = static_cast<ContactChangeInfo*>(pEnum->GetCurrent());
1109
1110                                 if (pContactChagneInfo->GetChangeType() == RECORD_CHANGE_TYPE_ADDED)
1111                                 {
1112                                         recordEventType = RECORD_ADDED;
1113                                         pContact.reset(GetContactN(pContactChagneInfo->GetContactId()));
1114                                         if (pContact == null)
1115                                         {
1116                                                 if (GetLastResult() == E_OBJ_NOT_FOUND)
1117                                                 {
1118                                                         continue;
1119                                                 }
1120                                                 else
1121                                                 {
1122                                                         break;
1123                                                 }
1124                                         }
1125                                 }
1126                                 else if (pContactChagneInfo->GetChangeType() == RECORD_CHANGE_TYPE_UPDATED)
1127                                 {
1128                                         recordEventType = RECORD_UPDATED;
1129                                         pContact.reset(GetContactN(pContactChagneInfo->GetContactId()));
1130                                         if (pContact == null)
1131                                         {
1132                                                 if (GetLastResult() == E_OBJ_NOT_FOUND)
1133                                                 {
1134                                                         continue;
1135                                                 }
1136                                                 else
1137                                                 {
1138                                                         break;
1139                                                 }
1140                                         }
1141                                 }
1142                                 else
1143                                 {
1144                                         recordEventType = RECORD_REMOVED;
1145                                         pContact.reset(new (std::nothrow) Contact());
1146                                         if (pContact == null)
1147                                         {
1148                                                 SysLogException(NID_SCL, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1149                                                 break;
1150                                         }
1151
1152                                         _RecordImpl::GetInstance(*pContact)->SetRecordId(pContactChagneInfo->GetContactId());
1153                                 }
1154
1155                                 __pIRecordEventListener->OnRecordChangedN(recordEventType, RECORD_TYPE_CONTACT, *pContact, null, null);
1156                         }
1157                 }
1158
1159         }
1160 }
1161
1162 void
1163 _AddressbookImpl::OnCategoryChanged(void)
1164 {
1165         if (__pIAddressbookEventListener == null && __pIRecordEventListener == null)
1166         {
1167                 return;
1168         }
1169
1170         std::unique_ptr<IList, AllElementsDeleter> pChangedCategoryList(GetChangedGroupsAfterN(__dbVersionForGroup, __dbVersionForGroup));
1171         SysTryReturnVoidResult(NID_SCL, pChangedCategoryList != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1172
1173         if (pChangedCategoryList->GetCount() > 0)
1174         {
1175                 if (__pIAddressbookEventListener != null)
1176                 {
1177                         __pIAddressbookEventListener->OnCategoriesChanged(*pChangedCategoryList);
1178                 }
1179                 else
1180                 {
1181                         RecordEventType recordEventType = RECORD_ADDED;
1182                         std::unique_ptr<IEnumerator> pEnum(pChangedCategoryList->GetEnumeratorN());
1183                         std::unique_ptr<Category> pCategory(null);
1184
1185                         while (pEnum->MoveNext() == E_SUCCESS)
1186                         {
1187                                 CategoryChangeInfo* pCategoryChagneInfo = static_cast<CategoryChangeInfo*>(pEnum->GetCurrent());
1188
1189                                 if (pCategoryChagneInfo->GetChangeType() == RECORD_CHANGE_TYPE_ADDED)
1190                                 {
1191                                         recordEventType = RECORD_ADDED;
1192                                         pCategory.reset(GetCategoryN(pCategoryChagneInfo->GetCategoryId()));
1193                                         if (pCategory == null)
1194                                         {
1195                                                 if (GetLastResult() == E_OBJ_NOT_FOUND)
1196                                                 {
1197                                                         continue;
1198                                                 }
1199                                                 else
1200                                                 {
1201                                                         break;
1202                                                 }
1203                                         }
1204                                 }
1205                                 else if (pCategoryChagneInfo->GetChangeType() == RECORD_CHANGE_TYPE_UPDATED)
1206                                 {
1207                                         recordEventType = RECORD_UPDATED;
1208                                         pCategory.reset(GetCategoryN(pCategoryChagneInfo->GetCategoryId()));
1209                                         if (pCategory == null)
1210                                         {
1211                                                 if (GetLastResult() == E_OBJ_NOT_FOUND)
1212                                                 {
1213                                                         continue;
1214                                                 }
1215                                                 else
1216                                                 {
1217                                                         break;
1218                                                 }
1219                                         }
1220                                 }
1221                                 else
1222                                 {
1223                                         recordEventType = RECORD_REMOVED;
1224                                         pCategory.reset(new (std::nothrow) Category());
1225                                         if (pCategory == null)
1226                                         {
1227                                                 SysLogException(NID_SCL, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1228                                                 break;
1229                                         }
1230
1231                                         _RecordImpl::GetInstance(*pCategory)->SetRecordId(pCategoryChagneInfo->GetCategoryId());
1232                                 }
1233
1234                                 __pIRecordEventListener->OnRecordChangedN(recordEventType, RECORD_TYPE_CATEGORY, *pCategory, null, null);
1235                         }
1236                 }
1237
1238         }
1239 }
1240
1241 void
1242 _AddressbookImpl::OnRelationChanged(void)
1243 {
1244         if (__pIAddressbookEventListener == null && __pIRecordEventListener == null)
1245         {
1246                 return;
1247         }
1248
1249         std::unique_ptr<IList, AllElementsDeleter> pChangedCategoryList(GetChangedRelationsAfterN(__dbVersionForRelation, __dbVersionForRelation));
1250         SysTryReturnVoidResult(NID_SCL, pChangedCategoryList != null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1251
1252         if (pChangedCategoryList->GetCount() > 0)
1253         {
1254                 if (__pIAddressbookEventListener != null)
1255                 {
1256                         __pIAddressbookEventListener->OnCategoriesChanged(*pChangedCategoryList);
1257                 }
1258                 else
1259                 {
1260                         RecordEventType recordEventType = RECORD_ADDED;
1261                         std::unique_ptr<IEnumerator> pEnum(pChangedCategoryList->GetEnumeratorN());
1262                         std::unique_ptr<Category> pCategory(null);
1263
1264                         while (pEnum->MoveNext() == E_SUCCESS)
1265                         {
1266                                 CategoryChangeInfo* pCategoryChagneInfo = static_cast<CategoryChangeInfo*>(pEnum->GetCurrent());
1267
1268                                 recordEventType = RECORD_UPDATED;
1269                                 pCategory.reset(GetCategoryN(pCategoryChagneInfo->GetCategoryId()));
1270                                 if (pCategory == null)
1271                                 {
1272                                         if (GetLastResult() == E_OBJ_NOT_FOUND)
1273                                         {
1274                                                 continue;
1275                                         }
1276                                         else
1277                                         {
1278                                                 break;
1279                                         }
1280                                 }
1281
1282                                 __pIRecordEventListener->OnRecordChangedN(recordEventType, RECORD_TYPE_CATEGORY, *pCategory, null, null);
1283                         }
1284                 }
1285         }
1286 }
1287
1288 _AddressbookImpl*
1289 _AddressbookImpl::GetInstance(Addressbook& addressbook)
1290 {
1291         return addressbook.__pAddressbookImpl;
1292 }
1293
1294 const _AddressbookImpl*
1295 _AddressbookImpl::GetInstance(const Addressbook& addressbook)
1296 {
1297         return addressbook.__pAddressbookImpl;
1298 }
1299
1300 }}  // Tizen::Social