summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/win/WebDatabaseManager.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-13 16:23:25 +0100
committerBen Murdoch <benm@google.com>2011-05-16 11:35:02 +0100
commit65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch)
treef478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit/win/WebDatabaseManager.cpp
parent47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff)
downloadexternal_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz
external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit/win/WebDatabaseManager.cpp')
-rw-r--r--Source/WebKit/win/WebDatabaseManager.cpp423
1 files changed, 423 insertions, 0 deletions
diff --git a/Source/WebKit/win/WebDatabaseManager.cpp b/Source/WebKit/win/WebDatabaseManager.cpp
new file mode 100644
index 0000000..bdcb549
--- /dev/null
+++ b/Source/WebKit/win/WebDatabaseManager.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDatabaseManager.h"
+#include "WebKitDLL.h"
+
+#if ENABLE(DATABASE)
+
+#include "CFDictionaryPropertyBag.h"
+#include "COMEnumVariant.h"
+#include "MarshallingHelpers.h"
+#include "WebNotificationCenter.h"
+#include "WebSecurityOrigin.h"
+
+#include <JavaScriptCore/MainThread.h>
+#include <WebCore/BString.h>
+#include <WebCore/COMPtr.h>
+#include <WebCore/DatabaseTracker.h>
+#include <WebCore/FileSystem.h>
+#include <WebCore/SecurityOrigin.h>
+
+using namespace WebCore;
+
+static inline bool isEqual(LPCWSTR s1, LPCWSTR s2)
+{
+ return !wcscmp(s1, s2);
+}
+
+class DatabaseDetailsPropertyBag : public IPropertyBag, public Noncopyable {
+public:
+ static DatabaseDetailsPropertyBag* createInstance(const DatabaseDetails&);
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+
+ // IPropertyBag
+ virtual HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog);
+ virtual HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT* pVar);
+private:
+ DatabaseDetailsPropertyBag(const DatabaseDetails& details)
+ : m_refCount(0)
+ , m_details(details) { }
+ ~DatabaseDetailsPropertyBag() { }
+
+ ULONG m_refCount;
+ DatabaseDetails m_details;
+};
+
+// DatabaseDetailsPropertyBag ------------------------------------------------------
+DatabaseDetailsPropertyBag* DatabaseDetailsPropertyBag::createInstance(const DatabaseDetails& details)
+{
+ DatabaseDetailsPropertyBag* instance = new DatabaseDetailsPropertyBag(details);
+ instance->AddRef();
+ return instance;
+}
+
+// IUnknown ------------------------------------------------------------------------
+ULONG STDMETHODCALLTYPE DatabaseDetailsPropertyBag::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Release()
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<DatabaseDetailsPropertyBag*>(this);
+ else if (IsEqualGUID(riid, IID_IPropertyBag))
+ *ppvObject = static_cast<DatabaseDetailsPropertyBag*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+// IPropertyBag --------------------------------------------------------------------
+HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog*)
+{
+ if (!pszPropName || !pVar)
+ return E_POINTER;
+
+ VariantInit(pVar);
+
+ if (isEqual(pszPropName, WebDatabaseDisplayNameKey)) {
+ COMVariantSetter<String>::setVariant(pVar, m_details.displayName());
+ return S_OK;
+ } else if (isEqual(pszPropName, WebDatabaseExpectedSizeKey)) {
+ COMVariantSetter<unsigned long long>::setVariant(pVar, m_details.expectedUsage());
+ return S_OK;
+ } else if (isEqual(pszPropName, WebDatabaseUsageKey)) {
+ COMVariantSetter<unsigned long long>::setVariant(pVar, m_details.currentUsage());
+ return S_OK;
+ }
+
+ return E_INVALIDARG;
+}
+
+HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
+{
+ if (!pszPropName || !pVar)
+ return E_POINTER;
+
+ return E_FAIL;
+}
+
+static COMPtr<WebDatabaseManager> s_sharedWebDatabaseManager;
+
+// WebDatabaseManager --------------------------------------------------------------
+WebDatabaseManager* WebDatabaseManager::createInstance()
+{
+ WebDatabaseManager* manager = new WebDatabaseManager();
+ manager->AddRef();
+ return manager;
+}
+
+WebDatabaseManager::WebDatabaseManager()
+ : m_refCount(0)
+{
+ gClassCount++;
+ gClassNameCount.add("WebDatabaseManager");
+}
+
+WebDatabaseManager::~WebDatabaseManager()
+{
+ gClassCount--;
+ gClassNameCount.remove("WebDatabaseManager");
+}
+
+// IUnknown ------------------------------------------------------------------------
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = static_cast<WebDatabaseManager*>(this);
+ else if (IsEqualGUID(riid, IID_IWebDatabaseManager))
+ *ppvObject = static_cast<WebDatabaseManager*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE WebDatabaseManager::AddRef()
+{
+ return ++m_refCount;
+}
+
+ULONG STDMETHODCALLTYPE WebDatabaseManager::Release()
+{
+ ULONG newRef = --m_refCount;
+ if (!newRef)
+ delete this;
+
+ return newRef;
+}
+
+template<> struct COMVariantSetter<RefPtr<SecurityOrigin> > : COMIUnknownVariantSetter<WebSecurityOrigin, RefPtr<SecurityOrigin> > {};
+
+// IWebDatabaseManager -------------------------------------------------------------
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::sharedWebDatabaseManager(
+ /* [retval][out] */ IWebDatabaseManager** result)
+{
+ if (!s_sharedWebDatabaseManager) {
+ s_sharedWebDatabaseManager.adoptRef(WebDatabaseManager::createInstance());
+ DatabaseTracker::tracker().setClient(s_sharedWebDatabaseManager.get());
+ }
+
+ return s_sharedWebDatabaseManager.copyRefTo(result);
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::origins(
+ /* [retval][out] */ IEnumVARIANT** result)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = 0;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ Vector<RefPtr<SecurityOrigin> > origins;
+ DatabaseTracker::tracker().origins(origins);
+ COMPtr<COMEnumVariant<Vector<RefPtr<SecurityOrigin> > > > enumVariant(AdoptCOM, COMEnumVariant<Vector<RefPtr<SecurityOrigin> > >::adopt(origins));
+
+ *result = enumVariant.releaseRef();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::databasesWithOrigin(
+ /* [in] */ IWebSecurityOrigin* origin,
+ /* [retval][out] */ IEnumVARIANT** result)
+{
+ if (!origin || !result)
+ return E_POINTER;
+
+ *result = 0;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
+ if (!webSecurityOrigin)
+ return E_FAIL;
+
+ Vector<String> databaseNames;
+ DatabaseTracker::tracker().databaseNamesForOrigin(webSecurityOrigin->securityOrigin(), databaseNames);
+
+ COMPtr<COMEnumVariant<Vector<String> > > enumVariant(AdoptCOM, COMEnumVariant<Vector<String> >::adopt(databaseNames));
+
+ *result = enumVariant.releaseRef();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::detailsForDatabase(
+ /* [in] */ BSTR databaseName,
+ /* [in] */ IWebSecurityOrigin* origin,
+ /* [retval][out] */ IPropertyBag** result)
+{
+ if (!origin || !result)
+ return E_POINTER;
+
+ *result = 0;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
+ if (!webSecurityOrigin)
+ return E_FAIL;
+
+ DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(String(databaseName, SysStringLen(databaseName)),
+ webSecurityOrigin->securityOrigin());
+
+ if (details.name().isNull())
+ return E_INVALIDARG;
+
+ *result = DatabaseDetailsPropertyBag::createInstance(details);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteAllDatabases()
+{
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ DatabaseTracker::tracker().deleteAllDatabases();
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteOrigin(
+ /* [in] */ IWebSecurityOrigin* origin)
+{
+ if (!origin)
+ return E_POINTER;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
+ if (!webSecurityOrigin)
+ return E_FAIL;
+
+ DatabaseTracker::tracker().deleteOrigin(webSecurityOrigin->securityOrigin());
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteDatabase(
+ /* [in] */ BSTR databaseName,
+ /* [in] */ IWebSecurityOrigin* origin)
+{
+ if (!origin)
+ return E_POINTER;
+
+ if (!databaseName)
+ return E_INVALIDARG;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
+ if (!webSecurityOrigin)
+ return E_FAIL;
+
+ DatabaseTracker::tracker().deleteDatabase(webSecurityOrigin->securityOrigin(), String(databaseName, SysStringLen(databaseName)));
+
+ return S_OK;
+}
+
+class DidModifyOriginData : public Noncopyable {
+public:
+ static void dispatchToMainThread(WebDatabaseManager* databaseManager, SecurityOrigin* origin)
+ {
+ DidModifyOriginData* context = new DidModifyOriginData(databaseManager, origin->threadsafeCopy());
+ callOnMainThread(&DidModifyOriginData::dispatchDidModifyOriginOnMainThread, context);
+ }
+
+private:
+ DidModifyOriginData(WebDatabaseManager* databaseManager, PassRefPtr<SecurityOrigin> origin)
+ : databaseManager(databaseManager)
+ , origin(origin)
+ {
+ }
+
+ static void dispatchDidModifyOriginOnMainThread(void* context)
+ {
+ ASSERT(isMainThread());
+ DidModifyOriginData* info = static_cast<DidModifyOriginData*>(context);
+ info->databaseManager->dispatchDidModifyOrigin(info->origin.get());
+ delete info;
+ }
+
+ WebDatabaseManager* databaseManager;
+ RefPtr<SecurityOrigin> origin;
+};
+
+void WebDatabaseManager::dispatchDidModifyOrigin(SecurityOrigin* origin)
+{
+ if (!isMainThread()) {
+ DidModifyOriginData::dispatchToMainThread(this, origin);
+ return;
+ }
+
+ static BSTR databaseDidModifyOriginName = SysAllocString(WebDatabaseDidModifyOriginNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+
+ COMPtr<WebSecurityOrigin> securityOrigin(AdoptCOM, WebSecurityOrigin::createInstance(origin));
+ notifyCenter->postNotificationName(databaseDidModifyOriginName, securityOrigin.get(), 0);
+}
+
+HRESULT STDMETHODCALLTYPE WebDatabaseManager::setQuota(
+ /* [in] */ BSTR origin,
+ /* [in] */ unsigned long long quota)
+{
+ if (!origin)
+ return E_POINTER;
+
+ if (this != s_sharedWebDatabaseManager)
+ return E_FAIL;
+
+ DatabaseTracker::tracker().setQuota(SecurityOrigin::createFromString(origin).get(), quota);
+
+ return S_OK;
+}
+
+void WebDatabaseManager::dispatchDidModifyDatabase(SecurityOrigin* origin, const String& databaseName)
+{
+ if (!isMainThread()) {
+ DidModifyOriginData::dispatchToMainThread(this, origin);
+ return;
+ }
+
+ static BSTR databaseDidModifyOriginName = SysAllocString(WebDatabaseDidModifyDatabaseNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+
+ COMPtr<WebSecurityOrigin> securityOrigin(AdoptCOM, WebSecurityOrigin::createInstance(origin));
+
+ RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ static CFStringRef databaseNameKey = MarshallingHelpers::LPCOLESTRToCFStringRef(WebDatabaseNameKey);
+ RetainPtr<CFStringRef> str(AdoptCF, databaseName.createCFString());
+ CFDictionarySetValue(userInfo.get(), databaseNameKey, str.get());
+
+ COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
+ userInfoBag->setDictionary(userInfo.get());
+
+ notifyCenter->postNotificationName(databaseDidModifyOriginName, securityOrigin.get(), userInfoBag.get());
+}
+
+void WebKitInitializeWebDatabasesIfNecessary()
+{
+ static bool initialized = false;
+ if (initialized)
+ return;
+
+ WTF::String databasesDirectory = WebCore::pathByAppendingComponent(WebCore::localUserSpecificStorageDirectory(), "Databases");
+ WebCore::DatabaseTracker::initializeTracker(databasesDirectory);
+
+ initialized = true;
+}
+
+#endif