Reviewed by Maciej
Renamed a method/parameter for clarity and consistency, as well as some style
cleanups and removing some ridiculously verbose log messages.
Also added an _isEmpty method to the database and bridge for WebKit's use.
Finally, added a central way for both WebKit and WebCore to get the icon database filename
* bridge/mac/WebCoreIconDatabaseBridge.h: Added _isEmpty and defaultDatabaseFilename
* bridge/mac/WebCoreIconDatabaseBridge.mm: Removed an unnecessary semicolon off most of these methods
(-[WebCoreIconDatabaseBridge openSharedDatabaseWithPath:]):
(-[WebCoreIconDatabaseBridge closeSharedDatabase]):
(-[WebCoreIconDatabaseBridge isOpen]):
(-[WebCoreIconDatabaseBridge _isEmpty]): Added
(-[WebCoreIconDatabaseBridge setPrivateBrowsingEnabled:]):
(-[WebCoreIconDatabaseBridge privateBrowsingEnabled]):
(-[WebCoreIconDatabaseBridge iconForPageURL:withSize:]):
(-[WebCoreIconDatabaseBridge iconURLForPageURL:]):
(-[WebCoreIconDatabaseBridge defaultIconWithSize:]):
(-[WebCoreIconDatabaseBridge retainIconForURL:]):
(-[WebCoreIconDatabaseBridge releaseIconForURL:]):
(-[WebCoreIconDatabaseBridge _setIconData:forIconURL:]):
(-[WebCoreIconDatabaseBridge _setHaveNoIconForIconURL:]):
(-[WebCoreIconDatabaseBridge _setIconURL:forPageURL:]):
(-[WebCoreIconDatabaseBridge _hasIconForIconURL:]):
(-[WebCoreIconDatabaseBridge defaultDatabaseFilename]): Added
* loader/icon/IconDatabase.cpp:
(WebCore::IconDatabase::defaultDatabaseFilename): Added
(WebCore::IconDatabase::open):
(WebCore::IconDatabase::isEmpty): Added
(WebCore::IconDatabase::retainIconForURL): Removed log message
(WebCore::IconDatabase::releaseIconForURL): Removed log message
* loader/icon/IconDatabase.h:
WebKit:
Reviewed by John, Timo, Adele, and Darin
In addition to a few style/good-practice cleanups, this patch will convert the old icon database
format to the WebCore format if the WebCore db is empty (implying this conversion has yet to take
place). After the conversion, it will delete all traces of the old format to free the unneeded space
* Misc/WebIconDatabase.m:
(-[WebIconDatabase init]):
(-[WebIconDatabase _setIconURL:forURL:]): Changed the bridge's name for this method to be more clear
(-[WebIconDatabase _createFileDatabase]):
(-[WebIconDatabase _iconDataForIconURL:]): This grabs the raw data for use in the conversion function
(-[WebIconDatabase _convertToWebCoreFormat]): This does the actual conversion
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15841
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2006-08-11 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Maciej
+
+ Renamed a method/parameter for clarity and consistency, as well as some style
+ cleanups and removing some ridiculously verbose log messages.
+ Also added an _isEmpty method to the database and bridge for WebKit's use.
+ Finally, added a central way for both WebKit and WebCore to get the icon database filename
+
+ * bridge/mac/WebCoreIconDatabaseBridge.h: Added _isEmpty and defaultDatabaseFilename
+ * bridge/mac/WebCoreIconDatabaseBridge.mm: Removed an unnecessary semicolon off most of these methods
+ (-[WebCoreIconDatabaseBridge openSharedDatabaseWithPath:]):
+ (-[WebCoreIconDatabaseBridge closeSharedDatabase]):
+ (-[WebCoreIconDatabaseBridge isOpen]):
+ (-[WebCoreIconDatabaseBridge _isEmpty]): Added
+ (-[WebCoreIconDatabaseBridge setPrivateBrowsingEnabled:]):
+ (-[WebCoreIconDatabaseBridge privateBrowsingEnabled]):
+ (-[WebCoreIconDatabaseBridge iconForPageURL:withSize:]):
+ (-[WebCoreIconDatabaseBridge iconURLForPageURL:]):
+ (-[WebCoreIconDatabaseBridge defaultIconWithSize:]):
+ (-[WebCoreIconDatabaseBridge retainIconForURL:]):
+ (-[WebCoreIconDatabaseBridge releaseIconForURL:]):
+ (-[WebCoreIconDatabaseBridge _setIconData:forIconURL:]):
+ (-[WebCoreIconDatabaseBridge _setHaveNoIconForIconURL:]):
+ (-[WebCoreIconDatabaseBridge _setIconURL:forPageURL:]):
+ (-[WebCoreIconDatabaseBridge _hasIconForIconURL:]):
+ (-[WebCoreIconDatabaseBridge defaultDatabaseFilename]): Added
+
+ * loader/icon/IconDatabase.cpp:
+ (WebCore::IconDatabase::defaultDatabaseFilename): Added
+ (WebCore::IconDatabase::open):
+ (WebCore::IconDatabase::isEmpty): Added
+ (WebCore::IconDatabase::retainIconForURL): Removed log message
+ (WebCore::IconDatabase::releaseIconForURL): Removed log message
+ * loader/icon/IconDatabase.h:
+
2006-08-11 David Hyatt <hyatt@apple.com>
Eliminate RenderImageButton.
- (void)setPrivateBrowsingEnabled:(BOOL)flag;
- (BOOL)privateBrowsingEnabled;
+- (NSString *)defaultDatabaseFilename;
+
- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL;
- (void)_setHaveNoIconForIconURL:(NSString *)iconURL;
-- (void)_setIconURL:(NSString *)iconURL forURL:(NSString *)url;
+- (void)_setIconURL:(NSString *)iconURL forPageURL:(NSString *)pageURL;
- (BOOL)_hasIconForIconURL:(NSString *)iconURL;
+- (BOOL)_isEmpty;
@end
@implementation WebCoreIconDatabaseBridge
-- (BOOL)openSharedDatabaseWithPath:(NSString *)path;
+- (BOOL)openSharedDatabaseWithPath:(NSString *)path
{
assert(path);
return NO;
}
-- (void)closeSharedDatabase;
+- (void)closeSharedDatabase
{
if (_iconDB) {
_iconDB->close();
}
}
-- (BOOL)isOpen;
+- (BOOL)isOpen
{
return _iconDB != 0;
}
+- (BOOL)_isEmpty
+{
+ return _iconDB ? _iconDB->isEmpty() : NO;
+}
+
- (BOOL)isIconExpiredForIconURL:(NSString *)iconURL
{
return _iconDB ? _iconDB->isIconExpiredForIconURL(iconURL) : NO;
return _iconDB ? _iconDB->isIconExpiredForPageURL(pageURL) : NO;
}
-- (void)setPrivateBrowsingEnabled:(BOOL)flag;
+- (void)setPrivateBrowsingEnabled:(BOOL)flag
{
if (_iconDB)
_iconDB->setPrivateBrowsingEnabled(flag);
}
-- (BOOL)privateBrowsingEnabled;
+- (BOOL)privateBrowsingEnabled
{
if (_iconDB)
return _iconDB->getPrivateBrowsingEnabled();
return false;
}
-- (NSImage *)iconForPageURL:(NSString *)url withSize:(NSSize)size;
+- (NSImage *)iconForPageURL:(NSString *)url withSize:(NSSize)size
{
ASSERT(_iconDB);
ASSERT(url);
return nil;
}
-- (NSString *)iconURLForPageURL:(NSString *)url;
+- (NSString *)iconURLForPageURL:(NSString *)url
{
ASSERT(_iconDB);
ASSERT(url);
return (NSString*)iconURL;
}
-- (NSImage *)defaultIconWithSize:(NSSize)size;
+- (NSImage *)defaultIconWithSize:(NSSize)size
{
ASSERT(_iconDB);
ASSERT(size.width);
return nil;
}
-- (void)retainIconForURL:(NSString *)url;
+- (void)retainIconForURL:(NSString *)url
{
ASSERT(_iconDB);
ASSERT(url);
_iconDB->retainIconForURL(String(url));
}
-- (void)releaseIconForURL:(NSString *)url;
+- (void)releaseIconForURL:(NSString *)url
{
ASSERT(_iconDB);
ASSERT(url);
_iconDB->releaseIconForURL(String(url));
}
-- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL;
+- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL
{
ASSERT(_iconDB);
ASSERT(data);
_iconDB->setIconDataForIconURL([data bytes], [data length], String(iconURL));
}
-- (void)_setHaveNoIconForIconURL:(NSString *)iconURL;
+- (void)_setHaveNoIconForIconURL:(NSString *)iconURL
{
ASSERT(_iconDB);
ASSERT(iconURL);
_iconDB->setHaveNoIconForIconURL(String(iconURL));
}
-- (void)_setIconURL:(NSString *)iconURL forURL:(NSString *)url;
+- (void)_setIconURL:(NSString *)iconURL forPageURL:(NSString *)pageURL
{
ASSERT(_iconDB);
ASSERT(iconURL);
- ASSERT(url);
+ ASSERT(pageURL);
- _iconDB->setIconURLForPageURL(String(iconURL), String(url));
+ _iconDB->setIconURLForPageURL(String(iconURL), String(pageURL));
}
-- (BOOL)_hasIconForIconURL:(NSString *)iconURL;
+- (BOOL)_hasIconForIconURL:(NSString *)iconURL
{
ASSERT(_iconDB);
ASSERT(iconURL);
return _iconDB->hasIconForIconURL(String(iconURL));
}
-
-
-
+- (NSString *)defaultDatabaseFilename
+{
+ return IconDatabase::defaultDatabaseFilename();
+}
@end
// FIXME - One optimization to be made when this is no longer in flux is to make query construction smarter - that is queries that are created from
// multiple strings and numbers should be handled differently than with String + String + String + etc.
-const char* DefaultIconDatabaseFilename = "/icon.db";
-
namespace WebCore {
IconDatabase* IconDatabase::m_sharedInstance = 0;
// Absent icons are rechecked once a week
const int IconDatabase::missingIconExpirationTime = 60*60*24*7;
+const String& IconDatabase::defaultDatabaseFilename()
+{
+ static String defaultDatabaseFilename = "icon.db";
+ return defaultDatabaseFilename;
+}
+
IconDatabase* IconDatabase::sharedIconDatabase()
{
bool IconDatabase::open(const String& databasePath)
{
close();
- String dbFilename = databasePath + DefaultIconDatabaseFilename;
+ String dbFilename;
+
+ if (databasePath[databasePath.length()] == '/')
+ dbFilename = databasePath + defaultDatabaseFilename();
+ else
+ dbFilename = databasePath + "/" + defaultDatabaseFilename();
+
if (!m_db.open(dbFilename)) {
LOG(IconDatabase, "Unable to open icon database at path %s", dbFilename.ascii().data());
return false;
m_db.close();
}
+bool IconDatabase::isEmpty()
+{
+ return !(SQLStatement(m_db, "SELECT iconID FROM PageURL LIMIT 1;").getColumnInt(0));
+}
+
bool IconDatabase::isValidDatabase()
{
if (!m_db.executeCommand("INSERT INTO PageRetain VALUES ('" + url + "', " + String::number(retainCount + 1) + ");"))
LOG_ERROR("Failed to increment retain count for url %s", _url.ascii().data());
- LOG(IconDatabase, "URL %s now has a retain count of %i", _url.ascii().data(), retainCount + 1);
}
void IconDatabase::releaseIconForURL(const String& _url)
--retainCount;
if (!m_db.executeCommand("INSERT INTO PageRetain VALUES ('" + url + "', " + String::number(retainCount) + ");"))
LOG_ERROR("Failed to decrement retain count for url %s", _url.ascii().data());
-
- LOG(IconDatabase, "URL %s now has a retain count of %i", _url.ascii().data(), retainCount);
-
+
// If we still have a positve retain count, we're done - lets bail
if (retainCount)
return;
bool open(const String& path);
bool isOpen() { return m_db.isOpen(); }
void close();
+
+ bool isEmpty();
Image* iconForPageURL(const String&, const IntSize&, bool cache = true);
Image* iconForIconURL(const String&, const IntSize&, bool cache = true);
void setHaveNoIconForIconURL(const String&);
void setIconURLForPageURL(const String& iconURL, const String& pageURL);
+ static const String& defaultDatabaseFilename();
+
static const int currentDatabaseVersion;
static const int iconExpirationTime;
static const int missingIconExpirationTime;
+2006-08-11 Brady Eidson <beidson@apple.com>
+
+ Reviewed by John, Timo, Adele, and Darin
+
+ In addition to a few style/good-practice cleanups, this patch will convert the old icon database
+ format to the WebCore format if the WebCore db is empty (implying this conversion has yet to take
+ place). After the conversion, it will delete all traces of the old format to free the unneeded space
+
+ * Misc/WebIconDatabase.m:
+ (-[WebIconDatabase init]):
+ (-[WebIconDatabase _setIconURL:forURL:]): Changed the bridge's name for this method to be more clear
+ (-[WebIconDatabase _createFileDatabase]):
+ (-[WebIconDatabase _iconDataForIconURL:]): This grabs the raw data for use in the conversion function
+ (-[WebIconDatabase _convertToWebCoreFormat]): This does the actual conversion
+
2006-08-11 Tim Omernick <timo@apple.com>
Reviewed by John Sullivan.
NSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey";
NSString *WebIconDatabaseEnabledDefaultsKey = @"WebIconDatabaseEnabled";
-NSString *WebIconDatabasePath = @"~/Library/Safari/Icons";
+NSString *WebIconDatabasePath = @"~/Library/Icons";
NSSize WebIconSmallSize = {16, 16};
NSSize WebIconMediumSize = {32, 32};
- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon;
- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache;
- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size;
+- (NSData *)_iconDataForIconURL:(NSString *)iconURLString;
+- (void)_convertToWebCoreFormat;
@end
@implementation WebIconDatabase
databaseDirectory = [databaseDirectory stringByExpandingTildeInPath];
[_private->databaseBridge openSharedDatabaseWithPath:databaseDirectory];
}
+
+ [self _convertToWebCoreFormat];
#else
_private->databaseBridge = nil;
#endif
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(_resetCachedWebPreferences:)
name:WebPreferencesChangedNotification object:nil];
-
-
+
+ // FIXME - Once the new iconDB is the only game in town, we need to remove any of the WebFileDatabase code
+ // that is threaded and expects certain files to exist - certain files we rip right out from underneath it
+ // in the _convertToWebCoreFormat method
+#ifdef ICONDEBUG
// Retain icons on disk then release them once clean-up has begun.
// This gives the client the opportunity to retain them before they are erased.
[self _retainOriginalIconsOnDisk];
[self performSelector:@selector(_releaseOriginalIconsOnDisk) withObject:nil afterDelay:0];
-
+#endif
+
return self;
}
ASSERT(_private->pageURLToIconURL);
#ifdef ICONDEBUG
- [_private->databaseBridge _setIconURL:iconURL forURL:URL];
+ [_private->databaseBridge _setIconURL:iconURL forPageURL:URL];
[self _sendNotificationForURL:URL];
return;
#endif
NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey];
if (!databaseDirectory) {
- databaseDirectory = @"~/Library/Icons";
+ databaseDirectory = WebIconDatabasePath;
[defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey];
}
databaseDirectory = [databaseDirectory stringByExpandingTildeInPath];
#endif
}
+- (NSData *)_iconDataForIconURL:(NSString *)iconURLString
+{
+ ASSERT(iconURLString);
+
+ NSData *iconData = [_private->fileDatabase objectForKey:iconURLString];
+
+ if ((id)iconData == (id)[NSNull null])
+ return nil;
+
+ return iconData;
+}
+
+- (void)_convertToWebCoreFormat
+{
+ ASSERT(_private);
+ ASSERT(_private->databaseBridge);
+
+ // If the WebCore Icon Database is not empty, we assume that this conversion has already
+ // taken place and skip the rest of the steps
+ if (![_private->databaseBridge _isEmpty])
+ return;
+
+ NSEnumerator *enumerator = [_private->pageURLToIconURL keyEnumerator];
+ NSString *url, *iconURL;
+
+ // First, we'll iterate through the PageURL->IconURL map
+ while ((url = [enumerator nextObject]) != nil) {
+ iconURL = [_private->pageURLToIconURL objectForKey:url];
+ if (!iconURL)
+ continue;
+ [_private->databaseBridge _setIconURL:iconURL forPageURL:url];
+ }
+
+ // Second, we'll iterate through the icon data we do have
+ enumerator = [_private->iconsOnDiskWithURLs objectEnumerator];
+ NSData *iconData;
+
+ while ((url = [enumerator nextObject]) != nil) {
+ iconData = [self _iconDataForIconURL:url];
+ if (iconData)
+ [_private->databaseBridge _setIconData:iconData forIconURL:url];
+ else {
+ // This really *shouldn't* happen, so it'd be good to track down why it might happen in a debug build
+ // however, we do know how to handle it gracefully in release
+ LOG_ERROR("%@ is marked as having an icon on disk, but we couldn't get the data for it", url);
+ [_private->databaseBridge _setHaveNoIconForIconURL:url];
+ }
+ }
+
+ // Finally, we'll iterate through the negative cache we have
+ enumerator = [_private->iconURLsWithNoIcons objectEnumerator];
+ while ((url = [enumerator nextObject]) != nil)
+ [_private->databaseBridge _setHaveNoIconForIconURL:url];
+
+ // After we're done converting old style icons over to webcore icons, we delete the entire directory hierarchy
+ // for the old icon DB
+ NSString *iconPath = [[NSUserDefaults standardUserDefaults] objectForKey:WebIconDatabaseDirectoryDefaultsKey];
+ if (!iconPath)
+ iconPath = WebIconDatabasePath;
+
+ NSString *fullIconPath = [iconPath stringByExpandingTildeInPath];
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ enumerator = [[fileManager directoryContentsAtPath:fullIconPath] objectEnumerator];
+
+ NSString *databaseFilename = [_private->databaseBridge defaultDatabaseFilename];
+
+ NSString *file;
+ while ((file = [enumerator nextObject]) != nil) {
+ if ([file isEqualTo:databaseFilename])
+ continue;
+ NSString *filePath = [fullIconPath stringByAppendingPathComponent:file];
+ if (![fileManager removeFileAtPath:filePath handler:nil])
+ LOG_ERROR("Failed to delete %@ from old icon directory", filePath);
+ }
+}
+
@end
@implementation WebIconDatabasePrivate