MythTV master
videometadatalistmanager.cpp
Go to the documentation of this file.
1#include <map>
2
6
8{
9 public:
12
13 private:
14 using int_to_meta = std::map<unsigned int, metadata_list::iterator>;
15 using string_to_meta = std::map<QString, metadata_list::iterator>;
16
17 public:
19 {
20 m_idMap.clear();
21 m_fileMap.clear();
22 m_metaList.swap(list);
23
24 for (auto p = m_metaList.begin(); p != m_metaList.end(); ++p)
25 {
26 m_idMap.insert(int_to_meta::value_type((*p)->GetID(), p));
27 m_fileMap.insert(
28 string_to_meta::value_type((*p)->GetFilename(), p));
29 }
30 }
31
32 const metadata_list &getList() const
33 {
34 return m_metaList;
35 }
36
37
38 VideoMetadataPtr byFilename(const QString &file_name) const
39 {
40 //NOLINTNEXTLINE(modernize-use-auto)
41 string_to_meta::const_iterator p = m_fileMap.find(file_name);
42 if (p != m_fileMap.end())
43 {
44 return *(p->second);
45 }
46 return {};
47 }
48
49 VideoMetadataPtr byID(unsigned int db_id) const
50 {
51 //NOLINTNEXTLINE(modernize-use-auto)
52 int_to_meta::const_iterator p = m_idMap.find(db_id);
53 if (p != m_idMap.end())
54 {
55 return *(p->second);
56 }
57 return {};
58 }
59
60 bool purgeByFilename(const QString &file_name)
61 {
62 return purge_entry(byFilename(file_name));
63 }
64
65 bool purgeByID(unsigned int db_id)
66 {
67 return purge_entry(byID(db_id));
68 }
69
70 private:
71 bool purge_entry(const VideoMetadataPtr& metadata)
72 {
73 if (metadata)
74 {
75 auto im = m_idMap.find(metadata->GetID());
76
77 if (im != m_idMap.end())
78 {
79 auto mdi = im->second;
80 (*mdi)->DeleteFromDatabase();
81
82 m_idMap.erase(im);
83 auto sm = m_fileMap.find(metadata->GetFilename());
84 if (sm != m_fileMap.end())
85 m_fileMap.erase(sm);
86 m_metaList.erase(mdi);
87 return true;
88 }
89 }
90
91 return false;
92 }
93
94 private:
98};
99
101 : m_imp(new VideoMetadataListManagerImp())
102{
103}
104
106{
107 delete m_imp;
108}
109
112{
113 QString sql = QString("WHERE intid = %1 LIMIT 1").arg(id);
114 metadata_list item;
115 loadAllFromDatabase(item, sql);
116 if (!item.empty())
117 {
118 return item.front();
119 }
120
121 return {new VideoMetadata()};
122}
123
129 const QString &sql,
130 const QStringList &bindValues)
131{
133 query.setForwardOnly(true);
134 QString BaseMetadataQuery(
135 "SELECT title, director, studio, plot, rating, year, releasedate,"
136 "userrating, length, playcount, filename, hash, showlevel, "
137 "coverfile, inetref, collectionref, homepage, childid, browse, watched, "
138 "playcommand, category, intid, trailer, screenshot, banner, fanart, "
139 "subtitle, tagline, season, episode, host, insertdate, processed, "
140 "contenttype FROM videometadata ");
141
142 if (!sql.isEmpty())
143 BaseMetadataQuery.append(sql);
144
145 query.prepare(BaseMetadataQuery);
146
147 for (int ix = 0 ; ix < bindValues.size() ; ix++)
148 {
149 query.bindValue(QString(":BIND") + QString::number(ix), bindValues.at(ix));
150 }
151
152 if (query.exec() && query.isActive())
153 {
154 while (query.next())
155 {
156 items.push_back(VideoMetadataPtr(new VideoMetadata(query)));
157 }
158 }
159 else
160 {
161 MythDB::DBError("Querying video metadata", query);
162 }
163}
164
166{
167 m_imp->setList(list);
168}
169
172{
173 return m_imp->getList();
174}
175
177VideoMetadataListManager::byFilename(const QString &file_name) const
178{
179 return m_imp->byFilename(file_name);
180}
181
183VideoMetadataListManager::byID(unsigned int db_id) const
184{
185 return m_imp->byID(db_id);
186}
187
188bool VideoMetadataListManager::purgeByFilename(const QString &file_name)
189{
190 return m_imp->purgeByFilename(file_name);
191}
192
194{
195 return m_imp->purgeByID(db_id);
196}
197
198const QString meta_node::kEmptyPath;
199
200const QString& meta_node::getPath() const
201{
202 return kEmptyPath;
203}
204
205const QString& meta_node::getFQPath()
206{
207 if (!m_fqPath.isEmpty())
208 return m_fqPath;
209
210 if (m_parent && !m_pathRoot)
211 m_fqPath = m_parent->getFQPath() + "/" + getPath();
212 else
213 {
214 QString p = getPath();
215 if (p.startsWith("myth://"))
216 m_fqPath = p;
217 else
218 m_fqPath = ((!p.isEmpty() && p[0] != '/') ? "/" : "") + p;
219 }
220
221 return m_fqPath;
222}
223
225{
226 m_parent = parent;
227}
228
229void meta_node::setPathRoot(bool is_root)
230{
231 m_pathRoot = is_root;
232}
233
234const QString meta_data_node::kMetaBug = "Bug";
235
236const QString& meta_data_node::getName() const
237{
238 if (m_data)
239 {
240 return m_data->GetTitle();
241 }
242
243 return kMetaBug;
244}
245
247{
248 return m_data;
249}
250
252{
253 return m_data;
254}
255
256meta_dir_node::meta_dir_node(const QString &path, const QString &name,
257 meta_dir_node *parent, bool is_path_root,
258 QString host, QString prefix,
259 QVariant data)
260 : meta_node(parent, is_path_root), m_path(path), m_name(name),
261 m_host(std::move(host)), m_prefix(std::move(prefix)), m_data(std::move(data))
262{
263 if (name.isEmpty())
264 m_name = path;
266}
267
269{
270 std::shared_ptr<MythSortHelper>sh = getMythSortHelper();
271
272 if (m_sortPath.isEmpty() and not m_path.isEmpty())
273 m_sortPath = sh->doPathname(m_path);
274 }
275
276void meta_dir_node::setName(const QString &name)
277{
278 m_name = name;
279}
280
281const QString &meta_dir_node::getName() const
282{
283 return m_name;
284}
285
286void meta_dir_node::SetHost(const QString &host)
287{
288 m_host = host;
289}
290
291const QString &meta_dir_node::GetHost() const
292{
293 return m_host;
294}
295
297{
299}
300
301const QString &meta_dir_node::GetPrefix() const
302{
303 return m_prefix;
304}
305
306const QString &meta_dir_node::getPath() const
307{
308 return m_path;
309}
310
311const QString &meta_dir_node::getSortPath() const
312{
313 return m_sortPath;
314}
315
316void meta_dir_node::setPath(const QString &path, const QString &sortPath)
317{
318 m_path = path;
319 m_sortPath = sortPath;
321}
322
323void meta_dir_node::SetData(const QVariant &data)
324{
325 m_data = data;
326}
327
328const QVariant &meta_dir_node::GetData() const
329{
330 return m_data;
331}
332
334{
335 return m_data.isValid();
336}
337
339 const QString &name,
340 const QString &host,
341 const QString &prefix,
342 const QVariant &data)
343{
344 return getSubDir(subdir, name, true, host, prefix, data);
345}
346
348{
349 m_subdirs.push_back(subdir);
350}
351
353 const QString &name,
354 bool create,
355 const QString &host,
356 const QString &prefix,
357 const QVariant &data)
358{
359 for (auto & entry : m_subdirs)
360 {
361 if (entry && (subdir == entry->getPath()))
362 {
363 return entry;
364 }
365 }
366
367 if (create)
368 {
369 smart_dir_node node(new meta_dir_node(subdir, name, this, false,
370 host, prefix, data));
371 m_subdirs.push_back(node);
372 return node;
373 }
374
375 return {};
376}
377
379{
380 entry->setParent(this);
381 m_entries.push_back(entry);
382}
383
385{
386 m_subdirs.clear();
387 m_entries.clear();
388}
389
391{
392 return m_subdirs.empty() && m_entries.empty();
393}
394
396{
397 return m_subdirs.size();
398}
399
400meta_dir_list::iterator meta_dir_node::dirs_begin()
401{
402 return m_subdirs.begin();
403}
404
405meta_dir_list::iterator meta_dir_node::dirs_end()
406{
407 return m_subdirs.end();
408}
409
410meta_dir_list::const_iterator meta_dir_node::dirs_begin() const
411{
412 return m_subdirs.begin();
413}
414
415meta_dir_list::const_iterator meta_dir_node::dirs_end() const
416{
417 return m_subdirs.end();
418}
419
420meta_data_list::iterator meta_dir_node::entries_begin()
421{
422 return m_entries.begin();
423}
424
425meta_data_list::iterator meta_dir_node::entries_end()
426{
427 return m_entries.end();
428}
429
430meta_data_list::const_iterator meta_dir_node::entries_begin() const
431{
432 return m_entries.begin();
433}
434
435meta_data_list::const_iterator meta_dir_node::entries_end() const
436{
437 return m_entries.end();
438}
439
440// Returns true if this directory or any of its subdirectories
441// have entries. TODO: cache this value
443{
444 bool ret = !m_entries.empty();
445
446 if (!ret)
447 {
448 for (const auto & subdir : m_subdirs)
449 {
450 if (subdir == nullptr)
451 continue;
452 ret = subdir->has_entries();
453 if (ret) break;
454 }
455 }
456
457 return ret;
458}
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
void setForwardOnly(bool f)
Definition: mythdbcon.h:218
bool isActive(void) const
Definition: mythdbcon.h:215
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
bool purge_entry(const VideoMetadataPtr &metadata)
bool purgeByFilename(const QString &file_name)
std::map< QString, metadata_list::iterator > string_to_meta
VideoMetadataPtr byFilename(const QString &file_name) const
const metadata_list & getList() const
void setList(metadata_list &list)
bool purgeByID(unsigned int db_id)
VideoMetadataListManager::metadata_list metadata_list
std::map< unsigned int, metadata_list::iterator > int_to_meta
VideoMetadataPtr byID(unsigned int db_id) const
simple_ref_ptr< VideoMetadata > VideoMetadataPtr
bool purgeByFilename(const QString &file_name)
VideoMetadataPtr byFilename(const QString &file_name) const
void setList(metadata_list &list)
VideoMetadataPtr byID(unsigned int db_id) const
std::list< VideoMetadataPtr > metadata_list
bool purgeByID(unsigned int db_id)
static VideoMetadataPtr loadOneFromDatabase(uint id)
static void loadAllFromDatabase(metadata_list &items, const QString &sql="", const QStringList &bindValues=QStringList())
Load videometadata database into memory.
const metadata_list & getList() const
class VideoMetadataListManagerImp * m_imp
const QString & GetTitle() const
const VideoMetadata * getData() const
const QString & getName() const override
VideoMetadata * m_data
static const QString kMetaBug
void addEntry(const smart_meta_node &entry)
entry_iterator entries_end()
const QString & getSortPath() const
const QString & getName() const override
void SetHost(const QString &host)
smart_dir_node addSubDir(const QString &subdir, const QString &name="", const QString &host="", const QString &prefix="", const QVariant &data=QVariant())
const QString & GetPrefix() const
void SetPrefix(const QString &prefix)
const QVariant & GetData() const
void SetData(const QVariant &data)
void setPath(const QString &path, const QString &sortPath=nullptr)
const QString & GetHost() const
smart_dir_node getSubDir(const QString &subdir, const QString &name="", bool create=true, const QString &host="", const QString &prefix="", const QVariant &data=QVariant())
void setName(const QString &name)
meta_data_list m_entries
const QString & getPath() const override
entry_iterator entries_begin()
bool DataIsValid(void) const
virtual const QString & getPath() const
void setParent(meta_node *parent)
meta_node * m_parent
void setPathRoot(bool is_root=true)
static const QString kEmptyPath
const QString & getFQPath()
unsigned int uint
Definition: freesurround.h:24
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
STL namespace.