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.
9 #include "ViewDatabase.h"
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"
23 #include "platform/posix/ConvUtils.h"
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,"
44 "sortAttributes integer,"
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
)
58 m_pDS
->exec("alter table view add skin text");
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"))
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
);
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
));
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,"
96 "sortAttributes integer,"
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());
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
)
121 if (nullptr == m_pDS
)
124 std::string
path1(path
);
125 URIUtils::AddSlashAtEnd(path1
);
126 if (path1
.empty()) path1
= "root://";
130 sql
= PrepareSQL("select * from view where window = %i and path='%s'", window
, path1
.c_str());
132 sql
= PrepareSQL("select * from view where window = %i and path='%s' and skin='%s'", window
, path1
.c_str(), skin
.c_str());
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();
148 CLog::Log(LOGERROR
, "{}, failed on path '{}'", __FUNCTION__
, path
);
153 bool CViewDatabase::SetViewState(const std::string
&path
, int window
, const CViewState
&state
, const std::string
&skin
)
157 if (nullptr == m_pDB
)
159 if (nullptr == m_pDS
)
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());
170 int idView
= m_pDS
->fv("idView").get_asInt();
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
);
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());
186 CLog::Log(LOGERROR
, "{} failed on path '{}'", __FUNCTION__
, path
);
191 bool CViewDatabase::ClearViewStates(int windowID
)
195 if (nullptr == m_pDB
)
197 if (nullptr == m_pDS
)
200 std::string sql
= PrepareSQL("delete from view where window = %i", windowID
);
205 CLog::Log(LOGERROR
, "{} failed on window '{}'", __FUNCTION__
, windowID
);