Merge lp:~stolowski/unity-scope-click/local-departments into lp:unity-scope-click/devel

Proposed by Paweł Stołowski
Status: Work in progress
Proposed branch: lp:~stolowski/unity-scope-click/local-departments
Merge into: lp:unity-scope-click/devel
Diff against target: 1506 lines (+902/-36)
24 files modified
debian/control (+1/-0)
libclickscope/click/CMakeLists.txt (+4/-0)
libclickscope/click/departments-db.cpp (+318/-0)
libclickscope/click/departments-db.h (+100/-0)
libclickscope/click/interface.cpp (+8/-2)
libclickscope/click/interface.h (+3/-1)
libclickscope/click/package.cpp (+9/-0)
libclickscope/click/package.h (+2/-0)
libclickscope/click/preview.cpp (+46/-7)
libclickscope/click/preview.h (+9/-3)
libclickscope/tests/CMakeLists.txt (+5/-1)
libclickscope/tests/test_departments-db.cpp (+228/-0)
libclickscope/tests/test_index.cpp (+4/-2)
scope/clickapps/CMakeLists.txt (+2/-1)
scope/clickapps/apps-query.cpp (+82/-7)
scope/clickapps/apps-query.h (+3/-1)
scope/clickapps/apps-scope.cpp (+11/-2)
scope/clickapps/apps-scope.h (+4/-0)
scope/clickstore/CMakeLists.txt (+2/-1)
scope/clickstore/store-query.cpp (+39/-1)
scope/clickstore/store-query.h (+3/-1)
scope/clickstore/store-scope.cpp (+12/-2)
scope/clickstore/store-scope.h (+2/-0)
scope/tests/test_query.cpp (+5/-4)
To merge this branch: bzr merge lp:~stolowski/unity-scope-click/local-departments
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Needs Fixing
Review via email: mp+224870@code.launchpad.net

Commit message

Support for departments in click apps scope, for locally installed apps.

Description of the change

