void CGUIControllerList::RegisterController(const std::string& addonId, const ADDON::VECADDONS& addonCache) { auto it = std::find_if(addonCache.begin(), addonCache.end(), [addonId](const AddonPtr& addon) { return addon->ID() == addonId; }); if (it != addonCache.end()) { ControllerPtr newController = std::dynamic_pointer_cast<CController>(*it); if (newController && newController->LoadLayout()) m_controllers.push_back(newController); } }
int CHTTPWebinterfaceAddonsHandler::HandleRequest() { m_responseData = ADDON_HEADER; ADDON::VECADDONS addons; if (!ADDON::CAddonMgr::GetInstance().GetAddons(addons, ADDON::ADDON_WEB_INTERFACE) || addons.empty()) { m_response.type = HTTPError; m_response.status = MHD_HTTP_INTERNAL_SERVER_ERROR; return MHD_YES; } for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) m_responseData += "<li><a href=/addons/" + (*addon)->ID() + "/>" + (*addon)->Name() + "</a></li>\n"; m_responseData += "</ul>\n</body></html>"; m_responseRange.SetData(m_responseData.c_str(), m_responseData.size()); m_response.type = HTTPMemoryDownloadNoFreeCopy; m_response.status = MHD_HTTP_OK; m_response.contentType = "text/html"; m_response.totalLength = m_responseData.size(); return MHD_YES; }
void CActiveAEDSPDatabase::CreateTables() { BeginTransaction(); CLog::Log(LOGINFO, "Audio DSP - %s - creating tables", __FUNCTION__); CLog::Log(LOGDEBUG, "Audio DSP - %s - creating table 'addons'", __FUNCTION__); m_pDS->exec( "CREATE TABLE addons (" "idAddon integer primary key, " "sName varchar(64), " "sUid varchar(32)" ")" ); CLog::Log(LOGDEBUG, "Audio DSP - %s - creating table 'modes'", __FUNCTION__); m_pDS->exec( "CREATE TABLE modes (" "idMode integer primary key, " "iType integer, " "iPosition integer, " "iStreamTypeFlags integer, " "iBaseType integer, " "bIsEnabled bool, " "sOwnIconPath varchar(255), " "sOverrideIconPath varchar(255), " "iModeName integer, " "iModeSetupName integer, " "iModeHelp integer, " "iModeDescription integer, " "sAddonModeName varchar(64), " "iAddonId integer, " "iAddonModeNumber integer, " "bHasSettings bool" ")" ); CLog::Log(LOGDEBUG, "Audio DSP - %s - create settings table", __FUNCTION__); m_pDS->exec( "CREATE TABLE settings (" "id integer primary key, " "strPath varchar(255), " "strFileName varchar(255), " "MasterStreamTypeSel integer, " "MasterStreamType integer, " "MasterBaseType integer, " "MasterModeId integer" ")" ); // disable all Audio DSP add-on when started the first time ADDON::VECADDONS addons; if (CAddonMgr::Get().GetAddons(ADDON_ADSPDLL, addons, true)) CLog::Log(LOGERROR, "Audio DSP - %s - failed to get add-ons from the add-on manager", __FUNCTION__); else { for (IVECADDONS it = addons.begin(); it != addons.end(); it++) CAddonMgr::Get().DisableAddon(it->get()->ID()); } }
void CPVRDatabase::UpdateTables(int iVersion) { if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); if (iVersion < 14) m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;"); if (iVersion < 15) { m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;"); } if (iVersion < 16) { /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */ } if (iVersion < 17) { m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer"); m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto } if (iVersion < 19) { // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades ADDON::VECADDONS addons; if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__); else { CAddonDatabase database; database.Open(); for (IVECADDONS it = addons.begin(); it != addons.end(); it++) { if (!database.IsSystemPVRAddonEnabled(it->get()->ID())) CAddonMgr::Get().DisableAddon(it->get()->ID()); } database.Close(); } } if (iVersion < 20) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool"); if (iVersion < 21) m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer"); if (iVersion < 22) m_pDS->exec("ALTER TABLE channels ADD bIsLocked bool"); if (iVersion < 23) m_pDS->exec("ALTER TABLE channelgroups ADD iLastWatched integer"); }
void CLangInfo::SettingOptionsLanguageNamesFiller(const CSetting *setting, std::vector< std::pair<std::string, std::string> > &list, std::string ¤t, void *data) { // find languages... ADDON::VECADDONS addons; if (!ADDON::CAddonMgr::GetInstance().GetAddons(ADDON::ADDON_RESOURCE_LANGUAGE, addons, true)) return; for (ADDON::VECADDONS::const_iterator addon = addons.begin(); addon != addons.end(); ++addon) list.push_back(make_pair((*addon)->Name(), (*addon)->Name())); sort(list.begin(), list.end(), SortLanguage()); }
std::set<std::string> CGUIControllerList::GetNewControllerIDs(ADDON::VECADDONS& addonCache) const { std::set<std::string> controllerIds; CAddonMgr::GetInstance().GetAddons(addonCache, ADDON_GAME_CONTROLLER); std::transform(addonCache.begin(), addonCache.end(), std::inserter(controllerIds, controllerIds.end()), [](const AddonPtr& addon) { return addon->ID(); }); return controllerIds; }
bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = false */) { bool bReturn(true); ADDON::VECADDONS map; ADDON::VECADDONS disableAddons; { CSingleLock lock(m_critSection); map = m_addons; } if (map.size() == 0) return false; for (unsigned iClientPtr = 0; iClientPtr < map.size(); iClientPtr++) { const AddonPtr clientAddon = map.at(iClientPtr); bool bEnabled = clientAddon->Enabled() && !m_addonDb.IsAddonDisabled(clientAddon->ID()); if (!bEnabled && IsKnownClient(clientAddon)) { CSingleLock lock(m_critSection); /* stop the client and remove it from the db */ StopClient(clientAddon, false); ADDON::VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), clientAddon); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } else if (bEnabled && (bInitialiseAllClients || !IsKnownClient(clientAddon) || !IsConnectedClient(clientAddon))) { bool bDisabled(false); // register the add-on in the pvr db, and create the CPVRClient instance int iClientId = RegisterClient(clientAddon); if (iClientId < 0) { // failed to register or create the add-on, disable it CLog::Log(LOGWARNING, "%s - failed to register add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } else { ADDON_STATUS status(ADDON_STATUS_UNKNOWN); PVR_CLIENT addon; { CSingleLock lock(m_critSection); if (!GetClient(iClientId, addon)) { CLog::Log(LOGWARNING, "%s - failed to find add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } } // throttle connection attempts, no more than 1 attempt per 5 seconds if (!bDisabled && addon->Enabled()) { time_t now; CDateTime::GetCurrentDateTime().GetAsTime(now); std::map<int, time_t>::iterator it = m_connectionAttempts.find(iClientId); if (it != m_connectionAttempts.end() && now < it->second) continue; m_connectionAttempts[iClientId] = now + 5; } // re-check the enabled status. newly installed clients get disabled when they're added to the db if (!bDisabled && addon->Enabled() && (status = addon->Create(iClientId)) != ADDON_STATUS_OK) { CLog::Log(LOGWARNING, "%s - failed to create add-on %s, status = %d", __FUNCTION__, clientAddon->Name().c_str(), status); if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE) { // failed to load the dll of this add-on, disable it CLog::Log(LOGWARNING, "%s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } } } if (bDisabled && (g_PVRManager.GetState() == ManagerStateStarted || g_PVRManager.GetState() == ManagerStateStarting)) CGUIDialogOK::ShowAndGetInput(24070, 24071, 16029, 0); } } // disable add-ons that failed to initialise if (disableAddons.size() > 0) { CSingleLock lock(m_critSection); for (ADDON::VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); it++) { // disable in the add-on db m_addonDb.DisableAddon((*it)->ID(), true); // remove from the pvr add-on list ADDON::VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }
void CPVRDatabase::CreateTables() { CLog::Log(LOGINFO, "PVR - %s - creating tables", __FUNCTION__); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'clients'", __FUNCTION__); m_pDS->exec( "CREATE TABLE clients (" "idClient integer primary key, " "sName varchar(64), " "sUid varchar(32)" ")" ); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channels (" "idChannel integer primary key, " "iUniqueId integer, " "bIsRadio bool, " "bIsHidden bool, " "bIsUserSetIcon bool, " "bIsLocked bool, " "sIconPath varchar(255), " "sChannelName varchar(64), " "bIsVirtual bool, " "bEPGEnabled bool, " "sEPGScraper varchar(32), " "iLastWatched integer," // TODO use mapping table "iClientId integer, " "iClientChannelNumber integer, " "sInputFormat varchar(32), " "sStreamURL varchar(255), " "iEncryptionSystem integer, " "idEpg integer" ")" ); // TODO use a mapping table so multiple backends per channel can be implemented // CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channels_clients'", __FUNCTION__); // m_pDS->exec( // "CREATE TABLE map_channels_clients (" // "idChannel integer primary key, " // "idClient integer, " // "iClientChannelNumber integer," // "sInputFormat string," // "sStreamURL string," // "iEncryptionSystem integer" // ");" // ); // m_pDS->exec("CREATE UNIQUE INDEX idx_idChannel_idClient on map_channels_clients(idChannel, idClient);"); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelgroups'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelgroups (" "idGroup integer primary key," "bIsRadio bool, " "iGroupType integer, " "sName varchar(64), " "iLastWatched integer" ")" ); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'map_channelgroups_channels'", __FUNCTION__); m_pDS->exec( "CREATE TABLE map_channelgroups_channels (" "idChannel integer, " "idGroup integer, " "iChannelNumber integer" ")" ); CLog::Log(LOGDEBUG, "PVR - %s - creating table 'channelsettings'", __FUNCTION__); m_pDS->exec( "CREATE TABLE channelsettings (" "idChannel integer primary key, " "iInterlaceMethod integer, " "iViewMode integer, " "fCustomZoomAmount float, " "fPixelRatio float, " "iAudioStream integer, " "iSubtitleStream integer," "fSubtitleDelay float, " "bSubtitles bool, " "fBrightness float, " "fContrast float, " "fGamma float," "fVolumeAmplification float, " "fAudioDelay float, " "bOutputToAllSpeakers bool, " "bCrop bool, " "iCropLeft integer, " "iCropRight integer, " "iCropTop integer, " "iCropBottom integer, " "fSharpness float, " "fNoiseReduction float, " "fCustomVerticalShift float, " "bCustomNonLinStretch bool, " "bPostProcess bool, " "iScalingMethod integer, " "iDeinterlaceMode integer " ")" ); // disable all PVR add-on when started the first time ADDON::VECADDONS addons; if (!CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true)) CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__); else { for (IVECADDONS it = addons.begin(); it != addons.end(); it++) CAddonMgr::Get().DisableAddon(it->get()->ID()); } }
int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!dialog) return 0; CFileItemList items; CStdString heading; int iTypes = 0; for (vector<ADDON::TYPE>::const_iterator it = types.begin(); it != types.end(); ++it) { if (*it == ADDON_UNKNOWN) continue; ADDON::VECADDONS addons; iTypes++; if (*it == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (*it == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (*it == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (*it == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(*it, addons); for (ADDON::IVECADDONS it2 = addons.begin() ; it2 != addons.end() ; ++it2) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*it2, "")); if (!items.Contains(item->GetPath())) items.Add(item); } if (!heading.IsEmpty()) heading += ", "; heading += TranslateType(*it, true); } if (iTypes == 0) return 0; dialog->SetHeading(heading); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) showNone = false; if (multipleSelection || iTypes > 1) dialog->EnableButton(true, 186); else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SORT_METHOD_LABEL, SortOrderAscending); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && iTypes == 1 && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(types[0],false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
int CGUIWindowAddonBrowser::SelectAddonID(ADDON::TYPE type, CStdStringArray &addonIDs, bool showNone /*= false*/, bool multipleSelection /*= true*/) { CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (type == ADDON_UNKNOWN || !dialog) return 0; ADDON::VECADDONS addons; if (type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio",addons); else if (type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable",addons); else if (type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image",addons); else if (type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video",addons); else CAddonMgr::Get().GetAddons(type, addons); CFileItemList items; for (ADDON::IVECADDONS i = addons.begin(); i != addons.end(); ++i) items.Add(CAddonsDirectory::FileItemFromAddon(*i, "")); dialog->SetHeading(TranslateType(type, true)); dialog->Reset(); dialog->SetUseDetails(true); if (multipleSelection) { showNone = false; dialog->EnableButton(true, 186); } else dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SORT_ON_TOP); items.Add(item); } items.Sort(SORT_METHOD_LABEL, SORT_ORDER_ASC); if (addonIDs.size() > 0) { for (CStdStringArray::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; it++) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->DoModal(); if (!multipleSelection && dialog->IsButtonPressed()) { // switch to the addons browser. vector<CStdString> params; params.push_back("addons://all/"+TranslateType(type,false)+"/"); params.push_back("return"); g_windowManager.ActivateWindow(WINDOW_ADDON_BROWSER, params); return 2; } if (!multipleSelection && dialog->GetSelectedLabel() == -1) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0 ; i < list.Size() ; i++) addonIDs.push_back(list.Get(i)->GetPath()); return 1; }
bool CPVRClients::UpdateAndInitialiseClients(bool bInitialiseAllClients /* = false */) { bool bReturn(true); ADDON::VECADDONS map; ADDON::VECADDONS disableAddons; { CSingleLock lock(m_critSection); map = m_addons; } if (map.size() == 0) return false; for (unsigned iClientPtr = 0; iClientPtr < map.size(); iClientPtr++) { const AddonPtr clientAddon = map.at(iClientPtr); bool bEnabled = clientAddon->Enabled() && !m_addonDb.IsAddonDisabled(clientAddon->ID()); if (!bEnabled && IsKnownClient(clientAddon)) { CSingleLock lock(m_critSection); /* stop the client and remove it from the db */ StopClient(clientAddon, false); ADDON::VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), clientAddon); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } else if (bEnabled && (bInitialiseAllClients || !IsKnownClient(clientAddon) || !IsConnectedClient(clientAddon))) { bool bDisabled(false); // register the add-on in the pvr db, and create the CPVRClient instance int iClientId = RegisterClient(clientAddon); if (iClientId < 0) { // failed to register or create the add-on, disable it CLog::Log(LOGWARNING, "%s - failed to register add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } else { PVR_CLIENT addon; if (!GetClient(iClientId, addon)) { CLog::Log(LOGWARNING, "%s - failed to find add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } // re-check the enabled status. newly installed clients get disabled when they're added to the db else if (addon->Enabled() && !addon->Create(iClientId)) { CLog::Log(LOGWARNING, "%s - failed to create add-on %s", __FUNCTION__, clientAddon->Name().c_str()); if (!addon.get() || !addon->DllLoaded()) { // failed to load the dll of this add-on, disable it CLog::Log(LOGWARNING, "%s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, clientAddon->Name().c_str()); disableAddons.push_back(clientAddon); bDisabled = true; } } } if (bDisabled && (g_PVRManager.GetState() == ManagerStateStarted || g_PVRManager.GetState() == ManagerStateStarting)) CGUIDialogOK::ShowAndGetInput(24070, 24071, 16029, 0); } } // disable add-ons that failed to initialise if (disableAddons.size() > 0) { CSingleLock lock(m_critSection); for (ADDON::VECADDONS::iterator it = disableAddons.begin(); it != disableAddons.end(); it++) { // disable in the add-on db m_addonDb.DisableAddon((*it)->ID(), true); // remove from the pvr add-on list ADDON::VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *it); if (addonPtr != m_addons.end()) m_addons.erase(addonPtr); } } return bReturn; }
bool CPVRDatabase::UpdateOldVersion(int iVersion) { bool bReturn = true; BeginTransaction(); try { if (iVersion < 11) { CLog::Log(LOGERROR, "PVR - %s - updating from table versions < 11 not supported. please delete '%s'", __FUNCTION__, GetBaseDBName()); bReturn = false; } else { if (iVersion < 12) m_pDS->exec("DROP VIEW vw_last_watched;"); if (iVersion < 13) m_pDS->exec("ALTER TABLE channels ADD idEpg integer;"); if (iVersion < 14) m_pDS->exec("ALTER TABLE channelsettings ADD fCustomVerticalShift float;"); if (iVersion < 15) { m_pDS->exec("ALTER TABLE channelsettings ADD bCustomNonLinStretch bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD bPostProcess bool;"); m_pDS->exec("ALTER TABLE channelsettings ADD iScalingMethod integer;"); } if (iVersion < 16) { /* sqlite apparently can't delete columns from an existing table, so just leave the extra column alone */ } if (iVersion < 17) { m_pDS->exec("ALTER TABLE channelsettings ADD iDeinterlaceMode integer"); m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 2 WHERE iInterlaceMethod NOT IN (0,1)"); // anything other than none: method auto => mode force m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 1 WHERE iInterlaceMethod = 1"); // method auto => mode auto m_pDS->exec("UPDATE channelsettings SET iDeinterlaceMode = 0, iInterlaceMethod = 1 WHERE iInterlaceMethod = 0"); // method none => mode off, method auto } if (iVersion < 18) { m_pDS->exec("DROP INDEX idx_channels_iClientId;"); m_pDS->exec("DROP INDEX idx_channels_iLastWatched;"); m_pDS->exec("DROP INDEX idx_channels_bIsRadio;"); m_pDS->exec("DROP INDEX idx_channels_bIsHidden;"); m_pDS->exec("DROP INDEX idx_idChannel_idGroup;"); m_pDS->exec("DROP INDEX idx_idGroup_iChannelNumber;"); m_pDS->exec("CREATE UNIQUE INDEX idx_channels_iClientId_iUniqueId on channels(iClientId, iUniqueId);"); m_pDS->exec("CREATE UNIQUE INDEX idx_idGroup_idChannel on map_channelgroups_channels(idGroup, idChannel);"); } if (iVersion < 19) { // bit of a hack, but we need to keep the version/contents of the non-pvr databases the same to allow clean upgrades ADDON::VECADDONS addons; if ((bReturn = CAddonMgr::Get().GetAddons(ADDON_PVRDLL, addons, true, false)) == false) CLog::Log(LOGERROR, "PVR - %s - failed to get add-ons from the add-on manager", __FUNCTION__); else { CAddonDatabase database; database.Open(); for (IVECADDONS it = addons.begin(); it != addons.end(); it++) { if (!database.IsSystemPVRAddonEnabled(it->get()->ID())) database.DisableAddon(it->get()->ID()); } database.Close(); } } if (iVersion < 20) m_pDS->exec("ALTER TABLE channels ADD bIsUserSetIcon bool"); if (iVersion < 21) m_pDS->exec("ALTER TABLE channelgroups ADD iGroupType integer"); } } catch (...) { CLog::Log(LOGERROR, "PVR - %s - error attempting to update the database version!", __FUNCTION__); bReturn = false; } if (bReturn) CommitTransaction(); else RollbackTransaction(); return bReturn; }