1 /* PlaylistDBWrapper.cpp */
2 
3 /* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4  *
5  * This file is part of sayonara player
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11 
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "PlaylistDBWrapper.h"
22 
23 #include "Utils/Algorithm.h"
24 #include "Utils/FileUtils.h"
25 #include "Utils/Parser/PlaylistParser.h"
26 #include "Utils/MetaData/MetaDataList.h"
27 #include "Utils/Playlist/CustomPlaylist.h"
28 #include "Utils/Tagging/Tagging.h"
29 
30 #include "Database/Connector.h"
31 #include "Database/Playlist.h"
32 
33 #include <utility>
34 
35 namespace Algorithm=Util::Algorithm;
36 using Playlist::DBWrapper;
37 
38 struct DBWrapper::Private
39 {
40 	DB::Playlist* playlistDatabase=nullptr;
41 };
42 
43 DBWrapper::DBWrapper()
44 {
45 	m = Pimpl::make<Private>();
46 	m->playlistDatabase = DB::Connector::instance()->playlistConnector();
47 }
48 
49 DBWrapper::~DBWrapper() = default;
50 
51 void DBWrapper::applyTags(MetaDataList& tracks)
52 {
53 	for(MetaData& md : tracks)
54 	{
55 		if(md.isExtern())
56 		{
57 			if(Util::File::isFile(md.filepath()))
58 			{
59 				Tagging::Utils::getMetaDataOfFile(md);
60 			}
61 		}
62 	}
63 }
64 
65 bool DBWrapper::getSkeletons(CustomPlaylistSkeletons& skeletons, Playlist::StoreType type, Playlist::SortOrder so)
66 {
67 	return m->playlistDatabase->getAllPlaylistSkeletons(skeletons, type, so);
68 }
69 
70 bool DBWrapper::getAllSkeletons(CustomPlaylistSkeletons& skeletons,
71 					   Playlist::SortOrder so)
72 {
73 	return getSkeletons(skeletons,
74 						 Playlist::StoreType::TemporaryAndPermanent,
75 						 so);
76 }
77 
78 bool DBWrapper::getTemporarySkeletons(CustomPlaylistSkeletons& skeletons,
79 												Playlist::SortOrder so)
80 {
81 	return getSkeletons(skeletons,
82 						 Playlist::StoreType::OnlyTemporary,
83 						 so);
84 }
85 
86 bool DBWrapper:: getNonTemporarySkeletons(CustomPlaylistSkeletons& skeletons,
87 													 Playlist::SortOrder so)
88 {
89 	return getSkeletons(skeletons,
90 						 Playlist::StoreType::OnlyPermanent,
91 						 so);
92 }
93 
94 bool DBWrapper::getPlaylists(CustomPlaylists& playlists, Playlist::StoreType type, Playlist::SortOrder so)
95 {
96 	Q_UNUSED(type)
97 
98 	bool success;
99 	CustomPlaylistSkeletons skeletons;
100 
101 	success = getAllSkeletons(skeletons, so);
102 	if(!success){
103 		return false;
104 	}
105 
106 	bool loadTemporary = (type == Playlist::StoreType::OnlyTemporary ||
107 	                      type == Playlist::StoreType::TemporaryAndPermanent);
108 
109 	bool loadPermanent = (type == Playlist::StoreType::OnlyPermanent ||
110 	                      type == Playlist::StoreType::TemporaryAndPermanent);
111 
112 	for(const CustomPlaylistSkeleton& skeleton : Algorithm::AsConst(skeletons))
113 	{
114 		CustomPlaylist pl(skeleton);
115 		if(pl.id() < 0){
116 			continue;
117 		}
118 
119 		success = m->playlistDatabase->getPlaylistById(pl);
120 
121 		if(!success){
122 			continue;
123 		}
124 
125 		applyTags(pl);
126 
127 		if( (pl.temporary() && loadTemporary) ||
128 			(!pl.temporary() && loadPermanent) )
129 		{
130 			playlists.push_back(pl);
131 		}
132 	}
133 
134 	return true;
135 }
136 
137 
138 bool DBWrapper::getAllPlaylists(CustomPlaylists& playlists, Playlist::SortOrder so)
139 {
140 	return getPlaylists(playlists,
141 						 Playlist::StoreType::TemporaryAndPermanent,
142 						 so);
143 }
144 
145 
146 bool DBWrapper::getTemporaryPlaylists(CustomPlaylists& playlists, Playlist::SortOrder so)
147 {
148 	return getPlaylists(playlists,
149 						 Playlist::StoreType::OnlyTemporary,
150 						 so);
151 }
152 
153 
154 bool DBWrapper::getNonTemporaryPlaylists(CustomPlaylists& playlists, Playlist::SortOrder so)
155 {
156 	return getPlaylists(playlists,
157 						 Playlist::StoreType::OnlyPermanent,
158 						 so);
159 }
160 
161 
162 CustomPlaylist DBWrapper::getPlaylistById(int id)
163 {
164 	bool success;
165 	CustomPlaylist pl;
166 	pl.setId(id);
167 
168 	success = m->playlistDatabase->getPlaylistById(pl);
169 	if(!success){
170 		return pl;
171 	}
172 
173 	return pl;
174 }
175 
176 
177 CustomPlaylist DBWrapper::getPlaylistByName(const QString& name)
178 {
179 	int id = m->playlistDatabase->getPlaylistIdByName(name);
180 
181 	if(id < 0){
182 		CustomPlaylist pl;
183 		pl.setId(-1);
184 		return pl;
185 	}
186 
187 	return getPlaylistById(id);
188 }
189 
190 bool DBWrapper::renamePlaylist(int id, const QString& new_name)
191 {
192 	return m->playlistDatabase->renamePlaylist(id, new_name);
193 }
194 
195 
196 bool DBWrapper::savePlaylistAs(const MetaDataList& v_md, const QString& name)
197 {
198 	auto* db = DB::Connector::instance();
199 
200 	db->transaction();
201 	bool success = m->playlistDatabase->storePlaylist(v_md, name, false);
202 	db->commit();
203 
204 	return success;
205 }
206 
207 bool DBWrapper::savePlaylistTemporary(const MetaDataList& tracks, const QString& name)
208 {
209 	auto* db = DB::Connector::instance();
210 
211 	db->transaction();
212 
213 	bool success = m->playlistDatabase->storePlaylist(tracks, name, true);
214 
215 	db->commit();
216 
217 	return success;
218 }
219 
220 
221 bool DBWrapper::savePlaylist(const CustomPlaylist& pl)
222 {
223 	auto* db = DB::Connector::instance();
224 
225 	db->transaction();
226 	// TODO! we don't need the two other parameters
227 	bool success = m->playlistDatabase->storePlaylist(pl, pl.id(), pl.temporary());
228 	db->commit();
229 
230 	return success;
231 }
232 
233 
234 bool DBWrapper::savePlaylist(const MetaDataList& v_md, int id, bool is_temporary)
235 {
236 	auto* db = DB::Connector::instance();
237 
238 	db->transaction();
239 	// TODO: see above
240 	bool success = m->playlistDatabase->storePlaylist(v_md, id, is_temporary);
241 	db->commit();
242 
243 	return success;
244 }
245 
246 
247 bool DBWrapper::deletePlaylist(int id)
248 {
249 	return m->playlistDatabase->deletePlaylist(id);
250 }
251 
252 
253 bool DBWrapper::deletePlaylist(const QString& name)
254 {
255 	int id = m->playlistDatabase->getPlaylistIdByName(name);
256 	return m->playlistDatabase->deletePlaylist(id);
257 }
258 
259 
260 bool DBWrapper::exists(const QString& name)
261 {
262 	int id = m->playlistDatabase->getPlaylistIdByName(name);
263 	return (id >= 0);
264 }
265 
266