Fix keymap.
[vuplus_xbmc] / xbmc / view / ViewDatabase.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://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, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "ViewDatabase.h"
22 #include "utils/URIUtils.h"
23 #include "view/ViewState.h"
24 #include "utils/LegacyPathTranslation.h"
25 #include "utils/log.h"
26 #include "utils/StringUtils.h"
27 #ifdef TARGET_POSIX
28 #include "linux/ConvUtils.h" // GetLastError()
29 #endif
30 #include "dbwrappers/dataset.h"
31 #include "SortFileItem.h"
32
33
34 //********************************************************************************************************************************
35 CViewDatabase::CViewDatabase(void)
36 {
37 }
38
39 //********************************************************************************************************************************
40 CViewDatabase::~CViewDatabase(void)
41 {
42
43 }
44
45 //********************************************************************************************************************************
46 bool CViewDatabase::Open()
47 {
48   return CDatabase::Open();
49 }
50
51 void CViewDatabase::CreateTables()
52 {
53   CLog::Log(LOGINFO, "create view table");
54   m_pDS->exec("CREATE TABLE view ("
55                 "idView integer primary key,"
56                 "window integer,"
57                 "path text,"
58                 "viewMode integer,"
59                 "sortMethod integer,"
60                 "sortOrder integer,"
61                 "sortAttributes integer,"
62                 "skin text)\n");
63 }
64
65 void CViewDatabase::CreateAnalytics()
66 {
67   CLog::Log(LOGINFO, "%s - creating indicies", __FUNCTION__);
68   m_pDS->exec("CREATE INDEX idxViews ON view(path)");
69   m_pDS->exec("CREATE INDEX idxViewsWindow ON view(window)");
70 }
71
72 void CViewDatabase::UpdateTables(int version)
73 {
74   if (version < 4)
75     m_pDS->exec("alter table view add skin text");
76   if (version < 5)
77   {
78     // translate legacy videodb:// and musicdb:// paths
79     std::vector< std::pair<int, std::string> > paths;
80     if (m_pDS->query("SELECT idView, path FROM view"))
81     {
82       while (!m_pDS->eof())
83       {
84         std::string originalPath = m_pDS->fv(1).get_asString();
85         std::string path = originalPath;
86         if (StringUtils::StartsWithNoCase(path, "musicdb://"))
87           path = CLegacyPathTranslation::TranslateMusicDbPath(path);
88         else if (StringUtils::StartsWithNoCase(path, "videodb://"))
89           path = CLegacyPathTranslation::TranslateVideoDbPath(path);
90
91         if (!StringUtils::EqualsNoCase(path, originalPath))
92           paths.push_back(std::make_pair(m_pDS->fv(0).get_asInt(), path));
93         m_pDS->next();
94       }
95       m_pDS->close();
96
97       for (std::vector< std::pair<int, std::string> >::const_iterator it = paths.begin(); it != paths.end(); it++)
98         m_pDS->exec(PrepareSQL("UPDATE view SET path='%s' WHERE idView=%d", it->second.c_str(), it->first).c_str());
99     }
100   }
101   if (version < 6)
102   {
103     // convert the "path" table
104     m_pDS->exec("CREATE TABLE tmp_view AS SELECT * FROM view");
105     m_pDS->exec("DROP TABLE view");
106
107     m_pDS->exec("CREATE TABLE view ("
108                 "idView integer primary key,"
109                 "window integer,"
110                 "path text,"
111                 "viewMode integer,"
112                 "sortMethod integer,"
113                 "sortOrder integer,"
114                 "sortAttributes integer,"
115                 "skin text)\n");
116     
117     m_pDS->query("SELECT * FROM tmp_view");
118     while (!m_pDS->eof())
119     {
120       SortDescription sorting = SortUtils::TranslateOldSortMethod((SORT_METHOD)m_pDS->fv(4).get_asInt());
121
122       CStdString sql = PrepareSQL("INSERT INTO view (idView, window, path, viewMode, sortMethod, sortOrder, sortAttributes, skin) VALUES (%i, %i, '%s', %i, %i, %i, %i, '%s')",
123         m_pDS->fv(0).get_asInt(), m_pDS->fv(1).get_asInt(), m_pDS->fv(2).get_asString().c_str(), m_pDS->fv(3).get_asInt(),
124         (int)sorting.sortBy, m_pDS->fv(5).get_asInt(), (int)sorting.sortAttributes, m_pDS->fv(6).get_asString().c_str());
125       m_pDS2->exec(sql);
126
127       m_pDS->next();
128     }
129     m_pDS->exec("DROP TABLE tmp_view");
130   }
131 }
132
133 bool CViewDatabase::GetViewState(const CStdString &path, int window, CViewState &state, const CStdString &skin)
134 {
135   try
136   {
137     if (NULL == m_pDB.get()) return false;
138     if (NULL == m_pDS.get()) return false;
139
140     CStdString path1(path);
141     URIUtils::AddSlashAtEnd(path1);
142     if (path1.empty()) path1 = "root://";
143
144     CStdString sql;
145     if (skin.empty())
146       sql = PrepareSQL("select * from view where window = %i and path='%s'", window, path1.c_str());
147     else
148       sql = PrepareSQL("select * from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str());
149     m_pDS->query(sql.c_str());
150
151     if (!m_pDS->eof())
152     { // have some information
153       state.m_viewMode = m_pDS->fv("viewMode").get_asInt();
154       state.m_sortDescription.sortBy = (SortBy)m_pDS->fv("sortMethod").get_asInt();
155       state.m_sortDescription.sortOrder = (SortOrder)m_pDS->fv("sortOrder").get_asInt();
156       state.m_sortDescription.sortAttributes = (SortAttribute)m_pDS->fv("sortAttributes").get_asInt();
157       m_pDS->close();
158       return true;
159     }
160     m_pDS->close();
161   }
162   catch (...)
163   {
164     CLog::Log(LOGERROR, "%s, failed on path '%s'", __FUNCTION__, path.c_str());
165   }
166   return false;
167 }
168
169 bool CViewDatabase::SetViewState(const CStdString &path, int window, const CViewState &state, const CStdString &skin)
170 {
171   try
172   {
173     if (NULL == m_pDB.get()) return false;
174     if (NULL == m_pDS.get()) return false;
175
176     CStdString path1(path);
177     URIUtils::AddSlashAtEnd(path1);
178     if (path1.empty()) path1 = "root://";
179
180     CStdString sql = PrepareSQL("select idView from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str());
181     m_pDS->query(sql.c_str());
182     if (!m_pDS->eof())
183     { // update the view
184       int idView = m_pDS->fv("idView").get_asInt();
185       m_pDS->close();
186       sql = PrepareSQL("update view set viewMode=%i,sortMethod=%i,sortOrder=%i,sortAttributes=%i where idView=%i",
187         state.m_viewMode, (int)state.m_sortDescription.sortBy, (int)state.m_sortDescription.sortOrder, (int)state.m_sortDescription.sortAttributes, idView);
188       m_pDS->exec(sql.c_str());
189     }
190     else
191     { // add the view
192       m_pDS->close();
193       sql = PrepareSQL("insert into view (idView, path, window, viewMode, sortMethod, sortOrder, sortAttributes, skin) values(NULL, '%s', %i, %i, %i, %i, %i, '%s')",
194         path1.c_str(), window, state.m_viewMode, (int)state.m_sortDescription.sortBy, (int)state.m_sortDescription.sortOrder, (int)state.m_sortDescription.sortAttributes, skin.c_str());
195       m_pDS->exec(sql.c_str());
196     }
197   }
198   catch (...)
199   {
200     CLog::Log(LOGERROR, "%s failed on path '%s'", __FUNCTION__, path.c_str());
201   }
202   return true;
203 }
204
205 bool CViewDatabase::ClearViewStates(int windowID)
206 {
207   try
208   {
209     if (NULL == m_pDB.get()) return false;
210     if (NULL == m_pDS.get()) return false;
211
212     CStdString sql = PrepareSQL("delete from view where window = %i", windowID);
213     m_pDS->exec(sql.c_str());
214   }
215   catch (...)
216   {
217     CLog::Log(LOGERROR, "%s failed on window '%i'", __FUNCTION__, windowID);
218   }
219   return true;
220 }