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