WebCore:
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 19:29:51 +0000 (19:29 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 19:29:51 +0000 (19:29 +0000)
        Reviewed by Anders

        Support for <rdar://problem/5556381> and <rdar://problem/5556379>

        The Database feature in the engine needs to support delegate calls for policy decisions and
        also provide notifications when origins and databases change their state.

        This patch also polishes off the missing features of the management API

        * page/Chrome.cpp: Implement the two UIDelegate methods
        (WebCore::Chrome::requestQuotaIncreaseForNewDatabase): Ask for more space to create a new database if it won't fit
        (WebCore::Chrome::requestQuotaIncreaseForDatabaseOperation): Ask for more space to complete an in-progress operation
        * page/Chrome.h:
        * page/ChromeClient.h:
        * platform/graphics/svg/SVGImageEmptyClients.h:
        (WebCore::SVGEmptyChromeClient::requestQuotaIncreaseForNewDatabase):
        (WebCore::SVGEmptyChromeClient::requestQuotaIncreaseForDatabaseOperation):

        * storage/Database.cpp:
        (WebCore::Database::openDatabase): Check to see if this database can be opened - the quota must be high
          enough and if it isn't, the UIDelegate should have a change to bump the quota.
          Also update the UI-relevant details (display name and estimated size) upon successful opening of the database

        * storage/DatabaseDetails.h: Remove the version parameter as it is a programatic detail of a
          site database and is not important to API clients
        (WebCore::DatabaseDetails::DatabaseDetails):
        (WebCore::DatabaseDetails::isValid):
        (WebCore::DatabaseDetails::name):

        * storage/DatabaseTracker.cpp:
        (WebCore::DatabaseTracker::openTrackerDatabase): Tweaked the schema here - there was a horrible bug with the old schema that would
          prevent you from having two databases of the same name from two different origins.  Also simplify the origin-management schema
        (WebCore::DatabaseTracker::canEstablishDatabase): Added.  Does some estimated size vs quota checks, and asks the UI delegate for
          more space if necessary
        (WebCore::DatabaseTracker::hasEntryForOrigin):
        (WebCore::DatabaseTracker::establishEntryForOrigin): Establishes a tracker entry for the given origin with the current default quota
          Also notifies the client of the new origin
        (WebCore::DatabaseTracker::setDatabaseDetails): Update the display name and estimated size for the given database
        (WebCore::DatabaseTracker::fullPathForDatabase): Tweak to add the ability to get the path without creating it - for management purposes
        (WebCore::DatabaseTracker::populateOrigins): Populate origins from the Origins table instead of the Databases table
        (WebCore::DatabaseTracker::origins):
        (WebCore::DatabaseTracker::detailsForNameAndOrigin): For API management
        (WebCore::DatabaseTracker::usageForDatabase):
        (WebCore::DatabaseTracker::usageForOrigin):
        (WebCore::DatabaseTracker::quotaForOrigin):
        (WebCore::DatabaseTracker::setQuota): Notify the client
        (WebCore::DatabaseTracker::addDatabase): Notify the client
        (WebCore::DatabaseTracker::deleteAllDatabases):
        (WebCore::DatabaseTracker::deleteDatabasesWithOrigin):
        (WebCore::DatabaseTracker::deleteDatabase):
        (WebCore::DatabaseTracker::deleteDatabaseFile):
        * storage/DatabaseTracker.h:

WebKit/gtk:

        Keep it building with new client method

        * WebCoreSupport/ChromeClientGtk.cpp:
        (WebKit::ChromeClient::requestQuotaIncreaseForNewDatabase):
        (WebKit::ChromeClient::requestQuotaIncreaseForDatabaseOperation):
        * WebCoreSupport/ChromeClientGtk.h:

WebKit/mac:

        Reviewed by Anders

        Support for <rdar://problem/5556381> and <rdar://problem/5556379>

        Hook up UI Delegate calls for the database engine feature and other small tweaks

        * Storage/WebDatabaseManager.mm:
        (-[WebDatabaseManager detailsForDatabase:withOrigin:]): Renamed databaseName parameter to databaseIdentifier for clarity
        (-[WebDatabaseManager deleteDatabase:withOrigin:]): Renamed databaseName parameter to databaseIdentifier for clarity
        * Storage/WebDatabaseManagerPrivate.h:

        * Storage/WebDatabaseTrackerClient.h:
        * Storage/WebDatabaseTrackerClient.mm:
        (WebDatabaseTrackerClient::dispatchDidModifyDatabase): Renamed databaseName parameter to databaseIdentifier for clarity

        * WebCoreSupport/WebChromeClient.h:
        * WebCoreSupport/WebChromeClient.mm:
        (WebChromeClient::requestQuotaIncreaseForNewDatabase): Call through to the UI Delegate
        (WebChromeClient::requestQuotaIncreaseForDatabaseOperation): Ditto

        * WebView/WebUIDelegatePrivate.h: Added the two UI Delegate methods

        * WebView/WebView.mm:
        (CallDelegateReturningUnsignedLongLong):
        (CallUIDelegateReturningUnsignedLongLong):
        * WebView/WebViewInternal.h:

WebKit/qt:

        Keep it building with new client method

        * WebCoreSupport/ChromeClientQt.cpp:
        (WebCore::ChromeClientQt::requestQuotaIncreaseForNewDatabase):
        (WebCore::ChromeClientQt::requestQuotaIncreaseForDatabaseOperation):
        * WebCoreSupport/ChromeClientQt.h:

WebKit/win:

        Keep it building with new client method

        * WebChromeClient.cpp:
        (ChromeClient::requestQuotaIncreaseForNewDatabase):
        (ChromeClient::requestQuotaIncreaseForDatabaseOperation):
        * WebChromeClient.h:

WebKit/wx:

        Keep it building with new client method

        * WebKitSupport/ChromeClientWx.cpp:
        (WebCore::ChromeClient::requestQuotaIncreaseForNewDatabase):
        (WebCore::ChromeClient::requestQuotaIncreaseForDatabaseOperation):
        * WebKitSupport/ChromeClientWx.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28192 268f45cc-cd09-0410-ab3c-d52691b4dbfc

31 files changed:
WebCore/ChangeLog
WebCore/page/Chrome.cpp
WebCore/page/Chrome.h
WebCore/page/ChromeClient.h
WebCore/platform/graphics/svg/SVGImageEmptyClients.h
WebCore/storage/Database.cpp
WebCore/storage/DatabaseDetails.h
WebCore/storage/DatabaseTracker.cpp
WebCore/storage/DatabaseTracker.h
WebKit/gtk/ChangeLog
WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
WebKit/mac/ChangeLog
WebKit/mac/Storage/WebDatabaseManager.mm
WebKit/mac/Storage/WebDatabaseManagerPrivate.h
WebKit/mac/Storage/WebDatabaseTrackerClient.h
WebKit/mac/Storage/WebDatabaseTrackerClient.mm
WebKit/mac/WebCoreSupport/WebChromeClient.h
WebKit/mac/WebCoreSupport/WebChromeClient.mm
WebKit/mac/WebView/WebUIDelegatePrivate.h
WebKit/mac/WebView/WebView.mm
WebKit/mac/WebView/WebViewInternal.h
WebKit/qt/ChangeLog
WebKit/qt/WebCoreSupport/ChromeClientQt.cpp
WebKit/qt/WebCoreSupport/ChromeClientQt.h
WebKit/win/ChangeLog
WebKit/win/WebChromeClient.cpp
WebKit/win/WebChromeClient.h
WebKit/wx/ChangeLog
WebKit/wx/WebKitSupport/ChromeClientWx.cpp
WebKit/wx/WebKitSupport/ChromeClientWx.h

index 21a59b8..edfc655 100644 (file)
@@ -1,3 +1,58 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Anders
+
+        Support for <rdar://problem/5556381> and <rdar://problem/5556379>
+
+        The Database feature in the engine needs to support delegate calls for policy decisions and
+        also provide notifications when origins and databases change their state.
+
+        This patch also polishes off the missing features of the management API
+
+        * page/Chrome.cpp: Implement the two UIDelegate methods
+        (WebCore::Chrome::requestQuotaIncreaseForNewDatabase): Ask for more space to create a new database if it won't fit
+        (WebCore::Chrome::requestQuotaIncreaseForDatabaseOperation): Ask for more space to complete an in-progress operation
+        * page/Chrome.h:
+        * page/ChromeClient.h:
+        * platform/graphics/svg/SVGImageEmptyClients.h:
+        (WebCore::SVGEmptyChromeClient::requestQuotaIncreaseForNewDatabase):
+        (WebCore::SVGEmptyChromeClient::requestQuotaIncreaseForDatabaseOperation):
+
+        * storage/Database.cpp:
+        (WebCore::Database::openDatabase): Check to see if this database can be opened - the quota must be high 
+          enough and if it isn't, the UIDelegate should have a change to bump the quota.
+          Also update the UI-relevant details (display name and estimated size) upon successful opening of the database
+
+        * storage/DatabaseDetails.h: Remove the version parameter as it is a programatic detail of a
+          site database and is not important to API clients
+        (WebCore::DatabaseDetails::DatabaseDetails):
+        (WebCore::DatabaseDetails::isValid):
+        (WebCore::DatabaseDetails::name):
+
+        * storage/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::openTrackerDatabase): Tweaked the schema here - there was a horrible bug with the old schema that would
+          prevent you from having two databases of the same name from two different origins.  Also simplify the origin-management schema
+        (WebCore::DatabaseTracker::canEstablishDatabase): Added.  Does some estimated size vs quota checks, and asks the UI delegate for 
+          more space if necessary
+        (WebCore::DatabaseTracker::hasEntryForOrigin):
+        (WebCore::DatabaseTracker::establishEntryForOrigin): Establishes a tracker entry for the given origin with the current default quota
+          Also notifies the client of the new origin
+        (WebCore::DatabaseTracker::setDatabaseDetails): Update the display name and estimated size for the given database
+        (WebCore::DatabaseTracker::fullPathForDatabase): Tweak to add the ability to get the path without creating it - for management purposes
+        (WebCore::DatabaseTracker::populateOrigins): Populate origins from the Origins table instead of the Databases table
+        (WebCore::DatabaseTracker::origins):
+        (WebCore::DatabaseTracker::detailsForNameAndOrigin): For API management
+        (WebCore::DatabaseTracker::usageForDatabase):
+        (WebCore::DatabaseTracker::usageForOrigin):
+        (WebCore::DatabaseTracker::quotaForOrigin):
+        (WebCore::DatabaseTracker::setQuota): Notify the client
+        (WebCore::DatabaseTracker::addDatabase): Notify the client 
+        (WebCore::DatabaseTracker::deleteAllDatabases):
+        (WebCore::DatabaseTracker::deleteDatabasesWithOrigin):
+        (WebCore::DatabaseTracker::deleteDatabase):
+        (WebCore::DatabaseTracker::deleteDatabaseFile):
+        * storage/DatabaseTracker.h:
+
 2007-11-29  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Beth Dakin and Darin Adler.
