WebCore:
[WebKit-https.git] / WebCore / loader / icon / IconDatabase.h
1 /*
2  * Copyright (C) 2006 Apple Computer, 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25  
26 #ifndef ICONDATABASE_H
27 #define ICONDATABASE_H
28
29 #include "config.h"
30
31 #include "IntSize.h"
32 #include "PlatformString.h"
33 #include "SQLDatabase.h"
34 #include "StringHash.h"
35 #include "Timer.h"
36
37 #include <wtf/HashMap.h>
38 #include <wtf/HashSet.h>
39
40 namespace WTF {
41
42     template<> struct IntHash<WebCore::IntSize> {
43         static unsigned hash(const WebCore::IntSize& key) { return intHash((static_cast<uint64_t>(key.width()) << 32 | key.height())); }
44         static bool equal(const WebCore::IntSize& a, const WebCore::IntSize& b) { return a == b; }
45     };
46     template<> struct DefaultHash<WebCore::IntSize> { typedef IntHash<WebCore::IntSize> Hash; };
47
48 } // namespace WTF
49
50 namespace WebCore { 
51
52 class Image;
53     
54 class SiteIcon {
55 public:
56     SiteIcon(const String& url); 
57     ~SiteIcon();
58     
59     void resetExpiration(time_t newExpiration = 0);
60     time_t getExpiration();
61         
62     Image* getImage(const IntSize&);    
63     String getIconURL() { return m_iconURL; }
64
65     void manuallySetImageData(unsigned char* data, int size);
66 private:
67     String m_iconURL;
68     time_t m_expire;
69     Image* m_image;
70     
71     // This allows us to cache whether or not a SiteIcon has queried the database for its data yet
72     // We assume we only have to do that once per object and any subsequent updating of the image
73     // data will be via manuallySetImageData()
74     bool m_dataQueried;
75     
76     // FIXME - Right now WebCore::Image doesn't have a very good API for accessing multiple representations
77     // Even the NSImage way of doing things that we do in WebKit isn't very clean...  once we come up with a 
78     // better way of handling that, we'll likely have a map of size-to-images similar to below
79     // typedef HashMap<IntSize, Image*> SizeImageMap;
80     // SizeImageMap m_images;
81 };
82
83
84 class IconDatabase
85 {
86 //TODO - SiteIcon is never to be used outside of IconDatabase, so make it an internal and remove the friendness
87 friend class SiteIcon;
88 public:
89     static IconDatabase* sharedIconDatabase();
90     
91     bool open(const String& path);
92     bool isOpen() { return m_mainDB.isOpen() && m_privateBrowsingDB.isOpen(); }
93     void close();
94     
95     bool isEmpty();
96  
97     Image* iconForPageURL(const String&, const IntSize&, bool cache = true);
98     Image* iconForIconURL(const String&, const IntSize&, bool cache = true);
99     String iconURLForPageURL(const String&);
100     Image* defaultIcon(const IntSize&);
101
102     void retainIconForPageURL(const String&);
103     void releaseIconForPageURL(const String&);
104     
105     void setPrivateBrowsingEnabled(bool flag);
106     bool getPrivateBrowsingEnabled() { return m_privateBrowsingEnabled; }
107
108     bool hasEntryForIconURL(const String&);
109
110     bool isIconExpiredForIconURL(const String&);
111     
112     // TODO - The following 3 methods were considered private in WebKit - analyze the impact of making them
113     // public here in WebCore - I don't see any real badness with doing that...  after all if Chuck Norris wants to muck
114     // around with the icons in his database, he's going to anyway
115     void setIconDataForIconURL(const void* data, int size, const String&);
116     void setHaveNoIconForIconURL(const String&);
117     void setIconURLForPageURL(const String& iconURL, const String& pageURL);
118
119     static const String& defaultDatabaseFilename();
120     
121     static const int currentDatabaseVersion;    
122     static const int iconExpirationTime;
123     static const int missingIconExpirationTime;
124     static const int updateTimerDelay;
125 private:
126     IconDatabase();
127     ~IconDatabase();
128     
129     // This tries to get the iconID for the IconURL and, if it doesn't exist and createIfNecessary is true,
130     // it will create the entry and return the new iconID
131     int64_t establishIconIDForIconURL(SQLDatabase&, const String&, bool createIfNecessary = true);
132
133     // Remove traces of the given pageURL
134     void forgetPageURL(const String& pageURL);
135     
136     // Remove the current database entry for this IconURL
137     void forgetIconForIconURLFromDatabase(const String&);
138     
139     void setIconURLForPageURLInDatabase(const String&, const String&);
140     
141     // Wipe all icons from the DB
142     void removeAllIcons();
143     
144     // Removes icons from the db that no longer have any PageURLs pointing to them
145     // If numberToPrune is negative, ALL dangling icons will be pruned
146     void pruneUnreferencedIcons(int numberToPrune);
147     
148     // Called by the startup timer, this method removes all icons that are unretained
149     // after initial retains are complete
150     void pruneUnretainedIconsOnStartup(Timer<IconDatabase>*);
151     
152     // Called by the prune timer, this method periodically removes all the icons in the pending-deletion
153     // queue
154     void updateDatabase(Timer<IconDatabase>*);
155     
156     // This is called by updateDatabase and when private browsing shifts, and when the DB is closed down
157     void syncDatabase();
158     
159     // Determine if an IconURL is still retained by anyone
160     bool isIconURLRetained(const String&);
161     
162     // Do a quick check to make sure the database tables are in place and the db version is current
163     bool isValidDatabase(SQLDatabase&);
164     
165     // Delete all tables from the given database
166     void clearDatabaseTables(SQLDatabase&);
167     
168     // Create the tables and triggers for the given database.
169     void createDatabaseTables(SQLDatabase&);
170     
171     // Returns the image data for the given IconURL, checking both databases if necessary
172     Vector<unsigned char> imageDataForIconURL(const String&);
173     
174     // Retains an iconURL, bringing it back from the brink if it was pending deletion
175     void retainIconURL(const String& iconURL);
176     
177     // Releases an iconURL, putting it on the pending delete queue if it's totally released
178     void releaseIconURL(const String& iconURL);
179     
180     // FIXME: This method is currently implemented in WebCoreIconDatabaseBridge so we can be in ObjC++ and fire off a loader in Webkit
181     // Once all of the loader logic is sufficiently moved into WebCore we need to move this implementation to IconDatabase.cpp
182     // using WebCore-style loaders
183     void loadIconFromURL(const String&);
184     
185     static IconDatabase* m_sharedInstance;
186     static const int DefaultCachedPageCount;
187     
188     SQLDatabase m_mainDB;
189     SQLDatabase m_privateBrowsingDB;
190     SQLDatabase* m_currentDB;
191     
192     bool m_privateBrowsingEnabled;
193     
194     Timer<IconDatabase> m_startupTimer;
195     Timer<IconDatabase> m_updateTimer;
196     
197     typedef HashMap<String, SiteIcon*> SiteIconMap;
198     SiteIconMap m_iconURLToSiteIcons;
199     
200     HashMap<String, String> m_pageURLToIconURLMap;
201     HashMap<String, String> m_pageURLsPendingAddition;
202
203     // This will keep track of the retaincount for each pageURL
204     HashMap<String, int> m_pageURLToRetainCount;
205     // This will keep track of the retaincount for each iconURL (ie - the number of pageURLs retaining this icon)
206     HashMap<String, int> m_iconURLToRetainCount;
207
208     HashSet<String> m_pageURLsPendingDeletion;
209     HashSet<String> m_iconURLsPendingDeletion;
210 };
211
212 } //namespace WebCore
213
214 #endif