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