Unreviewed, roll out http://trac.webkit.org/changeset/187972.
[WebKit-https.git] / Source / WebCore / Modules / webdatabase / DatabaseTracker.h
1 /*
2  * Copyright (C) 2007, 2008, 2013 Apple 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
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #ifndef DatabaseTracker_h
30 #define DatabaseTracker_h
31
32 #include "DatabaseDetails.h"
33 #include "DatabaseError.h"
34 #include "SQLiteDatabase.h"
35 #include "SecurityOriginHash.h"
36 #include <wtf/HashMap.h>
37 #include <wtf/HashSet.h>
38 #include <wtf/text/StringHash.h>
39 #include <wtf/text/WTFString.h>
40
41 namespace WebCore {
42
43 class Database;
44 class DatabaseContext;
45 class DatabaseManagerClient;
46 class OriginLock;
47 class SecurityOrigin;
48
49 class DatabaseTracker {
50     WTF_MAKE_NONCOPYABLE(DatabaseTracker); WTF_MAKE_FAST_ALLOCATED;
51 public:
52     // FIXME: This is a hack so we can easily delete databases from the UI process in WebKit2.
53     WEBCORE_EXPORT static std::unique_ptr<DatabaseTracker> trackerWithDatabasePath(const String& databasePath);
54
55     static void initializeTracker(const String& databasePath);
56
57     WEBCORE_EXPORT static DatabaseTracker& tracker();
58     // This singleton will potentially be used from multiple worker threads and the page's context thread simultaneously.  To keep this safe, it's
59     // currently using 4 locks.  In order to avoid deadlock when taking multiple locks, you must take them in the correct order:
60     // m_databaseGuard before quotaManager if both locks are needed.
61     // m_openDatabaseMapGuard before quotaManager if both locks are needed.
62     // m_databaseGuard and m_openDatabaseMapGuard currently don't overlap.
63     // notificationMutex() is currently independent of the other locks.
64
65     bool canEstablishDatabase(DatabaseContext*, const String& name, unsigned long estimatedSize, DatabaseError&);
66     bool retryCanEstablishDatabase(DatabaseContext*, const String& name, unsigned long estimatedSize, DatabaseError&);
67
68     void setDatabaseDetails(SecurityOrigin*, const String& name, const String& displayName, unsigned long estimatedSize);
69     String fullPathForDatabase(SecurityOrigin*, const String& name, bool createIfDoesNotExist = true);
70
71     void addOpenDatabase(Database*);
72     void removeOpenDatabase(Database*);
73     void getOpenDatabases(SecurityOrigin*, const String& name, HashSet<RefPtr<Database>>* databases);
74
75     unsigned long long getMaxSizeForDatabase(const Database*);
76
77     WEBCORE_EXPORT void closeAllDatabases();
78
79 private:
80     explicit DatabaseTracker(const String& databasePath);
81
82     bool hasAdequateQuotaForOrigin(SecurityOrigin*, unsigned long estimatedSize, DatabaseError&);
83
84 public:
85     void setDatabaseDirectoryPath(const String&);
86     String databaseDirectoryPath() const;
87
88     WEBCORE_EXPORT void origins(Vector<RefPtr<SecurityOrigin>>& result);
89     bool databaseNamesForOrigin(SecurityOrigin*, Vector<String>& result);
90
91     DatabaseDetails detailsForNameAndOrigin(const String&, SecurityOrigin*);
92
93     unsigned long long usageForOrigin(SecurityOrigin*);
94     unsigned long long quotaForOrigin(SecurityOrigin*);
95     void setQuota(SecurityOrigin*, unsigned long long);
96     RefPtr<OriginLock> originLockFor(SecurityOrigin*);
97
98     void deleteAllDatabases();
99     WEBCORE_EXPORT void deleteDatabasesModifiedSince(std::chrono::system_clock::time_point);
100     WEBCORE_EXPORT bool deleteOrigin(SecurityOrigin*);
101     bool deleteDatabase(SecurityOrigin*, const String& name);
102
103 #if PLATFORM(IOS)
104     WEBCORE_EXPORT void removeDeletedOpenedDatabases();
105     WEBCORE_EXPORT static bool deleteDatabaseFileIfEmpty(const String&);
106
107     // MobileSafari will grab this mutex on the main thread before dispatching the task to 
108     // clean up zero byte database files.  Any operations to open new database will have to
109     // wait for that task to finish by waiting on this mutex.
110     static Mutex& openDatabaseMutex();
111     
112     WEBCORE_EXPORT static void emptyDatabaseFilesRemovalTaskWillBeScheduled();
113     WEBCORE_EXPORT static void emptyDatabaseFilesRemovalTaskDidFinish();
114 #endif
115     
116     void setClient(DatabaseManagerClient*);
117
118     // From a secondary thread, must be thread safe with its data
119     void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name);
120
121     bool hasEntryForOrigin(SecurityOrigin*);
122
123     void doneCreatingDatabase(Database*);
124
125 private:
126     bool hasEntryForOriginNoLock(SecurityOrigin* origin);
127     String fullPathForDatabaseNoLock(SecurityOrigin*, const String& name, bool createIfDoesNotExist);
128     bool databaseNamesForOriginNoLock(SecurityOrigin* origin, Vector<String>& resultVector);
129     unsigned long long quotaForOriginNoLock(SecurityOrigin* origin);
130
131     String trackerDatabasePath() const;
132
133     enum TrackerCreationAction {
134         DontCreateIfDoesNotExist,
135         CreateIfDoesNotExist
136     };
137     void openTrackerDatabase(TrackerCreationAction);
138
139     String originPath(SecurityOrigin*) const;
140
141     bool hasEntryForDatabase(SecurityOrigin*, const String& databaseIdentifier);
142
143     bool addDatabase(SecurityOrigin*, const String& name, const String& path);
144
145     bool deleteDatabaseFile(SecurityOrigin*, const String& name);
146
147     void deleteOriginLockFor(SecurityOrigin*);
148
149     typedef HashSet<Database*> DatabaseSet;
150     typedef HashMap<String, DatabaseSet*> DatabaseNameMap;
151     typedef HashMap<RefPtr<SecurityOrigin>, DatabaseNameMap*> DatabaseOriginMap;
152
153     Mutex m_openDatabaseMapGuard;
154     mutable std::unique_ptr<DatabaseOriginMap> m_openDatabaseMap;
155
156     // This lock protects m_database, m_originLockMap, m_databaseDirectoryPath, m_originsBeingDeleted, m_beingCreated, and m_beingDeleted.
157     Mutex m_databaseGuard;
158     SQLiteDatabase m_database;
159
160     typedef HashMap<String, RefPtr<OriginLock>> OriginLockMap;
161     OriginLockMap m_originLockMap;
162
163     String m_databaseDirectoryPath;
164
165     DatabaseManagerClient* m_client;
166
167     typedef HashMap<String, long> NameCountMap;
168     typedef HashMap<RefPtr<SecurityOrigin>, NameCountMap*, SecurityOriginHash> CreateSet;
169     CreateSet m_beingCreated;
170     typedef HashSet<String> NameSet;
171     HashMap<RefPtr<SecurityOrigin>, NameSet*> m_beingDeleted;
172     HashSet<RefPtr<SecurityOrigin>> m_originsBeingDeleted;
173     bool isDeletingDatabaseOrOriginFor(SecurityOrigin*, const String& name);
174     void recordCreatingDatabase(SecurityOrigin*, const String& name);
175     void doneCreatingDatabase(SecurityOrigin*, const String& name);
176     bool creatingDatabase(SecurityOrigin*, const String& name);
177     bool canDeleteDatabase(SecurityOrigin*, const String& name);
178     void recordDeletingDatabase(SecurityOrigin*, const String& name);
179     void doneDeletingDatabase(SecurityOrigin*, const String& name);
180     bool isDeletingDatabase(SecurityOrigin*, const String& name);
181     bool canDeleteOrigin(SecurityOrigin*);
182     bool isDeletingOrigin(SecurityOrigin*);
183     void recordDeletingOrigin(SecurityOrigin*);
184     void doneDeletingOrigin(SecurityOrigin*);
185
186     static void scheduleForNotification();
187     static void notifyDatabasesChanged(void*);
188 };
189
190 } // namespace WebCore
191
192 #endif // DatabaseTracker_h