// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_DATABASE_H_
#define CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_DATABASE_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
namespace base {
class SequencedTaskRunner;
}
namespace leveldb {
class DB;
}
namespace contacts {
class Contact;
class UpdateMetadata;
typedef std::vector<const Contact*> ContactPointers;
// Interface for classes providing persistent storage of Contact objects.
class ContactDatabaseInterface {
public:
typedef std::vector<std::string> ContactIds;
typedef base::Callback<void(bool success)> InitCallback;
typedef base::Callback<void(bool success)> SaveCallback;
typedef base::Callback<void(bool success,
scoped_ptr<ScopedVector<Contact> >,
scoped_ptr<UpdateMetadata>)>
LoadCallback;
// Asynchronously destroys the object after all in-progress file operations
// have completed.
virtual void DestroyOnUIThread() {}
// Asynchronously initializes the object. |callback| will be invoked on the
// UI thread when complete.
virtual void Init(const base::FilePath& database_dir,
InitCallback callback) = 0;
// Asynchronously saves |contacts_to_save| and |metadata| to the database and
// removes contacts with IDs contained in |contact_ids_to_delete|. If
// |is_full_update| is true, all existing contacts in the database not present
// in |contacts_to_save| will be removed. |callback| will be invoked on the
// UI thread when complete. The caller must not make changes to the
// underlying passed-in Contact objects until the callback has been invoked.
virtual void SaveContacts(scoped_ptr<ContactPointers> contacts_to_save,
scoped_ptr<ContactIds> contact_ids_to_delete,
scoped_ptr<UpdateMetadata> metadata,
bool is_full_update,
SaveCallback callback) = 0;
// Asynchronously loads all contacts from the database and invokes |callback|
// when complete.
virtual void LoadContacts(LoadCallback callback) = 0;
protected:
virtual ~ContactDatabaseInterface() {}
};
class ContactDatabase : public ContactDatabaseInterface {
public:
ContactDatabase();
// ContactDatabaseInterface implementation.
virtual void DestroyOnUIThread() OVERRIDE;
virtual void Init(const base::FilePath& database_dir,
InitCallback callback) OVERRIDE;
virtual void SaveContacts(scoped_ptr<ContactPointers> contacts_to_save,
scoped_ptr<ContactIds> contact_ids_to_delete,
scoped_ptr<UpdateMetadata> metadata,
bool is_full_update,
SaveCallback callback) OVERRIDE;
virtual void LoadContacts(LoadCallback callback) OVERRIDE;
protected:
virtual ~ContactDatabase();
private:
// Are we currently being run by |task_runner_|?
bool IsRunByTaskRunner() const;
// Deletes |this|.
void DestroyFromTaskRunner();
// Passes the supplied parameters to |callback| after being called on the UI
// thread. Used for replies sent in response to |task_runner_|'s tasks, so
// that weak_ptrs can be used to avoid running the replies after the
// ContactDatabase has been deleted.
void RunInitCallback(InitCallback callback, const bool* success);
void RunSaveCallback(SaveCallback callback, const bool* success);
void RunLoadCallback(LoadCallback callback,
const bool* success,
scoped_ptr<ScopedVector<Contact> > contacts,
scoped_ptr<UpdateMetadata> metadata);
// Initializes the database in |database_dir| and updates |success|.
void InitFromTaskRunner(const base::FilePath& database_dir, bool* success);
// Saves data to disk and updates |success|.
void SaveContactsFromTaskRunner(scoped_ptr<ContactPointers> contacts_to_save,
scoped_ptr<ContactIds> contact_ids_to_delete,
scoped_ptr<UpdateMetadata> metadata,
bool is_full_update,
bool* success);
// Loads contacts from disk and updates |success|.
void LoadContactsFromTaskRunner(bool* success,
ScopedVector<Contact>* contacts,
UpdateMetadata* metadata);
// Used to run blocking tasks in-order.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
scoped_ptr<leveldb::DB> db_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<ContactDatabase> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ContactDatabase);
};
} // namespace contacts
#endif // CHROME_BROWSER_CHROMEOS_CONTACTS_CONTACT_DATABASE_H_