2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2011 Google, Inc. All Rights Reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "DatabaseContext.h"
31 #if ENABLE(SQL_DATABASE)
34 #include "ChromeClient.h"
36 #include "DatabaseTask.h"
37 #include "DatabaseThread.h"
38 #include "DatabaseTracker.h"
41 #include "SchemeRegistry.h"
42 #include "SecurityOrigin.h"
47 static DatabaseContext* existingDatabaseContextFrom(ScriptExecutionContext* context)
49 return static_cast<DatabaseContext*>(Supplement<ScriptExecutionContext>::from(context, "DatabaseContext"));
52 DatabaseContext::DatabaseContext(ScriptExecutionContext* context)
53 : m_scriptExecutionContext(context)
54 , m_hasOpenDatabases(false)
58 DatabaseContext::~DatabaseContext()
60 if (m_databaseThread) {
61 ASSERT(m_databaseThread->terminationRequested());
66 DatabaseContext* DatabaseContext::from(ScriptExecutionContext* context)
68 DatabaseContext* supplement = existingDatabaseContextFrom(context);
70 supplement = new DatabaseContext(context);
71 provideTo(context, "DatabaseContext", adoptPtr(supplement));
72 ASSERT(supplement == existingDatabaseContextFrom(context));
77 DatabaseThread* DatabaseContext::databaseThread()
79 if (!m_databaseThread && !m_hasOpenDatabases) {
80 // Create the database thread on first request - but not if at least one database was already opened,
81 // because in that case we already had a database thread and terminated it and should not create another.
82 m_databaseThread = DatabaseThread::create();
83 if (!m_databaseThread->start())
87 return m_databaseThread.get();
90 bool DatabaseContext::hasOpenDatabases(ScriptExecutionContext* context)
92 // We don't use DatabaseContext::from because we don't want to cause
93 // DatabaseContext to be allocated if we don't have one already.
94 DatabaseContext* databaseContext = existingDatabaseContextFrom(context);
97 return databaseContext->m_hasOpenDatabases;
100 void DatabaseContext::stopDatabases(ScriptExecutionContext* context, DatabaseTaskSynchronizer* cleanupSync)
102 // We don't use DatabaseContext::from because we don't want to cause
103 // DatabaseContext to be allocated if we don't have one already.
104 DatabaseContext* databaseContext = existingDatabaseContextFrom(context);
106 if (databaseContext && databaseContext->m_databaseThread)
107 databaseContext->m_databaseThread->requestTermination(cleanupSync);
108 else if (cleanupSync)
109 cleanupSync->taskCompleted();
112 bool DatabaseContext::allowDatabaseAccess() const
114 if (m_scriptExecutionContext->isDocument()) {
115 Document* document = static_cast<Document*>(m_scriptExecutionContext);
116 if (!document->page() || (document->page()->settings()->privateBrowsingEnabled() && !SchemeRegistry::allowsDatabaseAccessInPrivateBrowsing(document->securityOrigin()->protocol())))
120 ASSERT(m_scriptExecutionContext->isWorkerContext());
121 // allowDatabaseAccess is not yet implemented for workers.
125 void DatabaseContext::databaseExceededQuota(const String& name)
127 if (m_scriptExecutionContext->isDocument()) {
128 Document* document = static_cast<Document*>(m_scriptExecutionContext);
129 if (Page* page = document->page())
130 page->chrome()->client()->exceededDatabaseQuota(document->frame(), name);
133 ASSERT(m_scriptExecutionContext->isWorkerContext());
134 #if !PLATFORM(CHROMIUM)
135 // FIXME: This needs a real implementation; this is a temporary solution for testing.
136 const unsigned long long defaultQuota = 5 * 1024 * 1024;
137 DatabaseTracker::tracker().setQuota(m_scriptExecutionContext->securityOrigin(), defaultQuota);
141 } // namespace WebCore
143 #endif // ENABLE(SQL_DATABASE)