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