Merge pull request #22816 from CastagnaIT/fix_tx3g
[xbmc.git] / xbmc / view / ViewDatabase.cpp
blob7605cfbc85ed8d581f9b89527cfa324f6fa4e76c
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ViewDatabase.h"
11 #include <utility>
13 #include "dbwrappers/dataset.h"
14 #include "SortFileItem.h"
15 #include "utils/LegacyPathTranslation.h"
16 #include "utils/log.h"
17 #include "utils/SortUtils.h"
18 #include "utils/StringUtils.h"
19 #include "utils/URIUtils.h"
20 #include "view/ViewState.h"
22 #ifdef TARGET_POSIX
23 #include "platform/posix/ConvUtils.h"
24 #endif
25 CViewDatabase::CViewDatabase(void) = default;
27 CViewDatabase::~CViewDatabase(void) = default;
29 bool CViewDatabase::Open()
31 return CDatabase::Open();
34 void CViewDatabase::CreateTables()
36 CLog::Log(LOGINFO, "create view table");
37 m_pDS->exec("CREATE TABLE view ("
38 "idView integer primary key,"
39 "window integer,"
40 "path text,"
41 "viewMode integer,"
42 "sortMethod integer,"
43 "sortOrder integer,"
44 "sortAttributes integer,"
45 "skin text)");
48 void CViewDatabase::CreateAnalytics()
50 CLog::Log(LOGINFO, "{} - creating indices", __FUNCTION__);
51 m_pDS->exec("CREATE INDEX idxViews ON view(path)");
52 m_pDS->exec("CREATE INDEX idxViewsWindow ON view(window)");
55 void CViewDatabase::UpdateTables(int version)
57 if (version < 4)
58 m_pDS->exec("alter table view add skin text");
59 if (version < 5)
61 // translate legacy videodb:// and musicdb:// paths
62 std::vector< std::pair<int, std::string> > paths;
63 if (m_pDS->query("SELECT idView, path FROM view"))
65 while (!m_pDS->eof())
67 std::string originalPath = m_pDS->fv(1).get_asString();
68 std::string path = originalPath;
69 if (StringUtils::StartsWithNoCase(path, "musicdb://"))
70 path = CLegacyPathTranslation::TranslateMusicDbPath(path);
71 else if (StringUtils::StartsWithNoCase(path, "videodb://"))
72 path = CLegacyPathTranslation::TranslateVideoDbPath(path);
74 if (!StringUtils::EqualsNoCase(path, originalPath))
75 paths.emplace_back(m_pDS->fv(0).get_asInt(), path);
76 m_pDS->next();
78 m_pDS->close();
80 for (std::vector< std::pair<int, std::string> >::const_iterator it = paths.begin(); it != paths.end(); ++it)
81 m_pDS->exec(PrepareSQL("UPDATE view SET path='%s' WHERE idView=%d", it->second.c_str(), it->first));
84 if (version < 6)
86 // convert the "path" table
87 m_pDS->exec("ALTER TABLE view RENAME TO tmp_view");
89 m_pDS->exec("CREATE TABLE view ("
90 "idView integer primary key,"
91 "window integer,"
92 "path text,"
93 "viewMode integer,"
94 "sortMethod integer,"
95 "sortOrder integer,"
96 "sortAttributes integer,"
97 "skin text)\n");
99 m_pDS->query("SELECT * FROM tmp_view");
100 while (!m_pDS->eof())
102 SortDescription sorting = SortUtils::TranslateOldSortMethod((SORT_METHOD)m_pDS->fv(4).get_asInt());
104 std::string sql = PrepareSQL("INSERT INTO view (idView, window, path, viewMode, sortMethod, sortOrder, sortAttributes, skin) VALUES (%i, %i, '%s', %i, %i, %i, %i, '%s')",
105 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(),
106 (int)sorting.sortBy, m_pDS->fv(5).get_asInt(), (int)sorting.sortAttributes, m_pDS->fv(6).get_asString().c_str());
107 m_pDS2->exec(sql);
109 m_pDS->next();
111 m_pDS->exec("DROP TABLE tmp_view");
115 bool CViewDatabase::GetViewState(const std::string &path, int window, CViewState &state, const std::string &skin)
119 if (nullptr == m_pDB)
120 return false;
121 if (nullptr == m_pDS)
122 return false;
124 std::string path1(path);
125 URIUtils::AddSlashAtEnd(path1);
126 if (path1.empty()) path1 = "root://";
128 std::string sql;
129 if (skin.empty())
130 sql = PrepareSQL("select * from view where window = %i and path='%s'", window, path1.c_str());
131 else
132 sql = PrepareSQL("select * from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str());
133 m_pDS->query(sql);
135 if (!m_pDS->eof())
136 { // have some information
137 state.m_viewMode = m_pDS->fv("viewMode").get_asInt();
138 state.m_sortDescription.sortBy = (SortBy)m_pDS->fv("sortMethod").get_asInt();
139 state.m_sortDescription.sortOrder = (SortOrder)m_pDS->fv("sortOrder").get_asInt();
140 state.m_sortDescription.sortAttributes = (SortAttribute)m_pDS->fv("sortAttributes").get_asInt();
141 m_pDS->close();
142 return true;
144 m_pDS->close();
146 catch (...)
148 CLog::Log(LOGERROR, "{}, failed on path '{}'", __FUNCTION__, path);
150 return false;
153 bool CViewDatabase::SetViewState(const std::string &path, int window, const CViewState &state, const std::string &skin)
157 if (nullptr == m_pDB)
158 return false;
159 if (nullptr == m_pDS)
160 return false;
162 std::string path1(path);
163 URIUtils::AddSlashAtEnd(path1);
164 if (path1.empty()) path1 = "root://";
166 std::string sql = PrepareSQL("select idView from view where window = %i and path='%s' and skin='%s'", window, path1.c_str(), skin.c_str());
167 m_pDS->query(sql);
168 if (!m_pDS->eof())
169 { // update the view
170 int idView = m_pDS->fv("idView").get_asInt();
171 m_pDS->close();
172 sql = PrepareSQL("update view set viewMode=%i,sortMethod=%i,sortOrder=%i,sortAttributes=%i where idView=%i",
173 state.m_viewMode, (int)state.m_sortDescription.sortBy, (int)state.m_sortDescription.sortOrder, (int)state.m_sortDescription.sortAttributes, idView);
174 m_pDS->exec(sql);
176 else
177 { // add the view
178 m_pDS->close();
179 sql = PrepareSQL("insert into view (idView, path, window, viewMode, sortMethod, sortOrder, sortAttributes, skin) values(NULL, '%s', %i, %i, %i, %i, %i, '%s')",
180 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());
181 m_pDS->exec(sql);
184 catch (...)
186 CLog::Log(LOGERROR, "{} failed on path '{}'", __FUNCTION__, path);
188 return true;
191 bool CViewDatabase::ClearViewStates(int windowID)
195 if (nullptr == m_pDB)
196 return false;
197 if (nullptr == m_pDS)
198 return false;
200 std::string sql = PrepareSQL("delete from view where window = %i", windowID);
201 m_pDS->exec(sql);
203 catch (...)
205 CLog::Log(LOGERROR, "{} failed on window '{}'", __FUNCTION__, windowID);
207 return true;