blob: 4498b0875a4b649bccb20e69c184efb91d3f3c53 [file] [log] [blame]
// Copyright (c) 2013 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 CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/indexed_db/indexed_db.h"
#include "content/browser/indexed_db/indexed_db_metadata.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
#include "content/common/content_export.h"
#include "content/common/indexed_db/indexed_db_key.h"
#include "content/common/indexed_db/indexed_db_key_path.h"
#include "content/common/indexed_db/indexed_db_key_range.h"
#include "third_party/WebKit/public/platform/WebIDBCallbacks.h"
namespace content {
class LevelDBComparator;
class LevelDBDatabase;
class LevelDBFactory {
public:
virtual ~LevelDBFactory() {}
virtual leveldb::Status OpenLevelDB(
const base::FilePath& file_name,
const LevelDBComparator* comparator,
scoped_ptr<LevelDBDatabase>* db,
bool* is_disk_full) = 0;
virtual bool DestroyLevelDB(const base::FilePath& file_name) = 0;
};
class CONTENT_EXPORT IndexedDBBackingStore
: public base::RefCounted<IndexedDBBackingStore> {
public:
class CONTENT_EXPORT Transaction;
static scoped_refptr<IndexedDBBackingStore> Open(
const std::string& origin_identifier,
const base::FilePath& path_base,
const std::string& file_identifier,
WebKit::WebIDBCallbacks::DataLoss* data_loss);
static scoped_refptr<IndexedDBBackingStore> Open(
const std::string& origin_identifier,
const base::FilePath& path_base,
const std::string& file_identifier,
WebKit::WebIDBCallbacks::DataLoss* data_loss,
LevelDBFactory* factory);
static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
const std::string& file_identifier);
static scoped_refptr<IndexedDBBackingStore> OpenInMemory(
const std::string& file_identifier,
LevelDBFactory* factory);
base::WeakPtr<IndexedDBBackingStore> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
virtual std::vector<string16> GetDatabaseNames();
virtual bool GetIDBDatabaseMetaData(const string16& name,
IndexedDBDatabaseMetadata* metadata,
bool* success) WARN_UNUSED_RESULT;
virtual bool CreateIDBDatabaseMetaData(const string16& name,
const string16& version,
int64 int_version,
int64* row_id);
virtual bool UpdateIDBDatabaseMetaData(
IndexedDBBackingStore::Transaction* transaction,
int64 row_id,
const string16& version);
virtual bool UpdateIDBDatabaseIntVersion(
IndexedDBBackingStore::Transaction* transaction,
int64 row_id,
int64 int_version);
virtual bool DeleteDatabase(const string16& name);
bool GetObjectStores(int64 database_id,
IndexedDBDatabaseMetadata::ObjectStoreMap* map)
WARN_UNUSED_RESULT;
virtual bool CreateObjectStore(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const string16& name,
const IndexedDBKeyPath& key_path,
bool auto_increment);
virtual bool DeleteObjectStore(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id) WARN_UNUSED_RESULT;
class CONTENT_EXPORT RecordIdentifier {
public:
RecordIdentifier(const std::string& primary_key, int64 version);
RecordIdentifier();
~RecordIdentifier();
const std::string& primary_key() const { return primary_key_; }
int64 version() const { return version_; }
void Reset(const std::string& primary_key, int64 version) {
primary_key_ = primary_key;
version_ = version;
}
private:
// TODO(jsbell): Make it more clear that this is the *encoded* version of
// the key.
std::string primary_key_;
int64 version_;
DISALLOW_COPY_AND_ASSIGN(RecordIdentifier);
};
virtual bool GetRecord(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
std::string* record) WARN_UNUSED_RESULT;
virtual bool PutRecord(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
const std::string& value,
RecordIdentifier* record) WARN_UNUSED_RESULT;
virtual bool ClearObjectStore(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id) WARN_UNUSED_RESULT;
virtual bool DeleteRecord(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const RecordIdentifier& record) WARN_UNUSED_RESULT;
virtual bool GetKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64* current_number) WARN_UNUSED_RESULT;
virtual bool MaybeUpdateKeyGeneratorCurrentNumber(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 new_state,
bool check_current) WARN_UNUSED_RESULT;
virtual bool KeyExistsInObjectStore(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKey& key,
RecordIdentifier* found_record_identifier,
bool* found) WARN_UNUSED_RESULT;
virtual bool CreateIndex(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const string16& name,
const IndexedDBKeyPath& key_path,
bool is_unique,
bool is_multi_entry) WARN_UNUSED_RESULT;
virtual bool DeleteIndex(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id) WARN_UNUSED_RESULT;
virtual bool PutIndexDataForRecord(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKey& key,
const RecordIdentifier& record) WARN_UNUSED_RESULT;
virtual bool GetPrimaryKeyViaIndex(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKey& key,
scoped_ptr<IndexedDBKey>* primary_key) WARN_UNUSED_RESULT;
virtual bool KeyExistsInIndex(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKey& key,
scoped_ptr<IndexedDBKey>* found_primary_key,
bool* exists) WARN_UNUSED_RESULT;
class Cursor {
public:
virtual ~Cursor();
enum IteratorState {
READY = 0,
SEEK
};
struct CursorOptions {
CursorOptions();
~CursorOptions();
int64 database_id;
int64 object_store_id;
int64 index_id;
std::string low_key;
bool low_open;
std::string high_key;
bool high_open;
bool forward;
bool unique;
};
const IndexedDBKey& key() const { return *current_key_; }
bool Continue() { return Continue(NULL, SEEK); }
bool Continue(const IndexedDBKey* key, IteratorState state);
bool Advance(uint32 count);
bool FirstSeek();
virtual Cursor* Clone() = 0;
virtual const IndexedDBKey& primary_key() const;
virtual std::string* Value() = 0;
virtual const RecordIdentifier& record_identifier() const;
virtual bool LoadCurrentRow() = 0;
protected:
Cursor(LevelDBTransaction* transaction,
const CursorOptions& cursor_options);
explicit Cursor(const IndexedDBBackingStore::Cursor* other);
virtual std::string EncodeKey(const IndexedDBKey& key) = 0;
bool IsPastBounds() const;
bool HaveEnteredRange() const;
LevelDBTransaction* transaction_;
const CursorOptions cursor_options_;
scoped_ptr<LevelDBIterator> iterator_;
scoped_ptr<IndexedDBKey> current_key_;
IndexedDBBackingStore::RecordIdentifier record_identifier_;
};
virtual scoped_ptr<Cursor> OpenObjectStoreKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKeyRange& key_range,
indexed_db::CursorDirection);
virtual scoped_ptr<Cursor> OpenObjectStoreCursor(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
const IndexedDBKeyRange& key_range,
indexed_db::CursorDirection);
virtual scoped_ptr<Cursor> OpenIndexKeyCursor(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& key_range,
indexed_db::CursorDirection);
virtual scoped_ptr<Cursor> OpenIndexCursor(
IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKeyRange& key_range,
indexed_db::CursorDirection);
class Transaction {
public:
explicit Transaction(IndexedDBBackingStore* backing_store);
~Transaction();
void Begin();
bool Commit();
void Rollback();
void Reset() {
backing_store_ = NULL;
transaction_ = NULL;
}
static LevelDBTransaction* LevelDBTransactionFrom(
Transaction* transaction) {
return transaction->transaction_;
}
private:
IndexedDBBackingStore* backing_store_;
scoped_refptr<LevelDBTransaction> transaction_;
};
protected:
IndexedDBBackingStore(const std::string& identifier,
scoped_ptr<LevelDBDatabase> db,
scoped_ptr<LevelDBComparator> comparator);
virtual ~IndexedDBBackingStore();
friend class base::RefCounted<IndexedDBBackingStore>;
private:
static scoped_refptr<IndexedDBBackingStore> Create(
const std::string& identifier,
scoped_ptr<LevelDBDatabase> db,
scoped_ptr<LevelDBComparator> comparator);
bool FindKeyInIndex(IndexedDBBackingStore::Transaction* transaction,
int64 database_id,
int64 object_store_id,
int64 index_id,
const IndexedDBKey& key,
std::string* found_encoded_primary_key,
bool* found);
bool GetIndexes(int64 database_id,
int64 object_store_id,
IndexedDBObjectStoreMetadata::IndexMap* map)
WARN_UNUSED_RESULT;
std::string identifier_;
scoped_ptr<LevelDBDatabase> db_;
scoped_ptr<LevelDBComparator> comparator_;
base::WeakPtrFactory<IndexedDBBackingStore> weak_factory_;
};
} // namespace content
#endif // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_BACKING_STORE_H_