Release 4.0.0-preview1-00051
[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.Collections.Generic;
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     public class ContactsRecord : IDisposable
32     {
33         private string _uri = null;
34         private uint _id;
35         private Int64 _memoryPressure = ContactsViews.AverageSizeOfRecord;
36         internal IntPtr _recordHandle;
37
38         internal ContactsRecord(IntPtr handle)
39         {
40             _recordHandle = handle;
41             IntPtr viewUri;
42             int error = Interop.Record.GetUriP(handle, out viewUri);
43             if ((int)ContactsError.None != error)
44             {
45                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
46                 throw ContactsErrorFactory.CheckAndCreateException(error);
47             }
48             GC.AddMemoryPressure(_memoryPressure);
49             _uri = Marshal.PtrToStringAnsi(viewUri);
50         }
51
52         internal ContactsRecord(IntPtr handle, bool disposedValue)
53         {
54             _recordHandle = handle;
55             _disposedValue = disposedValue;
56             IntPtr viewUri;
57             int error = Interop.Record.GetUriP(handle, out viewUri);
58             if ((int)ContactsError.None != error)
59             {
60                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
61                 throw ContactsErrorFactory.CheckAndCreateException(error);
62             }
63
64             if (!_disposedValue)
65                 GC.AddMemoryPressure(_memoryPressure);
66             _uri = Marshal.PtrToStringAnsi(viewUri);
67         }
68
69         internal ContactsRecord(IntPtr handle, int id)
70         {
71             _recordHandle = handle;
72             _id = (uint)id;
73             IntPtr viewUri;
74             int error = Interop.Record.GetUriP(handle, out viewUri);
75             if ((int)ContactsError.None != error)
76             {
77                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
78                 throw ContactsErrorFactory.CheckAndCreateException(error);
79             }
80             _uri = Marshal.PtrToStringAnsi(viewUri);
81             GC.AddMemoryPressure(_memoryPressure);
82         }
83
84         /// <summary>
85         /// Creates a record.
86         /// </summary>
87         /// <param name="viewUri">The view URI</param>
88         /// <exception cref="NotSupportedException">Thrown when an invoked method is not supported</exception>
89         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
90         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
91         public ContactsRecord(string viewUri)
92         {
93             int error = Interop.Record.Create(viewUri, out _recordHandle);
94             if ((int)ContactsError.None != error)
95             {
96                 Log.Error(Globals.LogTag, "ContactsRecord Failed with error " + error);
97                 throw ContactsErrorFactory.CheckAndCreateException(error);
98             }
99             _uri = viewUri;
100             GC.AddMemoryPressure(_memoryPressure);
101         }
102
103         ~ContactsRecord()
104         {
105             Dispose(false);
106         }
107
108         /// <summary>
109         /// The URI of the record
110         /// </summary>
111         public string Uri
112         {
113             get
114             {
115                 return _uri;
116             }
117         }
118
119         #region IDisposable Support
120         internal bool _disposedValue = false; // To detect redundant calls
121
122         protected virtual void Dispose(bool disposing)
123         {
124             if (!_disposedValue)
125             {
126                 int error = Interop.Record.Destroy(_recordHandle, true);
127                 if ((int)ContactsError.None != error)
128                 {
129                     Log.Error(Globals.LogTag, "Dispose Failed with error " + error);
130                 }
131                 _disposedValue = true;
132                 GC.RemoveMemoryPressure(_memoryPressure);
133             }
134         }
135
136         /// <summary>
137         /// Releases all resources used by the ContactsRecord.
138         /// It should be called after finished using of the object.
139         /// </summary>
140         public void Dispose()
141         {
142             Dispose(true);
143         }
144         #endregion
145
146         /// <summary>
147         /// Makes a clone of a record.
148         /// </summary>
149         /// <returns>A cloned record</returns>
150         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory</exception>
151         public ContactsRecord Clone()
152         {
153             IntPtr _clonedRecordHandle;
154             int error = Interop.Record.Clone(_recordHandle, out _clonedRecordHandle);
155             if ((int)ContactsError.None != error)
156             {
157                 Log.Error(Globals.LogTag, "Clone Failed with error " + error);
158                 throw ContactsErrorFactory.CheckAndCreateException(error);
159             }
160             return new ContactsRecord(_clonedRecordHandle, (int)_id);
161         }
162
163         /// <summary>
164         /// Gets a value of the property from a record.
165         /// </summary>
166         /// <param name="propertyId">The property ID</param>
167         /// <returns>
168         /// The value of the property corresponding to property id.
169         /// </returns>
170         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
171         public T Get<T>(uint propertyId)
172         {
173             object parsedValue = null;
174             if (typeof(T) == typeof(string))
175             {
176                 string val;
177                 int error = Interop.Record.GetStr(_recordHandle, propertyId, out val);
178                 if ((int)ContactsError.None != error)
179                 {
180                     Log.Error(Globals.LogTag, "Get String Failed with error " + error);
181                     throw ContactsErrorFactory.CheckAndCreateException(error);
182                 }
183                 parsedValue = Convert.ChangeType(val, typeof(T));
184             }
185             else if (typeof(T) == typeof(int))
186             {
187                 int val;
188                 int error = Interop.Record.GetInt(_recordHandle, propertyId, out val);
189                 if ((int)ContactsError.None != error)
190                 {
191                     Log.Error(Globals.LogTag, "Get Int Failed with error " + error);
192                     throw ContactsErrorFactory.CheckAndCreateException(error);
193                 }
194                 parsedValue = Convert.ChangeType(val, typeof(T));
195             }
196             else if (typeof(T) == typeof(bool))
197             {
198                 bool val;
199                 int error = Interop.Record.GetBool(_recordHandle, propertyId, out val);
200                 if ((int)ContactsError.None != error)
201                 {
202                     Log.Error(Globals.LogTag, "Get Bool Failed with error " + error);
203                     throw ContactsErrorFactory.CheckAndCreateException(error);
204                 }
205                 parsedValue = Convert.ChangeType(val, typeof(T));
206             }
207             else if (typeof(T) == typeof(long))
208             {
209                 long val;
210                 int error = Interop.Record.GetLli(_recordHandle, propertyId, out val);
211                 if ((int)ContactsError.None != error)
212                 {
213                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
214                     throw ContactsErrorFactory.CheckAndCreateException(error);
215                 }
216                 parsedValue = Convert.ChangeType(val, typeof(T));
217             }
218             else if (typeof(T) == typeof(double))
219             {
220                 double val;
221                 int error = Interop.Record.GetDouble(_recordHandle, propertyId, out val);
222                 if ((int)ContactsError.None != error)
223                 {
224                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
225                     throw ContactsErrorFactory.CheckAndCreateException(error);
226                 }
227                 parsedValue = Convert.ChangeType(val, typeof(T));
228             }
229             else
230             {
231                 Log.Error(Globals.LogTag, "Not Supported Data Type");
232                 throw ContactsErrorFactory.CheckAndCreateException((int)ContactsError.NotSupported);
233             }
234             return (T)parsedValue;
235         }
236
237         /// <summary>
238         /// Sets a value of the property to a record.
239         /// </summary>
240         /// <param name="propertyId">The property ID</param>
241         /// <param name="value">The value to set</param>
242         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
243         public void Set<T>(uint propertyId, T value)
244         {
245             if (typeof(T) == typeof(string))
246             {
247                 string val = Convert.ToString(value);
248                 int error = Interop.Record.SetStr(_recordHandle, propertyId, val);
249                 if ((int)ContactsError.None != error)
250                 {
251                     Log.Error(Globals.LogTag, "Set String Failed with error " + error);
252                     throw ContactsErrorFactory.CheckAndCreateException(error);
253                 }
254             }
255             else if (typeof(T) == typeof(int))
256             {
257                 int val = Convert.ToInt32(value);
258                 int error = Interop.Record.SetInt(_recordHandle, propertyId, val);
259                 if ((int)ContactsError.None != error)
260                 {
261                     Log.Error(Globals.LogTag, "Set Int Failed with error " + error);
262                     throw ContactsErrorFactory.CheckAndCreateException(error);
263                 }
264             }
265             else if (typeof(T) == typeof(bool))
266             {
267                 bool val = Convert.ToBoolean(value);
268                 int error = Interop.Record.SetBool(_recordHandle, propertyId, val);
269                 if ((int)ContactsError.None != error)
270                 {
271                     Log.Error(Globals.LogTag, "Set Bool Failed with error " + error);
272                     throw ContactsErrorFactory.CheckAndCreateException(error);
273                 }
274             }
275             else if (typeof(T) == typeof(long))
276             {
277                 long val = Convert.ToInt64(value);
278                 int error = Interop.Record.SetLli(_recordHandle, propertyId, val);
279                 if ((int)ContactsError.None != error)
280                 {
281                     Log.Error(Globals.LogTag, "Set Long Failed with error " + error);
282                     throw ContactsErrorFactory.CheckAndCreateException(error);
283                 }
284             }
285             else if (typeof(T) == typeof(double))
286             {
287                 double val = Convert.ToDouble(value);
288                 int error = Interop.Record.SetDouble(_recordHandle, propertyId, val);
289                 if ((int)ContactsError.None != error)
290                 {
291                     Log.Error(Globals.LogTag, "Get Long Failed with error " + error);
292                     throw ContactsErrorFactory.CheckAndCreateException(error);
293                 }
294             }
295             else
296             {
297                 Log.Error(Globals.LogTag, "Not Supported Data Type");
298                 throw ContactsErrorFactory.CheckAndCreateException((int)ContactsError.NotSupported);
299             }
300         }
301
302         /// <summary>
303         /// Adds a child record to the parent record.
304         /// </summary>
305         /// <param name="propertyId">The property ID</param>
306         /// <param name="childRecord">The child record to add to parent record</param>
307         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
308         public void AddChildRecord(uint propertyId, ContactsRecord childRecord)
309         {
310             int error = Interop.Record.AddChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
311             if ((int)ContactsError.None != error)
312             {
313                 Log.Error(Globals.LogTag, "AddChildRecord Failed with error " + error);
314                 throw ContactsErrorFactory.CheckAndCreateException(error);
315             }
316             childRecord._disposedValue = true;
317         }
318
319         /// <summary>
320         /// Removes a child record from the parent record.
321         /// </summary>
322         /// <param name="propertyId">The property ID</param>
323         /// <param name="childRecord">The child record to remove from parent record</param>
324         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
325         public void RemoveChildRecord(uint propertyId, ContactsRecord childRecord)
326         {
327             int error = Interop.Record.RemoveChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
328             if ((int)ContactsError.None != error)
329             {
330                 Log.Error(Globals.LogTag, "RemoveChildRecord Failed with error " + error);
331                 throw ContactsErrorFactory.CheckAndCreateException(error);
332             }
333             childRecord._disposedValue = false;
334         }
335
336         /// <summary>
337         /// Gets the number of child records of a parent record.
338         /// </summary>
339         /// <param name="propertyId">The property ID</param>
340         /// <returns>The number of child records corresponding to property ID</returns>
341         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
342         public int GetChildRecordCount(uint propertyId)
343         {
344             int count = 0;
345             int error = Interop.Record.GetChildRecordCount(_recordHandle, propertyId, out count);
346             if ((int)ContactsError.None != error)
347             {
348                 Log.Error(Globals.LogTag, "GetChildRecordCount Failed with error " + error);
349                 throw ContactsErrorFactory.CheckAndCreateException(error);
350             }
351             return count;
352         }
353
354         /// <summary>
355         /// Gets a child record from the parent record
356         /// </summary>
357         /// <param name="propertyId">The property ID</param>
358         /// <param name="index">The index of child record</param>
359         /// <returns>The record </returns>
360         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
361         public ContactsRecord GetChildRecord(uint propertyId, int index)
362         {
363             IntPtr handle;
364
365             int error = Interop.Record.GetChildRecordAtP(_recordHandle, propertyId, index, out handle);
366             if ((int)ContactsError.None != error)
367             {
368                 Log.Error(Globals.LogTag, "GetChildRecord Failed with error " + error);
369                 throw ContactsErrorFactory.CheckAndCreateException(error);
370             }
371             return new ContactsRecord(handle, true);
372         }
373
374         /// <summary>
375         /// Clones a child record list corresponding to property ID
376         /// </summary>
377         /// <param name="propertyId">The property ID</param>
378         /// <returns>
379         /// The record list
380         /// </returns>
381         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
382         public ContactsList CloneChildRecordList(uint propertyId)
383         {
384             IntPtr listHandle;
385
386             int error = Interop.Record.CloneChildRecordList(_recordHandle, propertyId, out listHandle);
387             if ((int)ContactsError.None != error)
388             {
389                 Log.Error(Globals.LogTag, "CloneChildRecordList Failed with error " + error);
390                 throw ContactsErrorFactory.CheckAndCreateException(error);
391             }
392             ContactsList list = new ContactsList(listHandle);
393             return list;
394         }
395     }
396 }