index 174c40a..3b6ae9d 100644 (file)
@@ -342,11 +342,15 @@ void Chrome::print(Frame* frame)
     m_client->print(frame);
 }
 
-bool Chrome::runDatabaseSizeLimitPrompt(Frame* f, const String& origin)
+unsigned long long Chrome::requestQuotaIncreaseForNewDatabase(Frame* frame, const SecurityOriginData& origin, const String& databaseDisplayName, unsigned long long estimatedSize)
 {
-    return m_client->runDatabaseSizeLimitPrompt(f, origin);
+    return m_client->requestQuotaIncreaseForNewDatabase(frame, origin, databaseDisplayName, estimatedSize);
 }
 
+unsigned long long Chrome::requestQuotaIncreaseForDatabaseOperation(Frame* frame, const SecurityOriginData& origin, const String& databaseIdentifier, unsigned long long proposedNewQuota)
+{
+    return m_client->requestQuotaIncreaseForDatabaseOperation(frame, origin, databaseIdentifier, proposedNewQuota);
+}
 
 PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
 {
index 58bc614..38d4438 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
     class HitTestResult;
     class IntRect;
     class Page;
+    class SecurityOriginData;
     class String;
     
     struct FrameLoadRequest;
@@ -125,9 +126,9 @@ namespace WebCore {
 
         void print(Frame*);
 
-        bool runDatabaseSizeLimitPrompt(Frame*, const String& origin);
-
-
+        unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData& origin, const String& databaseDisplayName, unsigned long long estimatedSize);
+        unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData& origin, const String& databaseIdentifier, unsigned long long proposedNewQuota);
+        
 #if PLATFORM(MAC)
         void focusNSView(NSView*);
 #endif
index da0b1a1..c26cade 100644 (file)
@@ -30,6 +30,7 @@ namespace WebCore {
     class HitTestResult;
     class IntRect;
     class Page;
+    class SecurityOriginData;
     class String;
     
     struct FrameLoadRequest;
@@ -103,15 +104,8 @@ namespace WebCore {
 
         virtual void print(Frame*) = 0;
 
-//  Possible permission levels -
-//  -Allow just this database to be created
-//  -Allow this domain to create whatever it wants
-//  -Don't allow this database
-//  -Don't allow this domain to ever create any
-//  -Don't allow any databases
-//        virtual bool runDatabaseCreationPrompt(Frame*, const String& origin, const String& name) = 0;
-
-        virtual bool runDatabaseSizeLimitPrompt(Frame*, const String& origin) = 0;
+        virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData& origin, const String& databaseDisplayName, unsigned long long estimatedSize) = 0;
+        virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData& origin, const String& databaseIdentifier, unsigned long long proposedNewQuota) = 0;
 };
 
 }
index f6cc442..f981c2b 100644 (file)
@@ -116,8 +116,8 @@ public:
 
     virtual void print(Frame*) { }
 
