42d7da597ee78967d4267e0d5033e10e31bb6050
[platform/core/csapi/tizenfx.git] / src / Tizen.Pims.Contacts / Tizen.Pims.Contacts / ContactsRecord.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.Diagnostics.CodeAnalysis;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Pims.Contacts
22 {
23     /// <summary>
24     /// A record represents an actual record in the database.
25     /// </summary>
26     /// <remarks>
27     /// A record represents an actual record in the database, but you can also consider it a piece of information, such as an address, a phone number, or a group of contacts. 
28     /// A record can be a complex set of data, containing other data. For example, a contact record contains the address property, which is a reference to an address record. 
29     /// An address record belongs to a contact record, and its ContactId property is set to the identifier of the corresponding contact. In this case, the address is the child record of the contact and the contact is the parent record.
30     /// </remarks>
31     /// <since_tizen> 4 </since_tizen>
32     public class ContactsRecord : IDisposable
33     {
34         private string _uri = null;
35         private uint _id;
36         private Int64 _memoryPressure = ContactsViews.Record.AverageSize;
37         internal IntPtr _recordHandle;
38
39         internal ContactsRecord(IntPtr handle)
40         {
41             _recordHandle = handle;
42             IntPtr viewUri;
43             int error = Interop.Record.GetUriP(handle, out viewUri);
44             if ((int)ContactsError.None != error)
45             {
46                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
47                 throw ContactsErrorFactory.CheckAndCreateException(error);
48             }
49             GC.AddMemoryPressure(_memoryPressure);
50             _uri = Marshal.PtrToStringAnsi(viewUri);
51         }
52
53         internal ContactsRecord(IntPtr handle, bool disposedValue)
54         {
55             _recordHandle = handle;
56             _disposedValue = disposedValue;
57             IntPtr viewUri;
58             int error = Interop.Record.GetUriP(handle, out viewUri);
59             if ((int)ContactsError.None != error)
60             {
61                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
62                 throw ContactsErrorFactory.CheckAndCreateException(error);
63             }
64
65             if (!_disposedValue)
66                 GC.AddMemoryPressure(_memoryPressure);
67             _uri = Marshal.PtrToStringAnsi(viewUri);
68         }
69
70         internal ContactsRecord(IntPtr handle, int id)
71         {
72             _recordHandle = handle;
73             _id = (uint)id;
74             IntPtr viewUri;
75             int error = Interop.Record.GetUriP(handle, out viewUri);
76             if ((int)ContactsError.None != error)
77             {
78                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
79                 throw ContactsErrorFactory.CheckAndCreateException(error);
80             }
81             _uri = Marshal.PtrToStringAnsi(viewUri);
82             GC.AddMemoryPressure(_memoryPressure);
83         }
84
85         /// <summary>
86         /// Creates a record.
87         /// </summary>
88         /// <param name="viewUri">The view URI.</param>
89         /// <feature>http://tizen.org/feature/contact</feature>
90         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
91         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
92         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory.</exception>
93         /// <since_tizen> 4 </since_tizen>
94         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings")]
95         public ContactsRecord(string viewUri)
96         {
97             int error = Interop.Record.Create(viewUri, out _recordHandle);
98             if ((int)ContactsError.None != error)
99             {
100                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
101                 throw ContactsErrorFactory.CheckAndCreateException(error);
102             }
103             _uri = viewUri;
104             GC.AddMemoryPressure(_memoryPressure);
105         }
106
107         /// <summary>
108         /// The destructor.
109         /// </summary>
110         /// <since_tizen> 4 </since_tizen>
111         ~ContactsRecord()
112         {
113             Dispose(false);
114         }
115
116         /// <summary>
117         /// The URI of the record.
118         /// </summary>
119         /// <value>The URI of the record.</value>
120         /// <since_tizen> 4 </since_tizen>
121         [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
122         public string Uri
123         {
124             get
125             {
126                 return _uri;
127             }
128         }
129
130         #region IDisposable Support
131         internal bool _disposedValue = false; // To detect redundant calls
132
133         /// <summary>
134         /// Releases all the resources used by the ContactsRecord.
135         /// </summary>
136         /// <param name="disposing">Disposing by the user.</param>
137         /// <since_tizen> 4 </since_tizen>
138         protected virtual void Dispose(bool disposing)
139         {
140             if (disposing)
141             {
142                 //Called by User
143                 //Release your own managed resources here.
144                 //You should release all of your own disposable objects here
145             }
146
147             if (!_disposedValue)
148             {
149                 int error = Interop.Record.Destroy(_recordHandle, true);
150                 if ((int)ContactsError.None != error)
151                 {
152                     Log.Error(Globals.LogTag, "Dispose Failed with error " + error);
153                 }
154                 _disposedValue = true;
155                 GC.RemoveMemoryPressure(_memoryPressure);
156             }
157         }
158
159         /// <summary>
160         /// Releases all the resources used by the ContactsRecord.
161         /// It should be called after it has finished using the object.
162         /// </summary>
163         /// <since_tizen> 4 </since_tizen>
164         public void Dispose()
165         {
166             Dispose(true);
167             GC.SuppressFinalize(this);
168         }
169         #endregion
170
171         /// <summary>
172         /// Makes a clone of a record.
173         /// </summary>
174         /// <returns>A cloned record.</returns>
175         /// <feature>http://tizen.org/feature/contact</feature>
176         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
177         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory.</exception>
178         /// <since_tizen> 4 </since_tizen>
179         public ContactsRecord Clone()
180         {
181             IntPtr _clonedRecordHandle;
182             int error = Interop.Record.Clone(_recordHandle, out _clonedRecordHandle);
183             if ((int)ContactsError.None != error)
184             {
185                 Log.Error(Globals.LogTag, "Clone Failed with error " + error);
186                 throw ContactsErrorFactory.CheckAndCreateException(error);
187             }
188             return new ContactsRecord(_clonedRecordHandle, (int)_id);
189         }
190
191         /// <summary>
192         /// Gets a value of the property from a record.
193         /// </summary>
194         /// <param name="propertyId">The property ID.</param>
195         /// <returns>
196         /// The value of the property corresponding to a property ID.
197         /// </returns>
198         /// <feature>http://tizen.org/feature/contact</feature>
199         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
200         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
201         /// <since_tizen> 4 </since_tizen>
202         public T Get<T>(uint propertyId)
203         {
204             object parsedValue = null;
205             if (typeof(T) == typeof(string))
206             {
207                 string val;
208                 int error = Interop.Record.GetStr(_recordHandle, propertyId, out val);
209                 if ((int)ContactsError.None != error)
210                 {
211                     Log.Error(Globals.LogTag, "Get String Failed with error " + error);
212                     throw ContactsErrorFactory.CheckAndCreateException(error);
213                 }
214                 parsedValue = Convert.ChangeType(val, typeof(T));
215             }
216             else if (typeof(T) == typeof(int))
217             {
218                 int val;
219                 int error = Interop.Record.GetInt(_recordHandle, propertyId, out val);
220                 if ((int)ContactsError.None != error)
221                 {
222                     Log.Error(Globals.LogTag, "Get Int Failed with error " + error);
223                     throw ContactsErrorFactory.CheckAndCreateException(error);
224                 }
225                 parsedValue = Convert.ChangeType(val, typeof(T));
226             }
227             else if (typeof(T) == typeof(bool))
228             {
229                 bool val;
230                 int error = Interop.Record.GetBool(_recordHandle, propertyId, out val);
231                 if ((int)ContactsError.None != error)
232                 {
233                     Log.Error(Globals.LogTag, "Get Bool Failed with error " + error);
234                     throw ContactsErrorFactory.CheckAndCreateException(error);
235                 }
236                 parsedValue = Convert.ChangeType(val, typeof(T));
237             }
238             else if (typeof(T) == typeof(long))
239             {
240                 long val;
241                 int error = Interop.Record.GetLli(_recordHandle, propertyId, out val);
242                 if ((int)ContactsError.None != error)
243                 {
244                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
245                     throw ContactsErrorFactory.CheckAndCreateException(error);
246                 }
247                 parsedValue = Convert.ChangeType(val, typeof(T));
248             }
249             else if (typeof(T) == typeof(double))
250             {
251                 double val;
252                 int error = Interop.Record.GetDouble(_recordHandle, propertyId, out val);
253                 if ((int)ContactsError.None != error)
254                 {
255                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
256                     throw ContactsErrorFactory.CheckAndCreateException(error);
257                 }
258                 parsedValue = Convert.ChangeType(val, typeof(T));
259             }
260             else
261             {
262                 Log.Error(Globals.LogTag, "Not Supported Data Type");
263                 throw ContactsErrorFactory.CheckAndCreateException((int)ContactsError.NotSupported);
264             }
265             return (T)parsedValue;
266         }
267
268         /// <summary>
269         /// Sets a value of the property to a record.
270         /// </summary>
271         /// <feature>http://tizen.org/feature/contact</feature>
272         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
273         /// <param name="propertyId">The property ID.</param>
274         /// <param name="value">The value to set.</param>
275         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
276         /// <since_tizen> 4 </since_tizen>
277         public void Set<T>(uint propertyId, T value)
278         {
279             if (typeof(T) == typeof(string))
280             {
281                 string val = Convert.ToString(value);
282                 int error = Interop.Record.SetStr(_recordHandle, propertyId, val);
283                 if ((int)ContactsError.None != error)
284                 {
285                     Log.Error(Globals.LogTag, "Set String Failed with error " + error);
286                     throw ContactsErrorFactory.CheckAndCreateException(error);
287                 }
288             }
289             else if (typeof(T) == typeof(int))
290             {
291                 int val = Convert.ToInt32(value);
292                 int error = Interop.Record.SetInt(_recordHandle, propertyId, val);
293                 if ((int)ContactsError.None != error)
294                 {
295                     Log.Error(Globals.LogTag, "Set Int Failed with error " + error);
296                     throw ContactsErrorFactory.CheckAndCreateException(error);
297                 }
298             }
299             else if (typeof(T) == typeof(bool))
300             {
301                 bool val = Convert.ToBoolean(value);
302                 int error = Interop.Record.SetBool(_recordHandle, propertyId, val);
303                 if ((int)ContactsError.None != error)
304                 {
305                     Log.Error(Globals.LogTag, "Set Bool Failed with error " + error);
306                     throw ContactsErrorFactory.CheckAndCreateException(error);
307                 }
308             }
309             else if (typeof(T) == typeof(long))
310             {
311                 long val = Convert.ToInt64(value);
312                 int error = Interop.Record.SetLli(_recordHandle, propertyId, val);
313                 if ((int)ContactsError.None != error)
314                 {
315                     Log.Error(Globals.LogTag, "Set Long Failed with error " + error);
316                     throw ContactsErrorFactory.CheckAndCreateException(error);
317                 }
318             }
319             else if (typeof(T) == typeof(double))
320             {
321                 double val = Convert.ToDouble(value);
322                 int error = Interop.Record.SetDouble(_recordHandle, propertyId, val);
323                 if ((int)ContactsError.None != error)
324                 {
325                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
326                     throw ContactsErrorFactory.CheckAndCreateException(error);
327                 }
328             }
329             else
330             {
331                 Log.Error(Globals.LogTag, "Not Supported Data Type");
332                 throw ContactsErrorFactory.CheckAndCreateException((int)ContactsError.NotSupported);
333             }
334         }
335
336         /// <summary>
337         /// Adds a child record to the parent record.
338         /// </summary>
339         /// <param name="propertyId">The property ID.</param>
340         /// <param name="childRecord">The child record to add to the parent record<./param>
341         /// <feature>http://tizen.org/feature/contact</feature>
342         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
343         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
344         /// <since_tizen> 4 </since_tizen>
345         public void AddChildRecord(uint propertyId, ContactsRecord childRecord)
346         {
347             int error = Interop.Record.AddChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
348             if ((int)ContactsError.None != error)
349             {
350                 Log.Error(Globals.LogTag, "AddChildRecord Failed with error " + error);
351                 throw ContactsErrorFactory.CheckAndCreateException(error);
352             }
353             childRecord._disposedValue = true;
354         }
355
356         /// <summary>
357         /// Removes a child record from the parent record.
358         /// </summary>
359         /// <param name="propertyId">The property ID.</param>
360         /// <param name="childRecord">The child record to remove from the parent record.</param>
361         /// <feature>http://tizen.org/feature/contact</feature>
362         /// <exception cref="NotSupportedException">Thrown when feature is not supported.</exception>
363         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
364         /// <since_tizen> 4 </since_tizen>
365         public void RemoveChildRecord(uint propertyId, ContactsRecord childRecord)
366         {
367             int error = Interop.Record.RemoveChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
368             if ((int)ContactsError.None != error)
369             {
370                 Log.Error(Globals.LogTag, "RemoveChildRecord Failed with error " + error);
371                 throw ContactsErrorFactory.CheckAndCreateException(error);
372             }
373             childRecord._disposedValue = false;
374         }
375
376         /// <summary>
377         /// Gets the number of child records of a parent record.
378         /// </summary>
379         /// <param name="propertyId">The property ID.</param>
380         /// <returns>The number of child records corresponding to the property ID.</returns>
381         /// <feature>http://tizen.org/feature/contact</feature>
382         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
383         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
384         /// <since_tizen> 4 </since_tizen>
385         public int GetChildRecordCount(uint propertyId)
386         {
387             int count = 0;
388             int error = Interop.Record.GetChildRecordCount(_recordHandle, propertyId, out count);
389             if ((int)ContactsError.None != error)
390             {
391                 Log.Error(Globals.LogTag, "GetChildRecordCount Failed with error " + error);
392                 throw ContactsErrorFactory.CheckAndCreateException(error);
393             }
394             return count;
395         }
396
397         /// <summary>
398         /// Gets a child record from the parent record.
399         /// </summary>
400         /// <param name="propertyId">The property ID.</param>
401         /// <param name="index">The index of the child record.</param>
402         /// <returns>The record </returns>
403         /// <feature>http://tizen.org/feature/contact</feature>
404         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
405         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
406         /// <since_tizen> 4 </since_tizen>
407         public ContactsRecord GetChildRecord(uint propertyId, int index)
408         {
409             IntPtr handle;
410
411             int error = Interop.Record.GetChildRecordAtP(_recordHandle, propertyId, index, out handle);
412             if ((int)ContactsError.None != error)
413             {
414                 Log.Error(Globals.LogTag, "GetChildRecord Failed with error " + error);
415                 throw ContactsErrorFactory.CheckAndCreateException(error);
416             }
417             return new ContactsRecord(handle, true);
418         }
419
420         /// <summary>
421         /// Clones a child record list corresponding to the property ID.
422         /// </summary>
423         /// <param name="propertyId">The property ID.</param>
424         /// <returns>
425         /// The record list.
426         /// </returns>
427         /// <feature>http://tizen.org/feature/contact</feature>
428         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
429         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
430         /// <since_tizen> 4 </since_tizen>
431         public ContactsList CloneChildRecordList(uint propertyId)
432         {
433             IntPtr listHandle;
434
435             int error = Interop.Record.CloneChildRecordList(_recordHandle, propertyId, out listHandle);
436             if ((int)ContactsError.None != error)
437             {
438                 Log.Error(Globals.LogTag, "CloneChildRecordList Failed with error " + error);
439                 throw ContactsErrorFactory.CheckAndCreateException(error);
440             }
441             ContactsList list = new ContactsList(listHandle);
442             return list;
443         }
444     }
445 }