• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "DatabaseTracker.h"
33 
34 #if ENABLE(DATABASE)
35 
36 #include "AbstractDatabase.h"
37 #include "DatabaseObserver.h"
38 #include "QuotaTracker.h"
39 #include "PlatformString.h"
40 #include "ScriptExecutionContext.h"
41 #include "SecurityOrigin.h"
42 #include "SecurityOriginHash.h"
43 #include "SQLiteFileSystem.h"
44 #include <wtf/StdLibExtras.h>
45 
46 namespace WebCore {
47 
tracker()48 DatabaseTracker& DatabaseTracker::tracker()
49 {
50     DEFINE_STATIC_LOCAL(DatabaseTracker, tracker, (""));
51     return tracker;
52 }
53 
DatabaseTracker(const String &)54 DatabaseTracker::DatabaseTracker(const String&)
55 {
56     SQLiteFileSystem::registerSQLiteVFS();
57 }
58 
canEstablishDatabase(ScriptExecutionContext * scriptExecutionContext,const String & name,const String & displayName,unsigned long estimatedSize)59 bool DatabaseTracker::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize)
60 {
61     return DatabaseObserver::canEstablishDatabase(scriptExecutionContext, name, displayName, estimatedSize);
62 }
63 
setDatabaseDetails(SecurityOrigin *,const String &,const String &,unsigned long)64 void DatabaseTracker::setDatabaseDetails(SecurityOrigin*, const String&, const String&, unsigned long)
65 {
66     // Chromium sets the database details when the database is opened
67 }
68 
fullPathForDatabase(SecurityOrigin * origin,const String & name,bool)69 String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool)
70 {
71     return origin->databaseIdentifier() + "/" + name + "#";
72 }
73 
addOpenDatabase(AbstractDatabase * database)74 void DatabaseTracker::addOpenDatabase(AbstractDatabase* database)
75 {
76     ASSERT(database->scriptExecutionContext()->isContextThread());
77     MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
78     if (!m_openDatabaseMap)
79         m_openDatabaseMap.set(new DatabaseOriginMap());
80 
81     DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
82     if (!nameMap) {
83         nameMap = new DatabaseNameMap();
84         m_openDatabaseMap->set(database->securityOrigin(), nameMap);
85     }
86 
87     String name(database->stringIdentifier());
88     DatabaseSet* databaseSet = nameMap->get(name);
89     if (!databaseSet) {
90         databaseSet = new DatabaseSet();
91         nameMap->set(name, databaseSet);
92     }
93 
94     databaseSet->add(database);
95 
96     DatabaseObserver::databaseOpened(database);
97 }
98 
99 class TrackerRemoveOpenDatabaseTask : public ScriptExecutionContext::Task {
100 public:
create(PassRefPtr<AbstractDatabase> database)101     static PassOwnPtr<TrackerRemoveOpenDatabaseTask> create(PassRefPtr<AbstractDatabase> database)
102     {
103         return new TrackerRemoveOpenDatabaseTask(database);
104     }
105 
performTask(ScriptExecutionContext * context)106     virtual void performTask(ScriptExecutionContext* context)
107     {
108         DatabaseTracker::tracker().removeOpenDatabase(m_database.get());
109     }
110 
111 private:
TrackerRemoveOpenDatabaseTask(PassRefPtr<AbstractDatabase> database)112     TrackerRemoveOpenDatabaseTask(PassRefPtr<AbstractDatabase> database)
113         : m_database(database)
114     {
115     }
116 
117     RefPtr<AbstractDatabase> m_database;
118 };
119 
removeOpenDatabase(AbstractDatabase * database)120 void DatabaseTracker::removeOpenDatabase(AbstractDatabase* database)
121 {
122     if (!database->scriptExecutionContext()->isContextThread()) {
123         database->scriptExecutionContext()->postTask(TrackerRemoveOpenDatabaseTask::create(database));
124         return;
125     }
126 
127     MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
128     ASSERT(m_openDatabaseMap);
129     DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
130     ASSERT(nameMap);
131     String name(database->stringIdentifier());
132     DatabaseSet* databaseSet = nameMap->get(name);
133     ASSERT(databaseSet);
134     databaseSet->remove(database);
135 
136     if (databaseSet->isEmpty()) {
137         nameMap->remove(name);
138         delete databaseSet;
139         if (nameMap->isEmpty()) {
140             m_openDatabaseMap->remove(database->securityOrigin());
141             delete nameMap;
142         }
143     }
144 
145     DatabaseObserver::databaseClosed(database);
146 }
147 
148 
getOpenDatabases(SecurityOrigin * origin,const String & name,HashSet<RefPtr<AbstractDatabase>> * databases)149 void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<AbstractDatabase> >* databases)
150 {
151     MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
152     if (!m_openDatabaseMap)
153         return;
154 
155     DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin);
156     if (!nameMap)
157         return;
158 
159     DatabaseSet* databaseSet = nameMap->get(name);
160     if (!databaseSet)
161         return;
162 
163     for (DatabaseSet::iterator it = databaseSet->begin(); it != databaseSet->end(); ++it)
164         databases->add(*it);
165 }
166 
getMaxSizeForDatabase(const AbstractDatabase * database)167 unsigned long long DatabaseTracker::getMaxSizeForDatabase(const AbstractDatabase* database)
168 {
169     unsigned long long spaceAvailable = 0;
170     unsigned long long databaseSize = 0;
171     QuotaTracker::instance().getDatabaseSizeAndSpaceAvailableToOrigin(
172         database->securityOrigin()->databaseIdentifier(),
173         database->stringIdentifier(), &databaseSize, &spaceAvailable);
174     return databaseSize + spaceAvailable;
175 }
176 
interruptAllDatabasesForContext(const ScriptExecutionContext * context)177 void DatabaseTracker::interruptAllDatabasesForContext(const ScriptExecutionContext* context)
178 {
179     Vector<RefPtr<AbstractDatabase> > openDatabases;
180     {
181         MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
182 
183         if (!m_openDatabaseMap)
184             return;
185 
186         DatabaseNameMap* nameMap = m_openDatabaseMap->get(context->securityOrigin());
187         if (!nameMap)
188             return;
189 
190         DatabaseNameMap::const_iterator dbNameMapEndIt = nameMap->end();
191         for (DatabaseNameMap::const_iterator dbNameMapIt = nameMap->begin(); dbNameMapIt != dbNameMapEndIt; ++dbNameMapIt) {
192             DatabaseSet* databaseSet = dbNameMapIt->second;
193             DatabaseSet::const_iterator dbSetEndIt = databaseSet->end();
194             for (DatabaseSet::const_iterator dbSetIt = databaseSet->begin(); dbSetIt != dbSetEndIt; ++dbSetIt) {
195                 if ((*dbSetIt)->scriptExecutionContext() == context)
196                     openDatabases.append(*dbSetIt);
197             }
198         }
199     }
200 
201     Vector<RefPtr<AbstractDatabase> >::const_iterator openDatabasesEndIt = openDatabases.end();
202     for (Vector<RefPtr<AbstractDatabase> >::const_iterator openDatabasesIt = openDatabases.begin(); openDatabasesIt != openDatabasesEndIt; ++openDatabasesIt)
203         (*openDatabasesIt)->interrupt();
204 }
205 
206 }
207 
208 #endif // ENABLE(DATABASE)
209