1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_service_backend.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/location.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_data_request_manager.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_database.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_database_table.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::Bind; 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::FilePath; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDataServiceBackend::WebDataServiceBackend( 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const FilePath& path, 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Delegate* delegate, 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& db_thread) 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : base::RefCountedDeleteOnMessageLoop<WebDataServiceBackend>(db_thread), 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) db_path_(path), 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_manager_(new WebDataRequestManager()), 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) init_status_(sql::INIT_FAILURE), 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) init_complete_(false), 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_(delegate) { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDataServiceBackend::AddTable(scoped_ptr<WebDatabaseTable> table) { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!db_.get()); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tables_.push_back(table.release()); 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDataServiceBackend::InitDatabase() { 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LoadDatabaseIfNecessary(); 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (delegate_) { 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate_->DBLoaded(init_status_); 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)sql::InitStatus WebDataServiceBackend::LoadDatabaseIfNecessary() { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (init_complete_ || db_path_.empty()) { 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return init_status_; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) init_complete_ = true; 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_.reset(new WebDatabase()); 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (ScopedVector<WebDatabaseTable>::iterator it = tables_.begin(); 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it != tables_.end(); ++it) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_->AddTable(*it); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) init_status_ = db_->Init(db_path_); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (init_status_ != sql::INIT_OK) { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Cannot initialize the web database: " << init_status_; 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_.reset(NULL); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return init_status_; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_->BeginTransaction(); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return init_status_; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebDataServiceBackend::ShutdownDatabase() { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (db_ && init_status_ == sql::INIT_OK) 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_->CommitTransaction(); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) db_.reset(NULL); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) init_complete_ = true; // Ensures the init sequence is not re-run. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) init_status_ = sql::INIT_FAILURE; 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDataServiceBackend::DBWriteTaskWrapper( 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const WebDatabaseService::WriteTask& task, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request) { 74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (request->IsCancelled()) 75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ExecuteWriteTask(task); 78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) request_manager_->RequestCompleted(request.Pass()); 79a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void WebDataServiceBackend::ExecuteWriteTask( 82a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const WebDatabaseService::WriteTask& task) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LoadDatabaseIfNecessary(); 84a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (db_ && init_status_ == sql::INIT_OK) { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebDatabase::State state = task.Run(db_.get()); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (state == WebDatabase::COMMIT_NEEDED) 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Commit(); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDataServiceBackend::DBReadTaskWrapper( 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const WebDatabaseService::ReadTask& task, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<WebDataRequest> request) { 94a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (request->IsCancelled()) 95a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 96a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 97a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) request->SetResult(ExecuteReadTask(task).Pass()); 98a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) request_manager_->RequestCompleted(request.Pass()); 99a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)scoped_ptr<WDTypedResult> WebDataServiceBackend::ExecuteReadTask( 102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const WebDatabaseService::ReadTask& task) { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LoadDatabaseIfNecessary(); 104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (db_ && init_status_ == sql::INIT_OK) { 105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return task.Run(db_.get()); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return scoped_ptr<WDTypedResult>(); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WebDataServiceBackend::~WebDataServiceBackend() { 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ShutdownDatabase(); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void WebDataServiceBackend::Commit() { 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(db_); 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_EQ(sql::INIT_OK, init_status_); 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch db_->CommitTransaction(); 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch db_->BeginTransaction(); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 120