1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/webdata/common/web_database_service.h"
8 #include "base/location.h"
9 #include "components/webdata/common/web_data_request_manager.h"
10 #include "components/webdata/common/web_data_results.h"
11 #include "components/webdata/common/web_data_service_consumer.h"
12 #include "components/webdata/common/web_database_backend.h"
17 // Receives messages from the backend on the DB thread, posts them to
18 // WebDatabaseService on the UI thread.
19 class WebDatabaseService::BackendDelegate
20 : public WebDatabaseBackend::Delegate
{
23 const base::WeakPtr
<WebDatabaseService
>& web_database_service
)
24 : web_database_service_(web_database_service
),
25 callback_thread_(base::MessageLoopProxy::current()) {
28 void DBLoaded(sql::InitStatus status
) override
{
29 callback_thread_
->PostTask(
31 base::Bind(&WebDatabaseService::OnDatabaseLoadDone
,
32 web_database_service_
,
36 const base::WeakPtr
<WebDatabaseService
> web_database_service_
;
37 scoped_refptr
<base::MessageLoopProxy
> callback_thread_
;
40 WebDatabaseService::WebDatabaseService(
41 const base::FilePath
& path
,
42 const scoped_refptr
<base::MessageLoopProxy
>& ui_thread
,
43 const scoped_refptr
<base::MessageLoopProxy
>& db_thread
)
44 : base::RefCountedDeleteOnMessageLoop
<WebDatabaseService
>(ui_thread
),
47 db_thread_(db_thread
),
48 weak_ptr_factory_(this) {
49 // WebDatabaseService should be instantiated on UI thread.
50 DCHECK(ui_thread
->BelongsToCurrentThread());
51 // WebDatabaseService requires DB thread if instantiated.
52 DCHECK(db_thread
.get());
55 WebDatabaseService::~WebDatabaseService() {
58 void WebDatabaseService::AddTable(scoped_ptr
<WebDatabaseTable
> table
) {
59 if (!web_db_backend_
.get()) {
60 web_db_backend_
= new WebDatabaseBackend(
61 path_
, new BackendDelegate(weak_ptr_factory_
.GetWeakPtr()), db_thread_
);
63 web_db_backend_
->AddTable(table
.Pass());
66 void WebDatabaseService::LoadDatabase() {
67 DCHECK(web_db_backend_
.get());
69 FROM_HERE
, Bind(&WebDatabaseBackend::InitDatabase
, web_db_backend_
));
72 void WebDatabaseService::ShutdownDatabase() {
74 loaded_callbacks_
.clear();
75 error_callbacks_
.clear();
76 weak_ptr_factory_
.InvalidateWeakPtrs();
77 if (!web_db_backend_
.get())
80 FROM_HERE
, Bind(&WebDatabaseBackend::ShutdownDatabase
, web_db_backend_
));
83 WebDatabase
* WebDatabaseService::GetDatabaseOnDB() const {
84 DCHECK(db_thread_
->BelongsToCurrentThread());
85 return web_db_backend_
.get() ? web_db_backend_
->database() : NULL
;
88 scoped_refptr
<WebDatabaseBackend
> WebDatabaseService::GetBackend() const {
89 return web_db_backend_
;
92 void WebDatabaseService::ScheduleDBTask(
93 const tracked_objects::Location
& from_here
,
94 const WriteTask
& task
) {
95 DCHECK(web_db_backend_
.get());
96 scoped_ptr
<WebDataRequest
> request(
97 new WebDataRequest(NULL
, web_db_backend_
->request_manager().get()));
99 from_here
, Bind(&WebDatabaseBackend::DBWriteTaskWrapper
, web_db_backend_
,
100 task
, base::Passed(&request
)));
103 WebDataServiceBase::Handle
WebDatabaseService::ScheduleDBTaskWithResult(
104 const tracked_objects::Location
& from_here
,
105 const ReadTask
& task
,
106 WebDataServiceConsumer
* consumer
) {
108 DCHECK(web_db_backend_
.get());
109 scoped_ptr
<WebDataRequest
> request(
110 new WebDataRequest(consumer
, web_db_backend_
->request_manager().get()));
111 WebDataServiceBase::Handle handle
= request
->GetHandle();
112 db_thread_
->PostTask(
113 from_here
, Bind(&WebDatabaseBackend::DBReadTaskWrapper
, web_db_backend_
,
114 task
, base::Passed(&request
)));
118 void WebDatabaseService::CancelRequest(WebDataServiceBase::Handle h
) {
119 if (!web_db_backend_
.get())
121 web_db_backend_
->request_manager()->CancelRequest(h
);
124 void WebDatabaseService::RegisterDBLoadedCallback(
125 const DBLoadedCallback
& callback
) {
126 loaded_callbacks_
.push_back(callback
);
129 void WebDatabaseService::RegisterDBErrorCallback(
130 const DBLoadErrorCallback
& callback
) {
131 error_callbacks_
.push_back(callback
);
134 void WebDatabaseService::OnDatabaseLoadDone(sql::InitStatus status
) {
135 if (status
== sql::INIT_OK
) {
138 for (size_t i
= 0; i
< loaded_callbacks_
.size(); i
++) {
139 if (!loaded_callbacks_
[i
].is_null())
140 loaded_callbacks_
[i
].Run();
143 loaded_callbacks_
.clear();
145 // Notify that the database load failed.
146 for (size_t i
= 0; i
< error_callbacks_
.size(); i
++) {
147 if (!error_callbacks_
[i
].is_null())
148 error_callbacks_
[i
].Run(status
);
151 error_callbacks_
.clear();