Merge pull request #1129 from jmarshallnz/remove_smb_auth_details_in_add_source
[vuplus_xbmc] / xbmc / programs / ProgramDatabase.cpp
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21
22 #include "ProgramDatabase.h"
23 #include "Util.h"
24 #include "windows/GUIWindowFileManager.h"
25 #include "FileItem.h"
26 #include "settings/GUISettings.h"
27 #include "settings/Settings.h"
28 #include "utils/log.h"
29 #include "utils/URIUtils.h"
30 #include "dbwrappers/dataset.h"
31
32 using namespace XFILE;
33
34 //********************************************************************************************************************************
35 CProgramDatabase::CProgramDatabase(void)
36 {
37 }
38
39 //********************************************************************************************************************************
40 CProgramDatabase::~CProgramDatabase(void)
41 {
42
43 }
44
45 //********************************************************************************************************************************
46 bool CProgramDatabase::Open()
47 {
48   return CDatabase::Open();
49 }
50
51 bool CProgramDatabase::CreateTables()
52 {
53
54   try
55   {
56     CDatabase::CreateTables();
57
58     CLog::Log(LOGINFO, "create files table");
59     m_pDS->exec("CREATE TABLE files ( idFile integer primary key, strFilename text, titleId integer, xbedescription text, iTimesPlayed integer, lastAccessed integer, iRegion integer, iSize integer)\n");
60     CLog::Log(LOGINFO, "create files index");
61     m_pDS->exec("CREATE INDEX idxFiles ON files(strFilename)");
62     CLog::Log(LOGINFO, "create files - titleid index");
63     m_pDS->exec("CREATE INDEX idxTitleIdFiles ON files(titleId)");
64   }
65   catch (...)
66   {
67     CLog::Log(LOGERROR, "programdatabase::unable to create tables:%u",
68               GetLastError());
69     return false;
70   }
71
72   return true;
73 }
74
75 bool CProgramDatabase::UpdateOldVersion(int version)
76 {
77   return true;
78 }
79
80 uint32_t CProgramDatabase::GetTitleId(const CStdString& strFilenameAndPath)
81 {
82   if (NULL == m_pDB.get()) return 0;
83   if (NULL == m_pDS.get()) return 0;
84
85   try
86   {
87     CStdString strSQL = PrepareSQL("select * from files where files.strFileName like '%s'", strFilenameAndPath.c_str());
88     if (!m_pDS->query(strSQL.c_str()))
89       return 0;
90
91     int iRowsFound = m_pDS->num_rows();
92     if (iRowsFound == 0)
93     {
94       m_pDS->close();
95       return 0;
96     }
97     uint32_t dwTitleId = m_pDS->fv("files.TitleId").get_asInt();
98     m_pDS->close();
99     return dwTitleId;
100   }
101   catch (...)
102   {
103     CLog::Log(LOGERROR, "CProgramDatabase:GetTitleId(%s) failed", strFilenameAndPath.c_str());
104   }
105   return 0;
106 }
107
108 bool CProgramDatabase::SetTitleId(const CStdString& strFileName, uint32_t dwTitleId)
109 {
110   try
111   {
112     if (NULL == m_pDB.get()) return false;
113     if (NULL == m_pDS.get()) return false;
114
115     CStdString strSQL = PrepareSQL("select * from files where files.strFileName like '%s'", strFileName.c_str());
116     if (!m_pDS->query(strSQL.c_str())) return false;
117     int iRowsFound = m_pDS->num_rows();
118     if (iRowsFound == 0)
119     {
120       m_pDS->close();
121       return false;
122     }
123     int idFile = m_pDS->fv("files.idFile").get_asInt();
124     m_pDS->close();
125
126     CLog::Log(LOGDEBUG, "CProgramDatabase::SetTitle(%s), idFile=%i, region=%u",
127               strFileName.c_str(), idFile,dwTitleId);
128
129     strSQL=PrepareSQL("update files set titleId=%u where idFile=%i",
130                   dwTitleId, idFile);
131     m_pDS->exec(strSQL.c_str());
132     return true;
133   }
134   catch (...)
135   {
136     CLog::Log(LOGERROR, "CProgramDatabase:SetDescription(%s) failed", strFileName.c_str());
137   }
138
139   return false;
140 }
141
142 bool CProgramDatabase::GetXBEPathByTitleId(const uint32_t titleId, CStdString& strPathAndFilename)
143 {
144   try
145   {
146     if (NULL == m_pDB.get()) return false;
147     if (NULL == m_pDS.get()) return false;
148
149     CStdString strSQL=PrepareSQL("select files.strFilename from files where files.titleId=%u", titleId);
150     m_pDS->query(strSQL.c_str());
151     if (m_pDS->num_rows() > 0)
152     {
153       strPathAndFilename = m_pDS->fv("files.strFilename").get_asString();
154       strPathAndFilename.Replace('/', '\\');
155       m_pDS->close();
156       return true;
157     }
158     m_pDS->close();
159     return false;
160   }
161   catch (...)
162   {
163     CLog::Log(LOGERROR, "CProgramDatabase::GetXBEPathByTitleId(%u) failed",
164               titleId);
165   }
166   return false;
167 }
168
169 uint32_t CProgramDatabase::GetProgramInfo(CFileItem *item)
170 {
171   uint32_t titleID = 0;
172   try
173   {
174     if (NULL == m_pDB.get()) return false;
175     if (NULL == m_pDS.get()) return false;
176
177     CStdString strSQL = PrepareSQL("select xbedescription,iTimesPlayed,lastAccessed,titleId,iSize from files where strFileName like '%s'", item->GetPath().c_str());
178     m_pDS->query(strSQL.c_str());
179     if (!m_pDS->eof())
180     { // get info - only set the label if not preformatted
181       if (!item->IsLabelPreformated())
182         item->SetLabel(m_pDS->fv("xbedescription").get_asString());
183       item->m_iprogramCount = m_pDS->fv("iTimesPlayed").get_asInt();
184       item->m_strTitle = item->GetLabel();  // is this needed?
185       item->m_dateTime = TimeStampToLocalTime(_atoi64(m_pDS->fv("lastAccessed").get_asString().c_str()));
186       item->m_dwSize = _atoi64(m_pDS->fv("iSize").get_asString().c_str());
187       titleID = m_pDS->fv("titleId").get_asInt();
188       if (item->m_dwSize == -1)
189       {
190         CStdString strPath;
191         URIUtils::GetDirectory(item->GetPath(),strPath);
192         int64_t iSize = CGUIWindowFileManager::CalculateFolderSize(strPath);
193         CStdString strSQL=PrepareSQL("update files set iSize=%I64u where strFileName like '%s'",iSize,item->GetPath().c_str());
194         m_pDS->exec(strSQL.c_str());
195       }
196     }
197     m_pDS->close();
198   }
199   catch (...)
200   {
201     CLog::Log(LOGERROR, "CProgramDatabase::GetProgramInfo(%s) failed", item->GetPath().c_str());
202   }
203   return titleID;
204 }
205
206 bool CProgramDatabase::AddProgramInfo(CFileItem *item, unsigned int titleID)
207 {
208   try
209   {
210     if (NULL == m_pDB.get()) return false;
211     if (NULL == m_pDS.get()) return false;
212
213     int iRegion = -1;
214     if (g_guiSettings.GetBool("myprograms.gameautoregion"))
215     {
216         iRegion = 0;
217     }
218     FILETIME time;
219     item->m_dateTime=CDateTime::GetCurrentDateTime();
220     item->m_dateTime.GetAsTimeStamp(time);
221
222     ULARGE_INTEGER lastAccessed;
223     lastAccessed.u.LowPart = time.dwLowDateTime;
224     lastAccessed.u.HighPart = time.dwHighDateTime;
225
226     CStdString strPath;
227     URIUtils::GetDirectory(item->GetPath(),strPath);
228     // special case - programs in root of sources
229     bool bIsShare=false;
230     CUtil::GetMatchingSource(strPath,g_settings.m_programSources,bIsShare);
231     int64_t iSize=0;
232     if (bIsShare)
233     {
234       struct __stat64 stat;
235       if (CFile::Stat(item->GetPath(),&stat) == 0)
236         iSize = stat.st_size;
237     }
238     else
239       iSize = CGUIWindowFileManager::CalculateFolderSize(strPath);
240     if (titleID == 0)
241       titleID = (unsigned int) -1;
242     CStdString strSQL=PrepareSQL("insert into files (idFile, strFileName, titleId, xbedescription, iTimesPlayed, lastAccessed, iRegion, iSize) values(NULL, '%s', %u, '%s', %i, %I64u, %i, %I64u)", item->GetPath().c_str(), titleID, item->GetLabel().c_str(), 0, lastAccessed.QuadPart, iRegion, iSize);
243     m_pDS->exec(strSQL.c_str());
244     item->m_dwSize = iSize;
245   }
246   catch (...)
247   {
248     CLog::Log(LOGERROR, "CProgramDatabase::AddProgramInfo(%s) failed", item->GetPath().c_str());
249   }
250   return true;
251 }
252
253 FILETIME CProgramDatabase::TimeStampToLocalTime(uint64_t timeStamp )
254 {
255   FILETIME fileTime;
256   ::FileTimeToLocalFileTime( (const FILETIME *)&timeStamp, &fileTime);
257   return fileTime;
258 }
259
260 bool CProgramDatabase::IncTimesPlayed(const CStdString& strFileName)
261 {
262   try
263   {
264     if (NULL == m_pDB.get()) return false;
265     if (NULL == m_pDS.get()) return false;
266
267     CStdString strSQL = PrepareSQL("select * from files where files.strFileName like '%s'", strFileName.c_str());
268     if (!m_pDS->query(strSQL.c_str())) return false;
269     int iRowsFound = m_pDS->num_rows();
270     if (iRowsFound == 0)
271     {
272       m_pDS->close();
273       return false;
274     }
275     int idFile = m_pDS->fv("files.idFile").get_asInt();
276     int iTimesPlayed = m_pDS->fv("files.iTimesPlayed").get_asInt();
277     m_pDS->close();
278
279     CLog::Log(LOGDEBUG, "CProgramDatabase::IncTimesPlayed(%s), idFile=%i, iTimesPlayed=%i",
280               strFileName.c_str(), idFile, iTimesPlayed);
281
282     strSQL=PrepareSQL("update files set iTimesPlayed=%i where idFile=%i",
283                   ++iTimesPlayed, idFile);
284     m_pDS->exec(strSQL.c_str());
285     return true;
286   }
287   catch (...)
288   {
289     CLog::Log(LOGERROR, "CProgramDatabase:IncTimesPlayed(%s) failed", strFileName.c_str());
290   }
291
292   return false;
293 }
294
295 bool CProgramDatabase::SetDescription(const CStdString& strFileName, const CStdString& strDescription)
296 {
297   try
298   {
299     if (NULL == m_pDB.get()) return false;
300     if (NULL == m_pDS.get()) return false;
301
302     CStdString strSQL = PrepareSQL("select * from files where files.strFileName like '%s'", strFileName.c_str());
303     if (!m_pDS->query(strSQL.c_str())) return false;
304     int iRowsFound = m_pDS->num_rows();
305     if (iRowsFound == 0)
306     {
307       m_pDS->close();
308       return false;
309     }
310     int idFile = m_pDS->fv("files.idFile").get_asInt();
311     m_pDS->close();
312
313     CLog::Log(LOGDEBUG, "CProgramDatabase::SetDescription(%s), idFile=%i, description=%s",
314               strFileName.c_str(), idFile,strDescription.c_str());
315
316     strSQL=PrepareSQL("update files set xbedescription='%s' where idFile=%i",
317                   strDescription.c_str(), idFile);
318     m_pDS->exec(strSQL.c_str());
319     return true;
320   }
321   catch (...)
322   {
323     CLog::Log(LOGERROR, "CProgramDatabase:SetDescription(%s) failed", strFileName.c_str());
324   }
325
326   return false;
327 }