ba6333377e15734d773e7f18fa024ca5dd7488da
[platform/core/csapi/tizenfx.git] / src / Tizen.Pims.Contacts / Tizen.Pims.Contacts / ContactsDatabase.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Pims.Contacts
22 {
23     /// <summary>
24     /// ContactsDatabase provides methods to manage contacts information from/to the database.
25     /// </summary>
26     /// <remarks>
27     /// This class allows user to access/create/update db operations for contacts information.
28     /// </remarks>
29     public class ContactsDatabase
30     {
31         /// <summary>
32         /// Delegete for detecting the contacts database changes
33         /// </summary>
34         /// <param name="uri">The contacts view URI</param>
35         /// <remarks>
36         /// The delegate must be registered using AddDBChangedDelegate.
37         /// It's invoked when the designated view changes.
38         /// </remarks>
39         /// <see cref="AddDBChangedDelegate"/>
40         public delegate void ContactsDBChangedDelegate(string uri);
41         private Object thisLock = new Object();
42         private Interop.Database.ContactsDBStatusChangedCallback _contactsDBStatusChangedCallback;
43         private event EventHandler<DBStatusChangedEventArgs> _dbStatusChanged;
44         private Dictionary<string, ContactsDBChangedDelegate> _callbackMap = new Dictionary<string, ContactsDBChangedDelegate>();
45         private Dictionary<string, Interop.Database.ContactsDBChangedCallback> _delegateMap = new Dictionary<string, Interop.Database.ContactsDBChangedCallback>();
46         private Interop.Database.ContactsDBChangedCallback _dbChangedDelegate;
47
48         internal ContactsDatabase()
49         {
50             ///To be created in ContactsManager only.
51         }
52
53         /// <summary>
54         /// Enumeration for contacts database status.
55         /// </summary>
56         public enum DBStatus
57         {
58             /// <summary>
59             /// Normal
60             /// </summary>
61             Normal,
62             /// <summary>
63             /// Changing collation.
64             /// </summary>
65             ChangingCollation
66         }
67
68         /// <summary>
69         /// Enumeration for Contacts search range.
70         /// </summary>
71         public enum SearchRange
72         {
73             /// <summary>
74             /// Search record from name
75             /// </summary>
76             Name = 0x00000001,
77             /// <summary>
78             /// Search record from name and number
79             /// </summary>
80             Number = 0x00000002,
81             /// <summary>
82             /// Search record from name,number and data
83             /// </summary>
84             Data = 0x00000004,
85             /// <summary>
86             /// Search record from name,number,data and email. Now, support only PersonEmail view
87             /// </summary>
88             Email = 0x00000008,
89         }
90
91         /// <summary>
92         /// Occurs when contacts database status is changed.
93         /// </summary>
94         public event EventHandler<DBStatusChangedEventArgs> DBStatusChanged
95         {
96             add
97             {
98                 lock (thisLock)
99                 {
100                     _contactsDBStatusChangedCallback = (DBStatus status, IntPtr userData) =>
101                     {
102                         DBStatusChangedEventArgs args = new DBStatusChangedEventArgs(status);
103                         _dbStatusChanged?.Invoke(this, args);
104                     };
105
106                     int error = Interop.Database.AddStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
107                     if ((int)ContactsError.None != error)
108                     {
109                         Log.Error(Globals.LogTag, "Add StatusChanged Failed with error " + error);
110                     }
111                     else
112                     {
113                         _dbStatusChanged += value;
114                     }
115                 }
116
117             }
118
119             remove
120             {
121                 lock (thisLock)
122                 {
123                     int error = Interop.Database.RemoveStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
124                     if ((int)ContactsError.None != error)
125                     {
126                         Log.Error(Globals.LogTag, "Remove StatusChanged Failed with error " + error);
127                     }
128
129                     _dbStatusChanged -= value;
130                 }
131             }
132
133         }
134
135         /// <summary>
136         /// The contacts database status.
137         /// </summary>
138         public DBStatus Status
139         {
140             get
141             {
142                 DBStatus status;
143                 int error = Interop.Database.GetStatus(out status);
144                 if ((int)ContactsError.None != error)
145                 {
146                     Log.Error(Globals.LogTag, "GetStatus Failed with error " + error);
147                 }
148                 return status;
149             }
150         }
151
152         /// <summary>
153         /// Gets current contacts database version.
154         /// </summary>
155         /// <returns>The current contacts database version</returns>
156         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
157         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
158         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
159         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
160         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
161         public int GetVersion()
162         {
163             int version = -1;
164             int error = Interop.Database.GetVersion(out version);
165             if ((int)ContactsError.None != error)
166             {
167                 Log.Error(Globals.LogTag, "GetVersion() Failed with error " + error);
168                 throw ContactsErrorFactory.CheckAndCreateException(error);
169             }
170             return version;
171         }
172
173         /// <summary>
174         /// Gets last successful changed contacts database version on the current connection.
175         /// </summary>
176         /// <returns>The last successful changed contacts database version on the current connection</returns>
177         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
178         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
179         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
180         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
181         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
182         public int GetLastChangeVersion
183         {
184             get
185             {
186                 int version = -1;
187                 int error = Interop.Database.GetLastChangeVersion(out version);
188                 if ((int)ContactsError.None != error)
189                 {
190                     Log.Error(Globals.LogTag, "GetLastChangeVersion Failed with error " + error);
191                 }
192                 return version;
193             }
194         }
195
196         /// <summary>
197         /// Inserts a record into the contacts database.
198         /// </summary>
199         /// <param name="record">The record to insert</param>
200         /// <returns>The ID of inserted record</returns>
201         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
202         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
203         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
204         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
205         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
206         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
207         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
208         public int Insert(ContactsRecord record)
209         {
210             int id = -1;
211             int error = Interop.Database.Insert(record._recordHandle, out id);
212             if ((int)ContactsError.None != error)
213             {
214                 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
215                 throw ContactsErrorFactory.CheckAndCreateException(error);
216             }
217             return id;
218         }
219
220         /// <summary>
221         /// Inserts multiple records into the contacts database as a batch operation.
222         /// </summary>
223         /// <param name="list">The record list</param>
224         /// <returns>The inserted record ID array</returns>
225         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
226         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
227         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
228         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
229         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
230         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
231         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
232         public int[] Insert(ContactsList list)
233         {
234             IntPtr ids;
235             int count;
236             int error = Interop.Database.InsertRecords(list._listHandle, out ids, out count);
237             if ((int)ContactsError.None != error)
238             {
239                 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
240                 throw ContactsErrorFactory.CheckAndCreateException(error);
241             }
242
243             int[] idArr = new int[count];
244             Marshal.Copy(ids, idArr, 0, count);
245
246             return idArr;
247         }
248
249         /// <summary>
250         /// Gets a record from the contacts database.
251         /// </summary>
252         /// <param name="viewUri">The view URI of a record</param>
253         /// <param name="recordId">The record ID</param>
254         /// <returns>The record associated with the record ID</returns>
255         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
256         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
257         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
258         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
259         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
260         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
261         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
262         public ContactsRecord Get(string viewUri, int recordId)
263         {
264             IntPtr handle;
265             int error = Interop.Database.Get(viewUri, recordId, out handle);
266             if ((int)ContactsError.None != error)
267             {
268                 Log.Error(Globals.LogTag, "Get Failed with error " + error);
269                 throw ContactsErrorFactory.CheckAndCreateException(error);
270             }
271             return new ContactsRecord(handle);
272         }
273
274         /// <summary>
275         /// Updates a record in the contacts database.
276         /// </summary>
277         /// <param name="record">The record to update</param>
278         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
279         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
280         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
281         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
282         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
283         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
284         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
285         public void Update(ContactsRecord record)
286         {
287             int error = Interop.Database.Update(record._recordHandle);
288             if ((int)ContactsError.None != error)
289             {
290                 Log.Error(Globals.LogTag, "Update Failed with error " + error);
291                 throw ContactsErrorFactory.CheckAndCreateException(error);
292             }
293         }
294
295         /// <summary>
296         /// Updates multiple records in the contacts database as a batch operation.
297         /// </summary>
298         /// <param name="list">The record list</param>
299         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
300         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
301         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
302         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
303         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
304         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
305         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
306         public void Update(ContactsList list)
307         {
308             int error = Interop.Database.UpdateRecords(list._listHandle);
309             if ((int)ContactsError.None != error)
310             {
311                 Log.Error(Globals.LogTag, "Update Failed with error " + error);
312                 throw ContactsErrorFactory.CheckAndCreateException(error);
313             }
314         }
315
316         /// <summary>
317         /// Deletes a record from the contacts database with related child records.
318         /// </summary>
319         /// <param name="viewUri">The view URI of a record</param>
320         /// <param name="recordId">The record ID to delete</param>
321         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
322         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
323         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
324         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
325         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
326         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
327         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
328         public void Delete(string viewUri, int recordId)
329         {
330             int error = Interop.Database.Delete(viewUri, recordId);
331             if ((int)ContactsError.None != error)
332             {
333                 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
334                 throw ContactsErrorFactory.CheckAndCreateException(error);
335             }
336         }
337
338         /// <summary>
339         /// Deletes multiple records with related child records from the contacts database as a batch operation.
340         /// </summary>
341         /// <param name="viewUri">The view URI of the records to delete</param>
342         /// <param name="idArray">The record IDs to delete</param>
343         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
344         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
345         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
346         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
347         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
348         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
349         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
350         public void Delete(string viewUri, int[] idArray)
351         {
352             int error = Interop.Database.DeleteRecords(viewUri, idArray, idArray.Length);
353             if ((int)ContactsError.None != error)
354             {
355                 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
356                 throw ContactsErrorFactory.CheckAndCreateException(error);
357             }
358         }
359
360         /// <summary>
361         /// Replaces a record in the contacts database.
362         /// </summary>
363         /// <param name="record">The record to replace</param>
364         /// <param name="recordId">the record ID to be replaced</param>
365         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
366         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
367         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
368         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
369         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
370         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
371         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
372         public void Replace(ContactsRecord record, int recordId)
373         {
374             int error = Interop.Database.Replace(record._recordHandle, recordId);
375             if ((int)ContactsError.None != error)
376             {
377                 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
378                 throw ContactsErrorFactory.CheckAndCreateException(error);
379             }
380         }
381
382         /// <summary>
383         /// Replaces multiple records in the contacts database as a batch operation.
384         /// </summary>
385         /// <param name="list">The record list to replace</param>
386         /// <param name="idArray">The record IDs to be replaced</param>
387         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
388         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
389         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
390         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
391         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
392         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
393         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
394         public void Replace(ContactsList list, int[] idArray)
395         {
396             int error = Interop.Database.ReplaceRecords(list._listHandle, idArray, idArray.Length);
397             if ((int)ContactsError.None != error)
398             {
399                 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
400                 throw ContactsErrorFactory.CheckAndCreateException(error);
401             }
402         }
403
404         /// <summary>
405         /// Retrieves all records as a list.
406         /// </summary>
407         /// <param name="viewUri">The view URI to get records</param>
408         /// <param name="offset">The index from which results</param>
409         /// <param name="limit">The number to limit results(value 0 is used for all records)</param>
410         /// <returns>
411         /// The record list
412         /// </returns>
413         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
414         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
415         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
416         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
417         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
418         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
419         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
420         public ContactsList GetAll(string viewUri, int offset, int limit)
421         {
422             IntPtr handle;
423             int error = Interop.Database.GetRecords(viewUri, offset, limit, out handle);
424             if ((int)ContactsError.None != error)
425             {
426                 Log.Error(Globals.LogTag, "GetAll Failed with error " + error);
427                 throw ContactsErrorFactory.CheckAndCreateException(error);
428             }
429             return new ContactsList(handle);
430         }
431
432         /// <summary>
433         /// Retrieves records using a query.
434         /// </summary>
435         /// <param name="query">The query to filter the results</param>
436         /// <param name="offset">The index from which to get results</param>
437         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
438         /// <returns>
439         /// The record list
440         /// </returns>
441         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
442         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
443         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
444         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
445         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
446         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
447         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
448         public ContactsList GetRecordsWithQuery(ContactsQuery query, int offset, int limit)
449         {
450             IntPtr handle;
451             int error = Interop.Database.GetRecords(query._queryHandle, offset, limit, out handle);
452             if ((int)ContactsError.None != error)
453             {
454                 Log.Error(Globals.LogTag, "GetAllWithQuery Failed with error " + error);
455                 throw ContactsErrorFactory.CheckAndCreateException(error);
456             }
457             return new ContactsList(handle);
458         }
459
460         /// <summary>
461         /// Retrieves records changes since the given database version.
462         /// </summary>
463         /// <param name="viewUri">The view URI to get records</param>
464         /// <param name="addressbookId">The address book ID to filter</param>
465         /// <param name="contactsDBVersion">The contacts database version</param>
466         /// <param name="currentDBVersion">The current contacts database version</param>
467         /// <returns>
468         /// The record list
469         /// </returns>
470         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
471         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
472         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
473         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
474         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
475         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
476         public ContactsList GetChangesByVersion(string viewUri, int addressbookId, int contactsDBVersion, out int currentDBVersion)
477         {
478             IntPtr recordList;
479             int error = Interop.Database.GetChangesByVersion(viewUri, addressbookId, contactsDBVersion, out recordList,out currentDBVersion);
480             if ((int)ContactsError.None != error)
481             {
482                 Log.Error(Globals.LogTag, "GetChangesByVersion Failed with error " + error);
483                 throw ContactsErrorFactory.CheckAndCreateException(error);
484             }
485             return new ContactsList(recordList);
486         }
487
488         /// <summary>
489         /// Finds records based on a given keyword.
490         /// </summary>
491         /// <remarks>
492         /// This API works only for the Views below.
493         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
494         /// </remarks>
495         /// <param name="viewUri">The view URI to find records</param>
496         /// <param name="keyword">The keyword</param>
497         /// <param name="offset">The index from which to get results</param>
498         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
499         /// <returns></returns>
500         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
501         public ContactsList Search(string viewUri, string keyword, int offset, int limit)
502         {
503             IntPtr recordList;
504             int error = Interop.Database.Search(viewUri, keyword, offset, limit, out recordList);
505             if ((int)ContactsError.None != error)
506             {
507                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
508                 throw ContactsErrorFactory.CheckAndCreateException(error);
509             }
510             return new ContactsList(recordList);
511         }
512
513         /// <summary>
514         /// Finds records based on given query and keyword.
515         /// </summary>
516         /// <remarks>
517         /// This API works only for the Views below.
518         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
519         /// </remarks>
520         /// <param name="query">The query to filter</param>
521         /// <param name="keyword">The keyword</param>
522         /// <param name="offset">The index from which to get results</param>
523         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
524         /// <returns>The record list</returns>
525         public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit)
526         {
527             IntPtr recordList;
528             int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, out recordList);
529             if ((int)ContactsError.None != error)
530             {
531                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
532                 throw ContactsErrorFactory.CheckAndCreateException(error);
533             }
534             return new ContactsList(recordList);
535         }
536
537         /// <summary>
538         /// Finds records based on a keyword and range.
539         /// </summary>
540         /// <remarks>
541         /// This API works only for the Views below.
542         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
543         /// </remarks>
544         /// <param name="viewUri">The view URI</param>
545         /// <param name="keyword">The keyword</param>
546         /// <param name="offset">The index from which to get results</param>
547         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
548         /// <param name="range">The search range</param>
549         /// <returns>The record list</returns>
550         public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range)
551         {
552             IntPtr recordList;
553             int error = Interop.Database.Search(viewUri, keyword, offset, limit, out recordList);
554             if ((int)ContactsError.None != error)
555             {
556                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
557                 throw ContactsErrorFactory.CheckAndCreateException(error);
558             }
559             return new ContactsList(recordList);
560         }
561
562         /// <summary>
563         /// Finds records based on a given keyword for snippet
564         /// </summary>
565         /// <remarks>
566         /// This API works only for the Views below.
567         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
568         /// Because start match and end match are needed to be composed with keyword, this API performance is lower than Search(string viewUri, string keyword, int offset, int limit).
569         /// </remarks>
570         /// <param name="viewUri">The view URI to find records</param>
571         /// <param name="keyword">The keyword</param>
572         /// <param name="offset">The index from which to get results</param>
573         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
574         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
575         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
576         /// <param name="tokenNumber">The one side extra number of tokens near keyword(If negative value, full sentence is printed. e.g. if token number is 3 with 'abc' keyword, "my name is [abc]de and my home")</param>
577         /// <returns>The record list</returns>
578         public ContactsList Search(string viewUri, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
579         {
580             IntPtr recordList;
581             int error = Interop.Database.Search(viewUri, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
582             if ((int)ContactsError.None != error)
583             {
584                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
585                 throw ContactsErrorFactory.CheckAndCreateException(error);
586             }
587             return new ContactsList(recordList);
588         }
589
590         /// <summary>
591         /// Finds records based on given query and keyword for snippet.
592         /// </summary>
593         /// <remarks>
594         /// This API works only for the Views below.
595         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
596         /// Because start match and end match are needed to be composed with keyword, this API performance is lower than Search(ContactsQuery query, string keyword, int offset, int limit).
597         /// </remarks>
598         /// <param name="query">The query to filter</param>
599         /// <param name="keyword">The keyword</param>
600         /// <param name="offset">The index from which to get results</param>
601         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
602         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
603         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
604         /// <param name="tokenNumber">The one side extra number of tokens near keyword(If negative value, full sentence is printed. e.g. if token number is 3 with 'abc' keyword, "my name is [abc]de and my home")</param>
605         /// <returns>The record list</returns>
606         public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
607         {
608             IntPtr recordList;
609             int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
610             if ((int)ContactsError.None != error)
611             {
612                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
613                 throw ContactsErrorFactory.CheckAndCreateException(error);
614             }
615             return new ContactsList(recordList);
616         }
617
618         /// <summary>
619         /// Finds records based on a keyword and range for snippet.
620         /// </summary>
621         /// <remarks>
622         /// This API works only for the Views below.
623         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
624         /// Because start match and end match are needed to be composed with keyword, this API performance is lower than Search(string viewUri, string keyword, int offset, int limit, int range).
625         /// </remarks>
626         /// <param name="viewUri">The view URI</param>
627         /// <param name="keyword">The keyword</param>
628         /// <param name="offset">The index from which to get results</param>
629         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
630         /// <param name="range">The search range</param>
631         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
632         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
633         /// <param name="tokenNumber">The one side extra number of tokens near keyword(If negative value, full sentence is printed. e.g. if token number is 3 with 'abc' keyword, "my name is [abc]de and my home")</param>
634         /// <returns>The record list</returns>
635         public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range, string startMatch, string endMatch, int tokenNumber)
636         {
637             IntPtr recordList;
638             int error = Interop.Database.Search(viewUri, keyword, offset, limit, range, startMatch, endMatch, tokenNumber, out recordList);
639             if ((int)ContactsError.None != error)
640             {
641                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
642                 throw ContactsErrorFactory.CheckAndCreateException(error);
643             }
644             return new ContactsList(recordList);
645         }
646
647         /// <summary>
648         /// Gets the number of records in a specific view
649         /// </summary>
650         /// <param name="viewUri">The view URI</param>
651         /// <returns>The count of records</returns>
652         public int GetCount(string viewUri)
653         {
654             int count = -1;
655             int error = Interop.Database.GetCount(viewUri, out count);
656             if ((int)ContactsError.None != error)
657             {
658                 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
659                 throw ContactsErrorFactory.CheckAndCreateException(error);
660             }
661             return count;
662         }
663
664         /// <summary>
665         /// Gets the number of records matching a query.
666         /// </summary>
667         /// <param name="query">The query used for filtering the results</param>
668         /// <returns>The count of records</returns>
669         public int GetCount(ContactsQuery query)
670         {
671             int count = -1;
672             int error = Interop.Database.GetCount(query._queryHandle, out count);
673             if ((int)ContactsError.None != error)
674             {
675                 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
676                 throw ContactsErrorFactory.CheckAndCreateException(error);
677             }
678             return count;
679         }
680
681         /// <summary>
682         /// Registers a callback function to be invoked when a record changes.
683         /// </summary>
684         /// <param name="viewUri">The view URI of records whose changes are monitored</param>
685         /// <param name="callback">The callback function to register</param>
686         public void AddDBChangedDelegate(string viewUri, ContactsDBChangedDelegate callback)
687         {
688             _dbChangedDelegate = (string uri, IntPtr userData) =>
689             {
690                 _callbackMap[uri](uri);
691             };
692             int error = Interop.Database.AddChangedCb(viewUri, _dbChangedDelegate, IntPtr.Zero);
693             if ((int)ContactsError.None != error)
694             {
695                 Log.Error(Globals.LogTag, "AddDBChangedDelegate Failed with error " + error);
696                 throw ContactsErrorFactory.CheckAndCreateException(error);
697             }
698             _callbackMap[viewUri] = callback;
699             _delegateMap[viewUri] = _dbChangedDelegate;
700         }
701
702         /// <summary>
703         /// Unregisters a callback function.
704         /// </summary>
705         /// <param name="viewUri">The view URI of records whose changes are monitored</param>
706         /// <param name="callback">The callback function to register</param>
707         public void RemoveDBChangedDelegate(string viewUri, ContactsDBChangedDelegate callback)
708         {
709             int error = Interop.Database.RemoveChangedCb(viewUri, _delegateMap[viewUri], IntPtr.Zero);
710             if ((int)ContactsError.None != error)
711             {
712                 Log.Error(Globals.LogTag, "RemoveDBChangedDelegate Failed with error " + error);
713                 throw ContactsErrorFactory.CheckAndCreateException(error);
714             }
715             _callbackMap.Remove(viewUri);
716             _delegateMap.Remove(viewUri);
717         }
718     }
719 }