00001 #include <map>
00002
00003 #include "mythdb.h"
00004 #include "videometadatalistmanager.h"
00005
00006 class VideoMetadataListManagerImp
00007 {
00008 public:
00009 typedef VideoMetadataListManager::VideoMetadataPtr VideoMetadataPtr;
00010 typedef VideoMetadataListManager::metadata_list metadata_list;
00011
00012 private:
00013 typedef std::map<unsigned int, metadata_list::iterator> int_to_meta;
00014 typedef std::map<QString, metadata_list::iterator> string_to_meta;
00015
00016 public:
00017 void setList(metadata_list &list)
00018 {
00019 m_id_map.clear();
00020 m_file_map.clear();
00021 m_meta_list.swap(list);
00022
00023 for (metadata_list::iterator p = m_meta_list.begin();
00024 p != m_meta_list.end(); ++p)
00025 {
00026 m_id_map.insert(int_to_meta::value_type((*p)->GetID(), p));
00027 m_file_map.insert(
00028 string_to_meta::value_type((*p)->GetFilename(), p));
00029 }
00030 }
00031
00032 const metadata_list &getList() const
00033 {
00034 return m_meta_list;
00035 }
00036
00037
00038 VideoMetadataPtr byFilename(const QString &file_name) const
00039 {
00040 string_to_meta::const_iterator p = m_file_map.find(file_name);
00041 if (p != m_file_map.end())
00042 {
00043 return *(p->second);
00044 }
00045 return VideoMetadataPtr();
00046 }
00047
00048 VideoMetadataPtr byID(unsigned int db_id) const
00049 {
00050 int_to_meta::const_iterator p = m_id_map.find(db_id);
00051 if (p != m_id_map.end())
00052 {
00053 return *(p->second);
00054 }
00055 return VideoMetadataPtr();
00056 }
00057
00058 bool purgeByFilename(const QString &file_name)
00059 {
00060 return purge_entry(byFilename(file_name));
00061 }
00062
00063 bool purgeByID(unsigned int db_id)
00064 {
00065 return purge_entry(byID(db_id));
00066 }
00067
00068 private:
00069 bool purge_entry(VideoMetadataPtr metadata)
00070 {
00071 if (metadata)
00072 {
00073 int_to_meta::iterator im = m_id_map.find(metadata->GetID());
00074
00075 if (im != m_id_map.end())
00076 {
00077 metadata_list::iterator mdi = im->second;
00078 (*mdi)->DeleteFromDatabase();
00079
00080 m_id_map.erase(im);
00081 string_to_meta::iterator sm =
00082 m_file_map.find(metadata->GetFilename());
00083 if (sm != m_file_map.end())
00084 m_file_map.erase(sm);
00085 m_meta_list.erase(mdi);
00086 return true;
00087 }
00088 }
00089
00090 return false;
00091 }
00092
00093 private:
00094 metadata_list m_meta_list;
00095 int_to_meta m_id_map;
00096 string_to_meta m_file_map;
00097 };
00098
00099 VideoMetadataListManager::VideoMetadataListManager()
00100 {
00101 m_imp = new VideoMetadataListManagerImp();
00102 }
00103
00104 VideoMetadataListManager::~VideoMetadataListManager()
00105 {
00106 delete m_imp;
00107 }
00108
00109 VideoMetadataListManager::VideoMetadataPtr
00110 VideoMetadataListManager::loadOneFromDatabase(uint id)
00111 {
00112 QString sql = QString("WHERE intid = %1 LIMIT 1").arg(id);
00113 metadata_list item;
00114 loadAllFromDatabase(item, sql);
00115 if (item.size() > 0)
00116 {
00117 return item.front();
00118 }
00119
00120 return VideoMetadataPtr(new VideoMetadata());
00121 }
00122
00123 void VideoMetadataListManager::loadAllFromDatabase(metadata_list &items,
00124 const QString &sql)
00125 {
00126 MSqlQuery query(MSqlQuery::InitCon());
00127 query.setForwardOnly(true);
00128 QString BaseMetadataQuery(
00129 "SELECT title, director, studio, plot, rating, year, releasedate,"
00130 "userrating, length, playcount, filename, hash, showlevel, "
00131 "coverfile, inetref, collectionref, homepage, childid, browse, watched, "
00132 "playcommand, category, intid, trailer, screenshot, banner, fanart, "
00133 "subtitle, tagline, season, episode, host, insertdate, processed, "
00134 "contenttype FROM videometadata ");
00135
00136 if (!sql.isEmpty())
00137 BaseMetadataQuery.append(sql);
00138
00139 query.prepare(BaseMetadataQuery);
00140
00141 if (query.exec() && query.isActive())
00142 {
00143 while (query.next())
00144 {
00145 items.push_back(VideoMetadataPtr(new VideoMetadata(query)));
00146 }
00147 }
00148 else
00149 {
00150 MythDB::DBError("Querying video metadata", query);
00151 }
00152 }
00153
00154 void VideoMetadataListManager::setList(metadata_list &list)
00155 {
00156 m_imp->setList(list);
00157 }
00158
00159 const VideoMetadataListManager::metadata_list &
00160 VideoMetadataListManager::getList() const
00161 {
00162 return m_imp->getList();
00163 }
00164
00165 VideoMetadataListManager::VideoMetadataPtr
00166 VideoMetadataListManager::byFilename(const QString &file_name) const
00167 {
00168 return m_imp->byFilename(file_name);
00169 }
00170
00171 VideoMetadataListManager::VideoMetadataPtr
00172 VideoMetadataListManager::byID(unsigned int db_id) const
00173 {
00174 return m_imp->byID(db_id);
00175 }
00176
00177 bool VideoMetadataListManager::purgeByFilename(const QString &file_name)
00178 {
00179 return m_imp->purgeByFilename(file_name);
00180 }
00181
00182 bool VideoMetadataListManager::purgeByID(unsigned int db_id)
00183 {
00184 return m_imp->purgeByID(db_id);
00185 }
00186
00187 const QString meta_node::m_empty_path;
00188
00189 const QString& meta_node::getPath() const
00190 {
00191 return m_empty_path;
00192 }
00193
00194 const QString& meta_node::getFQPath()
00195 {
00196 if (m_fq_path.length())
00197 return m_fq_path;
00198
00199 if (m_parent && !m_path_root)
00200 m_fq_path = m_parent->getFQPath() + "/" + getPath();
00201 else
00202 {
00203 QString p = getPath();
00204 if (p.startsWith("myth://"))
00205 m_fq_path = p;
00206 else
00207 m_fq_path = ((p.length() && p[0] != '/') ? "/" : "") + p;
00208 }
00209
00210 return m_fq_path;
00211 }
00212
00213 void meta_node::setParent(meta_node *parent)
00214 {
00215 m_parent = parent;
00216 }
00217
00218 void meta_node::setPathRoot(bool is_root)
00219 {
00220 m_path_root = is_root;
00221 }
00222
00223 const QString meta_data_node::m_meta_bug = "Bug";
00224
00225 const QString& meta_data_node::getName() const
00226 {
00227 if (m_data)
00228 {
00229 return m_data->GetTitle();
00230 }
00231
00232 return m_meta_bug;
00233 }
00234
00235 const VideoMetadata* meta_data_node::getData() const
00236 {
00237 return m_data;
00238 }
00239
00240 VideoMetadata* meta_data_node::getData()
00241 {
00242 return m_data;
00243 }
00244
00245 meta_dir_node::meta_dir_node(const QString &path, const QString &name,
00246 meta_dir_node *parent, bool is_path_root,
00247 const QString &host, const QString &prefix,
00248 const QVariant &data)
00249 : meta_node(parent, is_path_root), m_path(path), m_name(name),
00250 m_host(host), m_prefix(prefix), m_data(data)
00251 {
00252 if (!name.length())
00253 m_name = path;
00254 }
00255
00256 void meta_dir_node::setName(const QString &name)
00257 {
00258 m_name = name;
00259 }
00260
00261 const QString &meta_dir_node::getName() const
00262 {
00263 return m_name;
00264 }
00265
00266 void meta_dir_node::SetHost(const QString &host)
00267 {
00268 m_host = host;
00269 }
00270
00271 const QString &meta_dir_node::GetHost() const
00272 {
00273 return m_host;
00274 }
00275
00276 void meta_dir_node::SetPrefix(const QString &prefix)
00277 {
00278 m_prefix = prefix;
00279 }
00280
00281 const QString &meta_dir_node::GetPrefix() const
00282 {
00283 return m_prefix;
00284 }
00285
00286 const QString &meta_dir_node::getPath() const
00287 {
00288 return m_path;
00289 }
00290
00291 void meta_dir_node::setPath(const QString &path)
00292 {
00293 m_path = path;
00294 }
00295
00296 void meta_dir_node::SetData(const QVariant &data)
00297 {
00298 m_data = data;
00299 }
00300
00301 const QVariant &meta_dir_node::GetData() const
00302 {
00303 return m_data;
00304 }
00305
00306 bool meta_dir_node::DataIsValid() const
00307 {
00308 return m_data.isValid();
00309 }
00310
00311 smart_dir_node meta_dir_node::addSubDir(const QString &subdir,
00312 const QString &name,
00313 const QString &host,
00314 const QString &prefix,
00315 const QVariant &data)
00316 {
00317 return getSubDir(subdir, name, true, host, prefix, data);
00318 }
00319
00320 void meta_dir_node::addSubDir(const smart_dir_node &subdir)
00321 {
00322 m_subdirs.push_back(subdir);
00323 }
00324
00325 smart_dir_node meta_dir_node::getSubDir(const QString &subdir,
00326 const QString &name,
00327 bool create,
00328 const QString &host,
00329 const QString &prefix,
00330 const QVariant &data)
00331 {
00332 for (meta_dir_list::const_iterator p = m_subdirs.begin();
00333 p != m_subdirs.end(); ++p)
00334 {
00335 if (subdir == (*p)->getPath())
00336 {
00337 return *p;
00338 }
00339 }
00340
00341 if (create)
00342 {
00343 smart_dir_node node(new meta_dir_node(subdir, name, this, false,
00344 host, prefix, data));
00345 m_subdirs.push_back(node);
00346 return node;
00347 }
00348
00349 return smart_dir_node();
00350 }
00351
00352 void meta_dir_node::addEntry(const smart_meta_node &entry)
00353 {
00354 entry->setParent(this);
00355 m_entries.push_back(entry);
00356 }
00357
00358 void meta_dir_node::clear()
00359 {
00360 m_subdirs.clear();
00361 m_entries.clear();
00362 }
00363
00364 bool meta_dir_node::empty() const
00365 {
00366 return m_subdirs.empty() && m_entries.empty();
00367 }
00368
00369 int meta_dir_node::subdir_count() const
00370 {
00371 return m_subdirs.size();
00372 }
00373
00374 meta_dir_list::iterator meta_dir_node::dirs_begin()
00375 {
00376 return m_subdirs.begin();
00377 }
00378
00379 meta_dir_list::iterator meta_dir_node::dirs_end()
00380 {
00381 return m_subdirs.end();
00382 }
00383
00384 meta_dir_list::const_iterator meta_dir_node::dirs_begin() const
00385 {
00386 return m_subdirs.begin();
00387 }
00388
00389 meta_dir_list::const_iterator meta_dir_node::dirs_end() const
00390 {
00391 return m_subdirs.end();
00392 }
00393
00394 meta_data_list::iterator meta_dir_node::entries_begin()
00395 {
00396 return m_entries.begin();
00397 }
00398
00399 meta_data_list::iterator meta_dir_node::entries_end()
00400 {
00401 return m_entries.end();
00402 }
00403
00404 meta_data_list::const_iterator meta_dir_node::entries_begin() const
00405 {
00406 return m_entries.begin();
00407 }
00408
00409 meta_data_list::const_iterator meta_dir_node::entries_end() const
00410 {
00411 return m_entries.end();
00412 }
00413
00414
00415
00416 bool meta_dir_node::has_entries() const
00417 {
00418 bool ret = m_entries.size();
00419
00420 if (!ret)
00421 {
00422 for (meta_dir_list::const_iterator p = m_subdirs.begin();
00423 p != m_subdirs.end(); ++p)
00424 {
00425 ret = (*p)->has_entries();
00426 if (ret) break;
00427 }
00428 }
00429
00430 return ret;
00431 }