OLD | NEW |
| (Empty) |
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 #include "content/browser/indexed_db/indexed_db_factory_impl.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/strings/utf_string_conversions.h" | |
9 #include "content/browser/indexed_db/indexed_db_backing_store.h" | |
10 #include "content/browser/indexed_db/indexed_db_database_impl.h" | |
11 #include "content/browser/indexed_db/indexed_db_tracing.h" | |
12 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" | |
13 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" | |
14 | |
15 namespace content { | |
16 | |
17 template <typename K, typename M> | |
18 static void CleanWeakMap(std::map<K, base::WeakPtr<M> >* map) { | |
19 std::map<K, base::WeakPtr<M> > other; | |
20 other.swap(*map); | |
21 | |
22 typename std::map<K, base::WeakPtr<M> >::const_iterator iter = other.begin(); | |
23 while (iter != other.end()) { | |
24 if (iter->second.get()) | |
25 (*map)[iter->first] = iter->second; | |
26 ++iter; | |
27 } | |
28 } | |
29 | |
30 static string16 ComputeFileIdentifier(const string16& database_identifier) { | |
31 string16 suffix(ASCIIToUTF16("@1")); | |
32 string16 result(database_identifier); | |
33 result.insert(result.end(), suffix.begin(), suffix.end()); | |
34 return result; | |
35 } | |
36 | |
37 static string16 ComputeUniqueIdentifier(const string16& name, | |
38 const string16& database_identifier) { | |
39 return ComputeFileIdentifier(database_identifier) + name; | |
40 } | |
41 | |
42 IndexedDBFactoryImpl::IndexedDBFactoryImpl() {} | |
43 | |
44 IndexedDBFactoryImpl::~IndexedDBFactoryImpl() {} | |
45 | |
46 void IndexedDBFactoryImpl::RemoveIDBDatabaseBackend( | |
47 const string16& unique_identifier) { | |
48 DCHECK(database_backend_map_.find(unique_identifier) != | |
49 database_backend_map_.end()); | |
50 database_backend_map_.erase(unique_identifier); | |
51 } | |
52 | |
53 void IndexedDBFactoryImpl::GetDatabaseNames( | |
54 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, | |
55 const string16& database_identifier, | |
56 const base::FilePath& data_directory) { | |
57 IDB_TRACE("IndexedDBFactoryImpl::get_database_names"); | |
58 scoped_refptr<IndexedDBBackingStore> backing_store = | |
59 OpenBackingStore(database_identifier, data_directory); | |
60 if (!backing_store) { | |
61 callbacks->OnError(IndexedDBDatabaseError( | |
62 WebKit::WebIDBDatabaseExceptionUnknownError, | |
63 "Internal error opening backing store for " | |
64 "indexedDB.webkitGetDatabaseNames.")); | |
65 return; | |
66 } | |
67 | |
68 callbacks->OnSuccess(backing_store->GetDatabaseNames()); | |
69 } | |
70 | |
71 void IndexedDBFactoryImpl::DeleteDatabase( | |
72 const string16& name, | |
73 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, | |
74 const string16& database_identifier, | |
75 const base::FilePath& data_directory) { | |
76 IDB_TRACE("IndexedDBFactoryImpl::delete_database"); | |
77 const string16 unique_identifier = | |
78 ComputeUniqueIdentifier(name, database_identifier); | |
79 | |
80 IndexedDBDatabaseMap::iterator it = | |
81 database_backend_map_.find(unique_identifier); | |
82 if (it != database_backend_map_.end()) { | |
83 // If there are any connections to the database, directly delete the | |
84 // database. | |
85 it->second->DeleteDatabase(callbacks); | |
86 return; | |
87 } | |
88 | |
89 // TODO(jsbell): Everything from now on should be done on another thread. | |
90 scoped_refptr<IndexedDBBackingStore> backing_store = | |
91 OpenBackingStore(database_identifier, data_directory); | |
92 if (!backing_store) { | |
93 callbacks->OnError(IndexedDBDatabaseError( | |
94 WebKit::WebIDBDatabaseExceptionUnknownError, | |
95 ASCIIToUTF16("Internal error opening backing store " | |
96 "for indexed_db.delete_database."))); | |
97 return; | |
98 } | |
99 | |
100 scoped_refptr<IndexedDBDatabaseImpl> database_backend = | |
101 IndexedDBDatabaseImpl::Create( | |
102 name, backing_store.get(), this, unique_identifier); | |
103 if (!database_backend) { | |
104 callbacks->OnError(IndexedDBDatabaseError( | |
105 WebKit::WebIDBDatabaseExceptionUnknownError, | |
106 ASCIIToUTF16("Internal error creating database backend for " | |
107 "indexed_db.delete_database."))); | |
108 return; | |
109 } | |
110 | |
111 database_backend_map_[unique_identifier] = database_backend.get(); | |
112 database_backend->DeleteDatabase(callbacks); | |
113 database_backend_map_.erase(unique_identifier); | |
114 } | |
115 | |
116 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( | |
117 const string16& database_identifier, | |
118 const base::FilePath& data_directory) { | |
119 const string16 file_identifier = ComputeFileIdentifier(database_identifier); | |
120 const bool open_in_memory = data_directory.empty(); | |
121 | |
122 IndexedDBBackingStoreMap::iterator it2 = | |
123 backing_store_map_.find(file_identifier); | |
124 if (it2 != backing_store_map_.end() && it2->second.get()) | |
125 return it2->second.get(); | |
126 | |
127 scoped_refptr<IndexedDBBackingStore> backing_store; | |
128 if (open_in_memory) { | |
129 backing_store = IndexedDBBackingStore::OpenInMemory(file_identifier); | |
130 } else { | |
131 backing_store = IndexedDBBackingStore::Open( | |
132 database_identifier, data_directory, file_identifier); | |
133 } | |
134 | |
135 if (backing_store) { | |
136 CleanWeakMap(&backing_store_map_); | |
137 backing_store_map_[file_identifier] = backing_store->GetWeakPtr(); | |
138 // If an in-memory database, bind lifetime to this factory instance. | |
139 if (open_in_memory) | |
140 session_only_backing_stores_.insert(backing_store); | |
141 | |
142 // All backing stores associated with this factory should be of the same | |
143 // type. | |
144 DCHECK(session_only_backing_stores_.empty() || open_in_memory); | |
145 | |
146 return backing_store; | |
147 } | |
148 | |
149 return 0; | |
150 } | |
151 | |
152 void IndexedDBFactoryImpl::Open( | |
153 const string16& name, | |
154 int64 version, | |
155 int64 transaction_id, | |
156 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, | |
157 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, | |
158 const string16& database_identifier, | |
159 const base::FilePath& data_directory) { | |
160 IDB_TRACE("IndexedDBFactoryImpl::open"); | |
161 const string16 unique_identifier = | |
162 ComputeUniqueIdentifier(name, database_identifier); | |
163 | |
164 scoped_refptr<IndexedDBDatabaseImpl> database_backend; | |
165 IndexedDBDatabaseMap::iterator it = | |
166 database_backend_map_.find(unique_identifier); | |
167 if (it == database_backend_map_.end()) { | |
168 scoped_refptr<IndexedDBBackingStore> backing_store = | |
169 OpenBackingStore(database_identifier, data_directory); | |
170 if (!backing_store) { | |
171 callbacks->OnError(IndexedDBDatabaseError( | |
172 WebKit::WebIDBDatabaseExceptionUnknownError, | |
173 ASCIIToUTF16( | |
174 "Internal error opening backing store for indexedDB.open."))); | |
175 return; | |
176 } | |
177 | |
178 database_backend = IndexedDBDatabaseImpl::Create( | |
179 name, backing_store.get(), this, unique_identifier); | |
180 if (!database_backend) { | |
181 callbacks->OnError(IndexedDBDatabaseError( | |
182 WebKit::WebIDBDatabaseExceptionUnknownError, | |
183 ASCIIToUTF16( | |
184 "Internal error creating database backend for indexedDB.open."))); | |
185 return; | |
186 } | |
187 | |
188 database_backend_map_[unique_identifier] = database_backend.get(); | |
189 } else { | |
190 database_backend = it->second; | |
191 } | |
192 | |
193 database_backend->OpenConnection( | |
194 callbacks, database_callbacks, transaction_id, version); | |
195 } | |
196 | |
197 } // namespace content | |
OLD | NEW |