WebKit/win/WebDatabaseManager.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer.
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution.
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission.
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #include "config.h"
       
    30 #include "WebDatabaseManager.h"
       
    31 #include "WebKitDLL.h"
       
    32 
       
    33 #if ENABLE(DATABASE)
       
    34 
       
    35 #include "CFDictionaryPropertyBag.h"
       
    36 #include "COMEnumVariant.h"
       
    37 #include "MarshallingHelpers.h"
       
    38 #include "WebNotificationCenter.h"
       
    39 #include "WebSecurityOrigin.h"
       
    40 
       
    41 #include <WebCore/BString.h>
       
    42 #include <WebCore/COMPtr.h>
       
    43 #include <WebCore/DatabaseTracker.h>
       
    44 #include <WebCore/FileSystem.h>
       
    45 #include <WebCore/SecurityOrigin.h>
       
    46 
       
    47 using namespace WebCore;
       
    48 
       
    49 static inline bool isEqual(LPCWSTR s1, LPCWSTR s2)
       
    50 {
       
    51     return !wcscmp(s1, s2);
       
    52 }
       
    53 
       
    54 class DatabaseDetailsPropertyBag : public IPropertyBag, public Noncopyable {
       
    55 public:
       
    56     static DatabaseDetailsPropertyBag* createInstance(const DatabaseDetails&);
       
    57 
       
    58     // IUnknown
       
    59     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
       
    60     virtual ULONG STDMETHODCALLTYPE AddRef();
       
    61     virtual ULONG STDMETHODCALLTYPE Release();
       
    62 
       
    63     // IPropertyBag
       
    64     virtual HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog);
       
    65     virtual HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT* pVar);
       
    66 private:
       
    67     DatabaseDetailsPropertyBag(const DatabaseDetails& details) 
       
    68         : m_refCount(0)
       
    69         , m_details(details) { }
       
    70     ~DatabaseDetailsPropertyBag() { }
       
    71 
       
    72     ULONG m_refCount;
       
    73     DatabaseDetails m_details;
       
    74 };
       
    75 
       
    76 // DatabaseDetailsPropertyBag ------------------------------------------------------
       
    77 DatabaseDetailsPropertyBag* DatabaseDetailsPropertyBag::createInstance(const DatabaseDetails& details)
       
    78 {
       
    79     DatabaseDetailsPropertyBag* instance = new DatabaseDetailsPropertyBag(details);
       
    80     instance->AddRef();
       
    81     return instance;
       
    82 }
       
    83 
       
    84 // IUnknown ------------------------------------------------------------------------
       
    85 ULONG STDMETHODCALLTYPE DatabaseDetailsPropertyBag::AddRef()
       
    86 {
       
    87     return ++m_refCount;
       
    88 }
       
    89 
       
    90 ULONG STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Release()
       
    91 {
       
    92     ULONG newRef = --m_refCount;
       
    93     if (!newRef)
       
    94         delete this;
       
    95 
       
    96     return newRef;
       
    97 }
       
    98 
       
    99 HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
       
   100 {
       
   101     *ppvObject = 0;
       
   102     if (IsEqualGUID(riid, IID_IUnknown))
       
   103         *ppvObject = static_cast<DatabaseDetailsPropertyBag*>(this);
       
   104     else if (IsEqualGUID(riid, IID_IPropertyBag))
       
   105         *ppvObject = static_cast<DatabaseDetailsPropertyBag*>(this);
       
   106     else
       
   107         return E_NOINTERFACE;
       
   108 
       
   109     AddRef();
       
   110     return S_OK;
       
   111 }
       
   112 
       
   113 // IPropertyBag --------------------------------------------------------------------
       
   114 HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog*)
       
   115 {
       
   116     if (!pszPropName || !pVar)
       
   117         return E_POINTER;
       
   118 
       
   119     VariantInit(pVar);
       
   120 
       
   121     if (isEqual(pszPropName, WebDatabaseDisplayNameKey)) {
       
   122         COMVariantSetter<String>::setVariant(pVar, m_details.displayName());
       
   123         return S_OK;
       
   124     } else if (isEqual(pszPropName, WebDatabaseExpectedSizeKey)) {
       
   125         COMVariantSetter<unsigned long long>::setVariant(pVar, m_details.expectedUsage());
       
   126         return S_OK;
       
   127     } else if (isEqual(pszPropName, WebDatabaseUsageKey)) {
       
   128         COMVariantSetter<unsigned long long>::setVariant(pVar, m_details.currentUsage());
       
   129         return S_OK;
       
   130     }
       
   131 
       
   132     return E_INVALIDARG;
       
   133 }
       
   134 
       
   135 HRESULT STDMETHODCALLTYPE DatabaseDetailsPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
       
   136 {
       
   137     if (!pszPropName || !pVar)
       
   138         return E_POINTER;
       
   139 
       
   140     return E_FAIL;
       
   141 }
       
   142 
       
   143 static COMPtr<WebDatabaseManager> s_sharedWebDatabaseManager;
       
   144 
       
   145 // WebDatabaseManager --------------------------------------------------------------
       
   146 WebDatabaseManager* WebDatabaseManager::createInstance()
       
   147 {
       
   148     WebDatabaseManager* manager = new WebDatabaseManager();
       
   149     manager->AddRef();
       
   150     return manager;    
       
   151 }
       
   152 
       
   153 WebDatabaseManager::WebDatabaseManager()
       
   154     : m_refCount(0)
       
   155 {
       
   156     gClassCount++;
       
   157     gClassNameCount.add("WebDatabaseManager");
       
   158 }
       
   159 
       
   160 WebDatabaseManager::~WebDatabaseManager()
       
   161 {
       
   162     gClassCount--;
       
   163     gClassNameCount.remove("WebDatabaseManager");
       
   164 }
       
   165 
       
   166 // IUnknown ------------------------------------------------------------------------
       
   167 HRESULT STDMETHODCALLTYPE WebDatabaseManager::QueryInterface(REFIID riid, void** ppvObject)
       
   168 {
       
   169     *ppvObject = 0;
       
   170     if (IsEqualGUID(riid, IID_IUnknown))
       
   171         *ppvObject = static_cast<WebDatabaseManager*>(this);
       
   172     else if (IsEqualGUID(riid, IID_IWebDatabaseManager))
       
   173         *ppvObject = static_cast<WebDatabaseManager*>(this);
       
   174     else
       
   175         return E_NOINTERFACE;
       
   176 
       
   177     AddRef();
       
   178     return S_OK;
       
   179 }
       
   180 
       
   181 ULONG STDMETHODCALLTYPE WebDatabaseManager::AddRef()
       
   182 {
       
   183     return ++m_refCount;
       
   184 }
       
   185 
       
   186 ULONG STDMETHODCALLTYPE WebDatabaseManager::Release()
       
   187 {
       
   188     ULONG newRef = --m_refCount;
       
   189     if (!newRef)
       
   190         delete this;
       
   191 
       
   192     return newRef;
       
   193 }
       
   194 
       
   195 template<> struct COMVariantSetter<RefPtr<SecurityOrigin> > : COMIUnknownVariantSetter<WebSecurityOrigin, RefPtr<SecurityOrigin> > {};
       
   196 
       
   197 // IWebDatabaseManager -------------------------------------------------------------
       
   198 HRESULT STDMETHODCALLTYPE WebDatabaseManager::sharedWebDatabaseManager( 
       
   199     /* [retval][out] */ IWebDatabaseManager** result)
       
   200 {
       
   201     if (!s_sharedWebDatabaseManager) {
       
   202         s_sharedWebDatabaseManager.adoptRef(WebDatabaseManager::createInstance());
       
   203         DatabaseTracker::tracker().setClient(s_sharedWebDatabaseManager.get());
       
   204     }
       
   205 
       
   206     return s_sharedWebDatabaseManager.copyRefTo(result);
       
   207 }
       
   208 
       
   209 HRESULT STDMETHODCALLTYPE WebDatabaseManager::origins( 
       
   210     /* [retval][out] */ IEnumVARIANT** result)
       
   211 {
       
   212     if (!result)
       
   213         return E_POINTER;
       
   214 
       
   215     *result = 0;
       
   216 
       
   217     if (this != s_sharedWebDatabaseManager)
       
   218         return E_FAIL;
       
   219 
       
   220     Vector<RefPtr<SecurityOrigin> > origins;
       
   221     DatabaseTracker::tracker().origins(origins);
       
   222         COMPtr<COMEnumVariant<Vector<RefPtr<SecurityOrigin> > > > enumVariant(AdoptCOM, COMEnumVariant<Vector<RefPtr<SecurityOrigin> > >::adopt(origins));
       
   223 
       
   224     *result = enumVariant.releaseRef();
       
   225     return S_OK;
       
   226 }
       
   227     
       
   228 HRESULT STDMETHODCALLTYPE WebDatabaseManager::databasesWithOrigin( 
       
   229     /* [in] */ IWebSecurityOrigin* origin,
       
   230     /* [retval][out] */ IEnumVARIANT** result)
       
   231 {
       
   232     if (!origin || !result)
       
   233         return E_POINTER;
       
   234 
       
   235     *result = 0;
       
   236 
       
   237     if (this != s_sharedWebDatabaseManager)
       
   238         return E_FAIL;
       
   239 
       
   240     COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
       
   241     if (!webSecurityOrigin)
       
   242         return E_FAIL;
       
   243 
       
   244     Vector<String> databaseNames;
       
   245     DatabaseTracker::tracker().databaseNamesForOrigin(webSecurityOrigin->securityOrigin(), databaseNames);
       
   246 
       
   247     COMPtr<COMEnumVariant<Vector<String> > > enumVariant(AdoptCOM, COMEnumVariant<Vector<String> >::adopt(databaseNames));
       
   248 
       
   249     *result = enumVariant.releaseRef();
       
   250     return S_OK;
       
   251 }
       
   252 
       
   253 HRESULT STDMETHODCALLTYPE WebDatabaseManager::detailsForDatabase( 
       
   254     /* [in] */ BSTR databaseName,
       
   255     /* [in] */ IWebSecurityOrigin* origin,
       
   256     /* [retval][out] */ IPropertyBag** result)
       
   257 {
       
   258     if (!origin || !result)
       
   259         return E_POINTER;
       
   260 
       
   261     *result = 0;
       
   262 
       
   263     if (this != s_sharedWebDatabaseManager)
       
   264         return E_FAIL;
       
   265 
       
   266     COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
       
   267     if (!webSecurityOrigin)
       
   268         return E_FAIL;
       
   269 
       
   270     DatabaseDetails details = DatabaseTracker::tracker().detailsForNameAndOrigin(String(databaseName, SysStringLen(databaseName)),
       
   271         webSecurityOrigin->securityOrigin());
       
   272 
       
   273     if (details.name().isNull())
       
   274         return E_INVALIDARG;
       
   275 
       
   276     *result = DatabaseDetailsPropertyBag::createInstance(details);
       
   277     return S_OK;
       
   278 }
       
   279     
       
   280 HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteAllDatabases()
       
   281 {
       
   282     if (this != s_sharedWebDatabaseManager)
       
   283         return E_FAIL;
       
   284 
       
   285     DatabaseTracker::tracker().deleteAllDatabases();
       
   286 
       
   287     return S_OK;
       
   288 }
       
   289 
       
   290 HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteOrigin( 
       
   291     /* [in] */ IWebSecurityOrigin* origin)
       
   292 {
       
   293     if (!origin)
       
   294         return E_POINTER;
       
   295 
       
   296     if (this != s_sharedWebDatabaseManager)
       
   297         return E_FAIL;
       
   298 
       
   299     COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
       
   300     if (!webSecurityOrigin)
       
   301         return E_FAIL;
       
   302 
       
   303     DatabaseTracker::tracker().deleteOrigin(webSecurityOrigin->securityOrigin());
       
   304 
       
   305     return S_OK;
       
   306 }
       
   307     
       
   308 HRESULT STDMETHODCALLTYPE WebDatabaseManager::deleteDatabase( 
       
   309     /* [in] */ BSTR databaseName,
       
   310     /* [in] */ IWebSecurityOrigin* origin)
       
   311 {
       
   312     if (!origin)
       
   313         return E_POINTER;
       
   314 
       
   315     if (!databaseName)
       
   316         return E_INVALIDARG;
       
   317 
       
   318     if (this != s_sharedWebDatabaseManager)
       
   319         return E_FAIL;
       
   320 
       
   321     COMPtr<WebSecurityOrigin> webSecurityOrigin(Query, origin);
       
   322     if (!webSecurityOrigin)
       
   323         return E_FAIL;
       
   324 
       
   325     DatabaseTracker::tracker().deleteDatabase(webSecurityOrigin->securityOrigin(), String(databaseName, SysStringLen(databaseName)));
       
   326 
       
   327     return S_OK;
       
   328 }
       
   329 
       
   330 void WebDatabaseManager::dispatchDidModifyOrigin(SecurityOrigin* origin)
       
   331 {
       
   332     static BSTR databaseDidModifyOriginName = SysAllocString(WebDatabaseDidModifyOriginNotification);
       
   333     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
       
   334 
       
   335     COMPtr<WebSecurityOrigin> securityOrigin(AdoptCOM, WebSecurityOrigin::createInstance(origin));
       
   336     notifyCenter->postNotificationName(databaseDidModifyOriginName, securityOrigin.get(), 0);
       
   337 }
       
   338 
       
   339 HRESULT STDMETHODCALLTYPE WebDatabaseManager::setQuota(
       
   340     /* [in] */ BSTR origin,
       
   341     /* [in] */ unsigned long long quota)
       
   342 {
       
   343     if (!origin)
       
   344         return E_POINTER;
       
   345 
       
   346     if (this != s_sharedWebDatabaseManager)
       
   347         return E_FAIL;
       
   348 
       
   349     DatabaseTracker::tracker().setQuota(SecurityOrigin::createFromString(origin).get(), quota);
       
   350 
       
   351     return S_OK;
       
   352 }
       
   353 
       
   354 void WebDatabaseManager::dispatchDidModifyDatabase(SecurityOrigin* origin, const String& databaseName)
       
   355 {
       
   356     static BSTR databaseDidModifyOriginName = SysAllocString(WebDatabaseDidModifyDatabaseNotification);
       
   357     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
       
   358 
       
   359     COMPtr<WebSecurityOrigin> securityOrigin(AdoptCOM, WebSecurityOrigin::createInstance(origin));
       
   360 
       
   361     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
       
   362 
       
   363     static CFStringRef databaseNameKey = MarshallingHelpers::LPCOLESTRToCFStringRef(WebDatabaseNameKey);
       
   364     RetainPtr<CFStringRef> str(AdoptCF, databaseName.createCFString());
       
   365     CFDictionarySetValue(userInfo.get(), databaseNameKey, str.get());
       
   366 
       
   367     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
       
   368     userInfoBag->setDictionary(userInfo.get());
       
   369 
       
   370     notifyCenter->postNotificationName(databaseDidModifyOriginName, securityOrigin.get(), userInfoBag.get());
       
   371 }
       
   372 
       
   373 void WebKitInitializeWebDatabasesIfNecessary()
       
   374 {
       
   375     static bool initialized = false;
       
   376     if (initialized)
       
   377         return;
       
   378 
       
   379     WebCore::String databasesDirectory = WebCore::pathByAppendingComponent(WebCore::localUserSpecificStorageDirectory(), "Databases");
       
   380     WebCore::DatabaseTracker::initializeTracker(databasesDirectory);
       
   381 
       
   382     initialized = true;
       
   383 }
       
   384 
       
   385 #endif