2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Diagnostics.CodeAnalysis;
20 using System.Runtime.InteropServices;
22 namespace Tizen.Pims.Contacts
26 /// ContactsDatabase provides methods to manage contacts information from/to the database.
29 /// This class allows user to access/create/update db operations for contacts information.
31 public class ContactsDatabase
33 private Object thisLock = new Object();
34 private Interop.Database.ContactsDBStatusChangedCallback _contactsDBStatusChangedCallback;
35 private EventHandler<DBStatusChangedEventArgs> _dbStatusChanged;
36 private Dictionary<string, EventHandler<DBChangedEventArgs>> _eventHandlerMap = new Dictionary<string, EventHandler<DBChangedEventArgs>>();
37 private Dictionary<string, Interop.Database.ContactsDBChangedCallback> _callbackMap = new Dictionary<string, Interop.Database.ContactsDBChangedCallback>();
38 private Interop.Database.ContactsDBChangedCallback _dbChangedDelegate;
40 internal ContactsDatabase()
42 /*To be created in ContactsManager only.*/
46 /// Enumeration for contacts database status.
55 /// Changing collation.
61 /// Enumeration for Contacts search range.
64 public enum SearchRanges
71 /// Search record from name
75 /// Search record from number
79 /// Search record from data
83 /// Search record from email. Now, support only PersonEmail view
89 /// Occurs when contacts database status is changed.
91 public event EventHandler<DBStatusChangedEventArgs> DBStatusChanged
97 if (_contactsDBStatusChangedCallback == null)
99 _contactsDBStatusChangedCallback = (DBStatus status, IntPtr userData) =>
101 DBStatusChangedEventArgs args = new DBStatusChangedEventArgs(status);
102 _dbStatusChanged?.Invoke(this, args);
106 if (_dbStatusChanged == null)
108 int error = Interop.Database.AddStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
109 if ((int)ContactsError.None != error)
111 Log.Error(Globals.LogTag, "Add StatusChanged Failed with error " + error);
115 _dbStatusChanged += value;
124 _dbStatusChanged -= value;
126 if (_dbStatusChanged == null)
128 int error = Interop.Database.RemoveStatusChangedCb(_contactsDBStatusChangedCallback, IntPtr.Zero);
129 if ((int)ContactsError.None != error)
131 Log.Error(Globals.LogTag, "Remove StatusChanged Failed with error " + error);
140 /// The current contacts database version.
142 /// <value>The current contacts database version.</value>
143 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
149 int error = Interop.Database.GetVersion(out version);
150 if ((int)ContactsError.None != error)
152 Log.Error(Globals.LogTag, "Version Failed with error " + error);
159 /// The last successful changed contacts database version on the current connection.
161 /// <value>The last successful changed contacts database version on the current connection.</value>
162 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
163 public int LastChangeVersion
168 int error = Interop.Database.GetLastChangeVersion(out version);
169 if ((int)ContactsError.None != error)
171 Log.Error(Globals.LogTag, "LastChangeVersion Failed with error " + error);
178 /// The contacts database status.
180 /// <value>The contacts database status.</value>
181 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
182 public DBStatus Status
186 DBStatus status = DBStatus.Normal;
187 int error = Interop.Database.GetStatus(out status);
188 if ((int)ContactsError.None != error)
190 Log.Error(Globals.LogTag, "GetStatus Failed with error " + error);
197 /// Inserts a record into the contacts database.
199 /// <param name="record">The record to insert</param>
200 /// <returns>The ID of inserted record</returns>
201 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
202 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
203 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
204 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
205 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
206 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
207 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
208 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
209 public int Insert(ContactsRecord record)
212 int error = Interop.Database.Insert(record._recordHandle, out id);
213 if ((int)ContactsError.None != error)
215 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
216 throw ContactsErrorFactory.CheckAndCreateException(error);
222 /// Inserts multiple records into the contacts database as a batch operation.
224 /// <param name="list">The record list</param>
225 /// <returns>The inserted record ID array</returns>
226 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
227 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
228 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
229 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
230 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
231 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
232 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
233 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
234 public int[] Insert(ContactsList list)
238 int error = Interop.Database.InsertRecords(list._listHandle, out ids, out count);
239 if ((int)ContactsError.None != error)
241 Log.Error(Globals.LogTag, "Insert Failed with error " + error);
242 throw ContactsErrorFactory.CheckAndCreateException(error);
245 int[] idArr = new int[count];
246 Marshal.Copy(ids, idArr, 0, count);
252 /// Gets a record from the contacts database.
254 /// <param name="viewUri">The view URI of a record</param>
255 /// <param name="recordId">The record ID</param>
256 /// <returns>The record associated with the record ID</returns>
257 /// <privilege>http://tizen.org/privilege/contact.read</privilege>
258 /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
259 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
260 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
261 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
262 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
263 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
264 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
265 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
266 public ContactsRecord Get(string viewUri, int recordId)
269 int error = Interop.Database.Get(viewUri, recordId, out handle);
270 if ((int)ContactsError.None != error)
272 Log.Error(Globals.LogTag, "Get Failed with error " + error);
273 throw ContactsErrorFactory.CheckAndCreateException(error);
275 return new ContactsRecord(handle);
279 /// Updates a record in the contacts database.
281 /// <param name="record">The record to update</param>
282 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
283 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
284 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
285 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
286 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
287 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
288 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
289 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
290 public void Update(ContactsRecord record)
292 int error = Interop.Database.Update(record._recordHandle);
293 if ((int)ContactsError.None != error)
295 Log.Error(Globals.LogTag, "Update Failed with error " + error);
296 throw ContactsErrorFactory.CheckAndCreateException(error);
301 /// Updates multiple records in the contacts database as a batch operation.
303 /// <param name="list">The record list</param>
304 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
305 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
306 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
307 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
308 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
309 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
310 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
311 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
312 public void Update(ContactsList list)
314 int error = Interop.Database.UpdateRecords(list._listHandle);
315 if ((int)ContactsError.None != error)
317 Log.Error(Globals.LogTag, "Update Failed with error " + error);
318 throw ContactsErrorFactory.CheckAndCreateException(error);
323 /// Deletes a record from the contacts database with related child records.
325 /// <param name="viewUri">The view URI of a record</param>
326 /// <param name="recordId">The record ID to delete</param>
327 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
328 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
329 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
330 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
331 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
332 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
333 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
334 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
335 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
336 public void Delete(string viewUri, int recordId)
338 int error = Interop.Database.Delete(viewUri, recordId);
339 if ((int)ContactsError.None != error)
341 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
342 throw ContactsErrorFactory.CheckAndCreateException(error);
347 /// Deletes multiple records with related child records from the contacts database as a batch operation.
349 /// <param name="viewUri">The view URI of the records to delete</param>
350 /// <param name="idArray">The record IDs to delete</param>
351 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
352 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
353 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
354 /// <exception cref="NotSupportedException">Thrown when an invoked method 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 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
359 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
360 public void Delete(string viewUri, int[] idArray)
362 int error = Interop.Database.DeleteRecords(viewUri, idArray, idArray.Length);
363 if ((int)ContactsError.None != error)
365 Log.Error(Globals.LogTag, "Delete Failed with error " + error);
366 throw ContactsErrorFactory.CheckAndCreateException(error);
371 /// Replaces a record in the contacts database.
373 /// <param name="record">The record to replace</param>
374 /// <param name="recordId">the record ID to be replaced</param>
375 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
376 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
377 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
378 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
379 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
380 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
381 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
382 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
383 public void Replace(ContactsRecord record, int recordId)
385 int error = Interop.Database.Replace(record._recordHandle, recordId);
386 if ((int)ContactsError.None != error)
388 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
389 throw ContactsErrorFactory.CheckAndCreateException(error);
394 /// Replaces multiple records in the contacts database as a batch operation.
396 /// <param name="list">The record list to replace</param>
397 /// <param name="idArray">The record IDs to be replaced</param>
398 /// <privilege>http://tizen.org/privilege/contact.write</privilege>
399 /// <privilege>http://tizen.org/privilege/callhistory.write</privilege>
400 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
401 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
402 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
403 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
404 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
405 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
406 public void Replace(ContactsList list, int[] idArray)
408 int error = Interop.Database.ReplaceRecords(list._listHandle, idArray, idArray.Length);
409 if ((int)ContactsError.None != error)
411 Log.Error(Globals.LogTag, "Replace Failed with error " + error);
412 throw ContactsErrorFactory.CheckAndCreateException(error);
417 /// Retrieves all records as a list.
419 /// <param name="viewUri">The view URI to get records</param>
420 /// <param name="offset">The index from which results</param>
421 /// <param name="limit">The number to limit results(value 0 is used for all records)</param>
425 /// <privilege>http://tizen.org/privilege/contact.read</privilege>
426 /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
427 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
428 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
429 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
430 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
431 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
432 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
433 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
434 public ContactsList GetAll(string viewUri, int offset, int limit)
437 int error = Interop.Database.GetRecords(viewUri, offset, limit, out handle);
438 if ((int)ContactsError.None != error)
440 Log.Error(Globals.LogTag, "GetAll Failed with error " + error);
441 throw ContactsErrorFactory.CheckAndCreateException(error);
443 return new ContactsList(handle);
447 /// Retrieves records using a query.
449 /// <param name="query">The query to filter the results</param>
450 /// <param name="offset">The index from which to get results</param>
451 /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
455 /// <privilege>http://tizen.org/privilege/contact.read</privilege>
456 /// <privilege>http://tizen.org/privilege/callhistory.read</privilege>
457 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
458 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
459 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
460 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
461 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
462 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
463 public ContactsList GetRecordsWithQuery(ContactsQuery query, int offset, int limit)
466 int error = Interop.Database.GetRecords(query._queryHandle, offset, limit, out handle);
467 if ((int)ContactsError.None != error)
469 Log.Error(Globals.LogTag, "GetAllWithQuery Failed with error " + error);
470 throw ContactsErrorFactory.CheckAndCreateException(error);
472 return new ContactsList(handle);
476 /// Retrieves records changes since the given database version.
478 /// <param name="viewUri">The view URI to get records</param>
479 /// <param name="addressBookId">The address book ID to filter</param>
480 /// <param name="contactsDBVersion">The contacts database version</param>
481 /// <param name="currentDBVersion">The current contacts database version</param>
485 /// <privilege>http://tizen.org/privilege/contact.read</privilege>
486 /// <exception cref="InvalidOperationException">Thrown when method failed due to invalid operation</exception>
487 /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
488 /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
489 /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
490 /// <exception cref="UnauthorizedAccessException">Thrown when application does not have proper privileges</exception>
491 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
492 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
493 public ContactsList GetChangesByVersion(string viewUri, int addressBookId, int contactsDBVersion, out int currentDBVersion)
496 int error = Interop.Database.GetChangesByVersion(viewUri, addressBookId, contactsDBVersion, out recordList,out currentDBVersion);
497 if ((int)ContactsError.None != error)
499 Log.Error(Globals.LogTag, "GetChangesByVersion Failed with error " + error);
500 throw ContactsErrorFactory.CheckAndCreateException(error);
502 return new ContactsList(recordList);
506 /// Finds records based on a given keyword.
509 /// This API works only for the Views below.
510 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
512 /// <param name="viewUri">The view URI to find records</param>
513 /// <param name="keyword">The keyword</param>
514 /// <param name="offset">The index from which to get results</param>
515 /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
516 /// <returns>The record list</returns>
517 /// <privilege>http://tizen.org/privilege/contact.read</privilege>
518 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
519 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
520 public ContactsList Search(string viewUri, string keyword, int offset, int limit)
523 int error = Interop.Database.Search(viewUri, keyword, offset, limit, out recordList);
524 if ((int)ContactsError.None != error)
526 Log.Error(Globals.LogTag, "Search Failed with error " + error);
527 throw ContactsErrorFactory.CheckAndCreateException(error);
529 return new ContactsList(recordList);
533 /// Finds records based on given query and keyword.
536 /// This API works only for the Views below.
537 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
539 /// <param name="query">The query to filter</param>
540 /// <param name="keyword">The keyword</param>
541 /// <param name="offset">The index from which to get results</param>
542 /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
543 /// <returns>The record list</returns>
544 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
545 public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit)
548 int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, out recordList);
549 if ((int)ContactsError.None != error)
551 Log.Error(Globals.LogTag, "Search Failed with error " + error);
552 throw ContactsErrorFactory.CheckAndCreateException(error);
554 return new ContactsList(recordList);
558 /// Finds records based on a keyword and range.
561 /// This API works only for the Views below.
562 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
564 /// <param name="viewUri">The view URI</param>
565 /// <param name="keyword">The keyword</param>
566 /// <param name="offset">The index from which to get results</param>
567 /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
568 /// <param name="range">The search range, it should be a element of SearchRange or bitwise OR operation of them</param>
569 /// <returns>The record list</returns>
570 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
571 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
572 public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range)
575 int error = Interop.Database.Search(viewUri, keyword, offset, limit, range, out recordList);
576 if ((int)ContactsError.None != error)
578 Log.Error(Globals.LogTag, "Search Failed with error " + error);
579 throw ContactsErrorFactory.CheckAndCreateException(error);
581 return new ContactsList(recordList);
585 /// Finds records based on a given keyword for snippet
588 /// This API works only for the Views below.
589 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
590 /// 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).
592 /// <param name="viewUri">The view URI to find records</param>
593 /// <param name="keyword">The keyword</param>
594 /// <param name="offset">The index from which to get results</param>
595 /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
596 /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
597 /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
598 /// <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>
599 /// <returns>The record list</returns>
600 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
601 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
602 public ContactsList Search(string viewUri, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
605 int error = Interop.Database.Search(viewUri, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
606 if ((int)ContactsError.None != error)
608 Log.Error(Globals.LogTag, "Search Failed with error " + error);
609 throw ContactsErrorFactory.CheckAndCreateException(error);
611 return new ContactsList(recordList);
615 /// Finds records based on given query and keyword for snippet.
618 /// This API works only for the Views below.
619 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned and PersonGroupNotAssigned.
620 /// 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).
622 /// <param name="query">The query to filter</param>
623 /// <param name="keyword">The keyword</param>
624 /// <param name="offset">The index from which to get results</param>
625 /// <param name="limit">The number to limit results(value 0 used for get all records)</param>
626 /// <param name="startMatch">The text which is inserted into the fragment before the keyword(If NULL, default is "[")</param>
627 /// <param name="endMatch">The text which is inserted into the fragment after the keyword(If NULL, default is "]")</param>
628 /// <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>
629 /// <returns>The record list</returns>
630 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
631 public ContactsList Search(ContactsQuery query, string keyword, int offset, int limit, string startMatch, string endMatch, int tokenNumber)
634 int error = Interop.Database.Search(query._queryHandle, keyword, offset, limit, startMatch, endMatch, tokenNumber, out recordList);
635 if ((int)ContactsError.None != error)
637 Log.Error(Globals.LogTag, "Search Failed with error " + error);
638 throw ContactsErrorFactory.CheckAndCreateException(error);
640 return new ContactsList(recordList);
644 /// Finds records based on a keyword and range for snippet.
647 /// This API works only for the Views below.
648 /// Person, PersonContact, PersonGroupRelation, PersonGroupAssigned, PersonGroupNotAssigned, PersonNumber and PersonEmail
649 /// 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).
651 /// <param name="viewUri">The view URI</param>
652 /// <param name="keyword">The keyword</param>
653 /// <param name="offset">The index from which to get results</param>
654 /// <param name="limit">The number to limit results(value 0 is used for get all records)</param>
655 /// <param name="range">The search range, it should be a element of SearchRange or bitwise OR operation of them</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 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
661 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
662 public ContactsList Search(string viewUri, string keyword, int offset, int limit, int range, string startMatch, string endMatch, int tokenNumber)
665 int error = Interop.Database.Search(viewUri, keyword, offset, limit, range, startMatch, endMatch, tokenNumber, out recordList);
666 if ((int)ContactsError.None != error)
668 Log.Error(Globals.LogTag, "Search Failed with error " + error);
669 throw ContactsErrorFactory.CheckAndCreateException(error);
671 return new ContactsList(recordList);
675 /// Gets the number of records in a specific view
677 /// <param name="viewUri">The view URI</param>
678 /// <returns>The count of records</returns>
679 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
680 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
681 public int GetCount(string viewUri)
684 int error = Interop.Database.GetCount(viewUri, out count);
685 if ((int)ContactsError.None != error)
687 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
688 throw ContactsErrorFactory.CheckAndCreateException(error);
694 /// Gets the number of records matching a query.
696 /// <param name="query">The query used for filtering the results</param>
697 /// <returns>The count of records</returns>
698 [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
699 public int GetCount(ContactsQuery query)
702 int error = Interop.Database.GetCount(query._queryHandle, out count);
703 if ((int)ContactsError.None != error)
705 Log.Error(Globals.LogTag, "GetCount Failed with error " + error);
706 throw ContactsErrorFactory.CheckAndCreateException(error);
712 /// Registers a EventHandler to be invoked when a record changes.
714 /// <param name="viewUri">The view URI of records whose changes are monitored</param>
715 /// <param name="DBChanged">The EventHandler to register</param>
716 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
717 public void AddDBChangedEventHandler(string viewUri, EventHandler<DBChangedEventArgs> DBChanged)
719 if (!_callbackMap.ContainsKey(viewUri))
721 _callbackMap[viewUri] = (string uri, IntPtr userData) =>
723 DBChangedEventArgs args = new DBChangedEventArgs(uri);
724 _eventHandlerMap[uri]?.Invoke(this, args);
727 int error = Interop.Database.AddChangedCb(viewUri, _callbackMap[viewUri], IntPtr.Zero);
728 if ((int)ContactsError.None != error)
730 Log.Error(Globals.LogTag, "AddDBChangedEventHandler Failed with error " + error);
731 throw ContactsErrorFactory.CheckAndCreateException(error);
735 EventHandler<DBChangedEventArgs> handler = null;
736 if (!_eventHandlerMap.TryGetValue(viewUri, out handler))
737 _eventHandlerMap.Add(viewUri, null);
739 _eventHandlerMap[viewUri] = handler + DBChanged;
743 /// Deregisters a EventHandler.
745 /// <param name="viewUri">The view URI of records whose changes are monitored</param>
746 /// <param name="DBChanged">The EventHandler to deregister</param>
747 [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
748 public void RemoveDBChangedEventHandler(string viewUri, EventHandler<DBChangedEventArgs> DBChanged)
750 EventHandler<DBChangedEventArgs> handler = null;
751 if (!_eventHandlerMap.TryGetValue(viewUri, out handler))
752 _eventHandlerMap.Add(viewUri, null);
754 _eventHandlerMap[viewUri] = handler - DBChanged;
756 if (_eventHandlerMap[viewUri] == null)
758 int error = Interop.Database.RemoveChangedCb(viewUri, _callbackMap[viewUri], IntPtr.Zero);
759 if ((int)ContactsError.None != error)
761 Log.Error(Globals.LogTag, "RemoveDBChangedEventHandler Failed with error " + error);
762 throw ContactsErrorFactory.CheckAndCreateException(error);
764 _callbackMap.Remove(viewUri);