void CAddonHelpers_PVR::PVRTransferRecordingEntry(void *addonData, const PVRHANDLE handle, const PVR_RECORDINGINFO *recording) { CAddonHelpers* addon = (CAddonHelpers*) addonData; if (addon == NULL || handle == NULL || recording == NULL) { CLog::Log(LOGERROR, "PVR: PVRTransferRecordingEntry is called with NULL-Pointer!!!"); return; } CPVRClient* client = (CPVRClient*) handle->CALLER_ADDRESS; CPVRRecordings *xbmcRecordings = (CPVRRecordings*) handle->DATA_ADDRESS; CPVRRecordingInfoTag tag; tag.SetClientIndex(recording->index); tag.SetClientID(client->GetClientID()); tag.SetTitle(recording->title); tag.SetRecordingTime(recording->recording_time); tag.SetDuration(CDateTimeSpan(0, 0, recording->duration / 60, recording->duration % 60)); tag.SetPriority(recording->priority); tag.SetLifetime(recording->lifetime); tag.SetDirectory(recording->directory); tag.SetPlot(recording->description); tag.SetPlotOutline(recording->subtitle); tag.SetStreamURL(recording->stream_url); tag.SetChannelName(recording->channel_name); xbmcRecordings->push_back(tag); return; }
bool CTextureDatabase::GetCachedTexture(const CStdString &url, CStdString &cacheFile, CStdString &imageHash) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; CStdString sql = PrepareSQL("select id, cachedurl, lasthashcheck, imagehash from texture where url='%s'", url.c_str()); m_pDS->query(sql.c_str()); if (!m_pDS->eof()) { // have some information int textureID = m_pDS->fv(0).get_asInt(); cacheFile = m_pDS->fv(1).get_asString(); CDateTime lastCheck; lastCheck.SetFromDBDateTime(m_pDS->fv(2).get_asString()); if (!lastCheck.IsValid() || lastCheck + CDateTimeSpan(1,0,0,0) < CDateTime::GetCurrentDateTime()) imageHash = m_pDS->fv(3).get_asString(); m_pDS->close(); // update the use count sql = PrepareSQL("update texture set usecount=usecount+1, lastusetime=CURRENT_TIMESTAMP where id=%u", textureID); m_pDS->exec(sql.c_str()); return true; } m_pDS->close(); } catch (...) { CLog::Log(LOGERROR, "%s, failed on url '%s'", __FUNCTION__, url.c_str()); } return false; }
bool CTextureDatabase::GetCachedTexture(const CStdString &url, CTextureDetails &details) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS.get()) return false; CStdString sql = PrepareSQL("SELECT id, cachedurl, lasthashcheck, imagehash, width, height FROM texture JOIN sizes ON (texture.id=sizes.idtexture AND sizes.size=1) WHERE url='%s'", url.c_str()); m_pDS->query(sql.c_str()); if (!m_pDS->eof()) { // have some information details.id = m_pDS->fv(0).get_asInt(); details.file = m_pDS->fv(1).get_asString(); CDateTime lastCheck; lastCheck.SetFromDBDateTime(m_pDS->fv(2).get_asString()); if (lastCheck.IsValid() && lastCheck + CDateTimeSpan(1,0,0,0) < CDateTime::GetCurrentDateTime()) details.hash = m_pDS->fv(3).get_asString(); details.width = m_pDS->fv(4).get_asInt(); details.height = m_pDS->fv(5).get_asInt(); m_pDS->close(); return true; } m_pDS->close(); } catch (...) { CLog::Log(LOGERROR, "%s, failed on url '%s'", __FUNCTION__, url.c_str()); } return false; }
bool CEpg::Update(time_t start, time_t end, int iUpdateTime, bool bStoreInDb /* = true */) { bool bGrabSuccess = true; bool bUpdate = false; CEpgDatabase *database = g_EpgContainer.GetDatabase(); if (bStoreInDb && (!database || !database->Open())) { CLog::Log(LOGERROR, "Epg - %s - cannot open the database", __FUNCTION__); return false; } CSingleLock lock(m_critSection); /* get the last update time from the database */ if (!m_lastScanTime.IsValid() && bStoreInDb) database->GetLastEpgScanTime(m_iEpgID, &m_lastScanTime); /* check if we have to update */ time_t iNow = 0; time_t iLastUpdate = 0; CDateTime::GetCurrentDateTime().GetAsTime(iNow); m_lastScanTime.GetAsTime(iLastUpdate); bUpdate = (iNow > iLastUpdate + iUpdateTime); if (bUpdate) { m_bInhibitSorting = true; bGrabSuccess = UpdateFromScraper(start, end); m_bInhibitSorting = false; /* store the loaded EPG entries in the database */ if (bGrabSuccess && size() > 0) { Sort(); FixOverlappingEvents(false); if (bStoreInDb) { database->PersistLastEpgScanTime(m_iEpgID, true); database->Persist(*this, true); PersistTags(true); database->CommitInsertQueries(); } m_lastScanTime = CDateTime::GetCurrentDateTime(); } else { m_lastScanTime = CDateTime::GetCurrentDateTime() - CDateTimeSpan(0, 0, 0, iUpdateTime + 300); /* try again in 5 minutes */ } } if (bStoreInDb) database->Close(); return bGrabSuccess; }
bool CPVRTimerInfoTag::SetDuration(int iDuration) { if (m_StartTime != NULL) { m_StopTime = m_StartTime + CDateTimeSpan(0, iDuration / 60, iDuration % 60, 0); return true; } return false; }
CDateTime CDateTime::GetUTCDateTime() { TIME_ZONE_INFORMATION tz; CDateTime time(GetCurrentDateTime()); switch(GetTimeZoneInformation(&tz)) { case TIME_ZONE_ID_DAYLIGHT: time += CDateTimeSpan(0, 0, tz.Bias + tz.DaylightBias, 0); break; case TIME_ZONE_ID_STANDARD: time += CDateTimeSpan(0, 0, tz.Bias + tz.StandardBias, 0); break; case TIME_ZONE_ID_UNKNOWN: time += CDateTimeSpan(0, 0, tz.Bias, 0); break; } return time; }
void CPVREpg::Cleanup(const CDateTime &Time) { CSingleLock lock(m_critSection); for (unsigned int i = 0; i < size(); i++) { CPVREpgInfoTag *tag = (CPVREpgInfoTag *) at(i); if ( tag && /* valid tag */ !tag->HasTimer() && /* no timer set */ (tag->End() + CDateTimeSpan(0, g_advancedSettings.m_iEpgLingerTime / 60, g_advancedSettings.m_iEpgLingerTime % 60, 0) < Time)) { DeleteInfoTag(tag); } } }
void CEpg::Cleanup(const CDateTime &Time) { CSingleLock lock(m_critSection); unsigned int iSize = size(); for (unsigned int iTagPtr = 0; iTagPtr < iSize; iTagPtr++) { CEpgInfoTag *tag = at(iTagPtr); if ( tag && /* valid tag */ (tag->End() + CDateTimeSpan(0, g_advancedSettings.m_iEpgLingerTime / 60, g_advancedSettings.m_iEpgLingerTime % 60, 0) < Time)) { erase(begin() + iTagPtr); --iSize; --iTagPtr; } } }
void CAddonMgr::UpdateRepos(bool force) { CSingleLock lock(m_critSection); if (!force && m_watch.IsRunning() && m_watch.GetElapsedSeconds() < 600) return; m_watch.StartZero(); VECADDONS addons; GetAddons(ADDON_REPOSITORY,addons); for (unsigned int i=0;i<addons.size();++i) { RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addons[i]); CDateTime lastUpdate = m_database.GetRepoTimestamp(repo->ID()); if (force || !lastUpdate.IsValid() || lastUpdate + CDateTimeSpan(0,6,0,0) < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGDEBUG,"Checking repository %s for updates",repo->Name().c_str()); CJobManager::GetInstance().AddJob(new CRepositoryUpdateJob(repo), NULL); } } }
static std::string LookupUPnPHost(const std::string& uuid) { #ifdef HAS_UPNP UPNP::CUPnP* upnp = UPNP::CUPnP::GetInstance(); if (!upnp->IsClientStarted()) { upnp->StartClient(); upnpInitReady = CDateTime::GetCurrentDateTime() + CDateTimeSpan(0, 0, 0, 10); } PLT_SyncMediaBrowser* browser = upnp->m_MediaBrowser; PLT_DeviceDataReference device; if (browser && NPT_SUCCEEDED(browser->FindServer(uuid.c_str(), device)) && !device.IsNull()) return (const char*)device->GetURLBase().GetHost(); #endif return ""; }
void CGUIWindowPVRGuide::UpdateData(void) { CPVRChannel CurrentChannel; CPVRManager::Get()->GetCurrentChannel(&CurrentChannel); m_bUpdateRequired = false; m_parent->m_vecItems->Clear(); if (m_iGuideView == GUIDE_VIEW_CHANNEL) { m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_CHANNEL); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029)); m_parent->SetLabel(CONTROL_LABELGROUP, CurrentChannel.ChannelName().c_str()); if (CurrentChannel.GetEPG(m_parent->m_vecItems) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/" + CurrentChannel.ChannelName() + "/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_NOW) { m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_NOW_NEXT); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19030)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19030)); if (CPVRManager::GetEpg()->GetEPGNow(m_parent->m_vecItems, CurrentChannel.IsRadio()) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/now/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_NEXT) { m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_NOW_NEXT); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19031)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19031)); if (CPVRManager::GetEpg()->GetEPGNext(m_parent->m_vecItems, CurrentChannel.IsRadio()) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/next/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_TIMELINE) { m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19032)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19032)); if (CPVRManager::GetEpg()->GetEPGAll(m_parent->m_vecItems, CurrentChannel.IsRadio()) > 0) { CDateTime now = CDateTime::GetCurrentDateTime(); CDateTime m_gridStart = now - CDateTimeSpan(0, 0, 0, (now.GetMinute() % 30) * 60 + now.GetSecond()) - CDateTimeSpan(0, g_guiSettings.GetInt("epg.lingertime") / 60, g_guiSettings.GetInt("epg.lingertime") % 60, 0); CDateTime m_gridEnd = m_gridStart + CDateTimeSpan(g_guiSettings.GetInt("epg.daystodisplay"), 0, 0, 0); m_parent->m_guideGrid = (CGUIEPGGridContainer*) m_parent->GetControl(CONTROL_LIST_TIMELINE); if (m_parent->m_guideGrid) { m_parent->m_guideGrid->SetStartEnd(m_gridStart, m_gridEnd); m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_TIMELINE); } // m_viewControl.SetSelectedItem(m_iSelected_GUIDE); } } m_parent->SetLabel(CONTROL_LABELHEADER, g_localizeStrings.Get(19029)); UpdateButtons(); }
CPVRTimerInfoTag *CPVRTimerInfoTag::CreateFromEpg(const CPVREpgInfoTag &tag) { /* create a new timer */ CPVRTimerInfoTag *newTag = new CPVRTimerInfoTag(); if (!newTag) { CLog::Log(LOGERROR, "%s - couldn't create new timer", __FUNCTION__); return NULL; } /* check if a valid channel is set */ const CPVRChannel *channel = tag.ChannelTag(); if (channel == NULL) { CLog::Log(LOGERROR, "%s - no channel set", __FUNCTION__); return NULL; } /* check if the epg end date is in the future */ if (tag.End() < CDateTime::GetCurrentDateTime()) { CLog::Log(LOGERROR, "%s - end time is in the past", __FUNCTION__); return NULL; } int iPriority = g_guiSettings.GetInt("pvrrecord.defaultpriority"); if (!iPriority) iPriority = 50; /* default to 50 */ int iLifetime = g_guiSettings.GetInt("pvrrecord.defaultlifetime"); if (!iLifetime) iLifetime = 30; /* default to 30 days */ int iMarginStart = g_guiSettings.GetInt("pvrrecord.marginstart"); if (!iMarginStart) iMarginStart = 5; /* default to 5 minutes */ int iMarginStop = g_guiSettings.GetInt("pvrrecord.marginstop"); if (!iMarginStop) iMarginStop = 10; /* default to 10 minutes */ /* set the timer data */ newTag->m_iClientIndex = (tag.UniqueBroadcastID() > 0 ? tag.UniqueBroadcastID() : channel->ClientID()); newTag->m_bIsActive = true; newTag->m_strTitle = tag.Title().IsEmpty() ? channel->ChannelName() : tag.Title(); newTag->m_iChannelNumber = channel->ChannelNumber(); newTag->m_iClientNumber = channel->ClientChannelNumber(); newTag->m_iClientID = channel->ClientID(); newTag->m_bIsRadio = channel->IsRadio(); newTag->m_StartTime = tag.Start() - CDateTimeSpan(0, iMarginStart / 60, iMarginStart % 60, 0); newTag->m_StopTime = tag.End() + CDateTimeSpan(0, iMarginStop / 60, iMarginStop % 60, 0); newTag->m_iPriority = iPriority; newTag->m_iLifetime = iLifetime; /* generate summary string */ newTag->m_strSummary.Format("%s %s %s %s %s", newTag->m_StartTime.GetAsLocalizedDate(), g_localizeStrings.Get(19159), newTag->m_StartTime.GetAsLocalizedTime("", false), g_localizeStrings.Get(19160), newTag->m_StopTime.GetAsLocalizedTime("", false)); /* unused only for reference */ newTag->m_strFileNameAndPath = "pvr://timers/new"; return newTag; }
int CWebServer::FinalizeRequest(IHTTPRequestHandler *handler, int responseStatus, struct MHD_Response *response) { if (handler == NULL || response == NULL) return MHD_NO; const HTTPRequest &request = handler->GetRequest(); const HTTPResponseDetails &responseDetails = handler->GetResponseDetails(); // if the request handler has set a content type and it hasn't been set as a header, add it if (!responseDetails.contentType.empty()) handler->AddResponseHeader(MHD_HTTP_HEADER_CONTENT_TYPE, responseDetails.contentType); // if the request handler has set a last modified date and it hasn't been set as a header, add it CDateTime lastModified; if (handler->GetLastModifiedDate(lastModified) && lastModified.IsValid()) handler->AddResponseHeader(MHD_HTTP_HEADER_LAST_MODIFIED, lastModified.GetAsRFC1123DateTime()); // check if the request handler has set Cache-Control and add it if not if (!handler->HasResponseHeader(MHD_HTTP_HEADER_CACHE_CONTROL)) { int maxAge = handler->GetMaximumAgeForCaching(); if (handler->CanBeCached() && maxAge == 0 && !responseDetails.contentType.empty()) { // don't cache HTML, CSS and JavaScript files if (!StringUtils::EqualsNoCase(responseDetails.contentType, "text/html") && !StringUtils::EqualsNoCase(responseDetails.contentType, "text/css") && !StringUtils::EqualsNoCase(responseDetails.contentType, "application/javascript")) maxAge = CDateTimeSpan(365, 0, 0, 0).GetSecondsTotal(); } // if the response can't be cached or the maximum age is 0 force the client not to cache if (!handler->CanBeCached() || maxAge == 0) handler->AddResponseHeader(MHD_HTTP_HEADER_CACHE_CONTROL, "private, max-age=0, " HEADER_VALUE_NO_CACHE); else { // create the value of the Cache-Control header std::string cacheControl = StringUtils::Format("public, max-age=%d", maxAge); // check if the response contains a Set-Cookie header because they must not be cached if (handler->HasResponseHeader(MHD_HTTP_HEADER_SET_COOKIE)) cacheControl += ", no-cache=\"set-cookie\""; // set the Cache-Control header handler->AddResponseHeader(MHD_HTTP_HEADER_CACHE_CONTROL, cacheControl); // set the Expires header CDateTime expiryTime = CDateTime::GetCurrentDateTime() + CDateTimeSpan(0, 0, 0, maxAge); handler->AddResponseHeader(MHD_HTTP_HEADER_EXPIRES, expiryTime.GetAsRFC1123DateTime()); } } // if the request handler can handle ranges and it hasn't been set as a header, add it if (handler->CanHandleRanges()) handler->AddResponseHeader(MHD_HTTP_HEADER_ACCEPT_RANGES, "bytes"); else handler->AddResponseHeader(MHD_HTTP_HEADER_ACCEPT_RANGES, "none"); // add MHD_HTTP_HEADER_CONTENT_LENGTH if (responseDetails.totalLength > 0) handler->AddResponseHeader(MHD_HTTP_HEADER_CONTENT_LENGTH, StringUtils::Format("%" PRIu64, responseDetails.totalLength)); // add all headers set by the request handler for (std::multimap<std::string, std::string>::const_iterator it = responseDetails.headers.begin(); it != responseDetails.headers.end(); ++it) AddHeader(response, it->first, it->second); #ifdef WEBSERVER_DEBUG std::multimap<std::string, std::string> headerValues; GetRequestHeaderValues(request.connection, MHD_RESPONSE_HEADER_KIND, headerValues); CLog::Log(LOGDEBUG, "webserver [OUT] %s %d %s", request.version.c_str(), responseStatus, request.pathUrlFull.c_str()); for (std::multimap<std::string, std::string>::const_iterator header = headerValues.begin(); header != headerValues.end(); ++header) CLog::Log(LOGDEBUG, "webserver [OUT] %s: %s", header->first.c_str(), header->second.c_str()); #endif int ret = MHD_queue_response(request.connection, responseStatus, response); MHD_destroy_response(response); delete handler; return ret; }
void CGUIWindowPVRGuide::UpdateData(void) { if (m_bIsFocusing) return; CLog::Log(LOGDEBUG, "CGUIWindowPVRGuide - %s - update window '%s'. set view to %d", __FUNCTION__, GetName(), m_iControlList); m_bIsFocusing = true; CPVRChannel CurrentChannel; bool bGotCurrentChannel = CPVRManager::Get()->GetCurrentChannel(&CurrentChannel); m_bUpdateRequired = false; m_parent->m_vecItems->Clear(); if (m_iGuideView == GUIDE_VIEW_CHANNEL) { m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_CHANNEL); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029)); if (bGotCurrentChannel) m_parent->SetLabel(CONTROL_LABELGROUP, CurrentChannel.ChannelName().c_str()); if (!bGotCurrentChannel || CPVRManager::Get()->GetCurrentEpg(m_parent->m_vecItems) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/" + CurrentChannel.ChannelName() + "/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_NOW) { bool bRadio = bGotCurrentChannel ? CurrentChannel.IsRadio() : false; m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_NOW_NEXT); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19030)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19030)); if (CPVRManager::GetEpg()->GetEPGNow(m_parent->m_vecItems, bRadio) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/now/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_NEXT) { bool bRadio = bGotCurrentChannel ? CurrentChannel.IsRadio() : false; m_parent->m_guideGrid = NULL; m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_GUIDE_NOW_NEXT); m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19031)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19031)); if (CPVRManager::GetEpg()->GetEPGNext(m_parent->m_vecItems, bRadio) == 0) { CFileItemPtr item; item.reset(new CFileItem("pvr://guide/next/empty.epg", false)); item->SetLabel(g_localizeStrings.Get(19028)); item->SetLabelPreformated(true); m_parent->m_vecItems->Add(item); } m_parent->m_viewControl.SetItems(*m_parent->m_vecItems); } else if (m_iGuideView == GUIDE_VIEW_TIMELINE) { bool bRadio = bGotCurrentChannel ? CurrentChannel.IsRadio() : false; m_parent->SetLabel(m_iControlButton, g_localizeStrings.Get(19029) + ": " + g_localizeStrings.Get(19032)); m_parent->SetLabel(CONTROL_LABELGROUP, g_localizeStrings.Get(19032)); if (CPVRManager::GetEpg()->GetEPGAll(m_parent->m_vecItems, bRadio) > 0) { m_parent->m_guideGrid = (CGUIEPGGridContainer*) m_parent->GetControl(CONTROL_LIST_TIMELINE); if (m_parent->m_guideGrid) { CDateTime gridStart = CDateTime::GetCurrentDateTime() - CDateTimeSpan(0, 0, g_advancedSettings.m_iEpgLingerTime, 0); CDateTime firstDate = CPVRManager::GetEpg()->GetFirstEPGDate(bRadio); CDateTime lastDate = CPVRManager::GetEpg()->GetLastEPGDate(bRadio); m_parent->m_guideGrid->SetStartEnd(firstDate > gridStart ? firstDate : gridStart, lastDate); m_parent->m_viewControl.SetCurrentView(CONTROL_LIST_TIMELINE); } // m_viewControl.SetSelectedItem(m_iSelected_GUIDE); } } m_parent->SetLabel(CONTROL_LABELHEADER, g_localizeStrings.Get(19029)); UpdateButtons(); m_bIsFocusing = false; }
bool CTextureDatabase::InvalidateCachedTexture(const CStdString &url) { CStdString date = (CDateTime::GetCurrentDateTime() - CDateTimeSpan(2, 0, 0, 0)).GetAsDBDateTime(); CStdString sql = PrepareSQL("UPDATE texture SET lasthashcheck='%s' WHERE url='%s'", date.c_str(), url.c_str()); return ExecuteQuery(sql); }