[NUI] Sync dalihub/TizenFX and Samsung/TizenFX (#530)
[platform/core/csapi/tizenfx.git] / src / Tizen.Pims.Calendar / Tizen.Pims.Calendar / CalendarRecord.cs
1 /*
2  * Copyright (c) 2018 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 IntPtr ConvertCalendarTimeToStruct(CalendarTime value)
160         {
161             Console.WriteLine("convert calendar");
162             IntPtr caltime = Interop.Record.CreateCalTime();
163             Interop.Record.SetCalTimeType(caltime, value._type);
164
165             if ((int)CalendarTime.Type.Utc == value._type)
166             {
167                 DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
168                 Interop.Record.SetCalTimeUtime(caltime, (value.UtcTime.Ticks - epoch.Ticks) / 10_000_000);
169                 //Log.Debug(Globals.LogTag, "Sameer local time is if:" + Interop.Record.GetCalTimeLocalMonth(caltime) + "," + Interop.Record.GetCalTimeLocalMday(caltime) + "," + Interop.Record.GetCalTimeLocalHour(caltime) + "," + Interop.Record.GetCalTimeLocalMinute(caltime));
170
171             }
172             else
173             {
174                 Interop.Record.SetCalTimeLocalYear(caltime, value.LocalTime.Year);
175                 Interop.Record.SetCalTimeLocalMonth(caltime, value.LocalTime.Month);
176                 Interop.Record.SetCalTimeLocalMday(caltime, value.LocalTime.Day);
177                 Interop.Record.SetCalTimeLocalHour(caltime, value.LocalTime.Hour);
178                 Interop.Record.SetCalTimeLocalMinute(caltime, value.LocalTime.Minute);
179                 Interop.Record.SetCalTimeLocalSecond(caltime, value.LocalTime.Second);
180                 //Log.Debug(Globals.LogTag, "Sameer local time is:" + Interop.Record.GetCalTimeLocalHour(caltime) + "," + Interop.Record.GetCalTimeLocalMinute(caltime));
181             }
182             return caltime;
183         }
184
185         internal static CalendarTime ConvertIntPtrToCalendarTime(IntPtr caltime)
186         {
187             CalendarTime value;
188             if ((int)CalendarTime.Type.Utc == Interop.Record.GetCalTimeType(caltime))
189             {
190                 DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
191                 value = new CalendarTime(Interop.Record.GetCalTimeUtime(caltime) * 10_000_000 + epoch.Ticks);
192             }
193             else
194             {
195                 value = new CalendarTime(Interop.Record.GetCalTimeLocalYear(caltime), Interop.Record.GetCalTimeLocalMonth(caltime), Interop.Record.GetCalTimeLocalMday(caltime),
196                     Interop.Record.GetCalTimeLocalHour(caltime), Interop.Record.GetCalTimeLocalMinute(caltime), Interop.Record.GetCalTimeLocalSecond(caltime));
197             }
198             value._type = Interop.Record.GetCalTimeType(caltime);
199             return value;
200         }
201
202         /// <summary>
203         /// Makes a clone of a record.
204         /// </summary>
205         /// <since_tizen> 4 </since_tizen>
206         /// <returns>
207         /// A cloned record.
208         /// </returns>
209         /// <feature>http://tizen.org/feature/calendar</feature>
210         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
211         /// <exception cref="OutOfMemoryException">Thrown when failed due to out of memory.</exception>
212         public CalendarRecord Clone()
213         {
214             IntPtr _clonedRecordHandle;
215             int error = Interop.Record.Clone(_recordHandle, out _clonedRecordHandle);
216             if (CalendarError.None != (CalendarError)error)
217             {
218                 Log.Error(Globals.LogTag, "Clone Failed with error " + error);
219                 throw CalendarErrorFactory.GetException(error);
220             }
221             return new CalendarRecord(_clonedRecordHandle, (int)_id);
222         }
223
224         /// <summary>
225         /// Get record URI.
226         /// </summary>
227         /// <since_tizen> 4 </since_tizen>
228         /// <value>The URI of the record</value>
229         [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings")]
230         public string Uri
231         {
232             get
233             {
234                 return _uri;
235             }
236         }
237
238         /// <summary>
239         /// Gets a object from a record.
240         /// </summary>
241         /// <since_tizen> 4 </since_tizen>
242         /// <param name="propertyId">The property ID</param>
243         /// <returns>
244         /// The value of the property corresponding to property id.
245         /// </returns>
246         /// <feature>http://tizen.org/feature/calendar</feature>
247         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
248         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
249         public T Get<T>(uint propertyId)
250         {
251             object parsedValue = null;
252             if (typeof(T) == typeof(string))
253             {
254                 string val;
255                 int error = Interop.Record.GetString(_recordHandle, propertyId, out val);
256                 if (CalendarError.None != (CalendarError)error)
257                 {
258                     Log.Error(Globals.LogTag, "Get String Failed [" + error + "]" + String.Format("{0:X}", propertyId));
259                     throw CalendarErrorFactory.GetException(error);
260                 }
261                 parsedValue = Convert.ChangeType(val, typeof(T));
262             }
263             else if (typeof(T) == typeof(int))
264             {
265                 int val;
266                 int error = Interop.Record.GetInteger(_recordHandle, propertyId, out val);
267                 if (CalendarError.None != (CalendarError)error)
268                 {
269                     Log.Error(Globals.LogTag, "Get Intger Failed [" + error + "]" + String.Format("{0:X}", propertyId));
270                     throw CalendarErrorFactory.GetException(error);
271                 }
272                 parsedValue = Convert.ChangeType(val, typeof(T));
273             }
274             else if (typeof(T) == typeof(long))
275             {
276                 long val;
277                 int error = Interop.Record.GetLli(_recordHandle, propertyId, out val);
278                 if (CalendarError.None != (CalendarError)error)
279                 {
280                     Log.Error(Globals.LogTag, "Get Long Failed [" + error + "]" + String.Format("{0:X}", propertyId));
281                     throw CalendarErrorFactory.GetException(error);
282                 }
283                 parsedValue = Convert.ChangeType(val, typeof(T));
284             }
285             else if (typeof(T) == typeof(double))
286             {
287                 double val;
288                 int error = Interop.Record.GetDouble(_recordHandle, propertyId, out val);
289                 if (CalendarError.None != (CalendarError)error)
290                 {
291                     Log.Error(Globals.LogTag, "Get Double Failed [" + error + "]" + String.Format("{0:X}", propertyId));
292                     throw CalendarErrorFactory.GetException(error);
293                 }
294                 parsedValue = Convert.ChangeType(val, typeof(T));
295             }
296             else if (typeof(T) == typeof(CalendarTime))
297             {
298                 IntPtr time;
299                 int error = Interop.Record.GetCalTime(_recordHandle, propertyId, out time);
300                 if (CalendarError.None != (CalendarError)error)
301                 {
302                     Log.Error(Globals.LogTag, "Get CalendarTime Failed [" + error + "]" + String.Format("{0:X}", propertyId));
303                     throw CalendarErrorFactory.GetException(error);
304                 }
305                 CalendarTime val = ConvertIntPtrToCalendarTime(time);
306                 parsedValue = Convert.ChangeType(val, typeof(T));
307             }
308             else
309             {
310                 Log.Error(Globals.LogTag, "Not supported Data T/ype");
311                 throw CalendarErrorFactory.GetException((int)CalendarError.NotSupported);
312             }
313             return (T)parsedValue;
314         }
315
316         /// <summary>
317         /// Sets a value of the property to a record.
318         /// </summary>
319         /// <since_tizen> 4 </since_tizen>
320         /// <param name="propertyId">The property ID</param>
321         /// <param name="value">value</param>
322         /// <feature>http://tizen.org/feature/calendar</feature>
323         /// <exception cref="NotSupportedException">Thrown when feature is not supported</exception>
324         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid</exception>
325         public void Set<T>(uint propertyId, T value)
326         {
327             if (typeof(T) == typeof(string))
328             {
329                 string val = Convert.ToString(value);
330                 int error = Interop.Record.SetString(_recordHandle, propertyId, val);
331                 if (CalendarError.None != (CalendarError)error)
332                 {
333                     Log.Error(Globals.LogTag, "Set String Failed [" + error + "]" + String.Format("{0:X}", propertyId));
334                     throw CalendarErrorFactory.GetException(error);
335                 }
336             }
337             else if (typeof(T) == typeof(int))
338             {
339                 int val = Convert.ToInt32(value);
340                 int error = Interop.Record.SetInteger(_recordHandle, propertyId, val);
341                 if (CalendarError.None != (CalendarError)error)
342                 {
343                     Log.Error(Globals.LogTag, "Set Integer Failed [" + error + "]" + String.Format("{0:X}", propertyId));
344                     throw CalendarErrorFactory.GetException(error);
345                 }
346             }
347             else if (typeof(T) == typeof(long))
348             {
349                 long val = Convert.ToInt64(value);
350                 int error = Interop.Record.SetLli(_recordHandle, propertyId, val);
351                 if (CalendarError.None != (CalendarError)error)
352                 {
353                     Log.Error(Globals.LogTag, "Set Long Failed [" + error + "]" + String.Format("{0:X}", propertyId));
354                     throw CalendarErrorFactory.GetException(error);
355                 }
356             }
357             else if (typeof(T) == typeof(double))
358             {
359                 double val = Convert.ToDouble(value);
360                 int error = Interop.Record.SetDouble(_recordHandle, propertyId, val);
361                 if (CalendarError.None != (CalendarError)error)
362                 {
363                     Log.Error(Globals.LogTag, "Set Double Failed [" + error + "]" + String.Format("{0:X}", propertyId));
364                     throw CalendarErrorFactory.GetException(error);
365                 }
366             }
367             else if (typeof(T) == typeof(CalendarTime))
368             {
369                 CalendarTime time = (CalendarTime)Convert.ChangeType(value, typeof(CalendarTime));
370                 //Interop.Record.DateTime val = ConvertCalendarTimeToStruct(time);
371                 IntPtr val = ConvertCalendarTimeToStruct(time);
372                 //int error = Interop.Record.SetCalendarTime(_recordHandle, propertyId, val);
373                 int error = Interop.Record.SetCalTime(_recordHandle, propertyId, val);
374                 if (CalendarError.None != (CalendarError)error)
375                 {
376                     Log.Error(Globals.LogTag, "Set CalendarTime Failed [" + error + "]" + String.Format("{0:X}", propertyId));
377                     throw CalendarErrorFactory.GetException(error);
378                 }
379             }
380             else
381             {
382                 Log.Error(Globals.LogTag, "Not supported Data T/ype");
383                 throw CalendarErrorFactory.GetException((int)CalendarError.NotSupported);
384             }
385         }
386
387         /// <summary>
388         /// Adds a child record to the parent record.
389         /// </summary>
390         /// <since_tizen> 4 </since_tizen>
391         /// <param name="propertyId">The property ID.</param>
392         /// <param name="childRecord">The child record.</param>
393         /// <feature>http://tizen.org/feature/calendar</feature>
394         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
395         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
396         public void AddChildRecord(uint propertyId, CalendarRecord childRecord)
397         {
398             int error = Interop.Record.AddChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
399             if (CalendarError.None != (CalendarError)error)
400             {
401                 Log.Error(Globals.LogTag, "AddChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
402                 throw CalendarErrorFactory.GetException(error);
403             }
404             childRecord._disposedValue = true;
405         }
406
407         /// <summary>
408         /// Removes a child record from the parent record.
409         /// </summary>
410         /// <since_tizen> 4 </since_tizen>
411         /// <param name="propertyId">The property ID.</param>
412         /// <param name="childRecord">The child record.</param>
413         /// <feature>http://tizen.org/feature/calendar</feature>
414         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
415         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
416         public void RemoveChildRecord(uint propertyId, CalendarRecord childRecord)
417         {
418             int error = Interop.Record.RemoveChildRecord(_recordHandle, propertyId, childRecord._recordHandle);
419             if (CalendarError.None != (CalendarError)error)
420             {
421                 Log.Error(Globals.LogTag, "RemoveChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
422                 throw CalendarErrorFactory.GetException(error);
423             }
424             childRecord._disposedValue = false;
425         }
426
427         /// <summary>
428         /// Gets a child record from the parent record.
429         /// </summary>
430         /// <since_tizen> 4 </since_tizen>
431         /// <param name="propertyId">The property ID.</param>
432         /// <returns>
433         /// The number of child records corresponding to property ID.
434         /// </returns>
435         /// <feature>http://tizen.org/feature/calendar</feature>
436         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
437         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
438         public int GetChildRecordCount(uint propertyId)
439         {
440             int count = 0;
441             int error = Interop.Record.GetChildRecordCount(_recordHandle, propertyId, out count);
442             if (CalendarError.None != (CalendarError)error)
443             {
444                 Log.Error(Globals.LogTag, "GetChildRecordCount Failed [" + error + "]" + String.Format("{0:X}", propertyId));
445                 throw CalendarErrorFactory.GetException(error);
446             }
447             return count;
448         }
449
450         /// <summary>
451         /// Gets a child record from the parent record.
452         /// </summary>
453         /// <since_tizen> 4 </since_tizen>
454         /// <param name="propertyId">The property ID.</param>
455         /// <param name="index">The child record index.</param>
456         /// <returns>
457         /// The record.
458         /// </returns>
459         /// <feature>http://tizen.org/feature/calendar</feature>
460         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
461         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
462         public CalendarRecord GetChildRecord(uint propertyId, int index)
463         {
464             IntPtr handle;
465
466             int error = Interop.Record.GetChildRecordPointer(_recordHandle, propertyId, index, out handle);
467             if (CalendarError.None != (CalendarError)error)
468             {
469                 Log.Error(Globals.LogTag, "GetChildRecord Failed [" + error + "]" + String.Format("{0:X}", propertyId));
470                 throw CalendarErrorFactory.GetException(error);
471             }
472             return new CalendarRecord(handle, true);
473         }
474
475         /// <summary>
476         /// Clones a child record list corresponding to property ID.
477         /// </summary>
478         /// <since_tizen> 4 </since_tizen>
479         /// <param name="propertyId">The property ID.</param>
480         /// <returns>
481         /// The record list.
482         /// </returns>
483         /// <feature>http://tizen.org/feature/calendar</feature>
484         /// <exception cref="NotSupportedException">Thrown when the feature is not supported.</exception>
485         /// <exception cref="ArgumentException">Thrown when one of the arguments provided to a method is not valid.</exception>
486         public CalendarList CloneChildRecordList(uint propertyId)
487         {
488             IntPtr listHandle;
489             int error = Interop.Record.CloneChildRecordList(_recordHandle, propertyId, out listHandle);
490             if (CalendarError.None != (CalendarError)error)
491             {
492                 Log.Error(Globals.LogTag, "CloneChildRecordList Failed with [" + error + "]" + String.Format("{0:X}", propertyId));
493                 throw CalendarErrorFactory.GetException(error);
494             }
495             CalendarList list = new CalendarList(listHandle);
496             return list;
497         }
498     }
499 }