Release 4.0.0-preview1-00249
[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.Diagnostics.CodeAnalysis;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.Pims.Contacts
23 {
24
25     /// <summary>
26     /// ContactsDatabase provides methods to manage contacts information from/to the database.
27     /// </summary>
28     /// <remarks>
29     /// This class allows user to access/create/update db operations for contacts information.
30     /// </remarks>
31     /// <since_tizen> 4 </since_tizen>
32     public class ContactsDatabase
33     {
34         private Object thisLock = new Object();
35         private Interop.Database.ContactsDBStatusChangedCallback _contactsDBStatusChangedCallback;
36         private EventHandler<DBStatusChangedEventArgs> _dbStatusChanged;
37         private Dictionary<string, EventHandler<DBChangedEventArgs>> _eventHandlerMap = new Dictionary<string, EventHandler<DBChangedEventArgs>>();
38         private Dictionary<string, Interop.Database.ContactsDBChangedCallback> _callbackMap = new Dictionary<string, Interop.Database.ContactsDBChangedCallback>();
39
40         internal ContactsDatabase()
41         {
42             /*To be created in ContactsManager only.*/
43         }
44
45         /// <summary>
46         /// Enumeration for contacts database status.
47         /// </summary>
48         /// <since_tizen> 4 </since_tizen>
49         public enum DBStatus
50         {
51             /// <summary>
52             /// Normal
53             /// </summary>
54             Normal,
55             /// <summary>
56             /// Changing collation.
57             /// </summary>
58             ChangingCollation
59         }
60
61         /// <summary>
62         /// Enumeration for Contacts search range.
63         /// </summary>
64         /// <since_tizen> 4 </since_tizen>
65         [Flags]
66         public enum SearchRanges
67         {
68             /// <summary>
69             /// None
70             /// </summary>
71             None = 0,
72             /// <summary>
73             /// Search record from name
74             /// </summary>
75             Name = 0x00000001,
76             /// <summary>
77             /// Search record from number
78             /// </summary>
79             Number = 0x00000002,
80             /// <summary>
81             /// Search record from data
82             /// </summary>
83             Data = 0x00000004,
84             /// <summary>
85             /// Search record from email. Now, support only PersonEmail view
86             /// </summary>
87             Email = 0x00000008,
88         }
89
90         /// <summary>
91         /// Occurs when contacts database status is changed.
92         /// </summary>
93         /// <since_tizen> 4 </since_tizen>
94         public event EventHandler<DBStatusChangedEventArgs> DBStatusChanged
95         {
96             add
97             {
98                 lock (thisLock)
99                 {
100                     if (_contactsDBStatusChangedCallback == null)
101                     {
102                         _contactsDBStatusChangedCallback = (DBStatus status, IntPtr userData) =>
103                         {
104                             DBStatusChangedEventArgs args = new DBStatusChangedEventArgs(status);
105                             _dbStatusChanged?.Invoke(this, args);
106                         };
107                     }
108
109                     if (_dbStatusChanged == null)
110                     {
111                         int error = Interop.Database.AddStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
112                         if ((int)ContactsError.None != error)
113                         {
114                             Log.Error(Globals.LogTag, "Add StatusChanged Failed with error " + error);
115                         }
116                     }
117
118                     _dbStatusChanged += value;
119                 }
120
121             }
122
123             remove
124             {
125                 lock (thisLock)
126                 {
127                     _dbStatusChanged -= value;
128
129                     if (_dbStatusChanged == null)
130                     {
131                         int error = Interop.Database.RemoveStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
132                         if ((int)ContactsError.None != error)
133                         {
134                             Log.Error(Globals.LogTag, "Remove StatusChanged Failed with error " + error);
135                         }
136                     }
137                 }
138             }
139
140         }
141
142         /// <summary>
143         /// The current contacts database version.
144         /// </summary>
145         /// <value>The current contacts database version.</value>
146         /// <since_tizen> 4 </since_tizen>
147         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
148         public int Version
149         {
150             get
151             {
152                 int version = -1;
153                 int error = Interop.Database.GetVersion(out version);
154                 if ((int)ContactsError.None != error)
155                 {
156                     Log.Error(Globals.LogTag, "Version Failed with error " + error);
157                 }
158                 return version;
159             }
160         }
161
162         /// <summary>
163         /// The last successful changed contacts database version on the current connection.
164         /// </summary>
165         /// <value>The last successful changed contacts database version on the current connection.</value>
166         /// <since_tizen> 4 </since_tizen>
167         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
168         public int LastChangeVersion
169         {
170             get
171             {
172                 int version = -1;
173                 int error = Interop.Database.GetLastChangeVersion(out version);
174                 if ((int)ContactsError.None != error)
175                 {
176                     Log.Error(Globals.LogTag, "LastChangeVersion Failed with error " + error);
177                 }
178                 return version;
179             }
180         }
181
182         /// <summary>
183         /// The contacts database status.
184         /// </summary>
185         /// <value>The contacts database status.</value>
186         /// <since_tizen> 4 </since_tizen>
187         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
188         public DBStatus Status
189         {
190             get
191             {
192                 DBStatus status = DBStatus.Normal;
193                 int error = Interop.Database.GetStatus(out status);
194                 if ((int)ContactsError.None != error)
195                 {
196                     Log.Error(Globals.LogTag, "GetStatus Failed with error " + error);
197                 }
198                 return status;
199             }
200         }
201
202         /// <summary>
203         /// Inserts a record into the contacts database.
204         /// </summary>
205         /// <param name="record">The record to insert</param>
206         /// <returns>The ID of inserted record</returns>
207         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
208         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
209         /// <feature>http://tizen.org/feature/contact</feature>
210         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
211         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
212         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
213         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
214         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
215         /// <since_tizen> 4 </since_tizen>
216         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
217         public int Insert(ContactsRecord record)
218         {
219             int id = -1;
220             int error = Interop.Database.Insert(record._recordHandle, out id);
221             if ((int)ContactsError.None != error)
222             {
223                 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
224                 throw ContactsErrorFactory.CheckAndCreateException(error);
225             }
226             return id;
227         }
228
229         /// <summary>
230         /// Inserts multiple records into the contacts database as a batch operation.
231         /// </summary>
232         /// <param name="list">The record list</param>
233         /// <returns>The inserted record ID array</returns>
234         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
235         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
236         /// <feature>http://tizen.org/feature/contact</feature>
237         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
238         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
239         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
240         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
241         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
242         /// <since_tizen> 4 </since_tizen>
243         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
244         public int[] Insert(ContactsList list)
245         {
246             IntPtr ids;
247             int count;
248             int error = Interop.Database.InsertRecords(list._listHandle, out ids, out count);
249             if ((int)ContactsError.None != error)
250             {
251                 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
252                 throw ContactsErrorFactory.CheckAndCreateException(error);
253             }
254
255             int[] idArr = new int[count];
256             Marshal.Copy(ids, idArr, 0, count);
257
258             return idArr;
259         }
260
261         /// <summary>
262         /// Gets a record from the contacts database.
263         /// </summary>
264         /// <param name="viewUri">The view URI of a record</param>
265         /// <param name="recordId">The record ID</param>
266         /// <returns>The record associated with the record ID</returns>
267         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
268         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
269         /// <feature>http://tizen.org/feature/contact</feature>
270         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
271         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
272         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
273         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
274         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
275         /// <since_tizen> 4 </since_tizen>
276         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
277         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
278         public ContactsRecord Get(string viewUri, int recordId)
279         {
280             IntPtr handle;
281             int error = Interop.Database.Get(viewUri, recordId, out handle);
282             if ((int)ContactsError.None != error)
283             {
284                 Log.Error(Globals.LogTag, "Get Failed with error " + error);
285                 throw ContactsErrorFactory.CheckAndCreateException(error);
286             }
287             return new ContactsRecord(handle);
288         }
289
290         /// <summary>
291         /// Updates a record in the contacts database.
292         /// </summary>
293         /// <param name="record">The record to update</param>
294         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
295         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
296         /// <feature>http://tizen.org/feature/contact</feature>
297         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
298         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
299         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
300         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
301         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
302         /// <since_tizen> 4 </since_tizen>
303         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
304         public void Update(ContactsRecord record)
305         {
306             int error = Interop.Database.Update(record._recordHandle);
307             if ((int)ContactsError.None != error)
308             {
309                 Log.Error(Globals.LogTag, "Update Failed with error " + error);
310                 throw ContactsErrorFactory.CheckAndCreateException(error);
311             }
312         }
313
314         /// <summary>
315         /// Updates multiple records in the contacts database as a batch operation.
316         /// </summary>
317         /// <param name="list">The record list</param>
318         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
319         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
320         /// <feature>http://tizen.org/feature/contact</feature>
321         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
322         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
323         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
324         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
325         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
326         /// <since_tizen> 4 </since_tizen>
327         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
328         public void Update(ContactsList list)
329         {
330             int error = Interop.Database.UpdateRecords(list._listHandle);
331             if ((int)ContactsError.None != error)
332             {
333                 Log.Error(Globals.LogTag, "Update Failed with error " + error);
334                 throw ContactsErrorFactory.CheckAndCreateException(error);
335             }
336         }
337
338         /// <summary>
339         /// Deletes a record from the contacts database with related child records.
340         /// </summary>
341         /// <param name="viewUri">The view URI of a record</param>
342         /// <param name="recordId">The record ID to delete</param>
343         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
344         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
345         /// <feature>http://tizen.org/feature/contact</feature>
346         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
347         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
348         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
349         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
350         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
351         /// <since_tizen> 4 </since_tizen>
352         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
353         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
354         public void Delete(string viewUri, int recordId)
355         {
356             int error = Interop.Database.Delete(viewUri, recordId);
357             if ((int)ContactsError.None != error)
358             {
359                 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
360                 throw ContactsErrorFactory.CheckAndCreateException(error);
361             }
362         }
363
364         /// <summary>
365         /// Deletes multiple records with related child records from the contacts database as a batch operation.
366         /// </summary>
367         /// <param name="viewUri">The view URI of the records to delete</param>
368         /// <param name="idArray">The record IDs to delete</param>
369         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
370         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
371         /// <feature>http://tizen.org/feature/contact</feature>
372         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
373         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
374         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
375         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
376         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
377         /// <since_tizen> 4 </since_tizen>
378         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
379         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
380         public void Delete(string viewUri, int[] idArray)
381         {
382             int error = Interop.Database.DeleteRecords(viewUri, idArray, idArray.Length);
383             if ((int)ContactsError.None != error)
384             {
385                 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
386                 throw ContactsErrorFactory.CheckAndCreateException(error);
387             }
388         }
389
390         /// <summary>
391         /// Replaces a record in the contacts database.
392         /// </summary>
393         /// <param name="record">The record to replace</param>
394         /// <param name="recordId">the record ID to be replaced</param>
395         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
396         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
397         /// <feature>http://tizen.org/feature/contact</feature>
398         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
399         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
400         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
401         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
402         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
403         /// <since_tizen> 4 </since_tizen>
404         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
405         public void Replace(ContactsRecord record, int recordId)
406         {
407             int error = Interop.Database.Replace(record._recordHandle, recordId);
408             if ((int)ContactsError.None != error)
409             {
410                 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
411                 throw ContactsErrorFactory.CheckAndCreateException(error);
412             }
413         }
414
415         /// <summary>
416         /// Replaces multiple records in the contacts database as a batch operation.
417         /// </summary>
418         /// <param name="list">The record list to replace</param>
419         /// <param name="idArray">The record IDs to be replaced</param>
420         /// <privilege>http://tizen.org/privilege/contact.write</privilege>
421         /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
422         /// <feature>http://tizen.org/feature/contact</feature>
423         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
424         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
425         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
426         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
427         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
428         /// <since_tizen> 4 </since_tizen>
429         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
430         public void Replace(ContactsList list, int[] idArray)
431         {
432             int error = Interop.Database.ReplaceRecords(list._listHandle, idArray, idArray.Length);
433             if ((int)ContactsError.None != error)
434             {
435                 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
436                 throw ContactsErrorFactory.CheckAndCreateException(error);
437             }
438         }
439
440         /// <summary>
441         /// Retrieves all records as a list.
442         /// </summary>
443         /// <param name="viewUri">The view URI to get records</param>
444         /// <param name="offset">The index from which results</param>
445         /// <param name="limit">The number to limit results(value 0 is used for all records)</param>
446         /// <returns>
447         /// The record list
448         /// </returns>
449         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
450         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
451         /// <feature>http://tizen.org/feature/contact</feature>
452         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
453         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
454         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
455         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
456         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
457         /// <since_tizen> 4 </since_tizen>
458         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
459         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
460         public ContactsList GetAll(string viewUri, int offset, int limit)
461         {
462             IntPtr handle;
463             int error = Interop.Database.GetRecords(viewUri, offset, limit, out handle);
464             if ((int)ContactsError.None != error)
465             {
466                 Log.Error(Globals.LogTag, "GetAll Failed with error " + error);
467                 throw ContactsErrorFactory.CheckAndCreateException(error);
468             }
469             return new ContactsList(handle);
470         }
471
472         /// <summary>
473         /// Retrieves records using a query.
474         /// </summary>
475         /// <param name="query">The query to filter the results</param>
476         /// <param name="offset">The index from which to get results</param>
477         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
478         /// <returns>
479         /// The record list
480         /// </returns>
481         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
482         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
483         /// <feature>http://tizen.org/feature/contact</feature>
484         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
485         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
486         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
487         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
488         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
489         /// <since_tizen> 4 </since_tizen>
490         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
491         public ContactsList GetRecordsWithQuery(ContactsQuery query, int offset, int limit)
492         {
493             IntPtr handle;
494             int error = Interop.Database.GetRecords(query._queryHandle, offset, limit, out handle);
495             if ((int)ContactsError.None != error)
496             {
497                 Log.Error(Globals.LogTag, "GetAllWithQuery Failed with error " + error);
498                 throw ContactsErrorFactory.CheckAndCreateException(error);
499             }
500             return new ContactsList(handle);
501         }
502
503         /// <summary>
504         /// Retrieves records changes since the given database version.
505         /// </summary>
506         /// <param name="viewUri">The view URI to get records</param>
507         /// <param name="addressBookId">The address book ID to filter</param>
508         /// <param name="contactsDBVersion">The contacts database version</param>
509         /// <param name="currentDBVersion">The current contacts database version</param>
510         /// <returns>
511         /// The record list
512         /// </returns>
513         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
514         /// <feature>http://tizen.org/feature/contact</feature>
515         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
516         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
517         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
518         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
519         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
520         /// <since_tizen> 4 </since_tizen>
521         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
522         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
523         public ContactsList GetChangesByVersion(string viewUri, int addressBookId, int contactsDBVersion, out int currentDBVersion)
524         {
525             IntPtr recordList;
526             int error = Interop.Database.GetChangesByVersion(viewUri, addressBookId, contactsDBVersion, out recordList,out currentDBVersion);
527             if ((int)ContactsError.None != error)
528             {
529                 Log.Error(Globals.LogTag, "GetChangesByVersion Failed with error " + error);
530                 throw ContactsErrorFactory.CheckAndCreateException(error);
531             }
532             return new ContactsList(recordList);
533         }
534
535         /// <summary>
536         /// Finds records based on a given keyword.
537         /// </summary>
538         /// <remarks>
539         /// This API works only for the Views below.
540         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
541         /// </remarks>
542         /// <param name="viewUri">The view URI to find records</param>
543         /// <param name="keyword">The keyword</param>
544         /// <param name="offset">The index from which to get results</param>
545         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
546         /// <returns>The record list</returns>
547         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
548         /// <feature>http://tizen.org/feature/contact</feature>
549         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
550         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
551         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
552         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
553         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
554         /// <since_tizen> 4 </since_tizen>
555         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
556         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
557         public ContactsList Search(string viewUri, string keyword, int offset, int limit)
558         {
559             IntPtr recordList;
560             int error = Interop.Database.Search(viewUri, keyword, offset, limit, out recordList);
561             if ((int)ContactsError.None != error)
562             {
563                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
564                 throw ContactsErrorFactory.CheckAndCreateException(error);
565             }
566             return new ContactsList(recordList);
567         }
568
569         /// <summary>
570         /// Finds records based on given query and keyword.
571         /// </summary>
572         /// <remarks>
573         /// This API works only for the Views below.
574         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
575         /// </remarks>
576         /// <param name="query">The query to filter</param>
577         /// <param name="keyword">The keyword</param>
578         /// <param name="offset">The index from which to get results</param>
579         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
580         /// <returns>The record list</returns>
581         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
582         /// <feature>http://tizen.org/feature/contact</feature>
583         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
584         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
585         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
586         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
587         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
588         /// <since_tizen> 4 </since_tizen>
589         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
590         public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit)
591         {
592             IntPtr recordList;
593             int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, out recordList);
594             if ((int)ContactsError.None != error)
595             {
596                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
597                 throw ContactsErrorFactory.CheckAndCreateException(error);
598             }
599             return new ContactsList(recordList);
600         }
601
602         /// <summary>
603         /// Finds records based on a keyword and range.
604         /// </summary>
605         /// <remarks>
606         /// This API works only for the Views below.
607         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
608         /// </remarks>
609         /// <param name="viewUri">The view URI</param>
610         /// <param name="keyword">The keyword</param>
611         /// <param name="offset">The index from which to get results</param>
612         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
613         /// <param name="range">The search range, it should be a element of SearchRange or bitwise OR operation of them</param>
614         /// <returns>The record list</returns>
615         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
616         /// <feature>http://tizen.org/feature/contact</feature>
617         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
618         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
619         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
620         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
621         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
622         /// <since_tizen> 4 </since_tizen>
623         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
624         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
625         public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range)
626         {
627             IntPtr recordList;
628             int error = Interop.Database.Search(viewUri, keyword, offset, limit, range, out recordList);
629             if ((int)ContactsError.None != error)
630             {
631                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
632                 throw ContactsErrorFactory.CheckAndCreateException(error);
633             }
634             return new ContactsList(recordList);
635         }
636
637         /// <summary>
638         /// Finds records based on a given keyword for snippet
639         /// </summary>
640         /// <remarks>
641         /// This API works only for the Views below.
642         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
643         /// 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).
644         /// </remarks>
645         /// <param name="viewUri">The view URI to find records</param>
646         /// <param name="keyword">The keyword</param>
647         /// <param name="offset">The index from which to get results</param>
648         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
649         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
650         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
651         /// <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>
652         /// <returns>The record list</returns>
653         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
654         /// <feature>http://tizen.org/feature/contact</feature>
655         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
656         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
657         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
658         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
659         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
660         /// <since_tizen> 4 </since_tizen>
661         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
662         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
663         public ContactsList Search(string viewUri, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
664         {
665             IntPtr recordList;
666             int error = Interop.Database.Search(viewUri, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
667             if ((int)ContactsError.None != error)
668             {
669                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
670                 throw ContactsErrorFactory.CheckAndCreateException(error);
671             }
672             return new ContactsList(recordList);
673         }
674
675         /// <summary>
676         /// Finds records based on given query and keyword for snippet.
677         /// </summary>
678         /// <remarks>
679         /// This API works only for the Views below.
680         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
681         /// 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).
682         /// </remarks>
683         /// <param name="query">The query to filter</param>
684         /// <param name="keyword">The keyword</param>
685         /// <param name="offset">The index from which to get results</param>
686         /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
687         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
688         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
689         /// <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>
690         /// <returns>The record list</returns>
691         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
692         /// <feature>http://tizen.org/feature/contact</feature>
693         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
694         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
695         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
696         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
697         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
698         /// <since_tizen> 4 </since_tizen>
699         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
700         public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
701         {
702             IntPtr recordList;
703             int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
704             if ((int)ContactsError.None != error)
705             {
706                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
707                 throw ContactsErrorFactory.CheckAndCreateException(error);
708             }
709             return new ContactsList(recordList);
710         }
711
712         /// <summary>
713         /// Finds records based on a keyword and range for snippet.
714         /// </summary>
715         /// <remarks>
716         /// This API works only for the Views below.
717         /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
718         /// 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).
719         /// </remarks>
720         /// <param name="viewUri">The view URI</param>
721         /// <param name="keyword">The keyword</param>
722         /// <param name="offset">The index from which to get results</param>
723         /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
724         /// <param name="range">The search range, it should be a element of SearchRange or bitwise OR operation of them</param>
725         /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
726         /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
727         /// <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>
728         /// <returns>The record list</returns>
729         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
730         /// <feature>http://tizen.org/feature/contact</feature>
731         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
732         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
733         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
734         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
735         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
736         /// <since_tizen> 4 </since_tizen>
737         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
738         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
739         public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range, string startMatch, string endMatch, int tokenNumber)
740         {
741             IntPtr recordList;
742             int error = Interop.Database.Search(viewUri, keyword, offset, limit, range, startMatch, endMatch, tokenNumber, out recordList);
743             if ((int)ContactsError.None != error)
744             {
745                 Log.Error(Globals.LogTag, "Search Failed with error " + error);
746                 throw ContactsErrorFactory.CheckAndCreateException(error);
747             }
748             return new ContactsList(recordList);
749         }
750
751         /// <summary>
752         /// Gets the number of records in a specific view
753         /// </summary>
754         /// <param name="viewUri">The view URI</param>
755         /// <returns>The count of records</returns>
756         /// <since_tizen> 4 </since_tizen>
757         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
758         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
759         public int GetCount(string viewUri)
760         {
761             int count = -1;
762             int error = Interop.Database.GetCount(viewUri, out count);
763             if ((int)ContactsError.None != error)
764             {
765                 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
766                 throw ContactsErrorFactory.CheckAndCreateException(error);
767             }
768             return count;
769         }
770
771         /// <summary>
772         /// Gets the number of records matching a query.
773         /// </summary>
774         /// <param name="query">The query used for filtering the results</param>
775         /// <returns>The count of records</returns>
776         /// <since_tizen> 4 </since_tizen>
777         [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
778         public int GetCount(ContactsQuery query)
779         {
780             int count = -1;
781             int error = Interop.Database.GetCount(query._queryHandle, out count);
782             if ((int)ContactsError.None != error)
783             {
784                 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
785                 throw ContactsErrorFactory.CheckAndCreateException(error);
786             }
787             return count;
788         }
789
790         /// <summary>
791         /// Registers a EventHandler to be invoked when a record changes.
792         /// </summary>
793         /// <param name="viewUri">The view URI of records whose changes are monitored</param>
794         /// <param name="DBChanged">The EventHandler to register</param>
795         /// <privilege>http://tizen.org/privilege/contact.read</privilege>
796         /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
797         /// <feature>http://tizen.org/feature/contact</feature>
798         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
799         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
800         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
801         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
802         /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
803         /// <since_tizen> 4 </since_tizen>
804         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
805         public void AddDBChangedEventHandler(string viewUri, EventHandler<DBChangedEventArgs> DBChanged)
806         {
807             if (!_callbackMap.ContainsKey(viewUri))
808             {
809                 _callbackMap[viewUri] = (string uri, IntPtr userData) =>
810                 {
811                     DBChangedEventArgs args = new DBChangedEventArgs(uri);
812                     _eventHandlerMap[uri]?.Invoke(this, args);
813                 };
814
815                 int error = Interop.Database.AddChangedCb(viewUri, _callbackMap[viewUri], IntPtr.Zero);
816                 if ((int)ContactsError.None != error)
817                 {
818                     Log.Error(Globals.LogTag, "AddDBChangedEventHandler Failed with error " + error);
819                     throw ContactsErrorFactory.CheckAndCreateException(error);
820                 }
821             }
822
823             EventHandler<DBChangedEventArgs> handler = null;
824             if (!_eventHandlerMap.TryGetValue(viewUri, out handler))
825                 _eventHandlerMap.Add(viewUri, null);
826
827             _eventHandlerMap[viewUri] = handler + DBChanged;
828         }
829
830         /// <summary>
831         /// Deregisters a EventHandler.
832         /// </summary>
833         /// <param name="viewUri">The view URI of records whose changes are monitored</param>
834         /// <param name="DBChanged">The EventHandler to deregister</param>
835         /// <feature>http://tizen.org/feature/contact</feature>
836         /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
837         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
838         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
839         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
840         /// <since_tizen> 4 </since_tizen>
841         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
842         public void RemoveDBChangedEventHandler(string viewUri, EventHandler<DBChangedEventArgs> DBChanged)
843         {
844             EventHandler<DBChangedEventArgs> handler = null;
845             if (!_eventHandlerMap.TryGetValue(viewUri, out handler))
846                 _eventHandlerMap.Add(viewUri, null);
847             else
848                 _eventHandlerMap[viewUri] = handler - DBChanged;
849
850             if (_eventHandlerMap[viewUri] == null)
851             {
852                 int error = Interop.Database.RemoveChangedCb(viewUri, _callbackMap[viewUri], IntPtr.Zero);
853                 if ((int)ContactsError.None != error)
854                 {
855                     Log.Error(Globals.LogTag, "RemoveDBChangedEventHandler Failed with error " + error);
856                     throw ContactsErrorFactory.CheckAndCreateException(error);
857                 }
858                 _callbackMap.Remove(viewUri);
859             }
860         }
861     }
862 }