-    virtual bool runDatabaseSizeLimitPrompt(Frame*, const String&) { return false; }
-
+    virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long) { return 0; }
+    virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long) { return 0; }
 };
 
 class SVGEmptyFrameLoaderClient : public FrameLoaderClient {
index e9fcd63..0b5aacd 100644 (file)
@@ -95,12 +95,20 @@ static const String& databaseVersionKey()
 
 PassRefPtr<Database> Database::openDatabase(Document* document, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode& e)
 {
+    if (!DatabaseTracker::tracker().canEstablishDatabase(document, name, displayName, estimatedSize)) {
+        // There should be an exception raised here in addition to returning a null Database object.  The question has been raised with the WHATWG
+        LOG(StorageAPI, "Database %s for origin %s not allowed to be established", name.ascii().data(), document->securityOrigin().toString().ascii().data());
+        return 0;
+    }
+    
     RefPtr<Database> database = new Database(document, name, expectedVersion);
 
     if (!database->openAndVerifyVersion(e)) {
        LOG(StorageAPI, "Failed to open and verify version (expected %s) of database %s", expectedVersion.ascii().data(), database->databaseDebugName().ascii().data());
        return 0;
     }
+    
+    DatabaseTracker::tracker().setDatabaseDetails(document->securityOrigin().securityOriginData(), name, displayName, estimatedSize);
 
     if (Page* page = document->frame()->page())
         page->inspectorController()->didOpenDatabase(database.get(), document->domain(), name, expectedVersion);
index 5e954e3..655c047 100644 (file)
@@ -39,25 +39,22 @@ public:
         , m_currentUsage(0)
     { }
     
-    DatabaseDetails(const String& databaseName, const String& databaseVersion, const String& displayName, unsigned long long expectedUsage, unsigned long long currentUsage)
+    DatabaseDetails(const String& databaseName, const String& displayName, unsigned long long expectedUsage, unsigned long long currentUsage)
         : m_name(databaseName)
-        , m_version(databaseVersion)
         , m_displayName(displayName)
         , m_expectedUsage(expectedUsage)
         , m_currentUsage(currentUsage)
     { }
     
-    bool isValid() const { return !(m_name.isEmpty() && m_version.isEmpty() && m_displayName.isEmpty() && !m_expectedUsage && !m_currentUsage); }
+    bool isValid() const { return !(m_name.isEmpty() && m_displayName.isEmpty() && !m_expectedUsage && !m_currentUsage); }
     
     const String& name() { return m_name; }
-    const String& version() { return m_version; }
     const String& displayName() { return m_displayName; }
     unsigned long long expectedUsage() { return m_expectedUsage; }
     unsigned long long currentUsage() { return m_currentUsage; }
     
 private:
     String m_name;
-    String m_version;
     String m_displayName;
     unsigned long long m_expectedUsage;
     unsigned long long m_currentUsage; 
index 771f315..e7afb1b 100644 (file)
 #include "DatabaseTracker.h"
 
 #include "Database.h"
+#include "DatabaseTrackerClient.h"
+#include "Document.h"
 #include "FileSystem.h"
-#include "NotImplemented.h"
+#include "Page.h"
 #include "SecurityOriginData.h"
 #include "SQLiteStatement.h"
 
@@ -109,25 +111,80 @@ void DatabaseTracker::openTrackerDatabase()
         return;
     }
     if (!m_database.tableExists("Origins")) {
-        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, creationPolicy INTEGER NOT NULL ON CONFLICT FAIL, sizePolicy INTEGER NOT NULL ON CONFLICT FAIL);")) {
+        if (!m_database.executeCommand("CREATE TABLE Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, quota INTEGER NOT NULL ON CONFLICT FAIL);")) {
             // FIXME: and here
         }
     }
 
     if (!m_database.tableExists("Databases")) {
-        if (!m_database.executeCommand("CREATE TABLE Databases (guid INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT UNIQUE ON CONFLICT REPLACE, name TEXT UNIQUE ON CONFLICT REPLACE, path TEXT NOT NULL ON CONFLICT FAIL);")) {
+        if (!m_database.executeCommand("CREATE TABLE Databases (guid INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT, name TEXT, displayName TEXT, estimatedSize INTEGER, path TEXT);")) {
             // FIXME: and here
         }
     }
 }
