WebCore:
authorbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Aug 2006 03:22:32 +0000 (03:22 +0000)
committerbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Aug 2006 03:22:32 +0000 (03:22 +0000)
        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

WebCore/ChangeLog
WebCore/bridge/mac/WebCoreIconDatabaseBridge.h
WebCore/bridge/mac/WebCoreIconDatabaseBridge.mm
WebCore/loader/icon/IconDatabase.cpp
WebCore/loader/icon/IconDatabase.h
WebKit/ChangeLog
WebKit/Misc/WebIconDatabase.m

index 5a16172e384d25b701beb92579924de273b2dbaf..67d0e8abb413b66a50d61990960b27698c79ec66 100644 (file)
@@ -1,3 +1,39 @@
+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.
index 83539833bbf88ebc2de93e5a234486647f29dab9..037b1ba8ccfcd824d3dca85cf96c50109fc19352 100644 (file)
@@ -56,11 +56,14 @@ typedef WebCore::IconDatabase WebCoreIconDatabase;
 - (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
 
 
index d6c5b5e173135fcdc5f8ae9b086ef77e4099a133..bc93c80d2bf1917f6774f433c32515888ab4afdf 100644 (file)
@@ -43,7 +43,7 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
 
 @implementation WebCoreIconDatabaseBridge
 
-- (BOOL)openSharedDatabaseWithPath:(NSString *)path;
+- (BOOL)openSharedDatabaseWithPath:(NSString *)path
 {
     assert(path);
     
@@ -55,7 +55,7 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     return NO;
 }
 
-- (void)closeSharedDatabase;
+- (void)closeSharedDatabase
 {
     if (_iconDB) {
         _iconDB->close();
@@ -63,11 +63,16 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     }
 }
 
-- (BOOL)isOpen;
+- (BOOL)isOpen
 {
     return _iconDB != 0;
 }
 
+- (BOOL)_isEmpty
+{
+    return _iconDB ? _iconDB->isEmpty() : NO;
+}
+
 - (BOOL)isIconExpiredForIconURL:(NSString *)iconURL
 {
     return _iconDB ? _iconDB->isIconExpiredForIconURL(iconURL) : NO;
@@ -78,20 +83,20 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     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);
@@ -119,7 +124,7 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     return nil;
 }
 
-- (NSString *)iconURLForPageURL:(NSString *)url;
+- (NSString *)iconURLForPageURL:(NSString *)url
 {
     ASSERT(_iconDB);
     ASSERT(url);
@@ -128,7 +133,7 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     return (NSString*)iconURL;
 }
 
-- (NSImage *)defaultIconWithSize:(NSSize)size;
+- (NSImage *)defaultIconWithSize:(NSSize)size
 {
     ASSERT(_iconDB);
     ASSERT(size.width);
@@ -140,21 +145,21 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     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);
@@ -163,7 +168,7 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     _iconDB->setIconDataForIconURL([data bytes], [data length], String(iconURL));
 }
 
-- (void)_setHaveNoIconForIconURL:(NSString *)iconURL;
+- (void)_setHaveNoIconForIconURL:(NSString *)iconURL
 {
     ASSERT(_iconDB);
     ASSERT(iconURL);
@@ -171,16 +176,16 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     _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);
@@ -188,7 +193,8 @@ void WebCore::IconDatabase::loadIconFromURL(const String& url)
     return _iconDB->hasIconForIconURL(String(iconURL));
 }
 
-
-
-
+- (NSString *)defaultDatabaseFilename
+{
+    return IconDatabase::defaultDatabaseFilename();
+}
 @end
index cf7b02e03be70a80fa38812223baae0ca0f90f37..b13b32c9d7e55ca1b67d5473738f996b7e7a39bd 100644 (file)
@@ -40,8 +40,6 @@
 // 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;
@@ -52,6 +50,12 @@ const int IconDatabase::iconExpirationTime = 60*60*24;
 // 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()
 {
@@ -71,7 +75,13 @@ IconDatabase::IconDatabase()
 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;
@@ -106,6 +116,11 @@ void IconDatabase::close()
     m_db.close();
 }
 
+bool IconDatabase::isEmpty()
+{
+    return !(SQLStatement(m_db, "SELECT iconID FROM PageURL LIMIT 1;").getColumnInt(0));
+}
+
 
 bool IconDatabase::isValidDatabase()
 {
@@ -488,7 +503,6 @@ void IconDatabase::retainIconForURL(const String& _url)
     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)
@@ -523,9 +537,7 @@ 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;
index d2f6a27b259f35b8d23bd56766c803c4863b5feb..5a75eb3eba0ebc4b4bfacec80bedd511847753ff 100644 (file)
@@ -85,6 +85,8 @@ public:
     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);
@@ -109,6 +111,8 @@ public:
     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;
index 8feb7ca8f97935eb96077a688fd137c04b4254d8..d989ba31a422ca19567561472d7ce0f976d1335d 100644 (file)
@@ -1,3 +1,18 @@
+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.
index 5be83ddd180ba72211be97c0d571c3f4cd0e670f..7c0d6e8f74543f26ccc1167f314b56926296f2b3 100644 (file)
@@ -53,7 +53,7 @@ NSString *WebIconDatabaseDidRemoveAllIconsNotification =   @"WebIconDatabaseDidR
 NSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey";
 NSString *WebIconDatabaseEnabledDefaultsKey =   @"WebIconDatabaseEnabled";
 
-NSString *WebIconDatabasePath = @"~/Library/Safari/Icons";
+NSString *WebIconDatabasePath = @"~/Library/Icons";
 
 NSSize WebIconSmallSize = {16, 16};
 NSSize WebIconMediumSize = {32, 32};
@@ -81,6 +81,8 @@ NSSize WebIconLargeSize = {128, 128};
 - (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
@@ -135,6 +137,8 @@ NSSize WebIconLargeSize = {128, 128};
         databaseDirectory = [databaseDirectory stringByExpandingTildeInPath];
         [_private->databaseBridge openSharedDatabaseWithPath:databaseDirectory];
     }
+    
+    [self _convertToWebCoreFormat];
 #else
     _private->databaseBridge = nil;
 #endif
@@ -156,13 +160,17 @@ NSSize WebIconLargeSize = {128, 128};
     [[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;
 }
 
@@ -459,7 +467,7 @@ NSSize WebIconLargeSize = {128, 128};
     ASSERT(_private->pageURLToIconURL);
     
 #ifdef ICONDEBUG
-    [_private->databaseBridge _setIconURL:iconURL forURL:URL];
+    [_private->databaseBridge _setIconURL:iconURL forPageURL:URL];
     [self _sendNotificationForURL:URL];
     return;
 #endif
@@ -537,7 +545,7 @@ NSSize WebIconLargeSize = {128, 128};
     NSString *databaseDirectory = [defaults objectForKey:WebIconDatabaseDirectoryDefaultsKey];
 
     if (!databaseDirectory) {
-        databaseDirectory = @"~/Library/Icons";
+        databaseDirectory = WebIconDatabasePath;
         [defaults setObject:databaseDirectory forKey:WebIconDatabaseDirectoryDefaultsKey];
     }
     databaseDirectory = [databaseDirectory stringByExpandingTildeInPath];
@@ -1035,6 +1043,82 @@ NSSize WebIconLargeSize = {128, 128};
 #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