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 #ifndef CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_H_
6 #define CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_H_
11 #include "base/files/file_path.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "content/common/content_export.h"
16 #include "content/common/dom_storage/dom_storage_types.h"
17 #include "third_party/leveldatabase/src/include/leveldb/status.h"
25 } // namespace leveldb
29 // SessionStorageDatabase holds the data from multiple namespaces and multiple
30 // origins. All DOMStorageAreas for session storage share the same
31 // SessionStorageDatabase.
33 // Only one thread is allowed to call the public functions other than
34 // ReadAreaValues and ReadNamespacesAndOrigins. Other threads are allowed to
35 // call ReadAreaValues and ReadNamespacesAndOrigins.
36 class CONTENT_EXPORT SessionStorageDatabase
:
37 public base::RefCountedThreadSafe
<SessionStorageDatabase
> {
39 explicit SessionStorageDatabase(const base::FilePath
& file_path
);
41 // Reads the (key, value) pairs for |namespace_id| and |origin|. |result| is
42 // assumed to be empty and any duplicate keys will be overwritten. If the
43 // database exists on disk then it will be opened. If it does not exist then
44 // it will not be created and |result| will be unmodified.
45 void ReadAreaValues(const std::string
& namespace_id
,
47 DOMStorageValuesMap
* result
);
49 // Updates the data for |namespace_id| and |origin|. Will remove all keys
50 // before updating the database if |clear_all_first| is set. Then all entries
51 // in |changes| will be examined - keys mapped to a null NullableString16 will
52 // be removed and all others will be inserted/updated as appropriate. It is
53 // allowed to write data into a shallow copy created by CloneNamespace, and in
54 // that case the copy will be made deep before writing the values.
55 bool CommitAreaChanges(const std::string
& namespace_id
,
58 const DOMStorageValuesMap
& changes
);
60 // Creates shallow copies of the areas for |namespace_id| and associates them
61 // with |new_namespace_id|.
62 bool CloneNamespace(const std::string
& namespace_id
,
63 const std::string
& new_namespace_id
);
65 // Deletes the data for |namespace_id| and |origin|.
66 bool DeleteArea(const std::string
& namespace_id
, const GURL
& origin
);
68 // Deletes the data for |namespace_id|.
69 bool DeleteNamespace(const std::string
& namespace_id
);
71 // Reads the namespace IDs and origins present in the database.
72 bool ReadNamespacesAndOrigins(
73 std::map
<std::string
, std::vector
<GURL
> >* namespaces_and_origins
);
76 friend class base::RefCountedThreadSafe
<SessionStorageDatabase
>;
78 friend class SessionStorageDatabase::DBOperation
;
79 friend class SessionStorageDatabaseTest
;
81 ~SessionStorageDatabase();
83 // Opens the database at file_path_ if it exists already and creates it if
84 // |create_if_needed| is true. Returns true if the database was opened, false
85 // if the opening failed or was not necessary (the database doesn't exist and
86 // |create_if_needed| is false). The possible failures are:
87 // - leveldb cannot open the database.
88 // - The database is in an inconsistent or errored state.
89 bool LazyOpen(bool create_if_needed
);
91 // Tries to open the database at file_path_, assigns |db| to point to the
92 // opened leveldb::DB instance.
93 leveldb::Status
TryToOpen(leveldb::DB
** db
);
95 // Returns true if the database is already open, false otherwise.
98 // Helpers for checking caller erros, invariants and database errors. All
99 // these return |ok|, for chaining.
100 bool CallerErrorCheck(bool ok
) const;
101 bool ConsistencyCheck(bool ok
);
102 bool DatabaseErrorCheck(bool ok
);
104 // Helper functions. All return true if the operation succeeded, and false if
105 // it failed (a database error or a consistency error). If the return type is
106 // void, the operation cannot fail. If they return false, ConsistencyCheck or
107 // DatabaseErrorCheck have already been called.
109 // Creates a namespace for |namespace_id| and updates the next namespace id if
110 // needed. If |ok_if_exists| is false, checks that the namespace didn't exist
112 bool CreateNamespace(const std::string
& namespace_id
,
114 leveldb::WriteBatch
* batch
);
116 // Reads the areas assoiated with |namespace_id| and puts the (origin, map_id)
117 // pairs into |areas|.
118 bool GetAreasInNamespace(const std::string
& namespace_id
,
119 std::map
<std::string
, std::string
>* areas
);
121 // Adds an association between |origin| and |map_id| into the namespace
123 void AddAreaToNamespace(const std::string
& namespace_id
,
124 const std::string
& origin
,
125 const std::string
& map_id
,
126 leveldb::WriteBatch
* batch
);
128 // Helpers for deleting data for |namespace_id| and |origin|.
129 bool DeleteAreaHelper(const std::string
& namespace_id
,
130 const std::string
& origin
,
131 leveldb::WriteBatch
* batch
);
133 // Retrieves the map id for |namespace_id| and |origin|. It's not an error if
134 // the map doesn't exist.
135 bool GetMapForArea(const std::string
& namespace_id
,
136 const std::string
& origin
,
137 const leveldb::ReadOptions
& options
,
139 std::string
* map_id
);
141 // Creates a new map for |namespace_id| and |origin|. |map_id| will hold the
142 // id of the created map. If there is a map for |namespace_id| and |origin|,
143 // this just overwrites the map id. The caller is responsible for decreasing
145 bool CreateMapForArea(const std::string
& namespace_id
,
148 leveldb::WriteBatch
* batch
);
149 // Reads the contents of the map |map_id| into |result|. If |only_keys| is
150 // true, only keys are aread from the database and the values in |result| will
152 bool ReadMap(const std::string
& map_id
,
153 const leveldb::ReadOptions
& options
,
154 DOMStorageValuesMap
* result
,
156 // Writes |values| into the map |map_id|.
157 void WriteValuesToMap(const std::string
& map_id
,
158 const DOMStorageValuesMap
& values
,
159 leveldb::WriteBatch
* batch
);
161 bool GetMapRefCount(const std::string
& map_id
, int64
* ref_count
);
162 bool IncreaseMapRefCount(const std::string
& map_id
,
163 leveldb::WriteBatch
* batch
);
164 // Decreases the ref count of a map by |decrease|. If the ref count goes to 0,
166 bool DecreaseMapRefCount(const std::string
& map_id
,
168 leveldb::WriteBatch
* batch
);
170 // Deletes all values in |map_id|.
171 bool ClearMap(const std::string
& map_id
, leveldb::WriteBatch
* batch
);
173 // Breaks the association between (|namespace_id|, |origin|) and |map_id| and
174 // creates a new map for (|namespace_id|, |origin|). Copies the data from the
175 // old map if |copy_data| is true.
176 bool DeepCopyArea(const std::string
& namespace_id
,
180 leveldb::WriteBatch
* batch
);
182 // Helper functions for creating the keys needed for the schema.
183 static std::string
NamespaceStartKey(const std::string
& namespace_id
);
184 static std::string
NamespaceKey(const std::string
& namespace_id
,
185 const std::string
& origin
);
186 static const char* NamespacePrefix();
187 static std::string
MapRefCountKey(const std::string
& map_id
);
188 static std::string
MapKey(const std::string
& map_id
, const std::string
& key
);
189 static const char* NextMapIdKey();
191 scoped_ptr
<leveldb::DB
> db_
;
192 base::FilePath file_path_
;
194 // For protecting the database opening code. Also guards the variables below.
197 // True if a database error has occurred (e.g., cannot read data).
199 // True if the database is in an inconsistent state.
200 bool is_inconsistent_
;
201 // True if the database is in a failed or inconsistent state, and we have
202 // already deleted it (as an attempt to recover later).
203 bool invalid_db_deleted_
;
205 // The number of database operations in progress. We need this so that we can
206 // delete an inconsistent database at the right moment.
207 int operation_count_
;
209 DISALLOW_COPY_AND_ASSIGN(SessionStorageDatabase
);
212 } // namespace content
214 #endif // CONTENT_BROWSER_DOM_STORAGE_SESSION_STORAGE_DATABASE_H_