+
+bool DatabaseTracker::canEstablishDatabase(Document* document, const String& name, const String& displayName, unsigned long estimatedSize)
+{
+    SecurityOriginData originData = document->securityOrigin().securityOriginData();
+    
+    // If this origin has no databases yet, establish an entry in the tracker database with the default quota
+    if (!hasEntryForOrigin(originData))
+        establishEntryForOrigin(originData);
+    
+    // If the new database will fit as-is, allow its creation
+    unsigned long long usage = usageForOrigin(originData);
+    if (usage + estimatedSize < quotaForOrigin(originData))
+        return true;
+    
+    // Otherwise, ask the UI Delegate for a new quota
+    Page* page;
+    if (!(page = document->page()))
+        return false;
+    
+    unsigned long long newQuota = page->chrome()->requestQuotaIncreaseForNewDatabase(document->frame(), originData, displayName, estimatedSize);
+    setQuota(originData, newQuota);
     
-String DatabaseTracker::fullPathForDatabase(const SecurityOriginData& origin, const String& name)
+    return usage + estimatedSize < newQuota;
+}
+
+bool DatabaseTracker::hasEntryForOrigin(const SecurityOriginData& origin)
+{
+    populateOrigins();
+    return m_originQuotaMap->contains(origin);
+}
+
+void DatabaseTracker::establishEntryForOrigin(const SecurityOriginData& origin)
+{
+    ASSERT(!hasEntryForOrigin(origin));
+    
+    SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)");
+    if (statement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to establish origin %s in the tracker", origin.stringIdentifier().ascii().data());
+        return;
+    }
+        
+    statement.bindText(1, origin.stringIdentifier());
+    statement.bindInt64(2, m_defaultQuota);
+    
+    if (statement.step() != SQLResultDone) {
+        LOG_ERROR("Unable to establish origin %s in the tracker", origin.stringIdentifier().ascii().data());
+        return;
+    }
+
+    populateOrigins();
+    m_originQuotaMap->set(origin, m_defaultQuota);
+    
+    if (m_client)
+        m_client->dispatchDidModifyOrigin(origin);
+}
+
+String DatabaseTracker::fullPathForDatabase(const SecurityOriginData& origin, const String& name, bool createIfNotExists)
 {
     String originIdentifier = origin.stringIdentifier();
     String originPath = pathByAppendingComponent(m_databasePath, originIdentifier);
     
     // Make sure the path for this SecurityOrigin exists
-    if (!makeAllDirectories(originPath))
+    if (createIfNotExists && !makeAllDirectories(originPath))
         return "";
     
     // See if we have a path for this database yet
@@ -143,6 +200,9 @@ String DatabaseTracker::fullPathForDatabase(const SecurityOriginData& origin, co
 
     if (result == SQLResultRow)
         return pathByAppendingComponent(originPath, statement.getColumnText16(0));
+    if (!createIfNotExists)
+        return "";
+        
     if (result != SQLResultDone) {
         LOG_ERROR("Failed to retrieve filename from Database Tracker for origin %s, name %s", origin.stringIdentifier().ascii().data(), name.ascii().data());
         return "";
@@ -179,22 +239,22 @@ String DatabaseTracker::fullPathForDatabase(const SecurityOriginData& origin, co
 
 void DatabaseTracker::populateOrigins()
 {
-    if (m_origins)
+    if (m_originQuotaMap)
         return;
 
-    m_origins.set(new HashSet<SecurityOriginData, SecurityOriginDataHash, SecurityOriginDataTraits>);
+    m_originQuotaMap.set(new HashMap<SecurityOriginData, unsigned long long, SecurityOriginDataHash, SecurityOriginDataTraits>);
 
     if (!m_database.isOpen())
         return;
 
-    SQLiteStatement statement(m_database, "SELECT DISTINCT origin FROM Databases;");
+    SQLiteStatement statement(m_database, "SELECT origin, quota FROM Origins");
 
     if (statement.prepare() != SQLResultOk)
         return;
 
     int result;
     while ((result = statement.step()) == SQLResultRow)
-        m_origins->add(statement.getColumnText16(0));
+        m_originQuotaMap->set(statement.getColumnText16(0), statement.getColumnInt64(1));
 
     if (result != SQLResultDone)
         LOG_ERROR("Failed to read in all origins from the database");
@@ -204,10 +264,10 @@ void DatabaseTracker::populateOrigins()
 
 void DatabaseTracker::origins(Vector<SecurityOriginData>& result)
 {
-    if (!m_origins)
+    if (!m_originQuotaMap)
         populateOrigins();
 
-    copyToVector(*(m_origins.get()), result);
+    copyKeysToVector(*(m_originQuotaMap.get()), result);
 }
 
 bool DatabaseTracker::databaseNamesForOrigin(const SecurityOriginData& origin, Vector<String>& resultVector)
@@ -236,32 +296,134 @@ bool DatabaseTracker::databaseNamesForOrigin(const SecurityOriginData& origin, V
 
 DatabaseDetails DatabaseTracker::detailsForNameAndOrigin(const String& name, const SecurityOriginData& origin)
 {
-    notImplemented();
-    return DatabaseDetails();
+    String originIdentifier = origin.stringIdentifier();
+        
+    SQLiteStatement statement(m_database, "SELECT displayName, estimatedSize FROM Databases WHERE origin=? AND name=?");
+    if (statement.prepare() != SQLResultOk)
+        return DatabaseDetails();
+   
+    statement.bindText(1, originIdentifier);
+    statement.bindText(2, name);
+    
+    int result = statement.step();
+    if (result == SQLResultDone)
+        return DatabaseDetails();
+    
+    if (result != SQLResultRow) {
+        LOG_ERROR("Error retrieving details for database %s in origin %s from tracker database", name.ascii().data(), originIdentifier.ascii().data());
+        return DatabaseDetails();
+    }
+    
+    return DatabaseDetails(name, statement.getColumnText(0), statement.getColumnInt64(1), usageForDatabase(name, origin));
 }
 
+void DatabaseTracker::setDatabaseDetails(const SecurityOriginData& origin, const String& name, const String& displayName, unsigned long estimatedSize)
+{
+    String originIdentifier = origin.stringIdentifier();
+    int64_t guid = 0;
+    
+    SQLiteStatement statement(m_database, "SELECT guid FROM Databases WHERE origin=? AND name=?");
+    if (statement.prepare() != SQLResultOk)
+        return;
+        
+    statement.bindText(1, originIdentifier);
+    statement.bindText(2, name);
+    
+    int result = statement.step();
+    if (result == SQLResultRow)
+        guid = statement.getColumnInt64(0);
+    statement.finalize();
+
+    if (guid == 0) {
+        if (result != SQLResultDone)
+            LOG_ERROR("Error to determing existence of database %s in origin %s in tracker database", name.ascii().data(), originIdentifier.ascii().data());
+        else {
+            // This case should never occur - we should never be setting database details for a database that doesn't already exist in the tracker
+            // But since the tracker file is an external resource not under complete control of our code, it's somewhat invalid to make this an ASSERT case
+            // So we'll print an error instead
+            LOG_ERROR("Could not retrieve guid for database %s in origin %s from the tracker database - it is invalid to set database details on a database that doesn't already exist in the tracker",
+                       name.ascii().data(), originIdentifier.ascii().data());
+        }
+        return;
+    }
+    
+    SQLiteStatement updateStatement(m_database, "UPDATE Databases SET displayName=?, estimatedSize=? WHERE guid=?");
+    if (updateStatement.prepare() != SQLResultOk)
+        return;
+    
+    updateStatement.bindText(1, displayName);
+    updateStatement.bindInt64(2, estimatedSize);
+    updateStatement.bindInt64(3, guid);
+    
+    if (updateStatement.step() != SQLResultDone) {
+        LOG_ERROR("Failed to update details for database %s in origin %s", name.ascii().data(), originIdentifier.ascii().data());
+        return;  
+    }
+    
+    if (m_client)
+        m_client->dispatchDidModifyDatabase(origin, name);
+}
+
+unsigned long long DatabaseTracker::usageForDatabase(const String& name, const SecurityOriginData& origin)
+{
+    String path = fullPathForDatabase(origin, name, false);
+    if (path.isEmpty())
+        return 0;
+        
+    long long size;
+    return fileSize(path, size) ? size : 0;
+}
 
 unsigned long long DatabaseTracker::usageForOrigin(const SecurityOriginData& origin)
 {
-    notImplemented();
-    return 0;
+    Vector<String> names;
+    databaseNamesForOrigin(origin, names);
+    
+    unsigned long long result = 0;
+    for (unsigned i = 0; i < names.size(); ++i)
+        result += usageForDatabase(names[i], origin);
+        
+    return result;
 }
 
 unsigned long long DatabaseTracker::quotaForOrigin(const SecurityOriginData& origin)
 {
-    notImplemented();
-    return 5 * 1024 * 1024;
+    populateOrigins();
+    return m_originQuotaMap->get(origin);
 }
 
 void DatabaseTracker::setQuota(const SecurityOriginData& origin, unsigned long long quota)
 {
-    notImplemented();
+    populateOrigins();
+    if (!m_originQuotaMap->contains(origin))
+        establishEntryForOrigin(origin);
+    
+    m_originQuotaMap->set(origin, quota);
+    
+    SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?");
+    
+    bool error = statement.prepare() != SQLResultOk;
+    if (!error) {
+        statement.bindInt64(1, quota);
+        statement.bindText(2, origin.stringIdentifier());
+        
+        error = !statement.executeCommand();
+    }
+        
+    if (error)
+        LOG_ERROR("Failed to set quota %llu in tracker database for origin %s", quota, origin.stringIdentifier().ascii().data());
+    
+    if (m_client)
+        m_client->dispatchDidModifyOrigin(origin);
 }
     
 bool DatabaseTracker::addDatabase(const SecurityOriginData& origin, const String& name, const String& path)
 {
     if (!m_database.isOpen())
         return false;
+        
+    // New database should never be added until the origin has been established
+    ASSERT(hasEntryForOrigin(origin));
 
     SQLiteStatement statement(m_database, "INSERT INTO Databases (origin, name, path) VALUES (?, ?, ?);");
 
@@ -276,25 +438,93 @@ bool DatabaseTracker::addDatabase(const SecurityOriginData& origin, const String
         LOG_ERROR("Failed to add database %s to origin %s: %s\n", name.ascii().data(), origin.stringIdentifier().ascii().data(), statement.lastErrorMsg());
         return false;
     }
-
-    populateOrigins();
-    m_origins->add(origin);
+    
+    if (m_client)
+        m_client->dispatchDidModifyOrigin(origin);
+    
     return true;
 }
 
 void DatabaseTracker::deleteAllDatabases()
 {
-    notImplemented();
+    populateOrigins();
+    
+    HashMap<SecurityOriginData, unsigned long long, SecurityOriginDataHash, SecurityOriginDataTraits>::const_iterator iter = m_originQuotaMap->begin();
+    HashMap<SecurityOriginData, unsigned long long, SecurityOriginDataHash, SecurityOriginDataTraits>::const_iterator end = m_originQuotaMap->end();
+
+    for (; iter != end; ++iter)
+        deleteDatabasesWithOrigin(iter->first);
 }
 
 void DatabaseTracker::deleteDatabasesWithOrigin(const SecurityOriginData& origin)
 {
-    notImplemented();
+    Vector<String> databaseNames;
+    if (!databaseNamesForOrigin(origin, databaseNames)) {
+        LOG_ERROR("Unable to retrieve list of database names for origin %s", origin.stringIdentifier().ascii().data());
+        return;
+    }
+    
+    for (unsigned i = 0; i < databaseNames.size(); ++i) {
+        if (!deleteDatabaseFile(origin, databaseNames[i])) {
+            LOG_ERROR("Unable to delete file for database %s in origin %s", databaseNames[i].ascii().data(), origin.stringIdentifier().ascii().data());
+            return;
+        }
+    }
+    
+    SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=?");
+    if (statement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to prepare deletion of databases from origin %s from tracker", origin.stringIdentifier().ascii().data());
+        return;
+    }
+        
+    statement.bindText(1, origin.stringIdentifier());
+    
+    if (!statement.executeCommand()) {
+        LOG_ERROR("Unable to execute deletion of databases from origin %s from tracker", origin.stringIdentifier().ascii().data());
+        return;
+    }
+    
+    if (m_client) {
+        m_client->dispatchDidModifyOrigin(origin);
+        for (unsigned i = 0; i < databaseNames.size(); ++i)
+            m_client->dispatchDidModifyDatabase(origin, databaseNames[i]);
+    }
 }
 
 void DatabaseTracker::deleteDatabase(const SecurityOriginData& origin, const String& name)
 {
-    notImplemented();
+    if (!deleteDatabaseFile(origin, name)) {
+        LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin.stringIdentifier().ascii().data());
+        return;
+    }
+    
+    SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=? AND name=?");
+    if (statement.prepare() != SQLResultOk) {
+        LOG_ERROR("Unable to prepare deletion of database %s from origin %s from tracker", name.ascii().data(), origin.stringIdentifier().ascii().data());
+        return;
+    }
+        
+    statement.bindText(1, origin.stringIdentifier());
+    statement.bindText(2, name);
+    
+    if (!statement.executeCommand()) {
+        LOG_ERROR("Unable to execute deletion of database %s from origin %s from tracker", name.ascii().data(), origin.stringIdentifier().ascii().data());
+        return;
+    }
+    
+    if (m_client) {
+        m_client->dispatchDidModifyOrigin(origin);
+        m_client->dispatchDidModifyDatabase(origin, name);
+    }
+}
+
+bool DatabaseTracker::deleteDatabaseFile(const SecurityOriginData& origin, const String& name)
+{
+    String fullPath = fullPathForDatabase(origin, name, false);
+    if (fullPath.isEmpty())
+        return true;
+        
+    return deleteFile(fullPath);
 }
 
 void DatabaseTracker::setClient(DatabaseTrackerClient* client)
index 6023aae..94d3878 100644 (file)
@@ -38,7 +38,9 @@
 namespace WebCore {
 
 class DatabaseTrackerClient;
+class Document;
 class SecurityOriginData;
+
 struct SecurityOriginDataHash;
 struct SecurityOriginDataTraits;
 
@@ -47,13 +49,16 @@ public:
     void setDatabasePath(const String&);
     const String& databasePath();
 
-    String fullPathForDatabase(const SecurityOriginData& origin, const String& name);
+    bool canEstablishDatabase(Document* document, const String& name, const String& displayName, unsigned long estimatedSize);
+    void setDatabaseDetails(const SecurityOriginData& origin, const String& name, const String& displayName, unsigned long estimatedSize);
+    String fullPathForDatabase(const SecurityOriginData& origin, const String& name, bool createIfNotExists = true);
 
     void origins(Vector<SecurityOriginData>& result);
     bool databaseNamesForOrigin(const SecurityOriginData& origin, Vector<String>& result);
 
     DatabaseDetails detailsForNameAndOrigin(const String&, const SecurityOriginData&);
     
+    unsigned long long usageForDatabase(const String&, const SecurityOriginData&);
     unsigned long long usageForOrigin(const SecurityOriginData&);
     unsigned long long quotaForOrigin(const SecurityOriginData&);
     void setQuota(const SecurityOriginData&, unsigned long long);
@@ -73,11 +78,16 @@ private:
 
     void openTrackerDatabase();
     
+    bool hasEntryForOrigin(const SecurityOriginData&);
+    void establishEntryForOrigin(const SecurityOriginData&);
+    
     bool addDatabase(const SecurityOriginData& origin, const String& name, const String& path);
     void populateOrigins();
+    
+    bool deleteDatabaseFile(const SecurityOriginData& origin, const String& name);
 
     SQLiteDatabase m_database;
-    mutable OwnPtr<HashSet<SecurityOriginData, SecurityOriginDataHash, SecurityOriginDataTraits> > m_origins;
+    mutable OwnPtr<HashMap<SecurityOriginData, unsigned long long, SecurityOriginDataHash, SecurityOriginDataTraits> > m_originQuotaMap;
 
     String m_databasePath;
     
index 3726391..d008429 100644 (file)
@@ -1,3 +1,12 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Keep it building with new client method
+
+        * WebCoreSupport/ChromeClientGtk.cpp:
+        (WebKit::ChromeClient::requestQuotaIncreaseForNewDatabase):
+        (WebKit::ChromeClient::requestQuotaIncreaseForDatabaseOperation):
+        * WebCoreSupport/ChromeClientGtk.h:
+
 2007-11-26  Alp Toker  <alp@atoker.com>
 
         Reviewed by Adam Roben.
index bd0669c..2001427 100644 (file)
@@ -302,9 +302,16 @@ void ChromeClient::print(Frame*)
     notImplemented();
 }
 
-bool ChromeClient::runDatabaseSizeLimitPrompt(Frame*, const String& origin)
+unsigned long long ChromeClient::requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long)
 {
     notImplemented();
-    return false;
+    return 0;
+}
+
+unsigned long long ChromeClient::requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long)
+{
+    notImplemented();
+    return 0;
 }
+        
 }
index b325b00..b5ea6b3 100644 (file)
@@ -102,7 +102,8 @@ namespace WebKit {
 
         virtual void print(WebCore::Frame*);
 
-        virtual bool runDatabaseSizeLimitPrompt(WebCore::Frame*, const WebCore::String&);
+        virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long);
+        virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long);
 
     private:
         WebKitPage* m_webPage;
index 955c1d8..e1e060b 100644 (file)
@@ -1,3 +1,32 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Anders
+
+        Support for <rdar://problem/5556381> and <rdar://problem/5556379>
+
+        Hook up UI Delegate calls for the database engine feature and other small tweaks
+
+        * Storage/WebDatabaseManager.mm:
+        (-[WebDatabaseManager detailsForDatabase:withOrigin:]): Renamed databaseName parameter to databaseIdentifier for clarity
+        (-[WebDatabaseManager deleteDatabase:withOrigin:]): Renamed databaseName parameter to databaseIdentifier for clarity
+        * Storage/WebDatabaseManagerPrivate.h:
+
+        * Storage/WebDatabaseTrackerClient.h:
+        * Storage/WebDatabaseTrackerClient.mm:
+        (WebDatabaseTrackerClient::dispatchDidModifyDatabase): Renamed databaseName parameter to databaseIdentifier for clarity
+
+        * WebCoreSupport/WebChromeClient.h:
+        * WebCoreSupport/WebChromeClient.mm:
+        (WebChromeClient::requestQuotaIncreaseForNewDatabase): Call through to the UI Delegate
+        (WebChromeClient::requestQuotaIncreaseForDatabaseOperation): Ditto
+
+        * WebView/WebUIDelegatePrivate.h: Added the two UI Delegate methods
+
+        * WebView/WebView.mm:
+        (CallDelegateReturningUnsignedLongLong):
+        (CallUIDelegateReturningUnsignedLongLong):
+        * WebView/WebViewInternal.h:
+
 2007-11-28  Kevin McCullough  <kmccullough@apple.com>
 
         Reviewed by Sam.
index b561a22..24d7654 100644 (file)
@@ -45,7 +45,7 @@ const NSString *WebDatabaseUsageKey = @"WebDatabaseUsageKey";
 
 const NSString *WebDatabaseDidModifyOriginNotification = @"WebDatabaseDidModifyOriginNotification";
 const NSString *WebDatabaseDidModifyDatabaseNotification = @"WebDatabaseDidModifyDatabaseNotification";
-const NSString *WebDatabaseNameKey = @"WebDatabaseNameKey";
+const NSString *WebDatabaseIdentifierKey = @"WebDatabaseIdentifierKey";
 
 @implementation WebDatabaseManager
 
@@ -84,16 +84,16 @@ const NSString *WebDatabaseNameKey = @"WebDatabaseNameKey";
     return [names autorelease];
 }
 
-- (NSDictionary *)detailsForDatabase:(NSString *)databaseName withOrigin:(WebSecurityOrigin *)origin
+- (NSDictionary *)detailsForDatabase:(NSString *)databaseIdentifier withOrigin:(WebSecurityOrigin *)origin
 {
     static id keys[3] = {WebDatabaseDisplayNameKey, WebDatabaseExpectedSizeKey, WebDatabaseUsageKey};
     
-    DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseName, *[origin _core]);
+    DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(databaseIdentifier, *[origin _core]);
     if (!details.isValid())
         return nil;
         
     id objects[3];
-    objects[0] = details.displayName().isEmpty() ? databaseName : (NSString *)details.displayName();
+    objects[0] = details.displayName().isEmpty() ? databaseIdentifier : (NSString *)details.displayName();
     objects[1] = [NSNumber numberWithUnsignedLongLong:details.expectedUsage()];
     objects[2] = [NSNumber numberWithUnsignedLongLong:details.currentUsage()];
     
@@ -110,9 +110,9 @@ const NSString *WebDatabaseNameKey = @"WebDatabaseNameKey";
     DatabaseTracker::tracker().deleteDatabasesWithOrigin(*[origin _core]);
 }
 
-- (void)deleteDatabase:(NSString *)databaseName withOrigin:(WebSecurityOrigin *)origin
+- (void)deleteDatabase:(NSString *)databaseIdentifier withOrigin:(WebSecurityOrigin *)origin
 {
-    DatabaseTracker::tracker().deleteDatabase(*[origin _core], databaseName);
+    DatabaseTracker::tracker().deleteDatabase(*[origin _core], databaseIdentifier);
 }
 
 @end