Support for departments in click apps scope, for locally installed apps.
Note: this is still WIP, and needs a change to /api/v1/package server call (as described on https://wiki.ubuntu.com/AppStore/Interfaces/ClickPackageIndex#Package_Details).

To post a comment you must log in.
Revision history for this message
Alejandro J. Cura (alecu) wrote :

Great work pawel!

I know the branch is in progress, so let me give an initial observation: in order for the branch to be more easily reviewable, and to make sure that it does not grow much more, please split it in a few branches.

The first one should only include all the methods that do the queries and the db access, and all the corresponding tests.
The second one should start filling the db from preview.cpp using the branch above.
The third one would query the db to build the combo of departments.

review: Needs Fixing
315. By Paweł Stołowski

Use recursive sql query when fetching packages from a department.

316. By Paweł Stołowski

Depend on sqlite >= 3.8.5 to ensure recursive sql statement is supported at runtime.

317. By Paweł Stołowski

Uncomment unlink.

Unmerged revisions

317. By Paweł Stołowski

Uncomment unlink.

316. By Paweł Stołowski

Depend on sqlite >= 3.8.5 to ensure recursive sql statement is supported at runtime.

315. By Paweł Stołowski

Use recursive sql query when fetching packages from a department.

314. By Paweł Stołowski

Apply department filter when querying for locally installed apps.

313. By Paweł Stołowski

Throw on empty arguments to database store methods. Keep database in clickscope subdir.

312. By Paweł Stołowski

Store package - department mapping when displaying the preview.

311. By Paweł Stołowski

More checks in the test.

310. By Paweł Stołowski

Test department name updates.

309. By Paweł Stołowski

Fixes around table definitions; test for no duplicated records.

308. By Paweł Stołowski

Populdate department in details.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'debian/control'
--- debian/control 2014-06-23 15:00:28 +0000
+++ debian/control 2014-07-02 12:34:49 +0000
@@ -29,6 +29,7 @@
29 ubuntu-app-launch-tools,29 ubuntu-app-launch-tools,
30 ubuntu-download-manager,30 ubuntu-download-manager,
31 ubuntu-sdk-libs,31 ubuntu-sdk-libs,
32 sqlite3 (>= 3.8.5),
32 ${misc:Depends},33 ${misc:Depends},
33 ${shlibs:Depends},34 ${shlibs:Depends},
34Breaks: unity (<< 7.0),35Breaks: unity (<< 7.0),
3536
=== modified file 'libclickscope/click/CMakeLists.txt'
--- libclickscope/click/CMakeLists.txt 2014-06-23 15:00:28 +0000
+++ libclickscope/click/CMakeLists.txt 2014-07-02 12:34:49 +0000
@@ -1,6 +1,7 @@
1SET (CMAKE_INCLUDE_CURRENT_DIR ON)1SET (CMAKE_INCLUDE_CURRENT_DIR ON)
2SET (CMAKE_AUTOMOC ON)2SET (CMAKE_AUTOMOC ON)
3find_package (Qt5Core REQUIRED)3find_package (Qt5Core REQUIRED)
4find_package (Qt5Sql REQUIRED)
4pkg_check_modules(JSON_CPP REQUIRED jsoncpp)5pkg_check_modules(JSON_CPP REQUIRED jsoncpp)
56
6add_definitions(7add_definitions(
@@ -14,6 +15,7 @@
14 download-manager.cpp15 download-manager.cpp
15 department-lookup.cpp16 department-lookup.cpp
16 departments.cpp17 departments.cpp
18 departments-db.cpp
17 highlights.cpp19 highlights.cpp
18 index.cpp20 index.cpp
19 interface.cpp21 interface.cpp
@@ -30,6 +32,8 @@
30 webclient.cpp32 webclient.cpp
31)33)
3234
35qt5_use_modules(${SCOPE_LIB_NAME} Sql)
36
33include_directories(37include_directories(
34 ${JSON_CPP_INCLUDE_DIRS}38 ${JSON_CPP_INCLUDE_DIRS}
35 ${CMAKE_SOURCE_DIR}/libclickscope39 ${CMAKE_SOURCE_DIR}/libclickscope
3640
=== added file 'libclickscope/click/departments-db.cpp'
--- libclickscope/click/departments-db.cpp 1970-01-01 00:00:00 +0000
+++ libclickscope/click/departments-db.cpp 2014-07-02 12:34:49 +0000
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#include "departments-db.h"
31#include <stdexcept>
32#include <iostream>
33#include <QSqlError>
34#include <QSqlRecord>
35#include <QVariant>
36#include <QStandardPaths>
37#include <QDir>
38
39namespace click
40{
41
42std::unique_ptr<click::DepartmentsDb> DepartmentsDb::create_db()
43{
44 auto const path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
45 if (!path.isEmpty())
46 {
47 QDir("/").mkpath(path);
48 const std::string dbpath = path.toStdString() + "/clickscope/click-departments.db";
49 return std::unique_ptr<DepartmentsDb>(new DepartmentsDb(dbpath));
50 }
51 throw std::runtime_error("Cannot determine cache directory");
52}
53
54DepartmentsDb::DepartmentsDb(const std::string& name)
55{
56 init_db(name);
57
58 delete_pkgmap_query_.reset(new QSqlQuery(db_));
59 insert_pkgmap_query_.reset(new QSqlQuery(db_));
60 insert_dept_id_query_.reset(new QSqlQuery(db_));
61 insert_dept_name_query_.reset(new QSqlQuery(db_));
62 select_pkgs_by_dept_.reset(new QSqlQuery(db_));
63 select_pkgs_by_dept_recursive_.reset(new QSqlQuery(db_));
64 select_parent_dept_.reset(new QSqlQuery(db_));
65 select_children_depts_.reset(new QSqlQuery(db_));
66 select_dept_name_.reset(new QSqlQuery(db_));
67
68 delete_pkgmap_query_->prepare("DELETE FROM pkgmap WHERE pkgid=:pkgid");
69 insert_pkgmap_query_->prepare("INSERT OR REPLACE INTO pkgmap (pkgid, deptid) VALUES (:pkgid, :deptid)");
70 insert_dept_id_query_->prepare("INSERT OR REPLACE INTO depts (deptid, parentid) VALUES (:deptid, :parentid)");
71 insert_dept_name_query_->prepare("INSERT OR REPLACE INTO deptnames (deptid, locale, name) VALUES (:deptid, :locale, :name)");
72 select_pkgs_by_dept_->prepare("SELECT pkgid FROM pkgmap WHERE deptid=:deptid");
73 select_pkgs_by_dept_recursive_->prepare("WITH RECURSIVE recdepts(deptid) AS (SELECT deptid FROM depts_v WHERE deptid=:deptid UNION SELECT depts_v.deptid FROM recdepts,depts_v WHERE recdepts.deptid=depts_v.parentid) SELECT pkgid FROM pkgmap NATURAL JOIN recdepts");
74 select_children_depts_->prepare("SELECT deptid,(SELECT COUNT(1) from DEPTS_V AS inner WHERE inner.parentid=outer.deptid) FROM DEPTS_V AS outer WHERE parentid=:parentid");
75 select_parent_dept_->prepare("SELECT parentid FROM depts_v WHERE deptid=:deptid");
76 select_dept_name_->prepare("SELECT name FROM deptnames WHERE deptid=:deptid AND locale=:locale");
77}
78
79void DepartmentsDb::init_db(const std::string& name)
80{
81 db_ = QSqlDatabase::addDatabase("QSQLITE");
82 db_.setDatabaseName(QString::fromStdString(name));
83 if (!db_.open())
84 {
85 throw std::runtime_error("Cannot open departments database");
86 }
87
88 QSqlQuery query;
89
90 //query.exec("PRAGMA foreign_keys = ON");
91
92 // package id -> department id mapping table
93 if (!query.exec("CREATE TABLE IF NOT EXISTS pkgmap (pkgid TEXT, deptid TEXT, CONSTRAINT pkey PRIMARY KEY (pkgid, deptid))"))
94 {
95 report_db_error(query.lastError(), "Failed to create pkgmap table");
96 }
97
98 // department id -> parent department id mapping table
99 if (!query.exec("CREATE TABLE IF NOT EXISTS depts (deptid TEXT, parentid TEXT, CONSTRAINT pkey PRIMARY KEY (deptid, parentid), CONSTRAINT fkey FOREIGN KEY (deptid) REFERENCES deptnames(deptid))"))
100 {
101 report_db_error(query.lastError(), "Failed to create depts table");
102 }
103
104 // department id, locale -> deparment name mapping table
105 if (!query.exec("CREATE TABLE IF NOT EXISTS deptnames (deptid TEXT, locale TEXT, name TEXT, CONSTRAINT deptuniq PRIMARY KEY (deptid, locale))"))
106 {
107 report_db_error(query.lastError(), "Failed to create depts table");
108 }
109
110 // name -> value table for storing arbitrary values such as schema version
111 if (!query.exec("CREATE TABLE IF NOT EXISTS meta (name TEXT PRIMARY KEY, value TEXT)"))
112 {
113 report_db_error(query.lastError(), "Failed to create meta table");
114 }
115 query.exec("INSERT INTO meta (name, value) VALUES ('version', 1)");
116
117 // view of the depts table that automatically adds fake "" department for root departments
118 if (!query.exec("CREATE VIEW IF NOT EXISTS depts_v AS SELECT deptid, parentid FROM depts UNION SELECT deptid,'' AS parentid FROM deptnames WHERE NOT EXISTS "
119 "(SELECT * FROM depts WHERE depts.deptid=deptnames.deptid)"))
120 {
121 report_db_error(query.lastError(), "Failed to create depts_v view");
122 }
123}
124
125void DepartmentsDb::report_db_error(const QSqlError& error, const std::string& message)
126{
127 throw std::runtime_error(message + ": " + error.text().toStdString());
128}
129
130std::string DepartmentsDb::get_department_name(const std::string& department_id, const std::list<std::string>& locales)
131{
132 for (auto const& locale: locales)
133 {
134 select_dept_name_->bindValue(":deptid", QVariant(QString::fromStdString(department_id)));
135 select_dept_name_->bindValue(":locale", QVariant(QString::fromStdString(locale)));
136
137 if (!select_dept_name_->exec())
138 {
139 report_db_error(select_dept_name_->lastError(), "Failed to query for department name of " + department_id + ", locale " + locale);
140 }
141
142 if (select_dept_name_->next())
143 {
144 return select_dept_name_->value(0).toString().toStdString();
145 }
146 }
147 throw std::logic_error("No name for department " + department_id);
148}
149
150std::string DepartmentsDb::get_parent_department_id(const std::string& department_id)
151{
152 select_parent_dept_->bindValue(":deptid", QVariant(QString::fromStdString(department_id)));
153 if (!select_parent_dept_->exec())
154 {
155 report_db_error(select_parent_dept_->lastError(), "Failed to query for parent department " + department_id);
156 }
157 if (!select_parent_dept_->next())
158 {
159 throw std::logic_error("Unknown department '" + department_id + "'");
160 }
161 return select_parent_dept_->value(0).toString().toStdString();
162}
163
164std::list<DepartmentsDb::DepartmentInfo> DepartmentsDb::get_children_departments(const std::string& department_id)
165{
166 // TODO: this should only return departments that have results, and set 'has_children' flag on the same basis.
167 // to be fixed when new sqlite3 is available.
168 select_children_depts_->bindValue(":parentid", QVariant(QString::fromStdString(department_id)));
169 if (!select_children_depts_->exec())
170 {
171 report_db_error(select_children_depts_->lastError(), "Failed to query for children departments of " + department_id);
172 }
173
174 std::list<DepartmentInfo> depts;
175 while (select_children_depts_->next())
176 {
177 const DepartmentInfo inf(select_children_depts_->value(0).toString().toStdString(), select_children_depts_->value(1).toBool());
178 depts.push_back(inf);
179 }
180
181 return depts;
182}
183
184std::unordered_set<std::string> DepartmentsDb::get_packages_for_department(const std::string& department_id, bool recursive)
185{
186 std::unordered_set<std::string> pkgs;
187 QSqlQuery *query = recursive ? select_pkgs_by_dept_recursive_.get() : select_pkgs_by_dept_.get();
188 query->bindValue(":deptid", QVariant(QString::fromStdString(department_id)));
189 if (!query->exec())
190 {
191 report_db_error(query->lastError(), "Failed to query for packages of department " + department_id);
192 }
193 while (query->next())
194 {
195 pkgs.insert(query->value(0).toString().toStdString());
196 }
197 return pkgs;
198}
199
200void DepartmentsDb::store_package_mapping(const std::string& package_id, const std::set<std::string>& department_ids)
201{
202 if (package_id.empty())
203 {
204 throw std::logic_error("Invalid empty package_id");
205 }
206
207 if (department_ids.size() == 0)
208 {
209 throw std::logic_error("Invalid empty departments list");
210 }
211
212 if (!db_.transaction())
213 {
214 std::cerr << "Failed to start transaction" << std::endl;
215 }
216
217 // delete package mapping first from any departments
218 delete_pkgmap_query_->bindValue(":pkgid", QVariant(QString::fromStdString(package_id)));
219 delete_pkgmap_query_->exec();
220
221 for (auto const& dept: department_ids)
222 {
223 if (dept.empty())
224 {
225 throw std::logic_error("Invalid empty department id");
226 }
227
228 insert_pkgmap_query_->bindValue(":pkgid", QVariant(QString::fromStdString(package_id)));
229 insert_pkgmap_query_->bindValue(":deptid", QVariant(QString::fromStdString(dept)));
230 if (!insert_pkgmap_query_->exec())
231 {
232 if (!db_.rollback())
233 {
234 std::cerr << "Failed to rollback transaction" << std::endl;
235 }
236 report_db_error(insert_pkgmap_query_->lastError(), "Failed to insert into pkgmap");
237 }
238 }
239
240 if (!db_.commit())
241 {
242 std::cerr << "Failed to commit transaction" << std::endl;
243 }
244}
245
246void DepartmentsDb::store_department_mapping(const std::string& department_id, const std::string& parent_department_id)
247{
248 if (department_id.empty())
249 {
250 throw std::logic_error("Invalid empty department id");
251 }
252
253 if (parent_department_id.empty())
254 {
255 throw std::logic_error("Invalid empty parent department id");
256 }
257
258 insert_dept_id_query_->bindValue(":deptid", QVariant(QString::fromStdString(department_id)));
259 insert_dept_id_query_->bindValue(":parentid", QVariant(QString::fromStdString(parent_department_id)));
260 if (!insert_dept_id_query_->exec())
261 {
262 report_db_error(insert_dept_id_query_->lastError(), "Failed to insert into depts");
263 }
264}
265
266void DepartmentsDb::store_department_name(const std::string& department_id, const std::string& locale, const std::string& name)
267{
268 if (department_id.empty())
269 {
270 throw std::logic_error("Invalid empty department id");
271 }
272
273 if (name.empty())
274 {
275 throw std::logic_error("Invalid empty department name");
276 }
277
278 insert_dept_name_query_->bindValue(":deptid", QVariant(QString::fromStdString(department_id)));
279 insert_dept_name_query_->bindValue(":locale", QVariant(QString::fromStdString(locale)));
280 insert_dept_name_query_->bindValue(":name", QVariant(QString::fromStdString(name)));
281
282 if (!insert_dept_name_query_->exec())
283 {
284 report_db_error(insert_dept_name_query_->lastError(), "Failed to insert into deptnames");
285 }
286}
287
288int DepartmentsDb::department_mapping_count() const
289{
290 QSqlQuery q(db_);
291 if (!q.exec("SELECT COUNT(*) FROM depts") || !q.next())
292 {
293 report_db_error(q.lastError(), "Failed to query depts table");
294 }
295 return q.value(0).toInt();
296}
297
298int DepartmentsDb::package_count() const
299{
300 QSqlQuery q(db_);
301 if (!q.exec("SELECT COUNT(*) FROM pkgmap") || !q.next())
302 {
303 report_db_error(q.lastError(), "Failed to query pkgmap table");
304 }
305 return q.value(0).toInt();
306}
307
308int DepartmentsDb::department_name_count() const
309{
310 QSqlQuery q(db_);
311 if (!q.exec("SELECT COUNT(*) FROM deptnames") || !q.next())
312 {
313 report_db_error(q.lastError(), "Failed to query deptnames table");
314 }
315 return q.value(0).toInt();
316}
317
318}
0319
=== added file 'libclickscope/click/departments-db.h'
--- libclickscope/click/departments-db.h 1970-01-01 00:00:00 +0000
+++ libclickscope/click/departments-db.h 2014-07-02 12:34:49 +0000
@@ -0,0 +1,100 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#ifndef CLICK_DEPARTMENTS_DB_H
31#define CLICK_DEPARTMENTS_DB_H
32
33#include <string>
34#include <set>
35#include <unordered_set>
36#include <list>
37#include <QSqlDatabase>
38#include <QSqlQuery>
39#include <memory>
40
41class QSqlError;
42
43namespace click
44{
45
46class DepartmentsDb final
47{
48public:
49 struct DepartmentInfo
50 {
51 DepartmentInfo(const std::string &id, bool children): id(id), has_children(children) {}
52 std::string id;
53 bool has_children;
54
55 bool operator==(const DepartmentInfo& other) const
56 {
57 return id == other.id && has_children == other.has_children;
58 }
59 };
60
61 DepartmentsDb(const std::string& name);
62 DepartmentsDb(const DepartmentsDb& other) = delete;
63 DepartmentsDb& operator=(const DepartmentsDb&) = delete;
64
65 std::string get_department_name(const std::string& department_id, const std::list<std::string>& locales);
66 std::unordered_set<std::string> get_packages_for_department(const std::string& department_id, bool recursive = true);
67 std::string get_parent_department_id(const std::string& department_id);
68 std::list<DepartmentInfo> get_children_departments(const std::string& department_id);
69
70 // FIXME: package can belong to only one department, get rid of set
71 void store_package_mapping(const std::string& package_id, const std::set<std::string>& department_ids);
72 void store_department_mapping(const std::string& department_id, const std::string& parent_department_id);
73 void store_department_name(const std::string& department_id, const std::string& locale, const std::string& name);
74
75 // these methods are mostly for tests
76 int department_mapping_count() const;
77 int package_count() const;
78 int department_name_count() const;
79
80 static std::unique_ptr<DepartmentsDb> create_db();
81
82private:
83 void init_db(const std::string& name);
84 static void report_db_error(const QSqlError& error, const std::string& message);
85
86 QSqlDatabase db_;
87 std::unique_ptr<QSqlQuery> delete_pkgmap_query_;
88 std::unique_ptr<QSqlQuery> insert_pkgmap_query_;
89 std::unique_ptr<QSqlQuery> insert_dept_id_query_;
90 std::unique_ptr<QSqlQuery> insert_dept_name_query_;
91 std::unique_ptr<QSqlQuery> select_pkgs_by_dept_;
92 std::unique_ptr<QSqlQuery> select_pkgs_by_dept_recursive_;
93 std::unique_ptr<QSqlQuery> select_parent_dept_;
94 std::unique_ptr<QSqlQuery> select_children_depts_;
95 std::unique_ptr<QSqlQuery> select_dept_name_;
96};
97
98}
99
100#endif
0101
=== modified file 'libclickscope/click/interface.cpp'
--- libclickscope/click/interface.cpp 2014-06-16 15:38:49 +0000
+++ libclickscope/click/interface.cpp 2014-07-02 12:34:49 +0000
@@ -228,13 +228,15 @@
228 *228 *
229 * Find all of the installed apps matching @search_query in a timeout.229 * Find all of the installed apps matching @search_query in a timeout.
230 */230 */
231std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query)231std::vector<click::Application> Interface::find_installed_apps(const std::string& search_query,
232 const std::unordered_set<std::string>& packages_in_department,
233 bool department_filter)
232{234{
233 std::vector<Application> result;235 std::vector<Application> result;
234236
235 bool include_desktop_results = show_desktop_apps();237 bool include_desktop_results = show_desktop_apps();
236238
237 auto enumerator = [&result, this, search_query, include_desktop_results]239 auto enumerator = [&result, this, search_query, packages_in_department, department_filter, include_desktop_results]
238 (const unity::util::IniParser& keyFile, const std::string& filename)240 (const unity::util::IniParser& keyFile, const std::string& filename)
239 {241 {
240 if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {242 if (keyFile.has_group(DESKTOP_FILE_GROUP) == false) {
@@ -250,6 +252,10 @@
250 || Interface::is_non_click_app(QString::fromStdString(filename))) {252 || Interface::is_non_click_app(QString::fromStdString(filename))) {
251 auto app = load_app_from_desktop(keyFile, filename);253 auto app = load_app_from_desktop(keyFile, filename);
252254
255 // check if apps is present in current department
256 if (department_filter && packages_in_department.find(app.name) == packages_in_department.end())
257 return;
258
253 if (search_query.empty()) {259 if (search_query.empty()) {
254 result.push_back(app);260 result.push_back(app);
255 } else {261 } else {
256262
=== modified file 'libclickscope/click/interface.h'
--- libclickscope/click/interface.h 2014-06-16 15:38:49 +0000
+++ libclickscope/click/interface.h 2014-07-02 12:34:49 +0000
@@ -90,7 +90,9 @@
90 virtual Application load_app_from_desktop(const unity::util::IniParser& keyFile,90 virtual Application load_app_from_desktop(const unity::util::IniParser& keyFile,
91 const std::string& filename);91 const std::string& filename);
92 static std::vector<Application> sort_apps(const std::vector<Application>& apps);92 static std::vector<Application> sort_apps(const std::vector<Application>& apps);
93 virtual std::vector<Application> find_installed_apps(const std::string& search_query);93 virtual std::vector<Application> find_installed_apps(const std::string& search_query,
94 const std::unordered_set<std::string>& packages_in_department = std::unordered_set<std::string>(),
95 bool department_filter = false);
9496
95 static bool is_non_click_app(const QString& filename);97 static bool is_non_click_app(const QString& filename);
9698
9799
=== modified file 'libclickscope/click/package.cpp'
--- libclickscope/click/package.cpp 2014-06-26 17:31:28 +0000
+++ libclickscope/click/package.cpp 2014-07-02 12:34:49 +0000
@@ -126,6 +126,15 @@
126 details.download_url = root[JsonKeys::download_url].asString();126 details.download_url = root[JsonKeys::download_url].asString();
127 details.license = root[JsonKeys::license].asString();127 details.license = root[JsonKeys::license].asString();
128128
129 if (root[JsonKeys::department].isArray())
130 {
131 auto const dept_array = root[JsonKeys::department];
132 if (dept_array.size() > 0)
133 {
134 details.department = dept_array[dept_array.size() - 1].asString();
135 }
136 }
137
129 // Optional details go here.138 // Optional details go here.
130 if (root[JsonKeys::version].isString())139 if (root[JsonKeys::version].isString())
131 details.version = root[JsonKeys::version].asString();140 details.version = root[JsonKeys::version].asString();
132141
=== modified file 'libclickscope/click/package.h'
--- libclickscope/click/package.h 2014-06-26 17:31:28 +0000
+++ libclickscope/click/package.h 2014-07-02 12:34:49 +0000
@@ -126,6 +126,7 @@
126 constexpr static const char* terms_of_service{"terms_of_service"};126 constexpr static const char* terms_of_service{"terms_of_service"};
127 constexpr static const char* license{"license"};127 constexpr static const char* license{"license"};
128 constexpr static const char* publisher{"publisher"};128 constexpr static const char* publisher{"publisher"};
129 constexpr static const char* department{"department"};
129 constexpr static const char* main_screenshot_url{"screenshot_url"};130 constexpr static const char* main_screenshot_url{"screenshot_url"};
130 constexpr static const char* more_screenshot_urls{"screenshot_urls"};131 constexpr static const char* more_screenshot_urls{"screenshot_urls"};
131 constexpr static const char* binary_filesize{"binary_filesize"};132 constexpr static const char* binary_filesize{"binary_filesize"};
@@ -149,6 +150,7 @@
149 json::Value::UInt64 binary_filesize;150 json::Value::UInt64 binary_filesize;
150 std::string version;151 std::string version;
151 std::string framework;152 std::string framework;
153 std::string department;
152};154};
153155
154std::ostream& operator<<(std::ostream& out, const PackageDetails& details);156std::ostream& operator<<(std::ostream& out, const PackageDetails& details);
155157
=== modified file 'libclickscope/click/preview.cpp'
--- libclickscope/click/preview.cpp 2014-06-23 15:00:28 +0000
+++ libclickscope/click/preview.cpp 2014-07-02 12:34:49 +0000
@@ -34,6 +34,7 @@
34#include <click/download-manager.h>34#include <click/download-manager.h>
35#include <click/launcher.h>35#include <click/launcher.h>
36#include <click/dbus_constants.h>36#include <click/dbus_constants.h>
37#include <click/departments-db.h>
3738
38#include <boost/algorithm/string/replace.hpp>39#include <boost/algorithm/string/replace.hpp>
3940
@@ -58,16 +59,18 @@
58Preview::Preview(const unity::scopes::Result& result,59Preview::Preview(const unity::scopes::Result& result,
59 const unity::scopes::ActionMetadata& metadata,60 const unity::scopes::ActionMetadata& metadata,
60 const QSharedPointer<click::web::Client>& client,61 const QSharedPointer<click::web::Client>& client,
61 const QSharedPointer<click::network::AccessManager>& nam)62 const QSharedPointer<click::network::AccessManager>& nam,
63 std::shared_ptr<click::DepartmentsDb> depts)
62 : PreviewQueryBase(result, metadata)64 : PreviewQueryBase(result, metadata)
63{65{
64 strategy.reset(choose_strategy(result, metadata, client, nam));66 strategy.reset(choose_strategy(result, metadata, client, nam, depts));
65}67}
6668
67PreviewStrategy* Preview::choose_strategy(const unity::scopes::Result &result,69PreviewStrategy* Preview::choose_strategy(const unity::scopes::Result &result,
68 const unity::scopes::ActionMetadata &metadata,70 const unity::scopes::ActionMetadata &metadata,
69 const QSharedPointer<web::Client> &client,71 const QSharedPointer<web::Client> &client,
70 const QSharedPointer<click::network::AccessManager>& nam)72 const QSharedPointer<click::network::AccessManager>& nam,
73 std::shared_ptr<click::DepartmentsDb> depts)
71{74{
72 if (metadata.scope_data().which() != scopes::Variant::Type::Null) {75 if (metadata.scope_data().which() != scopes::Variant::Type::Null) {
73 auto metadict = metadata.scope_data().get_dict();76 auto metadict = metadata.scope_data().get_dict();
@@ -86,7 +89,7 @@
86 std::string action_id = metadict["action_id"].get_string();89 std::string action_id = metadict["action_id"].get_string();
87 std::string download_url = metadict["download_url"].get_string();90 std::string download_url = metadict["download_url"].get_string();
88 if (action_id == click::Preview::Actions::INSTALL_CLICK) {91 if (action_id == click::Preview::Actions::INSTALL_CLICK) {
89 return new InstallingPreview(download_url, result, client, nam);92 return new InstallingPreview(download_url, result, client, nam, depts);
90 } else {93 } else {
91 qWarning() << "unexpected action id " << QString::fromStdString(action_id)94 qWarning() << "unexpected action id " << QString::fromStdString(action_id)
92 << " given with download_url" << QString::fromStdString(download_url);95 << " given with download_url" << QString::fromStdString(download_url);
@@ -346,9 +349,11 @@
346InstallingPreview::InstallingPreview(const std::string &download_url,349InstallingPreview::InstallingPreview(const std::string &download_url,
347 const unity::scopes::Result &result,350 const unity::scopes::Result &result,
348 const QSharedPointer<click::web::Client>& client,351 const QSharedPointer<click::web::Client>& client,
349 const QSharedPointer<click::network::AccessManager> &nam)352 const QSharedPointer<click::network::AccessManager> &nam,
353 std::shared_ptr<click::DepartmentsDb> depts)
350 : PreviewStrategy(result, client), download_url(download_url),354 : PreviewStrategy(result, client), download_url(download_url),
351 downloader(new click::Downloader(nam))355 downloader(new click::Downloader(nam)),
356 depts_db(depts)
352{357{
353}358}
354359
@@ -383,7 +388,9 @@
383 default:388 default:
384 std::string object_path = rc.first;389 std::string object_path = rc.first;
385 qDebug() << "Successfully created UDM Download.";390 qDebug() << "Successfully created UDM Download.";
386 populateDetails([this, reply, object_path](const PackageDetails &details){391 populateDetails([this, reply, object_path](const PackageDetails &details) {
392 store_department(details);
393
387 reply->push(headerWidgets(details));394 reply->push(headerWidgets(details));
388 reply->push(progressBarWidget(object_path));395 reply->push(progressBarWidget(object_path));
389 reply->push(descriptionWidgets(details));396 reply->push(descriptionWidgets(details));
@@ -403,6 +410,38 @@
403 });410 });
404}411}
405412
413void InstallingPreview::store_department(const PackageDetails& details)
414{
415 //
416 // store package -> department mapping in sqlite db
417 if (depts_db)
418 {
419 if (!details.department.empty())
420 {
421 try
422 {
423 depts_db->store_package_mapping(details.package.name, { details.department });
424 qDebug() << "Storing mapping for" << QString::fromStdString(details.package.name) << ":" << QString::fromStdString(details.department);
425 }
426 catch (const std::exception& e)
427 {
428 qWarning() << "Failed to store package mapping for package '"
429 << QString::fromStdString(details.package.name)
430 << "', department '" << QString::fromStdString(details.department)
431 << "':" << QString::fromStdString(e.what());
432 }
433 }
434 else
435 {
436 qWarning() << "Department is empty for package" << QString::fromStdString(details.package.name);
437 }
438 }
439 else
440 {
441 qWarning() << "Departments database not available";
442 }
443}
444
406scopes::PreviewWidgetList InstallingPreview::progressBarWidget(const std::string& object_path)445scopes::PreviewWidgetList InstallingPreview::progressBarWidget(const std::string& object_path)
407{446{
408 scopes::PreviewWidgetList widgets;447 scopes::PreviewWidgetList widgets;
409448
=== modified file 'libclickscope/click/preview.h'
--- libclickscope/click/preview.h 2014-06-18 04:39:23 +0000
+++ libclickscope/click/preview.h 2014-07-02 12:34:49 +0000
@@ -49,6 +49,7 @@
4949
50class Manifest;50class Manifest;
51class PreviewStrategy;51class PreviewStrategy;
52class DepartmentsDb;
5253
53class Preview : public unity::scopes::PreviewQueryBase54class Preview : public unity::scopes::PreviewQueryBase
54{55{
@@ -57,7 +58,8 @@
57 PreviewStrategy* choose_strategy(const unity::scopes::Result& result,58 PreviewStrategy* choose_strategy(const unity::scopes::Result& result,
58 const unity::scopes::ActionMetadata& metadata,59 const unity::scopes::ActionMetadata& metadata,
59 const QSharedPointer<web::Client> &client,60 const QSharedPointer<web::Client> &client,
60 const QSharedPointer<click::network::AccessManager>& nam);61 const QSharedPointer<click::network::AccessManager>& nam,
62 std::shared_ptr<click::DepartmentsDb> depts);
61public:63public:
62 struct Actions64 struct Actions
63 {65 {
@@ -82,7 +84,8 @@
82 Preview(const unity::scopes::Result& result,84 Preview(const unity::scopes::Result& result,
83 const unity::scopes::ActionMetadata& metadata,85 const unity::scopes::ActionMetadata& metadata,
84 const QSharedPointer<click::web::Client>& client,86 const QSharedPointer<click::web::Client>& client,
85 const QSharedPointer<click::network::AccessManager>& nam);87 const QSharedPointer<click::network::AccessManager>& nam,
88 std::shared_ptr<click::DepartmentsDb> depts);
86 // From unity::scopes::PreviewQuery89 // From unity::scopes::PreviewQuery
87 void cancelled() override;90 void cancelled() override;
88 virtual void run(unity::scopes::PreviewReplyProxy const& reply) override;91 virtual void run(unity::scopes::PreviewReplyProxy const& reply) override;
@@ -140,7 +143,8 @@
140 InstallingPreview(std::string const& download_url,143 InstallingPreview(std::string const& download_url,
141 const unity::scopes::Result& result,144 const unity::scopes::Result& result,
142 const QSharedPointer<click::web::Client>& client,145 const QSharedPointer<click::web::Client>& client,
143 const QSharedPointer<click::network::AccessManager>& nam);146 const QSharedPointer<click::network::AccessManager>& nam,
147 std::shared_ptr<click::DepartmentsDb> depts);
144148
145 virtual ~InstallingPreview();149 virtual ~InstallingPreview();
146150
@@ -148,8 +152,10 @@
148152
149protected:153protected:
150 virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path);154 virtual scopes::PreviewWidgetList progressBarWidget(const std::string& object_path);
155 void store_department(const PackageDetails& pkg);
151 std::string download_url;156 std::string download_url;
152 QSharedPointer<click::Downloader> downloader;157 QSharedPointer<click::Downloader> downloader;
158 std::shared_ptr<click::DepartmentsDb> depts_db;
153 void startLauncherAnimation(const PackageDetails& details);159 void startLauncherAnimation(const PackageDetails& details);
154};160};
155161
156162
=== modified file 'libclickscope/tests/CMakeLists.txt'
--- libclickscope/tests/CMakeLists.txt 2014-06-26 17:52:31 +0000
+++ libclickscope/tests/CMakeLists.txt 2014-07-02 12:34:49 +0000
@@ -6,6 +6,7 @@
6SET (CMAKE_AUTOMOC ON)6SET (CMAKE_AUTOMOC ON)
77
8find_package(Qt5Core REQUIRED)8find_package(Qt5Core REQUIRED)
9find_package(Qt5Sql REQUIRED)
910
10include_directories (11include_directories (
11 ${CMAKE_SOURCE_DIR}/libclickscope12 ${CMAKE_SOURCE_DIR}/libclickscope
@@ -15,6 +16,7 @@
15)16)
1617
17configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_data.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp)18configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test_data.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp)
19add_definitions(-DTEST_DIR="${CMAKE_CURRENT_BINARY_DIR}")
1820
19add_executable (${LIBCLICKSCOPE_TESTS_TARGET}21add_executable (${LIBCLICKSCOPE_TESTS_TARGET}
20 mock_network_access_manager.h22 mock_network_access_manager.h
@@ -31,11 +33,13 @@
31 test_reviews.cpp33 test_reviews.cpp
32 test_smartconnect.cpp34 test_smartconnect.cpp
33 test_webclient.cpp35 test_webclient.cpp
36 test_departments.cpp
37 test_departments-db.cpp
3438
35 ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp39 ${CMAKE_CURRENT_BINARY_DIR}/test_data.cpp
36)40)
3741
38qt5_use_modules(${LIBCLICKSCOPE_TESTS_TARGET} Core)42qt5_use_modules(${LIBCLICKSCOPE_TESTS_TARGET} Core Sql)
3943
40target_link_libraries(${LIBCLICKSCOPE_TESTS_TARGET}44target_link_libraries(${LIBCLICKSCOPE_TESTS_TARGET}
41 ${SCOPE_LIB_NAME}45 ${SCOPE_LIB_NAME}
4246
=== added file 'libclickscope/tests/test_departments-db.cpp'
--- libclickscope/tests/test_departments-db.cpp 1970-01-01 00:00:00 +0000
+++ libclickscope/tests/test_departments-db.cpp 2014-07-02 12:34:49 +0000
@@ -0,0 +1,228 @@
1/*
2 * Copyright (C) 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * In addition, as a special exception, the copyright holders give
17 * permission to link the code of portions of this program with the
18 * OpenSSL library under certain conditions as described in each
19 * individual source file, and distribute linked combinations
20 * including the two.
21 * You must obey the GNU General Public License in all respects
22 * for all of the code used other than OpenSSL. If you modify
23 * file(s) with this exception, you may extend this exception to your
24 * version of the file(s), but you are not obligated to do so. If you
25 * do not wish to do so, delete this exception statement from your
26 * version. If you delete this exception statement from all source
27 * files in the program, then also delete it here.
28 */
29
30#include <gtest/gtest.h>
31#include "fake_json.h"
32#include <click/departments-db.h>
33#include <memory>
34#include <algorithm>
35#include <unistd.h>
36
37using namespace click;
38
39class DepartmentsDbTest: public ::testing::Test
40{
41public:
42 const std::string db_path = TEST_DIR "/departments-db-test.sqlite";
43
44 void SetUp() override
45 {
46 db.reset(new DepartmentsDb(db_path));
47 db->store_department_name("tools", "", "Tools");
48 db->store_department_name("office", "", "Office");
49
50 db->store_department_mapping("office", "tools");
51
52 db->store_package_mapping("app1", {"tools"});
53 db->store_package_mapping("app2", {"office"});
54
55 db->store_department_name("games", "", "Games");
56 db->store_department_name("games", "pl_PL", "Gry");
57 db->store_department_name("rpg", "", "RPG");
58 db->store_department_name("card", "", "Card");
59 db->store_department_name("fps", "", "First Person Shooter");
60
61 db->store_department_mapping("rpg", "games");
62 db->store_department_mapping("card", "games");
63 db->store_department_mapping("fps", "games");
64
65 db->store_package_mapping("game1", {"rpg", "fps"});
66 db->store_package_mapping("game2", {"fps"});
67 }
68
69 void TearDown() override
70 {
71 unlink(db_path.c_str());
72 }
73
74protected:
75 std::unique_ptr<DepartmentsDb> db;
76};
77
78TEST_F(DepartmentsDbTest, testDepartmentNameLookup)
79{
80 {
81 EXPECT_EQ("Games", db->get_department_name("games", {"en_EN", ""}));
82 EXPECT_EQ("Gry", db->get_department_name("games", {"pl_PL", ""}));
83 EXPECT_EQ("First Person Shooter", db->get_department_name("fps", {"en_EN", ""}));
84 EXPECT_EQ("Office", db->get_department_name("office", {"en_EN", ""}));
85 EXPECT_EQ("Tools", db->get_department_name("tools", {"en_EN", ""}));
86
87 EXPECT_THROW(db->get_department_name("xyz", {"en_EN", ""}), std::logic_error);
88 }
89}
90
91TEST_F(DepartmentsDbTest, testDepartmentNameUpdates)
92{
93 {
94 EXPECT_EQ(7u, db->department_name_count());
95 db->store_department_name("tools", "", "Tools!");
96 EXPECT_EQ("Tools!", db->get_department_name("tools", {"en_EN", ""}));
97 db->store_department_name("games", "pl_PL", "Gry!!!");
98 EXPECT_EQ("Gry!!!", db->get_department_name("games", {"pl_PL"}));
99 EXPECT_EQ(7u, db->department_name_count());
100 }
101}
102
103TEST_F(DepartmentsDbTest, testDepartmentParentLookup)
104{
105 {
106 EXPECT_EQ("games", db->get_parent_department_id("rpg"));
107 EXPECT_EQ("games", db->get_parent_department_id("card"));
108 EXPECT_EQ("", db->get_parent_department_id("games"));
109
110 EXPECT_EQ("tools", db->get_parent_department_id("office"));
111 EXPECT_EQ("", db->get_parent_department_id("tools"));
112
113 EXPECT_THROW(db->get_parent_department_id("xyz"), std::logic_error);
114 }
115}
116
117TEST_F(DepartmentsDbTest, testDepartmentChildrenLookup)
118{
119 {
120 EXPECT_EQ(0, db->get_children_departments("xyz").size());
121 }
122 {
123 auto depts = db->get_children_departments("");
124 EXPECT_EQ(2u, depts.size());
125 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("tools", true)) != depts.end());
126 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("games", true)) != depts.end());
127 }
128 {
129 auto depts = db->get_children_departments("tools");
130 EXPECT_EQ(1u, depts.size());
131 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("office", false)) != depts.end());
132 }
133 {
134 auto depts = db->get_children_departments("games");
135 EXPECT_EQ(3u, depts.size());
136 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("rpg", false)) != depts.end());
137 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("fps", false)) != depts.end());
138 EXPECT_TRUE(std::find(depts.begin(), depts.end(), DepartmentsDb::DepartmentInfo("card", false)) != depts.end());
139 }
140}
141
142TEST_F(DepartmentsDbTest, testPackageLookup)
143{
144 {
145 auto pkgs = db->get_packages_for_department("rpg", false);
146 EXPECT_EQ(1u, pkgs.size());
147 EXPECT_TRUE(pkgs.find("game1") != pkgs.end());
148 }
149 {
150 auto pkgs = db->get_packages_for_department("fps", false);
151 EXPECT_EQ(2u, pkgs.size());
152 EXPECT_TRUE(pkgs.find("game1") != pkgs.end());
153 EXPECT_TRUE(pkgs.find("game2") != pkgs.end());
154 }
155 {
156 auto pkgs = db->get_packages_for_department("card", false);
157 EXPECT_EQ(0, pkgs.size());
158 }
159}
160
161TEST_F(DepartmentsDbTest, testRecursivePackageLookup)
162{
163 {
164 // get packages from subdepartments of games department
165 auto pkgs = db->get_packages_for_department("games", true);
166 EXPECT_EQ(2u, pkgs.size());
167 EXPECT_TRUE(pkgs.find("game1") != pkgs.end());
168 EXPECT_TRUE(pkgs.find("game2") != pkgs.end());
169 }
170 {
171 // rpg has no subdepartments, so we just get the packages of rpg department
172 auto pkgs = db->get_packages_for_department("rpg", true);
173 EXPECT_EQ(1u, pkgs.size());
174 EXPECT_TRUE(pkgs.find("game1") != pkgs.end());
175 }
176 {
177 auto pkgs = db->get_packages_for_department("card", true);
178 EXPECT_EQ(0, pkgs.size());
179 }
180}
181
182TEST_F(DepartmentsDbTest, testPackageUpdates)
183{
184 auto pkgs = db->get_packages_for_department("fps");
185 EXPECT_EQ(2, pkgs.size());
186 EXPECT_TRUE(pkgs.find("game2") != pkgs.end());
187
188 // game2 gets moved to card and removed from fps; game1 still in fps
189 db->store_package_mapping("game2", {"card"});
190
191 pkgs = db->get_packages_for_department("fps", false);
192 EXPECT_EQ(1, pkgs.size());
193 EXPECT_TRUE(pkgs.find("game2") == pkgs.end());
194 pkgs = db->get_packages_for_department("card", false);
195 EXPECT_EQ(1, pkgs.size());
196 EXPECT_TRUE(pkgs.find("game2") != pkgs.end());
197}
198
199TEST_F(DepartmentsDbTest, testInvalidDepartments)
200{
201 EXPECT_THROW(db->get_parent_department_id(""), std::logic_error);
202 EXPECT_THROW(db->get_parent_department_id("foooo"), std::logic_error);
203}
204
205TEST_F(DepartmentsDbTest, testEmptyArguments)
206{
207 EXPECT_THROW(db->store_department_name("", "", "Foo"), std::logic_error);
208 EXPECT_THROW(db->store_department_name("foo", "", ""), std::logic_error);
209 EXPECT_THROW(db->store_department_mapping("", "foo"), std::logic_error);
210 EXPECT_THROW(db->store_department_mapping("foo", ""), std::logic_error);
211 EXPECT_THROW(db->store_package_mapping("", {"foo"}), std::logic_error);
212 EXPECT_THROW(db->store_package_mapping("foo", {}), std::logic_error);
213 EXPECT_THROW(db->store_package_mapping("foo", {""}), std::logic_error);
214}
215
216TEST_F(DepartmentsDbTest, testNoDuplicates)
217{
218 db->store_package_mapping("game2", {"fps"});
219 db->store_package_mapping("game2", {"fps"});
220 db->store_department_name("games", "pl_PL", "Gry");
221 db->store_department_name("games", "pl_PL", "Gry");
222 db->store_department_mapping("office", "tools");
223 db->store_department_mapping("office", "tools");
224
225 EXPECT_EQ(7u, db->department_name_count());
226 EXPECT_EQ(5u, db->package_count());
227}
228
0229
=== modified file 'libclickscope/tests/test_index.cpp'
--- libclickscope/tests/test_index.cpp 2014-06-26 18:57:08 +0000
+++ libclickscope/tests/test_index.cpp 2014-07-02 12:34:49 +0000
@@ -342,7 +342,8 @@
342 {"sshot1", "sshot2"},342 {"sshot1", "sshot2"},
343 177582,343 177582,
344 "0.2",344 "0.2",
345 "None"345 "None",
346 "tools"
346 };347 };
347 EXPECT_CALL(*this, details_callback(fake_details, _)).Times(1);348 EXPECT_CALL(*this, details_callback(fake_details, _)).Times(1);
348 response->replyFinished();349 response->replyFinished();
@@ -389,7 +390,8 @@
389 {"sshot1", "sshot2"},390 {"sshot1", "sshot2"},
390 177582,391 177582,
391 "0.2",392 "0.2",
392 "None"393 "None",
394 "tools"
393 };395 };
394396
395 EXPECT_CALL(*this, details_callback(fake_details, _)).Times(1);397 EXPECT_CALL(*this, details_callback(fake_details, _)).Times(1);
396398
=== modified file 'scope/clickapps/CMakeLists.txt'
--- scope/clickapps/CMakeLists.txt 2014-06-04 14:45:48 +0000
+++ scope/clickapps/CMakeLists.txt 2014-07-02 12:34:49 +0000
@@ -1,6 +1,7 @@
1SET (CMAKE_INCLUDE_CURRENT_DIR ON)1SET (CMAKE_INCLUDE_CURRENT_DIR ON)
2SET (CMAKE_AUTOMOC ON)2SET (CMAKE_AUTOMOC ON)
3find_package (Qt5Core REQUIRED)3find_package (Qt5Core REQUIRED)
4find_package (Qt5Sql REQUIRED)
4pkg_check_modules(JSON_CPP REQUIRED jsoncpp)5pkg_check_modules(JSON_CPP REQUIRED jsoncpp)
56
6add_definitions(7add_definitions(
@@ -20,7 +21,7 @@
20 ${JSON_CPP_INCLUDE_DIRS}21 ${JSON_CPP_INCLUDE_DIRS}
21)22)
2223
23qt5_use_modules (${APPS_LIB_UNVERSIONED} Network)24qt5_use_modules (${APPS_LIB_UNVERSIONED} Network Sql)
2425
25target_link_libraries (${APPS_LIB_UNVERSIONED}26target_link_libraries (${APPS_LIB_UNVERSIONED}
26 ${SCOPE_LIB_NAME}27 ${SCOPE_LIB_NAME}
2728
=== modified file 'scope/clickapps/apps-query.cpp'
--- scope/clickapps/apps-query.cpp 2014-06-30 20:06:33 +0000
+++ scope/clickapps/apps-query.cpp 2014-07-02 12:34:49 +0000
@@ -29,6 +29,7 @@
2929
30#include <click/application.h>30#include <click/application.h>
31#include <click/interface.h>31#include <click/interface.h>
32#include <click/departments-db.h>
3233
33#include <click/key_file_locator.h>34#include <click/key_file_locator.h>
3435
@@ -37,6 +38,7 @@
37#include <unity/scopes/CannedQuery.h>38#include <unity/scopes/CannedQuery.h>
38#include <unity/scopes/SearchReply.h>39#include <unity/scopes/SearchReply.h>
39#include <unity/scopes/SearchMetadata.h>40#include <unity/scopes/SearchMetadata.h>
41#include <unity/scopes/Department.h>
4042
41#include <vector>43#include <vector>
4244
@@ -128,18 +130,21 @@
128130
129struct click::Query::Private131struct click::Query::Private
130{132{
131 Private(click::Index& index, const scopes::SearchMetadata& metadata)133 Private(click::Index& index, std::shared_ptr<click::DepartmentsDb> depts_db, const scopes::SearchMetadata& metadata)
132 : index(index),134 : index(index),
135 depts_db(depts_db),
133 meta(metadata)136 meta(metadata)
134 {137 {
135 }138 }
136 click::Index& index;139 click::Index& index;
140 std::shared_ptr<click::DepartmentsDb> depts_db;
137 scopes::SearchMetadata meta;141 scopes::SearchMetadata meta;
138};142};
139143
140click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata)144click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, std::shared_ptr<DepartmentsDb> depts_db,
145 scopes::SearchMetadata const& metadata)
141 : unity::scopes::SearchQueryBase(query, metadata),146 : unity::scopes::SearchQueryBase(query, metadata),
142 impl(new Private(index, metadata))147 impl(new Private(index, depts_db, metadata))
143{148{
144}149}
145150
@@ -194,15 +199,85 @@
194 }199 }
195}200}
196201
202void click::Query::push_local_departments(scopes::SearchReplyProxy const& replyProxy)
203{
204 auto const current_dep_id = query().department_id();
205 const std::list<std::string> locales = { search_metadata().locale(), "en_US", "" };
206
207 unity::scopes::Department::SPtr root;
208
209 try
210 {
211 static const std::string all_dept_name = _("All departments");
212
213 // create node for current department
214 auto name = current_dep_id == "" ? all_dept_name : impl->depts_db->get_department_name(current_dep_id, locales);
215 unity::scopes::Department::SPtr current = unity::scopes::Department::create(current_dep_id, query(), name);
216
217 // attach subdepartments to it
218 for (auto const& subdep: impl->depts_db->get_children_departments(current_dep_id))
219 {
220 name = impl->depts_db->get_department_name(subdep.id, locales);
221 unity::scopes::Department::SPtr dep = unity::scopes::Department::create(subdep.id, query(), name);
222 dep->set_has_subdepartments(subdep.has_children);
223 current->add_subdepartment(dep);
224 }
225
226 // if current is not the top, then gets its parent
227 if (current_dep_id != "")
228 {
229 auto const parent_dep_id = impl->depts_db->get_parent_department_id(current_dep_id);
230 root = unity::scopes::Department::create(parent_dep_id, query(), parent_dep_id == "" ? all_dept_name :
231 impl->depts_db->get_department_name(parent_dep_id, locales));
232 root->add_subdepartment(current);
233 }
234 else
235 {
236 root = current;
237 }
238
239 replyProxy->register_departments(root);
240 }
241 catch (const std::exception& e)
242 {
243 qWarning() << "Failed to push departments: " << QString::fromStdString(e.what());
244 }
245}
246
197void click::Query::run(scopes::SearchReplyProxy const& searchReply)247void click::Query::run(scopes::SearchReplyProxy const& searchReply)
198{248{
199 auto querystr = query().query_string();249 auto const querystr = query().query_string();
250 auto const current_dept = query().department_id();
251
200 std::string categoryTemplate = CATEGORY_APPS_SEARCH;252 std::string categoryTemplate = CATEGORY_APPS_SEARCH;
201 if (querystr.empty()) {253 if (querystr.empty()) {
202 categoryTemplate = CATEGORY_APPS_DISPLAY;254 categoryTemplate = CATEGORY_APPS_DISPLAY;
203 }255 if (impl->depts_db)
204 auto localResults = clickInterfaceInstance().find_installed_apps(256 {
205 querystr);257 push_local_departments(searchReply);
258 }
259 }
260
261 //
262 // get the set of packages that belong to current deparment;
263 // only apply department filtering if not in root of all departments.
264 bool apply_department_filter = (querystr.empty() && !current_dept.empty());
265 std::unordered_set<std::string> pkgs_in_department;
266 if (impl->depts_db && apply_department_filter)
267 {
268 try
269 {
270 pkgs_in_department = impl->depts_db->get_packages_for_department(current_dept);
271 }
272 catch (const std::exception& e)
273 {
274 qWarning() << "Failed to get packages of department" << QString::fromStdString(current_dept);
275 apply_department_filter = false; // disable so that we are not loosing any apps if something goes wrong
276 }
277 }
278
279 auto const localResults = clickInterfaceInstance().find_installed_apps(
280 querystr, pkgs_in_department, apply_department_filter);
206281
207 push_local_results(282 push_local_results(
208 searchReply,283 searchReply,
209284
=== modified file 'scope/clickapps/apps-query.h'
--- scope/clickapps/apps-query.h 2014-05-28 14:27:28 +0000
+++ scope/clickapps/apps-query.h 2014-07-02 12:34:49 +0000
@@ -44,6 +44,7 @@
4444
45class Application;45class Application;
46class Index;46class Index;
47class DepartmentsDb;
4748
48class Query : public scopes::SearchQueryBase49class Query : public scopes::SearchQueryBase
49{50{
@@ -60,7 +61,7 @@
60 constexpr static const char* VERSION{"version"};61 constexpr static const char* VERSION{"version"};
61 };62 };
6263
63 Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata);64 Query(unity::scopes::CannedQuery const& query, click::Index& index, std::shared_ptr<DepartmentsDb> depts_db, scopes::SearchMetadata const& metadata);
64 virtual ~Query();65 virtual ~Query();
6566
66 virtual void cancelled() override;67 virtual void cancelled() override;
@@ -72,6 +73,7 @@
72 virtual void push_local_results(scopes::SearchReplyProxy const &replyProxy,73 virtual void push_local_results(scopes::SearchReplyProxy const &replyProxy,
73 std::vector<click::Application> const &apps,74 std::vector<click::Application> const &apps,
74 std::string& categoryTemplate);75 std::string& categoryTemplate);
76 virtual void push_local_departments(scopes::SearchReplyProxy const& replyProxy);
7577
76private:78private:
77 struct Private;79 struct Private;
7880
=== modified file 'scope/clickapps/apps-scope.cpp'
--- scope/clickapps/apps-scope.cpp 2014-06-18 16:23:50 +0000
+++ scope/clickapps/apps-scope.cpp 2014-07-02 12:34:49 +0000
@@ -31,6 +31,7 @@
31#include <click/preview.h>31#include <click/preview.h>
32#include <click/interface.h>32#include <click/interface.h>
33#include <click/scope_activation.h>33#include <click/scope_activation.h>
34#include <click/departments-db.h>
3435
35#include <QSharedPointer>36#include <QSharedPointer>
3637
@@ -48,6 +49,14 @@
48 nam.reset(new click::network::AccessManager());49 nam.reset(new click::network::AccessManager());
49 client.reset(new click::web::Client(nam));50 client.reset(new click::web::Client(nam));
50 index.reset(new click::Index(client));51 index.reset(new click::Index(client));
52 try
53 {
54 depts_db = click::DepartmentsDb::create_db();
55 }
56 catch (const std::runtime_error& e)
57 {
58 std::cerr << "Failed to get cache directory" << std::endl;
59 }
51}60}
5261
53click::Scope::~Scope()62click::Scope::~Scope()
@@ -78,14 +87,14 @@
7887
79scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata)88scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata)
80{89{
81 return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, metadata));90 return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, depts_db, metadata));
82}91}
8392
8493
85unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,94unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
86 const unity::scopes::ActionMetadata& metadata) {95 const unity::scopes::ActionMetadata& metadata) {
87 qDebug() << "Scope::preview() called.";96 qDebug() << "Scope::preview() called.";
88 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam)};97 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};
89}98}
9099
91100
92101
=== modified file 'scope/clickapps/apps-scope.h'
--- scope/clickapps/apps-scope.h 2014-06-18 14:42:47 +0000
+++ scope/clickapps/apps-scope.h 2014-07-02 12:34:49 +0000
@@ -43,6 +43,9 @@
4343
44namespace click44namespace click
45{45{
46
47class DepartmentsDb;
48
46class Scope : public scopes::ScopeBase49class Scope : public scopes::ScopeBase
47{50{
48public:51public:
@@ -64,6 +67,7 @@
64 QSharedPointer<click::network::AccessManager> nam;67 QSharedPointer<click::network::AccessManager> nam;
65 QSharedPointer<click::web::Client> client;68 QSharedPointer<click::web::Client> client;
66 QSharedPointer<click::Index> index;69 QSharedPointer<click::Index> index;
70 std::shared_ptr<click::DepartmentsDb> depts_db;
6771
68 std::string installApplication(unity::scopes::Result const& result);72 std::string installApplication(unity::scopes::Result const& result);
69};73};
7074
=== modified file 'scope/clickstore/CMakeLists.txt'
--- scope/clickstore/CMakeLists.txt 2014-06-23 15:00:28 +0000
+++ scope/clickstore/CMakeLists.txt 2014-07-02 12:34:49 +0000
@@ -1,6 +1,7 @@
1SET (CMAKE_INCLUDE_CURRENT_DIR ON)1SET (CMAKE_INCLUDE_CURRENT_DIR ON)
2SET (CMAKE_AUTOMOC ON)2SET (CMAKE_AUTOMOC ON)
3find_package (Qt5Core REQUIRED)3find_package (Qt5Core REQUIRED)
4find_package (Qt5Sql REQUIRED)
4pkg_check_modules(JSON_CPP REQUIRED jsoncpp)5pkg_check_modules(JSON_CPP REQUIRED jsoncpp)
56
6add_definitions(7add_definitions(
@@ -19,7 +20,7 @@
19 ${JSON_CPP_INCLUDE_DIRS}20 ${JSON_CPP_INCLUDE_DIRS}
20)21)
2122
22qt5_use_modules (${STORE_LIB_UNVERSIONED} Network)23qt5_use_modules (${STORE_LIB_UNVERSIONED} Network Sql)
2324
24target_link_libraries (${STORE_LIB_UNVERSIONED}25target_link_libraries (${STORE_LIB_UNVERSIONED}
25 ${SCOPE_LIB_NAME}26 ${SCOPE_LIB_NAME}
2627
=== modified file 'scope/clickstore/store-query.cpp'
--- scope/clickstore/store-query.cpp 2014-06-26 18:07:51 +0000
+++ scope/clickstore/store-query.cpp 2014-07-02 12:34:49 +0000
@@ -32,6 +32,7 @@
32#include "store-query.h"32#include "store-query.h"
33#include "store-scope.h"33#include "store-scope.h"
34#include <click/qtbridge.h>34#include <click/qtbridge.h>
35#include <click/departments-db.h>
3536
36#include <click/key_file_locator.h>37#include <click/key_file_locator.h>
3738
@@ -96,25 +97,29 @@
96struct click::Query::Private97struct click::Query::Private
97{98{
98 Private(click::Index& index, click::DepartmentLookup& depts,99 Private(click::Index& index, click::DepartmentLookup& depts,
100 std::shared_ptr<click::DepartmentsDb> depts_db,
99 click::HighlightList& highlights, const scopes::SearchMetadata& metadata)101 click::HighlightList& highlights, const scopes::SearchMetadata& metadata)
100 : index(index),102 : index(index),
101 department_lookup(depts),103 department_lookup(depts),
104 depts_db(depts_db),
102 highlights(highlights),105 highlights(highlights),
103 meta(metadata)106 meta(metadata)
104 {107 {
105 }108 }
106 click::Index& index;109 click::Index& index;
107 click::DepartmentLookup& department_lookup;110 click::DepartmentLookup& department_lookup;
111 std::shared_ptr<click::DepartmentsDb> depts_db;
108 click::HighlightList& highlights;112 click::HighlightList& highlights;
109 scopes::SearchMetadata meta;113 scopes::SearchMetadata meta;
110 click::web::Cancellable search_operation;114 click::web::Cancellable search_operation;
111};115};
112116
113click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& depts,117click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& depts,
118 std::shared_ptr<click::DepartmentsDb> depts_db,
114 click::HighlightList& highlights,119 click::HighlightList& highlights,
115 scopes::SearchMetadata const& metadata)120 scopes::SearchMetadata const& metadata)
116 : unity::scopes::SearchQueryBase(query, metadata),121 : unity::scopes::SearchQueryBase(query, metadata),
117 impl(new Private(index, depts, highlights, metadata))122 impl(new Private(index, depts, depts_db, highlights, metadata))
118{123{
119}124}
120125
@@ -216,6 +221,30 @@
216 root->set_subdepartments(departments);221 root->set_subdepartments(departments);
217}222}
218223
224// recursively store all departments in the departments database
225void click::Query::store_departments(const click::DepartmentList& depts)
226{
227 assert(impl->depts_db);
228
229 qDebug() << "Storing departments in the database";
230 try
231 {
232 for (auto const& dept: depts)
233 {
234 impl->depts_db->store_department_name(dept->id(), impl->meta.locale(), dept->name());
235 for (auto const& subdep: dept->sub_departments())
236 {
237 impl->depts_db->store_department_mapping(subdep->id(), dept->id());
238 }
239 store_departments(dept->sub_departments());
240 }
241 }
242 catch (const std::exception &e)
243 {
244 qWarning() << "Failed to update database: " << QString::fromStdString(e.what());
245 }
246}
247
219void click::Query::push_package(const scopes::SearchReplyProxy& searchReply, scopes::Category::SCPtr category, const PackageSet &installedPackages, const Package& pkg)248void click::Query::push_package(const scopes::SearchReplyProxy& searchReply, scopes::Category::SCPtr category, const PackageSet &installedPackages, const Package& pkg)
220{249{
221 qDebug() << "pushing result" << QString::fromStdString(pkg.name);250 qDebug() << "pushing result" << QString::fromStdString(pkg.name);
@@ -371,6 +400,15 @@
371 impl->department_lookup.rebuild(rdeps);400 impl->department_lookup.rebuild(rdeps);
372 impl->highlights = highlights;401 impl->highlights = highlights;
373 qDebug() << "Total number of departments:" << impl->department_lookup.size() << ", highlights:" << highlights.size();402 qDebug() << "Total number of departments:" << impl->department_lookup.size() << ", highlights:" << highlights.size();
403
404 if (impl->depts_db)
405 {
406 store_departments(deps);
407 }
408 else
409 {
410 qWarning() << "Departments db not available";
411 }
374 }412 }
375 else413 else
376 {414 {
377415
=== modified file 'scope/clickstore/store-query.h'
--- scope/clickstore/store-query.h 2014-06-18 09:01:20 +0000
+++ scope/clickstore/store-query.h 2014-07-02 12:34:49 +0000
@@ -50,6 +50,7 @@
50class Application;50class Application;
51class Index;51class Index;
52class DepartmentLookup;52class DepartmentLookup;
53class DepartmentsDb;
5354
54class Query : public scopes::SearchQueryBase55class Query : public scopes::SearchQueryBase
55{56{
@@ -76,7 +77,7 @@
76 constexpr static const char* VERSION{"version"};77 constexpr static const char* VERSION{"version"};
77 };78 };
7879
79 Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& dept_lookup, click::HighlightList& highlights,80 Query(unity::scopes::CannedQuery const& query, click::Index& index, click::DepartmentLookup& dept_lookup, std::shared_ptr<click::DepartmentsDb> depts_db, click::HighlightList& highlights,
80 scopes::SearchMetadata const& metadata);81 scopes::SearchMetadata const& metadata);
81 virtual ~Query();82 virtual ~Query();
8283
@@ -86,6 +87,7 @@
8687
87protected:88protected:
88 virtual void populate_departments(const click::DepartmentList& depts, const std::string& current_department_id, unity::scopes::Department::SPtr &root);89 virtual void populate_departments(const click::DepartmentList& depts, const std::string& current_department_id, unity::scopes::Department::SPtr &root);
90 virtual void store_departments(const click::DepartmentList& depts);
89 virtual void push_departments(const scopes::SearchReplyProxy& searchReply, const scopes::Department::SCPtr& root);91 virtual void push_departments(const scopes::SearchReplyProxy& searchReply, const scopes::Department::SCPtr& root);
90 virtual void add_highlights(scopes::SearchReplyProxy const& searchReply, const PackageSet& installedPackages);92 virtual void add_highlights(scopes::SearchReplyProxy const& searchReply, const PackageSet& installedPackages);
91 virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, const PackageSet &installedPackages, const std::string &category);93 virtual void add_available_apps(const scopes::SearchReplyProxy &searchReply, const PackageSet &installedPackages, const std::string &category);
9294
=== modified file 'scope/clickstore/store-scope.cpp'
--- scope/clickstore/store-scope.cpp 2014-06-23 15:00:28 +0000
+++ scope/clickstore/store-scope.cpp 2014-07-02 12:34:49 +0000
@@ -28,6 +28,7 @@
28 */28 */
2929
30#include <click/qtbridge.h>30#include <click/qtbridge.h>
31#include <click/departments-db.h>
31#include <click/department-lookup.h>32#include <click/department-lookup.h>
32#include "store-scope.h"33#include "store-scope.h"
33#include "store-query.h"34#include "store-query.h"
@@ -42,6 +43,7 @@
42#include <click/click-i18n.h>43#include <click/click-i18n.h>
4344
44#include <logging.h>45#include <logging.h>
46#include <iostream>
4547
46bool click::Scope::old_api = false;48bool click::Scope::old_api = false;
4749
@@ -52,6 +54,14 @@
52 index.reset(new click::Index(client));54 index.reset(new click::Index(client));
53 depts.reset(new click::DepartmentLookup());55 depts.reset(new click::DepartmentLookup());
54 highlights.reset(new click::HighlightList());56 highlights.reset(new click::HighlightList());
57 try
58 {
59 depts_db = click::DepartmentsDb::create_db();
60 }
61 catch (const std::runtime_error& e)
62 {
63 std::cerr << "Failed to get cache directory" << std::endl;
64 }
55}65}
5666
57click::Scope::~Scope()67click::Scope::~Scope()
@@ -94,14 +104,14 @@
94104
95scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata)105scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata)
96{106{
97 return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, *depts, *highlights, metadata));107 return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, *depts, depts_db, *highlights, metadata));
98}108}
99109
100110
101unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,111unity::scopes::PreviewQueryBase::UPtr click::Scope::preview(const unity::scopes::Result& result,
102 const unity::scopes::ActionMetadata& metadata) {112 const unity::scopes::ActionMetadata& metadata) {
103 qDebug() << "Scope::preview() called.";113 qDebug() << "Scope::preview() called.";
104 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam)};114 return scopes::PreviewQueryBase::UPtr{new click::Preview(result, metadata, client, nam, depts_db)};
105}115}
106116
107unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata,117unity::scopes::ActivationQueryBase::UPtr click::Scope::perform_action(unity::scopes::Result const& result, unity::scopes::ActionMetadata const& metadata,
108118
=== modified file 'scope/clickstore/store-scope.h'
--- scope/clickstore/store-scope.h 2014-06-18 18:07:39 +0000
+++ scope/clickstore/store-scope.h 2014-07-02 12:34:49 +0000
@@ -46,6 +46,7 @@
46{46{
4747
48class DepartmentLookup;48class DepartmentLookup;
49class DepartmentsDb;
4950
50class Scope : public scopes::ScopeBase51class Scope : public scopes::ScopeBase
51{52{
@@ -73,6 +74,7 @@
73 QSharedPointer<click::Index> index;74 QSharedPointer<click::Index> index;
74 std::shared_ptr<click::DepartmentLookup> depts;75 std::shared_ptr<click::DepartmentLookup> depts;
75 std::shared_ptr<click::HighlightList> highlights;76 std::shared_ptr<click::HighlightList> highlights;
77 std::shared_ptr<click::DepartmentsDb> depts_db;
7678
77 std::string installApplication(unity::scopes::Result const& result);79 std::string installApplication(unity::scopes::Result const& result);
78 static bool old_api;80 static bool old_api;
7981
=== modified file 'scope/tests/test_query.cpp'
--- scope/tests/test_query.cpp 2014-06-24 17:18:53 +0000
+++ scope/tests/test_query.cpp 2014-07-02 12:34:49 +0000
@@ -98,8 +98,9 @@
98public:98public:
99 MockQueryBase(const unity::scopes::CannedQuery& query, click::Index& index,99 MockQueryBase(const unity::scopes::CannedQuery& query, click::Index& index,
100 click::DepartmentLookup& depts,100 click::DepartmentLookup& depts,
101 std::shared_ptr<click::DepartmentsDb> depts_db,
101 click::HighlightList& highlights,102 click::HighlightList& highlights,
102 scopes::SearchMetadata const& metadata) : click::Query(query, index, depts, highlights, metadata)103 scopes::SearchMetadata const& metadata) : click::Query(query, index, depts, depts_db, highlights, metadata)
103 {104 {
104105
105 }106 }
@@ -115,7 +116,7 @@
115 MockQuery(const unity::scopes::CannedQuery& query, click::Index& index,116 MockQuery(const unity::scopes::CannedQuery& query, click::Index& index,
116 click::DepartmentLookup& depts,117 click::DepartmentLookup& depts,
117 click::HighlightList& highlights,118 click::HighlightList& highlights,
118 scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata)119 scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, nullptr, highlights, metadata)
119 {120 {
120121
121 }122 }
@@ -140,8 +141,8 @@
140public:141public:
141 MockQueryRun(const unity::scopes::CannedQuery& query, click::Index& index,142 MockQueryRun(const unity::scopes::CannedQuery& query, click::Index& index,
142 click::DepartmentLookup& depts,143 click::DepartmentLookup& depts,
143 click::HighlightList& highlights, 144 click::HighlightList& highlights,
144 scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata)145 scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, nullptr, highlights, metadata)
145 {146 {
146147
147 }148 }

Subscribers

People subscribed via source and target branches

to all changes: