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
=
103 SortUtils::TranslateOldSortMethod(static_cast<SortMethod
>(m_pDS
->fv(4).get_asInt()));
105 std::string sql
= PrepareSQL("INSERT INTO view (idView, window, path, viewMode, sortMethod, sortOrder, sortAttributes, skin) VALUES (%i, %i, '%s', %i, %i, %i, %i, '%s')",
106 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(),
107 (int)sorting
.sortBy
, m_pDS
->fv(5).get_asInt(), (int)sorting
.sortAttributes
, m_pDS
->fv(6).get_asString().c_str());
112 m_pDS
->exec("DROP TABLE tmp_view");
116 bool CViewDatabase::GetViewState(const std::string
&path
, int window
, CViewState
&state
, const std::string
&skin
)
120 if (nullptr == m_pDB
)
122 if (nullptr == m_pDS
)
125 std::string
path1(path
);
126 URIUtils::AddSlashAtEnd(path1
);
127 if (path1
.empty()) path1
= "root://";
131 sql
= PrepareSQL("select * from view where window = %i and path='%s'", window
, path1
.c_str());
133 sql
= PrepareSQL("select * from view where window = %i and path='%s' and skin='%s'", window
, path1
.c_str(), skin
.c_str());
137 { // have some information
138 state
.m_viewMode
= m_pDS
->fv("viewMode").get_asInt();
139 state
.m_sortDescription
.sortBy
= (SortBy
)m_pDS
->fv("sortMethod").get_asInt();
140 state
.m_sortDescription
.sortOrder
= (SortOrder
)m_pDS
->fv("sortOrder").get_asInt();
141 state
.m_sortDescription
.sortAttributes
= (SortAttribute
)m_pDS
->fv("sortAttributes").get_asInt();
149 CLog::Log(LOGERROR
, "{}, failed on path '{}'", __FUNCTION__
, path
);
154 bool CViewDatabase::SetViewState(const std::string
&path
, int window
, const CViewState
&state
, const std::string
&skin
)
158 if (nullptr == m_pDB
)
160 if (nullptr == m_pDS
)
163 std::string
path1(path
);
164 URIUtils::AddSlashAtEnd(path1
);
165 if (path1
.empty()) path1
= "root://";
167 std::string sql
= PrepareSQL("select idView from view where window = %i and path='%s' and skin='%s'", window
, path1
.c_str(), skin
.c_str());
171 int idView
= m_pDS
->fv("idView").get_asInt();
173 sql
= PrepareSQL("update view set viewMode=%i,sortMethod=%i,sortOrder=%i,sortAttributes=%i where idView=%i",
174 state
.m_viewMode
, (int)state
.m_sortDescription
.sortBy
, (int)state
.m_sortDescription
.sortOrder
, (int)state
.m_sortDescription
.sortAttributes
, idView
);
180 sql
= PrepareSQL("insert into view (idView, path, window, viewMode, sortMethod, sortOrder, sortAttributes, skin) values(NULL, '%s', %i, %i, %i, %i, %i, '%s')",
181 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());
187 CLog::Log(LOGERROR
, "{} failed on path '{}'", __FUNCTION__
, path
);
192 bool CViewDatabase::ClearViewStates(int windowID
)
196 if (nullptr == m_pDB
)
198 if (nullptr == m_pDS
)
201 std::string sql
= PrepareSQL("delete from view where window = %i", windowID
);
206 CLog::Log(LOGERROR
, "{} failed on window '{}'", __FUNCTION__
, windowID
);