index 5bef5bb..99308d9 100644 (file)
@@ -38,7 +38,7 @@ extern const NSString *WebDatabaseDidModifyOriginNotification;
 // The notification object will be a WebSecurityOrigin object corresponding to the origin.
 // The notification userInfo will have a WebDatabaseNameKey whose value is the database name.
 extern const NSString *WebDatabaseDidModifyDatabaseNotification;
-extern const NSString *WebDatabaseNameKey;
+extern const NSString *WebDatabaseIdentifierKey;
 
 @class WebSecurityOrigin;
 
@@ -55,10 +55,10 @@ extern const NSString *WebDatabaseNameKey;
 - (NSArray *)databasesWithOrigin:(WebSecurityOrigin *)origin;
 
 // Will return the dictionary describing everything about the database for the passed origin and name
-- (NSDictionary *)detailsForDatabase:(NSString *)databaseName withOrigin:(WebSecurityOrigin *)origin;
+- (NSDictionary *)detailsForDatabase:(NSString *)databaseIdentifier withOrigin:(WebSecurityOrigin *)origin;
 
 - (void)deleteAllDatabases;
 - (void)deleteDatabasesWithOrigin:(WebSecurityOrigin *)origin;
-- (void)deleteDatabase:(NSString *)databaseName withOrigin:(WebSecurityOrigin *)origin;
+- (void)deleteDatabase:(NSString *)databaseIdentifier withOrigin:(WebSecurityOrigin *)origin;
 
 @end
index eb99faf..0e192d0 100644 (file)
@@ -35,7 +35,7 @@ public:
     
     virtual ~WebDatabaseTrackerClient();
     virtual void dispatchDidModifyOrigin(const WebCore::SecurityOriginData&);
-    virtual void dispatchDidModifyDatabase(const WebCore::SecurityOriginData&, const WebCore::String& databaseName);
+    virtual void dispatchDidModifyDatabase(const WebCore::SecurityOriginData&, const WebCore::String& databaseIdentifier);
 private:
     WebDatabaseTrackerClient();
 };
index 0722740..118293e 100644 (file)
@@ -57,11 +57,11 @@ void WebDatabaseTrackerClient::dispatchDidModifyOrigin(const SecurityOriginData&
                                                         object:webSecurityOrigin.get()];
 }
 
