1// Copyright (c) 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.
4
5#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_
6#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_
7
8#include <list>
9#include <map>
10#include <string>
11#include <utility>
12#include <vector>
13
14#include "base/basictypes.h"
15#include "base/memory/ref_counted.h"
16#include "content/browser/indexed_db/indexed_db.h"
17#include "content/browser/indexed_db/indexed_db_backing_store.h"
18#include "content/browser/indexed_db/indexed_db_callbacks.h"
19#include "content/browser/indexed_db/indexed_db_metadata.h"
20#include "content/browser/indexed_db/indexed_db_pending_connection.h"
21#include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
22#include "content/browser/indexed_db/list_set.h"
23#include "third_party/WebKit/public/platform/WebIDBTypes.h"
24#include "url/gurl.h"
25
26namespace content {
27
28class IndexedDBBlobInfo;
29class IndexedDBConnection;
30class IndexedDBDatabaseCallbacks;
31class IndexedDBFactory;
32class IndexedDBKey;
33class IndexedDBKeyPath;
34class IndexedDBKeyRange;
35class IndexedDBTransaction;
36struct IndexedDBValue;
37
38class CONTENT_EXPORT IndexedDBDatabase
39    : NON_EXPORTED_BASE(public base::RefCounted<IndexedDBDatabase>) {
40 public:
41  // An index and corresponding set of keys
42  typedef std::pair<int64, std::vector<IndexedDBKey> > IndexKeys;
43
44  // Identifier is pair of (origin url, database name).
45  typedef std::pair<GURL, base::string16> Identifier;
46
47  static const int64 kInvalidId = 0;
48  static const int64 kMinimumIndexId = 30;
49
50  static scoped_refptr<IndexedDBDatabase> Create(
51      const base::string16& name,
52      IndexedDBBackingStore* backing_store,
53      IndexedDBFactory* factory,
54      const Identifier& unique_identifier,
55      leveldb::Status* s);
56
57  const Identifier& identifier() const { return identifier_; }
58  IndexedDBBackingStore* backing_store() { return backing_store_.get(); }
59
60  int64 id() const { return metadata_.id; }
61  const base::string16& name() const { return metadata_.name; }
62
63  void AddObjectStore(const IndexedDBObjectStoreMetadata& metadata,
64                      int64 new_max_object_store_id);
65  void RemoveObjectStore(int64 object_store_id);
66  void AddIndex(int64 object_store_id,
67                const IndexedDBIndexMetadata& metadata,
68                int64 new_max_index_id);
69  void RemoveIndex(int64 object_store_id, int64 index_id);
70
71  void OpenConnection(const IndexedDBPendingConnection& connection);
72  void DeleteDatabase(scoped_refptr<IndexedDBCallbacks> callbacks);
73  const IndexedDBDatabaseMetadata& metadata() const { return metadata_; }
74
75  void CreateObjectStore(int64 transaction_id,
76                         int64 object_store_id,
77                         const base::string16& name,
78                         const IndexedDBKeyPath& key_path,
79                         bool auto_increment);
80  void DeleteObjectStore(int64 transaction_id, int64 object_store_id);
81  void CreateTransaction(int64 transaction_id,
82                         IndexedDBConnection* connection,
83                         const std::vector<int64>& object_store_ids,
84                         blink::WebIDBTransactionMode mode);
85  void Close(IndexedDBConnection* connection, bool forced);
86  void ForceClose();
87
88  // Ack that one of the connections notified with a "versionchange" event did
89  // not promptly close. Therefore a "blocked" event should be fired at the
90  // pending connection.
91  void VersionChangeIgnored();
92
93  void Commit(int64 transaction_id);
94  void Abort(int64 transaction_id);
95  void Abort(int64 transaction_id, const IndexedDBDatabaseError& error);
96
97  void CreateIndex(int64 transaction_id,
98                   int64 object_store_id,
99                   int64 index_id,
100                   const base::string16& name,
101                   const IndexedDBKeyPath& key_path,
102                   bool unique,
103                   bool multi_entry);
104  void DeleteIndex(int64 transaction_id, int64 object_store_id, int64 index_id);
105
106  IndexedDBTransactionCoordinator& transaction_coordinator() {
107    return transaction_coordinator_;
108  }
109  const IndexedDBTransactionCoordinator& transaction_coordinator() const {
110    return transaction_coordinator_;
111  }
112
113  void TransactionCreated(IndexedDBTransaction* transaction);
114  void TransactionFinished(IndexedDBTransaction* transaction, bool committed);
115
116  // Called by transactions to report failure committing to the backing store.
117  void TransactionCommitFailed(const leveldb::Status& status);
118
119  void Get(int64 transaction_id,
120           int64 object_store_id,
121           int64 index_id,
122           scoped_ptr<IndexedDBKeyRange> key_range,
123           bool key_only,
124           scoped_refptr<IndexedDBCallbacks> callbacks);
125  void Put(int64 transaction_id,
126           int64 object_store_id,
127           IndexedDBValue* value,
128           ScopedVector<storage::BlobDataHandle>* handles,
129           scoped_ptr<IndexedDBKey> key,
130           blink::WebIDBPutMode mode,
131           scoped_refptr<IndexedDBCallbacks> callbacks,
132           const std::vector<IndexKeys>& index_keys);
133  void SetIndexKeys(int64 transaction_id,
134                    int64 object_store_id,
135                    scoped_ptr<IndexedDBKey> primary_key,
136                    const std::vector<IndexKeys>& index_keys);
137  void SetIndexesReady(int64 transaction_id,
138                       int64 object_store_id,
139                       const std::vector<int64>& index_ids);
140  void OpenCursor(int64 transaction_id,
141                  int64 object_store_id,
142                  int64 index_id,
143                  scoped_ptr<IndexedDBKeyRange> key_range,
144                  blink::WebIDBCursorDirection,
145                  bool key_only,
146                  blink::WebIDBTaskType task_type,
147                  scoped_refptr<IndexedDBCallbacks> callbacks);
148  void Count(int64 transaction_id,
149             int64 object_store_id,
150             int64 index_id,
151             scoped_ptr<IndexedDBKeyRange> key_range,
152             scoped_refptr<IndexedDBCallbacks> callbacks);
153  void DeleteRange(int64 transaction_id,
154                   int64 object_store_id,
155                   scoped_ptr<IndexedDBKeyRange> key_range,
156                   scoped_refptr<IndexedDBCallbacks> callbacks);
157  void Clear(int64 transaction_id,
158             int64 object_store_id,
159             scoped_refptr<IndexedDBCallbacks> callbacks);
160
161  // Number of connections that have progressed passed initial open call.
162  size_t ConnectionCount() const;
163  // Number of open calls that are blocked on other connections.
164  size_t PendingOpenCount() const;
165  // Number of pending upgrades (0 or 1). Also included in ConnectionCount().
166  size_t PendingUpgradeCount() const;
167  // Number of running upgrades (0 or 1). Also included in ConnectionCount().
168  size_t RunningUpgradeCount() const;
169  // Number of pending deletes, blocked on other connections.
170  size_t PendingDeleteCount() const;
171
172  // Asynchronous tasks scheduled within transactions:
173  void CreateObjectStoreAbortOperation(int64 object_store_id,
174                                       IndexedDBTransaction* transaction);
175  void DeleteObjectStoreOperation(
176      int64 object_store_id,
177      IndexedDBTransaction* transaction);
178  void DeleteObjectStoreAbortOperation(
179      const IndexedDBObjectStoreMetadata& object_store_metadata,
180      IndexedDBTransaction* transaction);
181  void VersionChangeOperation(int64 version,
182                              scoped_refptr<IndexedDBCallbacks> callbacks,
183                              scoped_ptr<IndexedDBConnection> connection,
184                              IndexedDBTransaction* transaction);
185  void VersionChangeAbortOperation(const base::string16& previous_version,
186                                   int64 previous_int_version,
187                                   IndexedDBTransaction* transaction);
188  void DeleteIndexOperation(int64 object_store_id,
189                            int64 index_id,
190                            IndexedDBTransaction* transaction);
191  void CreateIndexAbortOperation(int64 object_store_id,
192                                 int64 index_id,
193                                 IndexedDBTransaction* transaction);
194  void DeleteIndexAbortOperation(int64 object_store_id,
195                                 const IndexedDBIndexMetadata& index_metadata,
196                                 IndexedDBTransaction* transaction);
197  void GetOperation(int64 object_store_id,
198                    int64 index_id,
199                    scoped_ptr<IndexedDBKeyRange> key_range,
200                    indexed_db::CursorType cursor_type,
201                    scoped_refptr<IndexedDBCallbacks> callbacks,
202                    IndexedDBTransaction* transaction);
203  struct PutOperationParams;
204  void PutOperation(scoped_ptr<PutOperationParams> params,
205                    IndexedDBTransaction* transaction);
206  void SetIndexesReadyOperation(size_t index_count,
207                                IndexedDBTransaction* transaction);
208  struct OpenCursorOperationParams;
209  void OpenCursorOperation(scoped_ptr<OpenCursorOperationParams> params,
210                           IndexedDBTransaction* transaction);
211  void CountOperation(int64 object_store_id,
212                      int64 index_id,
213                      scoped_ptr<IndexedDBKeyRange> key_range,
214                      scoped_refptr<IndexedDBCallbacks> callbacks,
215                      IndexedDBTransaction* transaction);
216  void DeleteRangeOperation(int64 object_store_id,
217                            scoped_ptr<IndexedDBKeyRange> key_range,
218                            scoped_refptr<IndexedDBCallbacks> callbacks,
219                            IndexedDBTransaction* transaction);
220  void ClearOperation(int64 object_store_id,
221                      scoped_refptr<IndexedDBCallbacks> callbacks,
222                      IndexedDBTransaction* transaction);
223
224 private:
225  friend class base::RefCounted<IndexedDBDatabase>;
226
227  class PendingDeleteCall;
228  class PendingSuccessCall;
229  class PendingUpgradeCall;
230
231  typedef std::map<int64, IndexedDBTransaction*> TransactionMap;
232  typedef std::list<IndexedDBPendingConnection> PendingOpenCallList;
233  typedef std::list<PendingDeleteCall*> PendingDeleteCallList;
234  typedef list_set<IndexedDBConnection*> ConnectionSet;
235
236  IndexedDBDatabase(const base::string16& name,
237                    IndexedDBBackingStore* backing_store,
238                    IndexedDBFactory* factory,
239                    const Identifier& unique_identifier);
240  ~IndexedDBDatabase();
241
242  bool IsOpenConnectionBlocked() const;
243  leveldb::Status OpenInternal();
244  void RunVersionChangeTransaction(scoped_refptr<IndexedDBCallbacks> callbacks,
245                                   scoped_ptr<IndexedDBConnection> connection,
246                                   int64 transaction_id,
247                                   int64 requested_version);
248  void RunVersionChangeTransactionFinal(
249      scoped_refptr<IndexedDBCallbacks> callbacks,
250      scoped_ptr<IndexedDBConnection> connection,
251      int64 transaction_id,
252      int64 requested_version);
253  void ProcessPendingCalls();
254
255  bool IsDeleteDatabaseBlocked() const;
256  void DeleteDatabaseFinal(scoped_refptr<IndexedDBCallbacks> callbacks);
257
258  scoped_ptr<IndexedDBConnection> CreateConnection(
259      scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
260      int child_process_id);
261
262  IndexedDBTransaction* GetTransaction(int64 transaction_id) const;
263
264  bool ValidateObjectStoreId(int64 object_store_id) const;
265  bool ValidateObjectStoreIdAndIndexId(int64 object_store_id,
266                                       int64 index_id) const;
267  bool ValidateObjectStoreIdAndOptionalIndexId(int64 object_store_id,
268                                               int64 index_id) const;
269  bool ValidateObjectStoreIdAndNewIndexId(int64 object_store_id,
270                                          int64 index_id) const;
271
272  scoped_refptr<IndexedDBBackingStore> backing_store_;
273  IndexedDBDatabaseMetadata metadata_;
274
275  const Identifier identifier_;
276  scoped_refptr<IndexedDBFactory> factory_;
277
278  IndexedDBTransactionCoordinator transaction_coordinator_;
279
280  TransactionMap transactions_;
281  PendingOpenCallList pending_open_calls_;
282  scoped_ptr<PendingUpgradeCall> pending_run_version_change_transaction_call_;
283  scoped_ptr<PendingSuccessCall> pending_second_half_open_;
284  PendingDeleteCallList pending_delete_calls_;
285
286  ConnectionSet connections_;
287
288  DISALLOW_COPY_AND_ASSIGN(IndexedDBDatabase);
289};
290
291}  // namespace content
292
293#endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_DATABASE_H_
294