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