-void WebDatabaseTrackerClient::dispatchDidModifyDatabase(const SecurityOriginData& origin, const String& databaseName)
+void WebDatabaseTrackerClient::dispatchDidModifyDatabase(const SecurityOriginData& origin, const String& databaseIdentifier)
 {
     RetainPtr<WebSecurityOrigin> webSecurityOrigin(AdoptNS, [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOriginData:&origin]);
     RetainPtr<NSDictionary> userInfo(AdoptNS, [[NSDictionary alloc] 
-                                               initWithObjectsAndKeys:(NSString *)databaseName, WebDatabaseNameKey, nil]);
+                                               initWithObjectsAndKeys:(NSString *)databaseIdentifier, WebDatabaseIdentifierKey, nil]);
     
     [[NSNotificationCenter defaultCenter] postNotificationName:WebDatabaseDidModifyDatabaseNotification
                                                         object:webSecurityOrigin.get()
index f32834a..41de805 100644 (file)
@@ -100,7 +100,8 @@ public:
 
     virtual void print(WebCore::Frame*);
 
-    virtual bool runDatabaseSizeLimitPrompt(WebCore::Frame*, const WebCore::String& origin);
+    virtual unsigned long long requestQuotaIncreaseForNewDatabase(WebCore::Frame*, const WebCore::SecurityOriginData& origin, const WebCore::String& databaseDisplayName, unsigned long long estimatedSize);
+    virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(WebCore::Frame*, const WebCore::SecurityOriginData& origin, const WebCore::String& databaseIdentifier, unsigned long long proposedNewQuota);
 
 private:
     WebView *m_webView;
index cc09eaa..fedd299 100644 (file)
@@ -36,6 +36,8 @@
 #import "WebHTMLView.h"
 #import "WebHTMLViewPrivate.h"
 #import "WebNSURLRequestExtras.h"
+#import "WebSecurityOriginPrivate.h"
+#import "WebSecurityOriginInternal.h"
 #import "WebUIDelegate.h"
 #import "WebUIDelegatePrivate.h"
 #import "WebView.h"
@@ -410,12 +412,19 @@ void WebChromeClient::print(Frame* frame)
     CallUIDelegate(m_webView, @selector(webView:printFrameView:), frameView);
 }
 
-bool WebChromeClient::runDatabaseSizeLimitPrompt(Frame* frame, const String& origin)
+unsigned long long WebChromeClient::requestQuotaIncreaseForNewDatabase(WebCore::Frame*, const WebCore::SecurityOriginData& origin, const WebCore::String& databaseDisplayName, unsigned long long estimatedSize)
 {
-    id delegate = [m_webView UIDelegate];
-    SEL selector = @selector(webView:runDatabaseSizeLimitPromptForOrigin:initiatedByFrame:);
-    if ([delegate respondsToSelector:selector])
-        return CallUIDelegateReturningBoolean(NO, m_webView, selector, (NSString *)origin, kit(frame));
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOriginData:reinterpret_cast<const WebCoreSecurityOriginData*>(&origin)];
+    unsigned long long result = CallUIDelegateReturningUnsignedLongLong(m_webView, @selector(webView:quotaForSecurityOrigin:toCreateDatabase:withEstimatedSize:), webOrigin, (NSString *)databaseDisplayName, estimatedSize);
+    [webOrigin release];
+    return result;
+}
 
-    return NO;
+unsigned long long WebChromeClient::requestQuotaIncreaseForDatabaseOperation(WebCore::Frame*, const WebCore::SecurityOriginData& origin, const WebCore::String& databaseIdentifier, unsigned long long proposedNewQuota)
+{
+    WebSecurityOrigin *webOrigin = [[WebSecurityOrigin alloc] _initWithWebCoreSecurityOriginData:reinterpret_cast<const WebCoreSecurityOriginData*>(&origin)];
+    unsigned long long result = CallUIDelegateReturningUnsignedLongLong(m_webView, @selector(webView:quotaForSecurityOrigin:toCreateDatabase:withEstimatedSize:), webOrigin, proposedNewQuota, (NSString *)databaseIdentifier);
+    [webOrigin release];
+    return result;
 }
+    
index 0589366..7468c3a 100644 (file)
@@ -66,6 +66,7 @@ enum {
     WebMenuItemTagInspectElement,
     WebMenuItemTagBaseApplication = 10000
 };
+@class WebSecurityOrigin;
 
 @interface NSObject (WebUIDelegatePrivate)
 
@@ -86,15 +87,29 @@ enum {
 - (void)webView:(WebView *)sender saveFrameView:(WebFrameView *)frameView showingPanel:(BOOL)showingPanel;
 
 /*!
-    @method webView:runDatabaseSizeLimitPromptForOrigin:initiatedByFrame:
+    @method webView:quotaForSecurityOrigin:toCreateDatabase:withEstimatedSize:
     @param sender The WebView sending the delegate method
-    @param origin The Origin of the database that has reached its size limit
-    @param frame The WebFrame whose JavaScript initiated this call.
-    @result YES if the user hit Allow, NO if the user chose Deny.
-    @discussion Clients should prompt the user for permission to allow databases
-    from this origin to continue to grow.
+    @param origin The security origin of the database that needs a larger quota to create a database
+    @param newDatabaseName The display name of the new database
+    @param estimatedSize The estimated maximum usage of the new database
+    @result The new quota, in bytes
+    @discussion If the new quota is less than or equal to the current usage for the given security origin, the new database will not be created.
+    Otherwise the database will created, even if the new quota doesn't allow for the entire estimated size.
 */
-- (BOOL)webView:(WebView *)sender runDatabaseSizeLimitPromptForOrigin:(NSString *)origin initiatedByFrame:(WebFrame *)frame;
+- (unsigned long long)webView:(WebView *)sender quotaForSecurityOrigin:(WebSecurityOrigin *)origin toCreateDatabase:(NSString *)newDatabaseName withEstimatedSize:(unsigned long long)estimatedSize;
+
+/*!
+    @method webView:quotaForSecurityOrigin:fromProposedQuota:database:
+    @param sender The WebView sending the delegate method
+    @param origin The security origin of the database that has reached its size limit
+    @param proposedNewQuota WebKit's best guess as to the required new quota
+    @param databaseIdentifier The string identifier of the database
+    @result The new quota, in bytes
+    @discussion If the new quota is less than the proposedNewQuota, the current database operation will fail.
+    If the new quota is equal to or greater than the proposedNewQuota, the current database operation will continue, 
+    possibly calling this delegate method again to request even more space
+*/
+- (unsigned long long)webView:(WebView *)sender quotaForSecurityOrigin:(WebSecurityOrigin *)origin fromProposedQuota:(unsigned long long)proposedNewQuota database:(NSString *)databaseIdentifier;
 
 - (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features;
 
index bf59e32..2f16d8e 100644 (file)
@@ -4245,6 +4245,34 @@ static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL s
     return 0.0f;
 }
 
+static inline unsigned long long CallDelegateReturningUnsignedLongLong(WebView *self, id delegate, SEL selector, id object1, id object2, unsigned long long integer)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return 0;
+    if (!self->_private->catchesDelegateExceptions)
+        return static_cast<unsigned long long>(objc_msgSend_fpret(delegate, selector, self, object1, object2, integer));
+    @try {
+        return static_cast<unsigned long long>(objc_msgSend_fpret(delegate, selector, self, object1, object2, integer));
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return 0;
+}
+
+static inline unsigned long long CallDelegateReturningUnsignedLongLong(WebView *self, id delegate, SEL selector, id object1, unsigned long long integer, id object2)
+{
+    if (!delegate || ![delegate respondsToSelector:selector])
+        return 0;
+    if (!self->_private->catchesDelegateExceptions)
+        return static_cast<unsigned long long>(objc_msgSend_fpret(delegate, selector, self, object1, integer, object2));
+    @try {
+        return static_cast<unsigned long long>(objc_msgSend_fpret(delegate, selector, self, object1, integer, object2));
+    } @catch(id exception) {
+        ReportDiscardedDelegateException(selector, exception);
+    }
+    return 0;
+}
+
 static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector)
 {
     if (!delegate || ![delegate respondsToSelector:selector])
@@ -4453,6 +4481,16 @@ float CallUIDelegateReturningFloat(WebView *self, SEL selector)
     return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector);
 }
 
