Release 4.0.0-preview1-00172
[platform/core/csapi/tizenfx.git] / src / Tizen.Content.MediaContent / Tizen.Content.MediaContent / TagCommand.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.Linq;
20
21 namespace Tizen.Content.MediaContent
22 {
23     /// <summary>
24     /// Provides the commands to manage tags in the database.
25     /// </summary>
26     /// <seealso cref="Tag"/>
27     public class TagCommand : MediaCommand
28     {
29         /// <summary>
30         /// Initializes a new instance of the <see cref="TagCommand"/> class with the specified <see cref="MediaDatabase"/>.
31         /// </summary>
32         /// <param name="database">The <see cref="MediaDatabase"/> that the commands run on.</param>
33         /// <exception cref="ArgumentNullException"><paramref name="database"/> is null.</exception>
34         /// <exception cref="ObjectDisposedException"><paramref name="database"/> has already been disposed of.</exception>
35         public TagCommand(MediaDatabase database) : base(database)
36         {
37         }
38
39         /// <summary>
40         /// Retrieves the number of tags.
41         /// </summary>
42         /// <returns>The number of tags.</returns>
43         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
44         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
45         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
46         public int Count()
47         {
48             return Count(arguments: null);
49         }
50
51         /// <summary>
52         /// Retrieves the number of tags with the <see cref="CountArguments"/>.
53         /// </summary>
54         /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
55         /// <returns>The number of tags filtered.</returns>
56         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
57         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
58         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
59         public int Count(CountArguments arguments)
60         {
61             ValidateDatabase();
62
63             return CommandHelper.Count(Interop.Tag.GetTagCount, arguments);
64         }
65
66
67         /// <summary>
68         /// Deletes a tag from the database.
69         /// </summary>
70         /// <privilege>http://tizen.org/privilege/content.write</privilege>
71         /// <param name="tagId">The tag ID to delete.</param>
72         /// <returns>true if the matched record was found and deleted, otherwise false.</returns>
73         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
74         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
75         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
76         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
77         /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
78         public bool Delete(int tagId)
79         {
80             ValidateDatabase();
81
82             if (tagId <= 0)
83             {
84                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
85                     "Tag id can't be less than or equal to zero.");
86             }
87
88             if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
89             {
90                 return false;
91             }
92
93             CommandHelper.Delete(Interop.Tag.Delete, tagId);
94             return true;
95         }
96
97
98         /// <summary>
99         /// Inserts a tag into the database with the specified name.
100         /// </summary>
101         /// <privilege>http://tizen.org/privilege/content.write</privilege>
102         /// <param name="name">The name of tag.</param>
103         /// <returns>The <see cref="Tag"/> instance that contains the record information inserted.</returns>
104         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
105         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
106         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
107         /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
108         /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
109         public Tag Insert(string name)
110         {
111             ValidateDatabase();
112
113             if (name == null)
114             {
115                 throw new ArgumentNullException(nameof(name));
116             }
117
118             if (name.Length == 0)
119             {
120                 throw new ArgumentException("Tag name can't be an empty string.");
121             }
122
123             Interop.Tag.Insert(name, out var handle).ThrowIfError("Failed to insert a new tag");
124
125             try
126             {
127                 return new Tag(handle);
128             }
129             finally
130             {
131                 Interop.Tag.Destroy(handle);
132             }
133         }
134
135         /// <summary>
136         /// Updates a tag with the specified name.
137         /// </summary>
138         /// <privilege>http://tizen.org/privilege/content.write</privilege>
139         /// <param name="tagId">The tag ID to update.</param>
140         /// <param name="name">The new name.</param>
141         /// <returns>true if the matched record was found and updated, otherwise false.</returns>
142         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
143         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
144         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
145         /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
146         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
147         /// <exception cref="UnauthorizedAccessException">The caller has no required privilege.</exception>
148         public bool UpdateName(int tagId, string name)
149         {
150             ValidateDatabase();
151
152             if (tagId <= 0)
153             {
154                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
155                     "Tag id can't be less than or equal to zero.");
156             }
157
158             if (name == null)
159             {
160                 throw new ArgumentNullException(nameof(name));
161             }
162
163             if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
164             {
165                 return false;
166             }
167
168             Interop.Tag.Create(out var handle).ThrowIfError("Failed to update");
169
170             try
171             {
172                 Interop.Tag.SetName(handle, name).ThrowIfError("Failed to update");
173                 Interop.Tag.Update(tagId, handle).ThrowIfError("Failed to update");
174
175                 return true;
176             }
177             finally
178             {
179                 Interop.Tag.Destroy(handle);
180             }
181         }
182
183         /// <summary>
184         /// Retrieves the tag with the specified ID.
185         /// </summary>
186         /// <param name="tagId">The tag ID to select.</param>
187         /// <returns>The <see cref="Tag"/> instance if the matched record was found in the database, otherwise null.</returns>
188         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
189         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
190         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
191         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
192         public Tag Select(int tagId)
193         {
194             ValidateDatabase();
195
196             if (tagId <= 0)
197             {
198                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
199                     "Tag id can't be less than or equal to zero.");
200             }
201
202             IntPtr handle = IntPtr.Zero;
203
204             try
205             {
206                 Interop.Tag.GetTagFromDb(tagId, out handle).ThrowIfError("Failed to query");
207
208                 if (handle == IntPtr.Zero)
209                 {
210                     return null;
211                 }
212                 return new Tag(handle);
213             }
214             finally
215             {
216                 if (handle != IntPtr.Zero)
217                 {
218                     Interop.Tag.Destroy(handle);
219                 }
220             }
221
222         }
223
224         /// <summary>
225         /// Retrieves all the tags.
226         /// </summary>
227         /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
228         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
229         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
230         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
231         public MediaDataReader<Tag> Select()
232         {
233             return Select(arguments: null);
234         }
235
236         /// <summary>
237         /// Retrieves the tags with the <see cref="SelectArguments"/>.
238         /// </summary>
239         /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
240         /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
241         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
242         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
243         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
244         public MediaDataReader<Tag> Select(SelectArguments arguments)
245         {
246             ValidateDatabase();
247
248             return CommandHelper.Select(arguments, Interop.Tag.ForeachTagFromDb, Tag.FromHandle);
249         }
250
251         /// <summary>
252         /// Retrieves the number of media info of the tag.
253         /// </summary>
254         /// <param name="tagId">The tag ID.</param>
255         /// <returns>The number of the media information.</returns>
256         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
257         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
258         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
259         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
260         public int CountMedia(int tagId)
261         {
262             return CountMedia(tagId, null);
263         }
264
265         /// <summary>
266         /// Retrieves the number of the media information of the tag with the <see cref="CountArguments"/>.
267         /// </summary>
268         /// <param name="tagId">The tag ID to query with.</param>
269         /// <param name="arguments">The criteria to use to filter. This value can be null.</param>
270         /// <returns>The number of the media information.</returns>
271         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
272         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
273         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
274         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
275         public int CountMedia(int tagId, CountArguments arguments)
276         {
277             ValidateDatabase();
278
279             if (tagId <= 0)
280             {
281                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
282                     "Tag id can't be less than or equal to zero.");
283             }
284
285             return CommandHelper.Count(Interop.Tag.GetMediaCount, tagId, arguments);
286         }
287
288         /// <summary>
289         /// Retrieves the media information of the tag.
290         /// </summary>
291         /// <param name="tagId">The tag ID.</param>
292         /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
293         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
294         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
295         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
296         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
297         public MediaDataReader<MediaInfo> SelectMedia(int tagId)
298         {
299             return SelectMedia(tagId, null);
300         }
301
302         /// <summary>
303         /// Retrieves the media information of the tag with the <see cref="SelectArguments"/>.
304         /// </summary>
305         /// <param name="tagId">The tag ID.</param>
306         /// <param name="filter">The criteria to use to filter. This value can be null.</param>
307         /// <returns>The <see cref="MediaDataReader{TRecord}"/> containing the results.</returns>
308         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
309         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
310         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
311         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
312         public MediaDataReader<MediaInfo> SelectMedia(int tagId, SelectArguments filter)
313         {
314             ValidateDatabase();
315
316             if (tagId <= 0)
317             {
318                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
319                     "Tag id can't be less than or equal to zero.");
320             }
321
322             return CommandHelper.SelectMedia(Interop.Tag.ForeachMediaFromDb, tagId, filter);
323         }
324
325         private bool UpdateMember(int tagId, IEnumerable<string> mediaIds,
326             Func<IntPtr, string, MediaContentError> func)
327         {
328             ValidateDatabase();
329
330             if (tagId <= 0)
331             {
332                 throw new ArgumentOutOfRangeException(nameof(tagId), tagId,
333                     "Tag id can't be less than or equal to zero.");
334             }
335
336             if (mediaIds == null)
337             {
338                 throw new ArgumentNullException(nameof(mediaIds));
339             }
340
341             if (mediaIds.Count() == 0)
342             {
343                 throw new ArgumentException("mediaIds has no element.", nameof(mediaIds));
344             }
345
346             if (CommandHelper.Count(Interop.Tag.GetTagCount, $"{TagColumns.Id}={tagId}") == 0)
347             {
348                 return false;
349             }
350
351             IntPtr handle = IntPtr.Zero;
352             Interop.Tag.Create(out handle).ThrowIfError("Failed to initialize update member operation");
353
354             try
355             {
356                 foreach (var mediaId in mediaIds)
357                 {
358                     if (mediaId == null)
359                     {
360                         throw new ArgumentException("Media id should not be null.", nameof(mediaIds));
361                     }
362
363                     if (string.IsNullOrWhiteSpace(mediaId))
364                     {
365                         throw new ArgumentException("Media id should not be a zero-length string.", nameof(mediaId));
366                     }
367
368                     func(handle, mediaId).ThrowIfError("Failed to update member");
369                 }
370
371                 Interop.Tag.Update(tagId, handle).ThrowIfError("Failed to run member update");
372                 return true;
373             }
374             finally
375             {
376                 if (handle != IntPtr.Zero)
377                 {
378                     Interop.Tag.Destroy(handle);
379                 }
380             }
381         }
382
383         /// <summary>
384         /// Adds the media to a tag.
385         /// </summary>
386         /// <param name="tagId">The tag ID that the media will be added to.</param>
387         /// <param name="mediaId">The media ID to add to the tag.</param>
388         /// <returns>true if the matched record was found and updated, otherwise false.</returns>
389         /// <remarks>The invalid media ID will be ignored.</remarks>
390         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
391         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
392         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
393         /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
394         /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
395         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
396         public bool AddMedia(int tagId, string mediaId)
397         {
398             ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
399
400             return AddMedia(tagId, new string[] { mediaId });
401         }
402
403         /// <summary>
404         /// Adds the media set to a tag.
405         /// </summary>
406         /// <param name="tagId">The tag ID that the media will be added to.</param>
407         /// <param name="mediaIds">The media ID to add to the tag.</param>
408         /// <returns>true if the matched record was found and updated, otherwise false.</returns>
409         /// <remarks>The invalid media IDs will be ignored.</remarks>
410         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
411         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
412         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
413         /// <exception cref="ArgumentNullException"><paramref name="mediaIds"/> is null.</exception>
414         /// <exception cref="ArgumentException">
415         ///     <paramref name="mediaIds"/> has no element.\n
416         ///     -or-\n
417         ///     <paramref name="mediaIds"/> contains null value.\n
418         ///     -or-\n
419         ///     <paramref name="mediaIds"/> contains a zero-length string, contains only white space.\n
420         /// </exception>
421         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
422         public bool AddMedia(int tagId, IEnumerable<string> mediaIds)
423         {
424             return UpdateMember(tagId, mediaIds, Interop.Tag.AddMedia);
425         }
426
427         /// <summary>
428         /// Removes the media from a tag.
429         /// </summary>
430         /// <param name="tagId">The tag ID.</param>
431         /// <param name="mediaId">The media ID to remove from the tag.</param>
432         /// <returns>true if the matched record was found and updated, otherwise false.</returns>
433         /// <remarks>The invalid media ID will be ignored.</remarks>
434         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
435         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
436         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
437         /// <exception cref="ArgumentNullException"><paramref name="mediaId"/> is null.</exception>
438         /// <exception cref="ArgumentException"><paramref name="mediaId"/> is a zero-length string, contains only white space.</exception>
439         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
440         public bool RemoveMedia(int tagId, string mediaId)
441         {
442             ValidationUtil.ValidateNotNullOrEmpty(mediaId, nameof(mediaId));
443
444             return RemoveMedia(tagId, new string[] { mediaId });
445         }
446
447         /// <summary>
448         /// Removes the media set from a tag.
449         /// </summary>
450         /// <param name="tagId">The tag ID.</param>
451         /// <param name="mediaIds">The collection of media ID to remove from the tag.</param>
452         /// <returns>true if the matched record was found and updated, otherwise false.</returns>
453         /// <remarks>The invalid IDs will be ignored.</remarks>
454         /// <exception cref="InvalidOperationException">The <see cref="MediaDatabase"/> is disconnected.</exception>
455         /// <exception cref="ObjectDisposedException">The <see cref="MediaDatabase"/> has already been disposed of.</exception>
456         /// <exception cref="MediaDatabaseException">An error occurred while executing the command.</exception>
457         /// <exception cref="ArgumentNullException"><paramref name="mediaIds"/> is null.</exception>
458         /// <exception cref="ArgumentException">
459         ///     <paramref name="mediaIds"/> has no element.\n
460         ///     -or-\n
461         ///     <paramref name="mediaIds"/> contains null value.\n
462         ///     -or-\n
463         ///     <paramref name="mediaIds"/> contains a zero-length string or white space.\n
464         /// </exception>
465         /// <exception cref="ArgumentOutOfRangeException"><paramref name="tagId"/> is less than or equal to zero.</exception>
466         public bool RemoveMedia(int tagId, IEnumerable<string> mediaIds)
467         {
468             return UpdateMember(tagId, mediaIds, Interop.Tag.RemoveMedia);
469         }
470     }
471 }