+unsigned long long CallUIDelegateReturningUnsignedLongLong(WebView *self, SEL selector, id object1, id object2, unsigned long long integer)
+{
+    return CallDelegateReturningUnsignedLongLong(self, self->_private->UIDelegate, selector, object1, object2, integer);
+}
+
+unsigned long long CallUIDelegateReturningUnsignedLongLong(WebView *self, SEL selector, id object1, unsigned long long integer, id object2)
+{
+    return CallDelegateReturningUnsignedLongLong(self, self->_private->UIDelegate, selector, object1, integer, object2);
+}
+
 BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector)
 {
     return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector);
index e67ee13..672ae9c 100644 (file)
@@ -167,6 +167,8 @@ id CallUIDelegate(WebView *, SEL, id, BOOL);
 id CallUIDelegate(WebView *, SEL, id, id, id);
 id CallUIDelegate(WebView *, SEL, id, NSUInteger);
 float CallUIDelegateReturningFloat(WebView *, SEL);
+unsigned long long CallUIDelegateReturningUnsignedLongLong(WebView *, SEL, id, id, unsigned long long);
+unsigned long long CallUIDelegateReturningUnsignedLongLong(WebView *, SEL, id, unsigned long long, id);
 BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL);
 BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL, id);
 BOOL CallUIDelegateReturningBoolean(BOOL, WebView *, SEL, id, id);
index 334808b..64d5927 100644 (file)
@@ -1,3 +1,12 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Keep it building with new client method
+
+        * WebCoreSupport/ChromeClientQt.cpp:
+        (WebCore::ChromeClientQt::requestQuotaIncreaseForNewDatabase):
+        (WebCore::ChromeClientQt::requestQuotaIncreaseForDatabaseOperation):
+        * WebCoreSupport/ChromeClientQt.h:
+
 2007-11-22  Simon Hausmann  <hausmann@webkit.org>
 
         Reviewed by Adam Treat.
index d8803a0..20578ca 100644 (file)
@@ -307,10 +307,16 @@ void ChromeClientQt::print(Frame*)
     notImplemented();
 }
 
-bool ChromeClientQt::runDatabaseSizeLimitPrompt(Frame*, const String& origin)
+unsigned long long ChromeClientQt::requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long)
 {
     notImplemented();
-    return false;
+    return 0;
+}
+
+unsigned long long ChromeClientQt::requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long)
+{
+    notImplemented();
+    return 0;
 }
 
 }
index 0e48c74..aa49cdc 100644 (file)
@@ -107,7 +107,8 @@ namespace WebCore {
 
         virtual void print(Frame*);
 
-        virtual bool runDatabaseSizeLimitPrompt(Frame*, const String&);
+        virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long);
+        virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long);
 
         QWebPage* m_webPage;
     };
index 45327bc..094b068 100644 (file)
@@ -1,3 +1,12 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Keep it building with new client method
+
+        * WebChromeClient.cpp:
+        (ChromeClient::requestQuotaIncreaseForNewDatabase):
+        (ChromeClient::requestQuotaIncreaseForDatabaseOperation):
+        * WebChromeClient.h:
+
 2007-11-29  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Beth Dakin and Darin Adler.
index 207396b..68ac001 100644 (file)
@@ -456,14 +456,14 @@ void WebChromeClient::print(Frame* frame)
             uiDelegate2->printFrame(m_webView, kit(frame));
 }
 
-bool WebChromeClient::runDatabaseSizeLimitPrompt(Frame* frame, const String& prompt)
+unsigned long long ChromeClient::requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long)
 {
-    COMPtr<IWebUIDelegate3> delegate = uiDelegate3();
-    if (!delegate)
-        return false;
-    BOOL result = FALSE;
-    delegate->runDatabaseSizeLimitPrompt(m_webView, BString(prompt), kit(frame), &result);
-    return result;
+    return 0;
+}
+
+unsigned long long ChromeClient::requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long)
+{
+    return 0;
 }
 
 COMPtr<IWebUIDelegate> WebChromeClient::uiDelegate()
index 01a49e7..da12fd5 100644 (file)
@@ -98,7 +98,8 @@ public:
 
     virtual void print(WebCore::Frame*);
 
-    virtual bool runDatabaseSizeLimitPrompt(WebCore::Frame*, const WebCore::String& origin);
+    virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long);
+    virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long);
 
     virtual WebView* webView() const { return m_webView; }
 
index c1e8b0c..43b2f60 100644 (file)
@@ -1,3 +1,12 @@
+2007-11-29  Brady Eidson  <beidson@apple.com>
+
+        Keep it building with new client method
+
+        * WebKitSupport/ChromeClientWx.cpp:
+        (WebCore::ChromeClient::requestQuotaIncreaseForNewDatabase):
+        (WebCore::ChromeClient::requestQuotaIncreaseForDatabaseOperation):
+        * WebKitSupport/ChromeClientWx.h:
+
 2007-11-25  Kevin Ollivier  <kevino@theolliviers.com>
 
         wx build fix. Don't get xslt-config options at bake time, do it
index 838afc6..a85a38a 100644 (file)
@@ -302,10 +302,16 @@ void ChromeClientWx::print(Frame*)
     notImplemented();
 }
 
-bool ChromeClientWx::runDatabaseSizeLimitPrompt(Frame*, const String& origin)
+unsigned long long ChromeClient::requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long)
 {
     notImplemented();
-    return false;
+    return 0;
+}
+
+unsigned long long ChromeClient::requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long)
+{
+    notImplemented();
+    return 0;
 }
 
 }
index 9a1bfce..596d925 100644 (file)
@@ -102,8 +102,9 @@ public:
     virtual void setToolTip(const String&);
 
     virtual void print(Frame*);
-    
-    virtual bool runDatabaseSizeLimitPrompt(Frame*, const String& origin);
+
+    virtual unsigned long long requestQuotaIncreaseForNewDatabase(Frame*, const SecurityOriginData&, const String&, unsigned long long);
+    virtual unsigned long long requestQuotaIncreaseForDatabaseOperation(Frame*, const SecurityOriginData&, const String&, unsigned long long);    
 };
 
 }